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

allocating array that needs integer*8 index

McBane__George
Beginner
559 Views

I am following up on an old forum topic at 

https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/271074?language=en-us&https=1

I would like to use one allocatable array that is longer than 2**31 elements in my program, where the default INTEGER size is 4 bytes.  The advice in that earlier post was

------------------

It is advisable to create an index parameter

INTEGER, PARAMETER :: BigArrayIndex = 8 ! place in some module

ChangeBigArrayIndexto whatever you want.

Then

SUBROUTINE YourSubroutine(N,...)
USE ModuleContainingBigArrayIndex
INTEGER(KIND=BigArrayIndex),INTENT(IN)::N
INTEGER(KIND=BigArrayIndex) :: I, J ...
...
DO I=1,N
...
BigArray(I) = expression

----------------------------------

That makes sense to me.  But how do I declare BigArray to start with?  And, if I need BigArray to be allocatable, so I would like to do

double precision, allocatable :: BigArray(:)

....

allocate(BigArray(N))

how do I tell the compiler that BigArray needs to be addressed with an 8-byte index? It seems to me that either the declaration or the ALLOCATE statement needs to contain that information.

Thanks,

George.

 

 

0 Kudos
1 Reply
FortranFan
Honored Contributor II
559 Views

McBane, George wrote:

..

how do I tell the compiler that BigArray needs to be addressed with an 8-byte index? It seems to me that either the declaration or the ALLOCATE statement needs to contain that information.

George,

The data kind of an array is independent of its shape (and the total number of elements).  So you can have an integer array, say of 16-bit kind (with typically a decimal exponent range of 10), of N elements where N is a large number that is limited only by the capabilities of your processor - hardware, OS, Fortran compiler, etc. Similarly you can have a floating-point array of the so-called single or double or quadruple precision of lengths greater than supported by the default integer per Intel Fortran (max 2**31).  In Fortran, you would just declare the kind of your array 'data' separately from their shapes.  Find a silly example below.

   use, intrinsic :: iso_fortran_env, only : I8 => int64

   implicit none

   ! Employ named constants of the same kind for array sizes and element processing
   integer(kind=I8), parameter :: ONE = 1_i8
   integer(kind=I8), parameter :: TWO = 2_i8
   integer(kind=I8), parameter :: NUM_ELEMS = TWO**32 ! Arbitrary size
   integer(kind=I8) :: I

   integer, allocatable :: big_array(:) ! Array itself can be a regular integer or any other kind

   allocate( big_array(NUM_ELEMS) )
   big_array(ONE:TWO**31) = 0 ; big_array(TWO**31+ONE:NUM_ELEMS) = 42
   i = TWO**31 + TWO
   print *, "i = ", i
   print *, "big_array(i) = ", big_array(i), "; expected is 42"

end

Upon execution,

 i =  2147483650
 big_array(i) =  42 ; expected is 42

As suggested in the above code snippet, use defined kinds for array bounds/sizes and indices to process the array elements.  See this Dr Fortran blog: https://software.intel.com/en-us/blogs/2017/03/27/doctor-fortran-in-it-takes-all-kinds

0 Kudos
Reply