-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shape<D> and StrideShape<D> should be merged #367
Comments
Note that Shape and StrideShape are different in this way:
I will look closer at this later -- but merging them means either adding or removing features. |
Refreshing my memory: We allow custom strides (StrideShape) when the user provides the elements for us (Array::from_shape_vec). Consider the question: How does Array::from_elem work with a Stride Shape. How do we handle "holes" in the storage, assuming we have a non-Copy element type (that must have its destructor run correctly for each element when the array drops)? |
I think the what While |
That's the simple part. See the question about custom strides in particular arrays that don't cover all elements in the base storage. |
I think it seems good to force from_elem and zeros constructors to always make contiguous arrays. We can still improve the interface. |
We can simply raise error that the given fn from_elem<Sh: IntoShape<D>>(shape: Sh, elem: A) -> Result<Self, NonContiguousStrideError> {
if shape.is_custom() {
Err(NonContiguousStrideError::new())
}
... (current implementation)
} My concern is that the interface about shape is very complicated, e.g. there are |
Sorry that I don't have so much time for this question during the week. I share your concern for the complexity of the API here, and it's a concern I keep in mind with ndarray all the time. We can do so much with the type system, but we need find solutions that don't make the library too hard to understand or use. We have to find a balance, and you can find traces of this balance conversation all over the issues in this repo! I will not lose this issue and I would want to discuss many other solutions than the proposed one, for example other ways of unifying the shape API or better documentation. But first let's try to finish the Array::zeros(Equivalently The current shape API for
Ok, so far so good. A bit of infidelity there, a panic case, but it's supposedly in an uncommon case. It's pretty hard to run into. Positive points:
I think this question answers itself:
|
I understand that you want to assure the contiguous memory layout by a type system using Then, my concern changes: Does
No problem, it is not a hurried issue. I thank your conscientious comments a lot. |
Sure, StrideShape includes the shapes + strides that Shape can describe. I've been wondering if we can make the API more clear without changing how this actually works. Maybe by for example using a more specific trait than something as indirect as the current |
My original concern is After discussion in this thread, I understood the roles of My plan is here:
For example, these three shape API is better in a following case:
In current API, fn some_func<A, S: Data<Elem=A>, D: Dimension>(x: &ArrayBase<S, D>) -> Array<A, D> {
let mut a = Array::zeros(x.shape());
// modify a ...
a
} In this case fn some_func<A, S: Data<Elem=A>, D: Dimension>(x: &ArrayBase<S, D>) -> Array<A, D> {
let mut a = Array::zeros(x.shape_as_cont());
// modify a ...
a
} the stride is explicitly dropped with |
OK, so the naming of methods dim and shape seem to be part of the problem. |
Add raw_dim to the mix, if you also take these into account, what's the best solution? |
Can we remove |
Deref can not do custom conversions like that. In general it can only give references to interior fields, there is no tuple inside an ix2. |
I'll try to propose something later today. |
Sure, you are correct. A remaining issue is the type of stride as discussed in #283 trait Dimension {
type Strd: Stride<Dim = Self>;
// current impl
}
trait Stride {
type Dim: Dimension<Strd = Self>;
// and other common methods
}
type Ixs2 = Dim<[Ixs; 2]>; // or define Strd<I> instead of Dim
impl Stride for Ixs2 {
type Dim = Ix2;
...
} Then we can implement |
Let's leave the strongly typed strides out of this if we can, so that we have a problem small enough to solve. |
I simply haven't had time to come back to this yet. |
I got confused by My naming suggestions for |
I am confusing around
Shape<D>
,StrideShape<D>
,Dim
, and&[Ix]
. In my understanding, these can be grouped as follow:Shape<D>
StrideShape<D>
Dim
&[Ix]
And each of types in a group should be merged. I think
StrideShape<D>
andDim
are enough.Since
ArrayBase<S, D>
already hasstride: D
,StrideShape<D>
is appropriate, and it should be re-namedShape<D>
instead. Associated to this,ShapeBuilder
should be also simplified to generateStrideShape<D>
(and renamed toIntoShape
similar toIntoDimension
).What do you think?
If you agree, I will create PR :)
Thanks!
The text was updated successfully, but these errors were encountered: