Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28446 Discussions

Coarray type with an allocatable component of length zero

Laasner__Raul
Beginner
455 Views

I get a SIGSEGV when running the following code

[fortran]

 type t
  real, allocatable :: a(:)
 end type t
 type(t) :: data


  •  allocate(data%a(0))
     print*, size(data[1]%a)
    end program
  • [/fortran]

    If, instead of the last line I put

    [fortran]

    print*, size(data%a)

    [/fortran]

    it runs successfully by printing 0 for each image. In principle I could work out the problem by using 'allocated' statements, but

    [fortran]

    allocated(data[1]%a)

    [/fortran]

    produces

    [plain]

    The argument to the ALLOCATED intrinsic cannot be a coindexed object.

    [/plain]

    On the other hand, using 'allocated(data%a)' correctly prints T for each image, but I specifically need to use the square brackets with either 'size' or 'allocated' in my code.

    Thanks

    0 Kudos
    7 Replies
    Yuan_C_Intel
    Employee
    455 Views

    Hi, Raul

    I have checked your problem and reproduced it.

    Do you really need to allocate with length zero? If I modify to length 1, there is no error for size(data[1]%a).

    Seems the zero size allocated array cannot be accessed by other image, but only by local image, since there is no actual memory associated it.

    I checked the Fortran 2008 standard and cannot find a specific rule for zero length allocation, so I want to understand whether your usage is reasonable and if compiler should support this.

    Thank you

    Yolanda

    0 Kudos
    Laasner__Raul
    Beginner
    455 Views

    Generally it would not be a problem, but it can happen that I have less data points than the number of cpus. The code tries to distribute the input data equally over all images but then some images will get no data. The problem arises at the end of my program, where the first image gathers the results from all images and writes to a file (one resulting number per input data point). I agree that creating a zero length array is suspicious. Instead, I could simply leave it deallocated. But what does the standard say about statements such as 'allocated(data[1]%a)', which also fails?

    In the end it's not a major issue and I have already written a workaround. Still, I would like to keep the code as clean as possible.

    0 Kudos
    Yuan_C_Intel
    Employee
    455 Views

    Hi Raul

    Thank you for the explaining.

    I have confirmed that the standard does support zero length allocated array. I'm going to enter it in our problem tracking system. I will let you know when I have an update on this issue.

    For allocated itrinsics, the standard does not require the argument to be an indexed object. Supported arguments are an allocatable array or scalar.

    Thanks,

    0 Kudos
    reinhold-bader
    New Contributor II
    455 Views

    Hello,

    some comments:

    1. Your code is not conforming in that you need to insert a synchronization statement (SYNC ALL) after the ALLOCATE statement. Otherwise there will be a race condition, because the SIZE query on a different image may execute before image 1 allocates the object (to whatever size). Unfortunately even with the additional statement the crash persists, so I agree that there is a bug in the compiler, because zero size is permitted for arrays.
    2. Using the ALLOCATED intrinsic on a coindexed object is indeed not possible. The standard says that the argument of ALLOCATED must be allocatable, but remote allocation is not supported in the language.

    Regards

    Reinhold

    0 Kudos
    Laasner__Raul
    Beginner
    455 Views

    Thank you for the comments.

    In my actual code I believe all the necessary sync alls are present so that does not seem to be a problem. Also, if I use an auxiliary variable like this

    [fortran]

      type t
         real, allocatable :: a(:)
      end type t
     
      type(t) :: data

  • , tmp
      allocate(data%a(0))
      tmp = data[1]
      print*, size(tmp%a)
  • end program

    [/fortran]

    then it works but now it fails with any nonzero length array.

    0 Kudos
    Yuan_C_Intel
    Employee
    455 Views

    Hi, Raul

    This has been fixed in Intel(R) Parallel Studio XE Composer Edition for Fortran Linux* 2015.

    'allocated(data[1]%a)' statement should work as well.

    However I will still get an MPI error for getting size(data[1]%a) :

    $ ifort -coarray=shared test.f90
    $ ./a.out
    Internal ICAF error: The indirect put/get memory address is out of range for the mpi window.
    application called MPI_Abort(comm=0x84000000, 3) - process 2

    Thank you.

     

     

    0 Kudos
    Laasner__Raul
    Beginner
    455 Views

    With ifort 15.0.1 I still get an error with all three cases: using allocated(data[1]%a), size(data[1]%a), and using an auxiliary variable. Perhaps in some newer version this behavior will be changed.

    0 Kudos
    Reply