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

Reply via email to