Re: Batch operations

2016-10-11 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 11 October 2016 at 03:20:54 UTC, Stefan Koch wrote:
On Tuesday, 11 October 2016 at 03:05:12 UTC, Nicholas Wilson 
wrote:
Splitting this from the colour 
thread(https://forum.dlang.org/thread/mailman.961.1475765646.2994.digitalmar...@puremagic.com?page=1).


[...]


This will bloat like hell.
The best way would be to provide special Range-Definitions for 
those.

Such as
T[4] Front4 ()
or popFront4


It will be possible to have an overload for ranges that have 
slicing, that copies in chunks.


Re: Batch operations

2016-10-10 Thread rikki cattermole via Digitalmars-d

On 11/10/2016 4:20 PM, Stefan Koch wrote:

On Tuesday, 11 October 2016 at 03:05:12 UTC, Nicholas Wilson wrote:

Splitting this from the colour
thread(https://forum.dlang.org/thread/mailman.961.1475765646.2994.digitalmar...@puremagic.com?page=1).


[...]


This will bloat like hell.
The best way would be to provide special Range-Definitions for those.
Such as
T[4] Front4 ()
or popFront4


We would also want 2, 8 and 16 for SIMD reasons.


Re: Batch operations

2016-10-10 Thread Stefan Koch via Digitalmars-d
On Tuesday, 11 October 2016 at 03:05:12 UTC, Nicholas Wilson 
wrote:
Splitting this from the colour 
thread(https://forum.dlang.org/thread/mailman.961.1475765646.2994.digitalmar...@puremagic.com?page=1).


[...]


This will bloat like hell.
The best way would be to provide special Range-Definitions for 
those.

Such as
T[4] Front4 ()
or popFront4


Batch operations

2016-10-10 Thread Nicholas Wilson via Digitalmars-d
Splitting this from the colour 
thread(https://forum.dlang.org/thread/mailman.961.1475765646.2994.digitalmar...@puremagic.com?page=1).


So currently D does not have a way to express batch operations 
that work seamlessly with normal ranges.


Manu suggested to use the array operation syntax. I suggest 
something along the lines of the following, forwarding any 
operations to the static array.


struct InBatchesOfN(size_t N,R) if( N!=0 && isInputRange!R
 && 
hasLength!R)

{
R r;
static struct Batch
{
ElementType!(R)[N] elements;
auto get() { return elements[]; }
alias get this;
Batch opBinary(string op)(Batch rhs) 
if(hasOperator!(ElementType!(R),op))

{
Batch b;
foreach(i; iota(N)) mixin("b.elements[i] = 
elememts[i] "~op~" rhs.elements[i]");

return b;
}
//repeat for opUnary,opOpAssign,opDispatch etc...
}
Batch batch;
this(R _r)
{
// could have overloads where undefined elements == 
ElementType!(R).init

assert(_r.length % N ==0);
r = _r;
foreach( i; iota(N))
{
batch[i] = r.front;
r.popFront;
}
}
bool empty() { return r.empty; }
auto front() { return batch; }
void popFront()
{
foreach(i; iota(N))
{
batch.elements[i] = r.front;
r.popFront;
}
}
}

auto inBatchesOf(size_t N,R)(R r)
{
return InBatchesOfN(r);
}

Thoughts?