Formal Review of std.range.ndslice

Ilya Yaroshenko via Digitalmars-d digitalmars-d at puremagic.com
Sun Dec 13 14:32:43 PST 2015


On Sunday, 13 December 2015 at 21:24:36 UTC, Stefan Frijters 
wrote:
> On Sunday, 13 December 2015 at 15:59:19 UTC, Ilya Yaroshenko 
> wrote:
>> Could you please post reduced code example that caused dmd to 
>> segfault?
>
> Took dustmite about 6 hours to reduce, and then I went at it 
> manually for a bit, so this is the smallest I could get it:
>
> import std.experimental.ndslice;
>
> int main() {
>   Field force;
>   foreach(p, e; force) e;
> }
>
> struct Field {
>   alias arr this;
>   Slice!(3, double*) arr;
> }
>
> Compiled with dmd 2.069.1 via dub build:
>
> {
>     "name": "dlbc",
>     "sourcePaths": ["src"],
>     "dependencies": {
>         "dip80-ndslice": "~>0.8.3",
>     },
> }

More reduced code:

import std.experimental.ndslice;

void main() {
	Slice!(3, double*) force = new double[60].sliced(3, 4, 5);

	// Correct code. Compiles!
	for(auto r = force.byElement; !r.empty; r.popFront)
	{
		size_t[3] p = r.index;
		double e = r.front;
	}

	// Wrong foreach params. dmd failed with exit code -11.
	//foreach(p, e; force)
	//{
	//}
}

dub.json
{
     "name": "dlbc",
     "dependencies": {
         "dip80-ndslice": "~>0.8.3",
     },
}

> dip80-ndslice 0.8.3: target for configuration "library" is up 
> to date.
> dlbc ~master: building configuration "application"...
> Segmentation fault
> dmd failed with exit code 139.
>
> Since it's a segfault in the compiler, should I put it on 
> Bugzilla too?

Yes
1. Please note in Bugzilla report that program code is incorrect 
(see example of correct above).
2. More reduced code can be used for report:

void main() {
	Slice!(3, double*) force = new double[60].sliced(3, 4, 5);
	// Wrong foreach params. dmd failed with exit code -11.
	foreach(p, e; force)
	{
	}
}

>> 2D way: &slice[0, 0]   or   &(slice.front.front());
>>
>> ND way: &(slice.byElement.front())
>>
>> Note: Comparing with unstandard  there is no guarantee that 
>> the first element in a ndarray is the first element in memory. 
>> `reversed` and `allReversed` should not be used to preserve 
>> strides positive.
>
> Hm, I assumed the underlying array would be a single block of 
> data and then a bunch of pointers would be used to keep track 
> of any slices. I'll try to figure out how to give the data to C 
> then (for MPI and HDF5, to be exact).

Probably you may need something like that:

auto ar = new double[60]; //remember ar
auto slice = ar.sliced(3, 4, 5);

However, if you have not changed slice's structure (except 
transposition), then

assert (ar == 
(&(slice.byElement.front()))[0..slice.elementsCount]);

Ilya


More information about the Digitalmars-d mailing list