Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!

CoArray bug.

jimdempseyatthecove
Black Belt
193 Views

The following program exhibits a compiler bug in CoArrays

!  BugCAF.f90 
module foo
    integer, parameter :: NS=500, NA=1024
    complex(8), allocatable :: InputA(:,:,:)[:]     ! (NS,NS,NA)    only Image 1 will allocate
    integer,    allocatable :: OutputM(:)[:]        ! (NA)          only Image 1 will allocate
    complex(8), allocatable :: OutputZ(:,:,:)[:]    ! (NS,NS,NA)    only Image 1 will allocate
    integer,    allocatable :: OutputISUPPZ(:,:)[:] ! (NS,NA)       only Image 1 will allocate
    
    contains
    
subroutine AllocateData()
	    allocate(InputA(NS,NS,NA)[*])
        allocate(OutputM(NA)[*])
        allocate(OutputZ(NS,NS,NA)[*])
        allocate(OutputISUPPZ(NS,NA)[*])
end subroutine AllocateData

subroutine DeallocateData()
	    deallocate(InputA)
        deallocate(OutputM)
        deallocate(OutputZ)
        deallocate(OutputISUPPZ)
end subroutine DeallocateData

    end module foo

subroutine showBug()
    use foo
    implicit none
  
    real(8), allocatable :: work(:)
    complex(8), allocatable :: tempA(:,:)

    integer, allocatable :: localISUPPZ(:)
    complex(8), allocatable :: localZ(:,:)
    integer :: I,M
    
    allocate(work(NS),tempA(NS,NS)) ! local storage
    allocate(localISUPPZ(NS),localZ(NS,NS))
    
    do I = THIS_IMAGE(), NA, NUM_IMAGES()
        tempA(:,:) = InputA(:,:,I)[1]   ! load from image 1
        localISUPPZ(:) = OutputISUBZ(:,I)[1] ! ***** this works to read an integer coarray
!        call HEEVR(tempA,work,Z=localZ,ISUPPZ=localISUPPZ,IL=1,IU=10,M=M)
        OutputZ(:,:,I)[1] = localZ(:,:)
        OutputM(I)[1] = M
        OutputISUBZ(:,I)[1] = localISUPPZ(:) ! ***** error #6911: The syntax of this substring is invalid. [OUTPUTISUBZ]
    end do
    
    deallocate(work,tempA) ! local storage
    deallocate(localISUPPZ,localZ)
end subroutine showBug
    
program BugCAF
    use foo
    implicit none
    call AllocateData()
    call ShowBug()
    call DeallocateData()
end program BugCAF

 When reading an integer array coarray no problem
When writing to an integer array coarray problem

Jim Dempsey

0 Kudos
5 Replies
jimdempseyatthecove
Black Belt
188 Views

Note, if I change the type of OutputISUPPZ from integer to real, the compiler has no complaints.

Jim Dempsey

FortranFan
Honored Contributor II
179 Views

Jim,

It looks like you've have typographical errors: 'OUTPUTISUPPZ' vs 'OUTPUTISUBZ'.

The compiler is remiss in giving you misleading error messages.

If you've support, perhaps you can file a request at OSC for better description of the error in the messages? 

FortranFan
Honored Contributor II
178 Views

Separately it's unclear what you're trying in this code.  The reproducer, while not illustrative of any algorithm or a scheme, also appears non-conforming e.g., reading an object before it's defined.

Anyways, you may want to look further into the fork-join model with standard Fortran coarrays and consider how to set up data, then 'sync' followed by parallel operations consuming data, and 'sync' before clean up.  Did you intend something like this?

    ..
    if ( this_image() == 1 ) call AllocateData()
    sync all ! or a sync variant thereof?
    call ShowBug()
    sync all ! or a sync variant thereof?
    if ( this_image() == 1 ) call DeallocateData()
    ..

 

jimdempseyatthecove
Black Belt
174 Views

Yes, my error, I just found this too.

With IMPLICIT NONE, the compiler should have issued a different error message.

Thanks for taking (wasting) your time on this.

Jim

jimdempseyatthecove
Black Belt
172 Views

The omission of THIS_IMAGE occurred as a process of making a reproducer. The actual code is like this:

subroutine DeallocateTestData()
    implicit none
    
!dir$ if defined(UseCoarray)
    if(THIS_IMAGE() == 1) then
	    deallocate(InputA)
        deallocate(OutputM)
        deallocate(OutputZ)
        deallocate(OutputISUPPZ)
    endif
!dir$ elseif defined(UseMPI)
    if(rank == 0) then
	    deallocate(InputA)
        deallocate(OutputM)
        deallocate(OutputZ)
        deallocate(OutputISUPPZ)
    endif
!dir$ else
	deallocate(InputA)
    deallocate(OutputM)
    deallocate(OutputZ)
    deallocate(OutputISUPPZ)
!dir$ endif
end subroutine DeallocateTestData
...
    
!dir$ if defined(UseCoarray)
    if(THIS_IMAGE() == 1) then
	    allocate(InputA(NS,NS,NA)[*])
        allocate(OutputM(NA)[*])
        allocate(OutputZ(NS,NS,NA)[*])
        allocate(OutputISUPPZ(NS,NA)[*])
!dir$ elseif defined(UseMPI)
    if(rank == 0) then
	    allocate(InputA(NS,NS,NA))
        allocate(OutputM(NA))
        allocate(OutputZ(NS,NS,NA))
        allocate(OutputISUPPZ(NS,NA))
!dir$ else
	allocate(InputA(NS,NS,NA))
    allocate(OutputM(NA))
    allocate(OutputZ(NS,NS,NA))
    allocate(OutputISUPPZ(NS,NA))
!dir$ endif
  ... populate test data by...
      main thread or
      coarray image 1 or
      mpi image 0
   ...
!dir$ if defined(UseCoarray)
    endif
    SYNC ALL
!dir$ elseif defined(UseMPI)
    endif
    SYNC ALL
!dir$ endif

 

This is from a benchmark program that I am writing to explore

sequential + MKL sequential
sequential + MKL threaded
OpenMP + MKL sequential
OpenMP + MKL threaded
CAF + MKL sequential
CAF + MKL threaded
MPI + MKL sequential
MPI + MKL threaded
CAF + OpenMP + MKL sequential
CAF + OpenMP + MKL threaded
MPI + OpenMP + MKL sequential
MPI + OpenMP + MKL threaded

I've got it working prior to CAF and MPI.

I will post it on the forum when it is done.

Jim

Reply