Hi,
I'm also interested in an array of arrays, so tried the following
code. The only difference is that the dimension is now [1..3][1..2],
and the result is essentially the same as Damian's (i.e.,
'slice' != 'normal'). I'm using chapel-1.16 on Mac OSX10.11.
// print utility routine
proc show( a, msg )
{
writeln( "------------------------------" );
writeln( "[ ", msg, " ]" );
writeln( a[1][1], ' ', a[1][2] );
writeln( a[2][1], ' ', a[2][2] );
writeln( a[3][1], ' ', a[3][2] );
writeln();
writeln( "a = ", a );
writeln( "a.domain = ", a.domain );
writeln( "a[1].domain = ", a[1].domain );
writeln( "a[2].domain = ", a[2].domain );
writeln( "a[3].domain = ", a[3].domain );
writeln( "a[1..3] = ", a[1..3] );
writeln( "a[1..3][1] = ", a[1..3][1] );
writeln( "a[1..3][2] = ", a[1..3][2] );
}
proc main()
{
// An array of arrays.
var a: [1..3][1..2] real;
var r = 1..3;
// var r = 1..2;
// var r = 2..3; // halt reached - array index out of bounds: (1)
writeln( "r = ", r );
a[r][1] = -3.0;
a[r][2] = 3.0;
show( a, 'slice' );
[i in 1..3] a[i][1] = -3.0;
[i in 1..3] a[i][2] = 3.0;
show( a, 'normal' );
}
The result with r = 1..3:
r = 1..3
------------------------------
[ slice ]
-3.0 -3.0
3.0 3.0
0.0 0.0
a = -3.0 -3.0 3.0 3.0 0.0 0.0
a.domain = {1..3}
a[1].domain = {1..2}
a[2].domain = {1..2}
a[3].domain = {1..2}
a[1..3] = -3.0 -3.0 3.0 3.0 0.0 0.0
a[1..3][1] = -3.0 -3.0
a[1..3][2] = 3.0 3.0
------------------------------
[ normal ]
-3.0 3.0
-3.0 3.0
-3.0 3.0
a = -3.0 3.0 -3.0 3.0 -3.0 3.0
a.domain = {1..3}
a[1].domain = {1..2}
a[2].domain = {1..2}
a[3].domain = {1..2}
a[1..3] = -3.0 3.0 -3.0 3.0 -3.0 3.0
a[1..3][1] = -3.0 3.0
a[1..3][2] = -3.0 3.0
If I change "r" to 1..2, I get the same result as r = 1..3
for some reason. If I change "r" to 2..3, it results
in a run-time error (the same as Damian's another e-mail).
halt reached - array index out of bounds: (1)
Please note also that "writeln( a[1..3][1] )" prints
only two elements for some reason...
# Is this potentially related to some internal
handling of "jagged" arrays? (if sub-arrays are allocated
non-contiguously on memory, unlike ordinary 2-dim arrays)
https://stackoverflow.com/questions/45090779/chapel-array-of-arrays-vs-2-dim-array-on-memory
---
The similar problem also exists in Fortran (an array of array), but
in this case, the Fortran standard seems to be prohibiting such slicing.
For example, the slicing of a 2-dim (rectangular) array works as expected
(of course),
integer :: a( 3, 3 )
a( 1:3, 1 ) = -3.0
but this is not allowed for an array of allocatable arrays
a( 1:3 ) % b( 1 ) = -3.0 !! compiler error
where b(:) is an allocatable array in a user-defined type
e.g., created by
type A_t
integer, allocatable :: b(:)
endtype
type( A_t ), allocatable :: a(:)
allocate( a( 3 ) )
do i = 1, 3
allocate( a( i ) % b( 3 ) )
enddo
I guess this is prohibited because the location
of b(1) are scattered on memory and cannot be accessed
with uniform stride by a simple expression
(such as offset + i * some stride).
But I'm not sure if this is related to the case of
"var a: [1..3][1..2] int" in Chapel...
Best regards,
Takeshi
2018-03-18 13:02 GMT+09:00 Damian McGuckin <[email protected]>:
>
> Looking at the simple code:
>
> proc main
> {
> var a : [1..3][1..3] real;
> var r = 1..3;
>
> a[r][1] = -3.0;
> a[r][2] = 3.0;
> a[r][3] = 3.0;
> writeln('sliced');
> writeln(a[1][1], ' ', a[1][2], ' ', a[1][3]);
> writeln(a[2][1], ' ', a[2][2], ' ', a[2][3]);
> writeln(a[3][1], ' ', a[3][2], ' ', a[3][3]);
>
> [i in 1..3] a[i][1] = -3.0;
> [i in 1..3] a[i][2] = 3.0;
> [i in 1..3] a[i][3] = 3.0;
> writeln('normal');
> writeln(a[1][1], ' ', a[1][2], ' ', a[1][3]);
> writeln(a[2][1], ' ', a[2][2], ' ', a[2][3]);
> writeln(a[3][1], ' ', a[3][2], ' ', a[3][3]);
> }
>
> produces:
>
> sliced
> -3.0 -3.0 -3.0
> 3.0 3.0 3.0
> 3.0 3.0 3.0
> normal
> -3.0 3.0 3.0
> -3.0 3.0 3.0
> -3.0 3.0 3.0
>
> Am I missing something here. Should not the results should agree.
>
> I use array of arrays to be consistent with my own old C++ code. Also, as
> Chapel does not seem to allow initialization of a multi-dimensional array,
> I avoid them. I raised a related issue in April 2015 in case you want to
> cross-reference anything.
>
> Note that the Fortran
>
> a(1:3,1) = -3.0
> a(1:3,2) = 3.0
> a(1:3,3) = 3.0
> or even
> a(2:3,1) = -3.0
>
> has worked correctly in various non-standard/standard Fortran compilers
> for at least 38 years.
>
> The alternative Chapel
>
> proc main
> {
> var a : [1..3, 1..3] real;
> var r = 1..3;
>
> a[r, 1] = -3.0;
> a[r, 2] = 3.0;
> a[r, 3] = 3.0;
> writeln('sliced');
> writeln(a[1, 1], ' ', a[1, 2], ' ', a[1, 3]);
> writeln(a[2, 1], ' ', a[2, 2], ' ', a[2, 3]);
> writeln(a[3, 1], ' ', a[3, 2], ' ', a[3, 3]);
>
> [i in 1..3] a[i, 1] = -3.0;
> [i in 1..3] a[i, 2] = 3.0;
> [i in 1..3] a[i, 3] = 3.0;
> writeln('normal');
> writeln(a[1, 1], ' ', a[1, 2], ' ', a[1, 3]);
> writeln(a[2, 1], ' ', a[2, 2], ' ', a[2, 3]);
> writeln(a[3, 1], ' ', a[3, 2], ' ', a[3, 3]);
> }
>
> Produces consistent results.
>
> Back in April 2015, I was struggling with multi-dimensional arrays and how
> to assign then at declaration time (which I do not think was possible at
> that time and still is not I believe).
>
> I think you said multidimensional arrays were going to be more consistent
> at the time. My examples prove that 3 years later, your advice is still
> wise.
>
> But I still cannot initialize my multidimensional array easily.
>
> And even my workaround appears broken in some sense of the word.
>
> The sliced example (of anything less than a full column or row) works too!
>
> proc main
> {
> var a : [1..3, 1..3] real;
> var r = 1..3;
>
> a[r, 1] = -3.0;
> a[r, 2] = 3.0;
> a[r, 3] = 3.0;
> writeln('sliced');
> writeln(a[1, 1], ' ', a[1, 2], ' ', a[1, 3]);
> writeln(a[2, 1], ' ', a[2, 2], ' ', a[2, 3]);
> writeln(a[3, 1], ' ', a[3, 2], ' ', a[3, 3]);
>
> [i in 1..3] a[i, 1] = -3.0;
> [i in 1..3] a[i, 2] = 3.0;
> [i in 1..3] a[i, 3] = 3.0;
> writeln('normal');
> writeln(a[1, 1], ' ', a[1, 2], ' ', a[1, 3]);
> writeln(a[2, 1], ' ', a[2, 2], ' ', a[2, 3]);
> writeln(a[3, 1], ' ', a[3, 2], ' ', a[3, 3]);
>
> a[1, 1] = -3.0;
> a[2..3, 1] = -3.0; // <---------- SUB-SLICE
> a[1..3, 2] = 3.0;
> a[1..3, 3] = 3.0;
> writeln('sub-sliced');
> writeln(a[1, 1], ' ', a[1, 2], ' ', a[1, 3]);
> writeln(a[2, 1], ' ', a[2, 2], ' ', a[2, 3]);
> writeln(a[3, 1], ' ', a[3, 2], ' ', a[3, 3]);
> }
>
> It works as expected. If instead of a multidimensional array, you use an
> array of arrays, the sub-slicing, i.e. slicing anything other than a full
> column or row, fails.
>
> Regards - Damian
>
> Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
> Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted
> here
> Views & opinions here are mine and not those of any past or present
> employer
>
> ------------------------------------------------------------
> ------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> _______________________________________________
> Chapel-developers mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/chapel-developers
>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Chapel-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-developers