Bug 15134 – std.parallelism taskPool.amap fails to compile with array of structs or Tuples with named members
Status
RESOLVED
Resolution
INVALID
Severity
blocker
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2015-10-01T18:32:00Z
Last change time
2015-10-01T19:31:19Z
Assigned to
nobody
Creator
jayn
Comments
Comment #0 by jayn — 2015-10-01T18:32:48Z
This code result in the compile error. Commenting out the taskPool.amap line builds ok. Similar error for Tuples with named members substituted for the struct definitions of TR, TI, TO. Some analysis was done by Ali Cehreli in this thread, which also has the Tuple implementation:
http://forum.dlang.org/post/[email protected]
import std.algorithm, std.parallelism, std.range;
import std.typecons;
import std.meta;
import std.stdio;
// define some input measurement sample tuples and output metric tuples
struct TR { long raw;}
struct TI {long L1I_MISS; long L1D_MISS; }
struct TO { TR L1_MISS; }
// various metric definitions
// using Tuples with defined names for each member, and use the names here in the metrics.
TR met_l1_miss ( ref TI m){ TR rv; rv.raw = m.L1I_MISS+m.L1D_MISS; return rv; }
// a convenience to use all the metrics above as a list
alias Metrics = AliasSeq!(met_l1_miss);
void main(string[] argv)
{
auto samples = iota(100);
auto meas = new TI[samples.length];
auto results = new TO[samples.length];
// Initialize some values for the measured samples
foreach(i, ref m; meas){
m.L1D_MISS= 100+i; m.L1I_MISS=100-i;
}
ref TI getTerm(int i)
{
return meas[i];
}
// compute the metric results for the above measured sample values in parallel
taskPool.amap!(Metrics)(std.algorithm.map!getTerm(samples),results);
TR rv1 = met_l1_miss( meas[1]);
writeln("measurements:", meas[1]);
writeln("rv1:", rv1);
writeln("results:", results[1]);
}
Severity Code Description Project File Line
Error Error: static assert "Wrong buffer type." C:\D\dmd2\src\phobos\std\parallelism.d 1668
Error instantiated from here: amap!(MapResult!(getTerm, Result), TO[]) d:\visd\dmapbug\dmapbug\main.d 35
Comment #1 by jayn — 2015-10-01T19:24:07Z
This may be my problem. I see this works with array of struct as inputs and a Tuple as result with named members. So this is not a blocker. I'll need to check if there was some other problem with the original example which had named Tuple members and array of Tuple as the input.
import std.algorithm, std.parallelism, std.range;
import std.typecons;
import std.meta;
import std.stdio;
// define some input measurement sample tuples and output metric tuples
struct TI {long L1I_MISS; long L1D_MISS; long cycles; }
alias TO = Tuple!(long, "raw", double, "per_cyc");
// various metric definitions
// using Tuples with defined names for each member, and use the names here in the metrics.
TO met_l1_miss ( ref TI m){ TO rv; rv.raw = m.L1I_MISS+m.L1D_MISS; rv.per_cyc = cast(double)rv.raw/m.cycles; return rv; }
// a convenience to use all the metrics above as a list
alias Metrics = AliasSeq!(met_l1_miss);
void main(string[] argv)
{
auto samples = iota(100);
auto meas = new TI[samples.length];
auto results = new TO[samples.length];
// Initialize some values for the measured samples
foreach(i, ref m; meas){
m.L1D_MISS= 100+i; m.L1I_MISS=100-i; m.cycles= 10+i;
}
ref TI getTerm(int i)
{
return meas[i];
}
// compute the metric results for the above measured sample values in parallel
taskPool.amap!(Metrics)(std.algorithm.map!getTerm(samples),results);
TO rv1 = met_l1_miss( meas[1]);
writeln("measurements:", meas[1]);
writeln("rv1:", rv1);
writeln("results:", results[1]);
}
Comment #2 by jayn — 2015-10-01T19:29:24Z
Must have been my bug. Inputs with named Tuple members also works. I'm going to close this.
import std.algorithm, std.parallelism, std.range;
import std.typecons;
import std.meta;
import std.stdio;
// define some input measurement sample tuples and output metric tuples
alias TI = Tuple!(long, "L1I_MISS",long, "L1D_MISS", long, "cycles" );
alias TO = Tuple!(long, "raw", double, "per_cyc");
// various metric definitions
// using Tuples with defined names for each member, and use the names here in the metrics.
TO met_l1_miss ( ref TI m){ TO rv; rv.raw = m.L1I_MISS+m.L1D_MISS; rv.per_cyc = cast(double)rv.raw/m.cycles; return rv; }
// a convenience to use all the metrics above as a list
alias Metrics = AliasSeq!(met_l1_miss);
void main(string[] argv)
{
auto samples = iota(100);
auto meas = new TI[samples.length];
auto results = new TO[samples.length];
// Initialize some values for the measured samples
foreach(i, ref m; meas){
m.L1D_MISS= 100+i; m.L1I_MISS=100-i; m.cycles= 10+i;
}
ref TI getTerm(int i)
{
return meas[i];
}
// compute the metric results for the above measured sample values in parallel
taskPool.amap!(Metrics)(std.algorithm.map!getTerm(samples),results);
TO rv1 = met_l1_miss( meas[1]);
writeln("measurements:", meas[1]);
writeln("rv1:", rv1);
writeln("results:", results[1]);
}