C++ / Why Iterators Got It All Wrong
Ilya Yaroshenko via Digitalmars-d
digitalmars-d at puremagic.com
Sun Sep 3 02:24:03 PDT 2017
On Sunday, 3 September 2017 at 02:43:51 UTC, Moritz Maxeiner
wrote:
> On Sunday, 3 September 2017 at 02:08:20 UTC, Ilya Yaroshenko
> wrote:
>> On Tuesday, 29 August 2017 at 12:50:08 UTC, Robert M. Münch
>> wrote:
>>> Maybe of interest:
>>> https://www.think-cell.com/en/career/talks/iterators/#1
>>>
>>> I haven't read everything, so not sure if it worth to take a
>>> look.
>>
>> Iterators has no proper alternative when one need to implement
>> generic tensor library like Mir Algorithm [1].
>
> Out of curiosity: Could you elaborate on what the issues are
> with using a range based API internally (if it's performance,
> the "why")?
There are three general kinds of dynamic dense tensors. Mir
implements all of them:
1. Contiguous tensors. Their data is located contiguously in
memory. Single dense memory chunk. All strides between
subs-tensors can be computed from lengths.
2. Canonical tensors. Only data for one dimension is dense, other
dimensions has strides that can not be computed from lengths.
BLAS matrixes are canonical tensors: they have two lengths and
one stride.
3. Universal tensors. Each dimension has a stride. Numpy ndarrays
are universal tensors.
Finite random access range Issues:
1. Main API issue is that full featured random access range (RAR)
API (with slicing, and all opIndex* operators like `[]*=` ) is
much larger comparing with unbounded random access iterator (the
same API as pointer).
2. Random access range holds its length. Yes, Phobos has infinity
ranges (mir hasn't), but the practice is that almost any RAR
constructed using Phobos has length and you can not strip when
type is constructed. Anyway, infinity RAR is just a
pointer/iterator that can move forward but can not move backward.
Tensors hold their own lengths for each dimensions, so range's
length is just a useless payload.
3. Ranges can not move backward (auto b = a[-4 .. $].). This
means one can not implement dynamic `reversed`(flip) [1, 2]
operation for dimensions that have strides (universal or
canonical tensors). _Dynamic_ means that instead of construct a
new type with reversed order for a dimension, we just negate the
corresponding stride and move the cursor.
[1]
http://docs.algorithm.dlang.io/latest/mir_ndslice_dynamic.html#.reversed
[2]
https://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.flip.html
Best regards,
Ilya
More information about the Digitalmars-d
mailing list