Derived types and PARAMETER

Hi,

I’m using a trial version of PGI Workstation 12.5, and I get some compiler errors in my code. I isolated the cause of one of them and I prepared a short code to demonstrate it. So, consider the following modules:

MODULE latt

   IMPLICIT NONE

   TYPE :: lattice
      INTEGER :: ndim, vol, dim(3)
   END TYPE lattice

   INTEGER, PARAMETER :: l1 = 8
   INTEGER, PARAMETER :: l2 = 8
   INTEGER, PARAMETER :: l3 = 8
   INTEGER, PARAMETER :: ldim(3) = [ l1,l2,l3 ]
   INTEGER, PARAMETER :: lvol    =   l1*l2*l3

   TYPE(lattice), PARAMETER :: cube = lattice(3, lvol, ldim)

END MODULE latt

MODULE lattfield

   USE latt
   IMPLICIT NONE

   INTEGER, PARAMETER :: l(3) = cube%dim

   TYPE :: field
      REAL :: site(l(1),l(2),l(3)) = 0.
   END TYPE field

END MODULE lattfield

Compiling them with “pgfortran -c”, I get the following error:

PGF90-S-0084-Illegal use of symbol site - array must have constant bounds in a derived type (test.f90: 28)
PGF90-S-0084-Illegal use of symbol site - must be a deferred shape array (test.f90: 28)
0 inform, 0 warnings, 2 severes, 0 fatal for lattfield

It’s as if the components of the derived type PARAMETER ‘cube’ are not recognized as constant values. Is this a bug of the compiler, or is it predicted in the Fortran standard? It compiles and behaves well with ifort and gfortran.

Thanks,
helvio

Hi helvio,

Is this a bug of the compiler, or is it predicted in the Fortran standard?

It looks valid to me so I’ve submitted a problem report (TPR#18852) and have asked our engineers to investigate.

A work around would be to explicitly initialise each array element:

% cat test.f90 
MODULE latt

   IMPLICIT NONE

   TYPE :: lattice
      INTEGER :: ndim, vol, dim(3)
   END TYPE lattice

   INTEGER, PARAMETER :: l1 = 8
   INTEGER, PARAMETER :: l2 = 8
   INTEGER, PARAMETER :: l3 = 8
   INTEGER, PARAMETER :: ldim(3) = [ l1,l2,l3 ]
   INTEGER, PARAMETER :: lvol    =   l1*l2*l3

   TYPE(lattice), PARAMETER :: cube = lattice(3, lvol, ldim)

END MODULE latt

MODULE lattfield

   USE latt
   IMPLICIT NONE

   INTEGER, PARAMETER :: l(3) = (/cube%dim(1),cube%dim(2),cube%dim(3)/)
!   INTEGER, PARAMETER :: l(3) = cube%dim

   TYPE :: field
      REAL :: site(l(1),l(2),l(3)) = 0.
   END TYPE field

END MODULE lattfield

% pgf90 test.f90 -c
%

Thanks,
Mat

Thanks Mat!

I forgot to try the explicit initialization of each array element in my example. It works, indeed! But in my (longer) code I still get the same error even after your suggestion (I have tried it before)…

I can’t post my code - just the dependencies that contain the code that originates the error message is nearly 8000 lines long! But I will try to isolate the problem. If I am able to create a short enough example that returns the same error message even with your suggestion, I will post it here at a later occasion.

Meanwhile, I found another problem with the compilation of an extension of this code, but it warrants an independent post.

helvio

I can’t post my code - just the dependencies that contain the code that originates the error message is nearly 8000 lines long! But I will try to isolate the problem. If I am able to create a short enough example that returns the same error message even with your suggestion, I will post it here at a later occasion.

We do appreciate your efforts and having a narrowed down example is very helpful. Though, if you are not able to narrow it down and are able to share the code, please feel free to send the entire code to PGI Customer Support (trs@pgroup.com). If it’s too big to email, we can arrange for you FTP the code.

Thanks,
Mat

I was actually able to pinpoint the problems and to create a code (even simpler than above) that exemplifies all of them.

MODULE latt

   IMPLICIT NONE

   TYPE :: lattice
      INTEGER :: dim(3)
   END TYPE lattice

   INTEGER, PARAMETER :: np(3) = 2           ! MPI Cartesian grid
   INTEGER, PARAMETER :: ldim(3) = 8         ! Lattice dimensions (full)
   INTEGER, PARAMETER :: bdim(3) = ldim/np   ! Lattice dimensions (block)

   TYPE(lattice), PARAMETER :: cube = lattice(ldim)     ! <== [1]
   !TYPE(lattice), PARAMETER :: cube = lattice(ldim/np) ! <== [2]
   !TYPE(lattice), PARAMETER :: cube = lattice(bdim)    ! <== [3]

END MODULE latt

MODULE lattfields

   USE latt
   IMPLICIT NONE

   INTEGER, PARAMETER :: l(3) = (/ cube%dim(1), cube%dim(2), cube%dim(3) /)
   !INTEGER, PARAMETER :: l(3) = cube%dim

   TYPE :: field
      REAL :: site(l(1),l(2),l(3)) = 0.
   END TYPE field

END MODULE lattfields

PROGRAM test2

   USE latt

   PRINT *, np
   PRINT *, ldim
   PRINT *, bdim

END PROGRAM test2

The code above compiles and builds successfully. It corresponds to the code in the first post modified with your suggestion. And it outputs the correct numbers, as it should:

2 2 2
8 8 8
4 4 4

However, if I use line [2] with a valid integer array division, the compilation issues the following error:

PGF90-S-0084-Illegal use of symbol site - array must have constant bounds in a derived type (test2.f90: 28)
PGF90-S-0084-Illegal use of symbol site - must be a deferred shape array (test2.f90: 28)
0 inform, 0 warnings, 2 severes, 0 fatal for lattfields

If I do the integer array division elsewhere and use line [3], then the compilation issues the following error.

PGF90-S-0000-Internal compiler error. field initializer not found 0 (test2.f90: 24)
PGF90-S-0000-Internal compiler error. field initializer not found 0 (test2.f90: 24)
PGF90-S-0000-Internal compiler error. field initializer not found 0 (test2.f90: 24)
PGF90-S-0084-Illegal use of symbol site - array must have constant bounds in a derived type (test2.f90: 28)
PGF90-S-0084-Illegal use of symbol site - must be a deferred shape array (test2.f90: 28)
0 inform, 0 warnings, 5 severes, 0 fatal for lattfields

So, even by initializing the PARAMETER array explicitly like you suggested, the problem seems to persist in other situations. It’s needless to say that it compiles well with other compilers, as it should.

Thanks,
helvio

Thanks Helvio. I have added this information to TPR#18852.

  • Mat

Hello,

This problem is corrected in the 14.1 release.

thanks,
dave