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

Accessing my top 10GB RAM using Intel Fortran 11 with i7 processor

phil_ede
Beginner
1,420 Views
I need to compile a legacy program (NEC) using the Intel Fortran 11 compiler in W7x64 on an i7 processor with 12 GB RAM. I need to ensure that the system is correctly configured so the compiler will produce code correctly accessing the upper 10GB or so of RAM.

In order to overcome compiler error 7938 due to argument mismatching, I have the compiler option "Check Routine Interfaces" set to no.
I am therefore aware that I also need to ensure that I am accessing contiguous memory, but this should not be a problem as the upper 9GB is completely free.

If I configure the code to exceed about 1GB, (121,000, 000 real*8 numbers) I am getting a fatal error LNK1248: image size exceeds maximum allowable size (80000000).
Any advice on how to proceed would be appreciated.
Thanks
0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
1,420 Views
The program load image (code plus size of static data) cannot exceed 2GB (Windows) even on x64 platform. Or more precisely the linker section cannot exceed the 2GB limit. To go above this (for data)you need to use allocatable arrays (or heap arrays declared in function or subroutine. The allocatable array descriptor will need to be placed in a MODULE and the USE (module name) will have to be inserted into your 17 subroutines. You may have to insert the USE (module name) into your PROGRAM or your initialization subroutine, and in there insert an ALLOCATE to allocate the memory for your very large array.

! BigArray.f90
MODULE BigArray
REAL(8), ALLOCATABLE :: Array(:,:,:)
END MODULE BigArray

-----------------
! YourProgram.f90
PROGRAM YourProgram
USE BigArray
...
ALLOCATE(Array(123,456,789))
...
CALL YourSub()
...
DEALLOCATE(Array)
END PROGRAM YourProgram
--------------
! YourSub.f90
SUBROUTINE YourSub()
USE BigArray
...
Scalar = Array(I,J,K)
...
END SUBROUTINE YourSub

-----------

Effectively youmove the declaration of the array from COMMON to any MODULE, then access the array (or what was in common) by way of USE (module name here).

Other than for the ALLOCATE and DEALLOCATE the operation is straitforward.

Jim Dempsey

View solution in original post

0 Kudos
8 Replies
TimP
Honored Contributor III
1,420 Views
Why not post on the Windows Fortran forum, after reading more of the relevant past posts (assuming the search tool has been fixed, as claimed)?
If you're so concerned about correctness, why not fix the program instead of disabling compiler diagnostics?
The Windows Fortran, even the Intel64 one, limits addressing in static objects to 2GB. This has been discussed more thoroughly on that forum, several times. The recommended solution, if that is your problem, is to make such an array allocatable, probably using heap-arrays option.
If you are using the ia32 compiler, as you seem to imply, you will need to switch to the Intel64 compiler in order to escape the 32-bit addressing limit. You can't do "64-bit programming" when targetting 32-bit mode.
0 Kudos
phil_ede
Beginner
1,420 Views
Thank you Tim. I will most certainly do more searching. Sadly, NEC is a large program, developed over 40 years at Lawrence Livermore, and altering, testing, and verifying the code would be non-trivial.
According to the referenced link, Intel introduced extra checking partly to avoid problems with mis-matched arguments arising, as I understand it, from memory fragmentation, so firstly I need to ensure that I am writing to memory contiguously.
I downloaded the package labelled "Intel Visual Fortran for IA-32 and Intel 64 (with Microsoft Visual Studio Shell and Libraries)" which seems to bundle the 32 and 64 bit versions together.I am using Intel Fortran compiler version 11.1.065 and have the configuration manager set to x64. I am not aware of any alternative versions apart from 11.1.067 which has just been released.
Previously working in a defence environment, all large mathematical modells were developed in Windows and run on Unix which provides a full 64 bit working environment.
I accept there may be need for coding changes in order to access all the memory, but I raised the issue on this forum hopeful for advice on compiler configuration and correct management of memory and processors by Windows.
Thanks again
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,420 Views
If your code has this very large array in common then you will have to remove it (leave the old code in where it is but comment it out). Then work the array name into a module as an allocatable.

If the array is local to a subroutine, then follow Tim18's suggestion and use the compiler option for heap arrays.

If you take the module route, make sure you do not have multiple source files with this array in common as well as not using equivilence into this array.

Compile the code with the module (and commented old array declaration). This should generate a list of errors provided your code has implicit none. This error list will identify the files that need to have the USE xxx. If your code is not using implicit none then a search of the solution will be required. Bear in mind that this may generate false positives.

Good luck hunting.

Jim Dempsey
0 Kudos
phil_ede
Beginner
1,420 Views
Thanks Jim. I think I had just about understood all that, but there are over 17,000 lines of code in nearly 200 subroutines so any alterations need planning on paper first. About 17 subroutines share the very large array, but only some other smaller scalable arrays are equivalenced, so I feel confident I can first move the large array out into its own common block throughout, compile and test, then transfer it to a module. However, only 7 subroutines share the data so it should work.
I am not sure what you mean by implicit none. Is this a compiler option ?
Thanks again
Phil
0 Kudos
TimP
Honored Contributor III
1,420 Views
implicit none (sometimes spelled implicit undefined 3 decades ago) ahead of your declarations in each subroutine is the recommended replacement for the default typing, to help catch errors. As you say, most Fortrans other than Intel's have a command line option with the effect of implicit none.
Nearly every legacy code I worked on had problems such as typos with letter O and number 0 mixed up.
0 Kudos
jesmin
Beginner
1,420 Views
Thanks alot for this ultimate conversatation .. this is beneficial for me...
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,421 Views
The program load image (code plus size of static data) cannot exceed 2GB (Windows) even on x64 platform. Or more precisely the linker section cannot exceed the 2GB limit. To go above this (for data)you need to use allocatable arrays (or heap arrays declared in function or subroutine. The allocatable array descriptor will need to be placed in a MODULE and the USE (module name) will have to be inserted into your 17 subroutines. You may have to insert the USE (module name) into your PROGRAM or your initialization subroutine, and in there insert an ALLOCATE to allocate the memory for your very large array.

! BigArray.f90
MODULE BigArray
REAL(8), ALLOCATABLE :: Array(:,:,:)
END MODULE BigArray

-----------------
! YourProgram.f90
PROGRAM YourProgram
USE BigArray
...
ALLOCATE(Array(123,456,789))
...
CALL YourSub()
...
DEALLOCATE(Array)
END PROGRAM YourProgram
--------------
! YourSub.f90
SUBROUTINE YourSub()
USE BigArray
...
Scalar = Array(I,J,K)
...
END SUBROUTINE YourSub

-----------

Effectively youmove the declaration of the array from COMMON to any MODULE, then access the array (or what was in common) by way of USE (module name here).

Other than for the ALLOCATE and DEALLOCATE the operation is straitforward.

Jim Dempsey

0 Kudos
phil_ede
Beginner
1,420 Views
Thank you Jim.
0 Kudos
Reply