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

What is the maximum array rank?

Arm_N_
Beginner
5,533 Views

Hi,

I ran the program on intel visual fortran compiler,using Fortran 2003, and got this error message:

error #6204: There are too many dimensions; the maximum rank is 7.

I remembered that in the user manual the inter visual fortran compiler can handle up to the maximum rank of 15.

Could anyone please suggest this? I appreciate all answers.  Thank you very much.

0 Kudos
22 Replies
Mark_Lewy
Valued Contributor I
4,950 Views

A maximum rank of 15 is new in Fortran 2008.  The Intel Fortran Compiler has this as a feature in v15.0 (XE 2015) and claims support for up to 31 dimensions.  What version are you using, as I can't remember exactly when this got added, but it claims to have available in 13.0 update 1 (XE 2013), according to the help?

0 Kudos
andrew_4619
Honored Contributor III
4,950 Views

Fortran 90 was a limit of 7 , fortran 2008 is a limit of 15. Current Ifort supports 15 (and I think more) are you running an old version?

0 Kudos
Lorri_M_Intel
Employee
4,950 Views
If you're compiling with /stand:f03, even with a recent compiler, we give a warning for rank > 7. --Lorri
0 Kudos
mecej4
Honored Contributor III
4,950 Views

I heard from somebody that seven subscripts should be more than enough for most purposes, since the number of generalized coordinates (in mechanics) is 3 (position) + 3 (velocity) + 1 (time) = 7. The most recent Intel Fortran allows 31, but we probably have to wait for a few years before we can do something useful with arrays of such large dimensions. A "small" array of integer or real type with 31 dimensions, each of range 1:2,  would take 233 bytes. The following program runs with Intel Fortran 15.0.

program tst
implicit none
integer, parameter :: d1=1,d2=2,d3=1,d4=2,d5=1,d6=2,d7=1,d8=2,d9=1,da=2, &
                      f1=1,f2=2,f3=1,f4=2,f5=1,f6=2,f7=1,f8=2,f9=1,fa=2, &
					  g1=1,g2=2,g3=1,g4=2,g5=1,g6=2,g7=1,g8=2,g9=1,ga=2, &
					  ha=1
integer(kind=1) :: array31(d1,d2,d3,d4,d5,d6,d7,d8,d9,da, &
                           f1,f2,f3,f4,f5,f6,f7,f8,f9,fa, &
                           g1,g2,g3,g4,g5,g6,g7,g8,g9,ga, ha)
array31 = 0_1
array31(1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2, &
        1,2,1,2,1,2,1,2,1,2,1) = 127_1
write(*,*)array31
end program

 

0 Kudos
Steven_L_Intel1
Employee
4,950 Views

You didn't say which compiler version you used. We raised the maximum rank from 7 to 31 in version 12 (Fortran 2008 specifies 15.) Lorri is correct that if you ask for standards checking, you get a warning, but not with the text you cited. So all I can guess is that you are using a VERY old compiler version.

0 Kudos
JVanB
Valued Contributor II
4,950 Views
program P
   use ISO_FORTRAN_ENV
   implicit none
   type T
   end type T
   type(T) A(2,2,2,2,2,2,2,2,2,2, &
             2,2,2,2,2,2,2,2,2,2, &
             2,2,2,2,2,2,2,2,2,2, &
!             2, & ! This would cause failure
             2)
   type U
      type(T) M(2,2,2,2,2,2,2,2,2,2, &
                2,2,2,2,2,2,2,2,2,2)
   end type U
   type(U) B(2,2,2,2,2,2,2,2,2,2, &
             2,2,2,2,2,2,2,2,2,2)
   A = T()
   write(*,*) size(A,kind=INT64)
   B = U(T())
   write(*,*) size(B,kind=INT64)*size( &
      B(1,1,1,1,1,1,1,1,1,1, &
        1,1,1,1,1,1,1,1,1,1)%M, &
      kind=INT64)
end program P

 

maxrank.obj: catastrophic error: Variable P$B.0.1 too large for NTCOFF.  Bigger
than 2GB.  Use heap instead
compilation aborted for maxrank.f90 (code 1)

 

0 Kudos
Steven_L_Intel1
Employee
4,950 Views

Well, that's another story.... You can declare such a thing allocatable and allocate it on an 64-bit system.

0 Kudos
Arm_N_
Beginner
4,950 Views

Sorry for insufficient information.  I think here is the version you are asking about (as in the attached)

 

Intel(R) Visual Fortran Compiler Integration for Microsoft Visual Studio* 2008, 11.1.3471.2008, Copyright (C) 2002-2010 Intel Corporation
Microsoft Visual Studio 2008 Version 9.0.21022.8.RTM

On the help page it said "Intel® Visual Fortran Compiler Professional Edition 11.1"

Please clarify whether this can support more than the rank of 7.  I apologize in advance if this information may be insufficient again.  

 

 

 

0 Kudos
andrew_4619
Honored Contributor III
4,950 Views

As Steve said in post #6 "We raised the maximum rank from 7 to 31 in version 12 " you have version 11 so rank 7 it is. 11 is pretty old by the way.

0 Kudos
JVanB
Valued Contributor II
4,950 Views

The thing is, I don't understand the error message I got in Quote #7. How come 0 > 2 GB?

 

0 Kudos
Arm_N_
Beginner
4,950 Views

Thanks a lot for all answers!  I think I need to buy a newer version.

0 Kudos
Arjen_Markus
Honored Contributor II
4,950 Views

Repeat Offender, this is probably a wrap-around of the integer: the actual value does not fit into the default integer type and then the higher bits are chopped off. SInce the number is a power of 2, chopping of those higher bits means you are left with a trail of zero bits.

0 Kudos
JVanB
Valued Contributor II
4,950 Views

No.

 

0 Kudos
mecej4
Honored Contributor III
4,950 Views

I think that Repeat Offender's point is that type T contains no components, so an array of type T, no matter how large the dimensions declared, ought to occupy zero bytes. Likewise, any derived type that ultimately is a collection of component of type T (and nothing else) should occupy zero bytes. Correct, R.O.?

0 Kudos
Arjen_Markus
Honored Contributor II
4,950 Views

Ah, missed that. The program below shows that such types indeed occupy zero bytes:

! zerosize.f90 --
!     How large are zero-sized types really?
!
program zerosize
    implicit none

    integer :: sz
    character(len=1), dimension(1) :: char

    type zero
        ! Nothing
    end type zero

    type zero_container
        type(zero) :: something
    end type zero_container

    type(zero)                :: scalar
    type(zero), dimension(10) :: array
    type(zero_container)      :: container

    write(*,*) 'Via iolength:'
    inquire( iolength=sz) scalar
    write(*,*) 'Scalar:    ', sz
    inquire( iolength=sz) array
    write(*,*) 'Array:     ', sz
    inquire( iolength=sz) container
    write(*,*) 'Container: ', sz

    write(*,*) 'Via transfer():'
    write(*,*) 'Scalar:    ', size(transfer(scalar,char))
    write(*,*) 'Array:     ', size(transfer(array,char))
    write(*,*) 'Container: ', size(transfer(container,char))

end program zerosize


Result:

 Via iolength:
 Scalar:               0
 Array:                0
 Container:            0
 Via transfer():
 Scalar:               0
 Array:                0
 Container:            0

 

 

0 Kudos
andrew_4619
Honored Contributor III
4,950 Views

I think RO's zero size entity has >2GB elements so I suspect the compiler assumes these have a size in its checks.

Is in not all pretty  hypothetical?

0 Kudos
jimdempseyatthecove
Honored Contributor III
4,950 Views

RE: zero size

While the data portion may be zero sized, (depending on program statements and compiler options) arrays may require array descriptors.

type(zero), dimension(:), allocatable :: array
...
allocate(array(10))
...

The size(array) would indicate 0 but the RAM requirements is that of the array descriptor.

*** Note, I do not know if the above allocate would succeed or fail. If it worked properly, the array descriptor would indicate 10 elements in a rank 1 array with size of 0.

Jim Dempsey

0 Kudos
mecej4
Honored Contributor III
4,950 Views

Does the value returned by the intrinsic function size() include the space overhead for descriptors? My guess is 'no', but I don't know if the Fortran standard says so or otherwise. I doubt that the space consumed by descriptors is affected by the size of the array rather than by just the complexity of the object that the descriptor is associated with.

0 Kudos
Arjen_Markus
Honored Contributor II
4,950 Views

No, size() counts the number of array elements. Adding the overhead for descriptors would be rather awkward, if only because they are an implementation detail. And it would make size() rather useless for such things as:

allocate( a(2*size(b) )

 

0 Kudos
Steven_L_Intel1
Employee
4,587 Views

I should have noticed in RO's code that the type was zero-sized. The descriptor does not get included in the computations and is separate from the data. In the case of the error RO saw, my assumption is that this part of the compiler computed that the number of elements exceeded 2**31 and figured it could not be represented in static memory, which is true on Windows (even 64-bit). That the type is zero-sized is an amusing exception but I am not inclined to suggest a check be added for that.

If you have a derived type containing a deferred-shape array, sizeof() will give you a size that includes the descriptor(s). C_SIZEOF from ISO_C_BINDING will also do this, but in the current version this is not supported in constant expressions.

0 Kudos
Reply