Fortran

From 太極
Jump to navigation Jump to search

Visual Studio

Solution and Project files

If I create a helloWorld (Fortran) project, the project folder has the following structure

helloWorld |-- helloWorld  | -- Release  -- helloWorld.exe
           |               |
           |               | -- x64      |-- Release    -- helloWorld.exe
           |               |
           |               | helloWorld.u2d (binary)
           |               | helloWorld.vfproj (text in xml)
           |               | main.f90
           |
           |-- helloWorld.sln (text)
           |-- helloWorld.suo (binary)            

For C/C++ project, we will see vcxproj and vcxproj.user files.

Location of source files

If we want to make the project portable, it is a good idea to put the source code under the project folder. For example, the <main.f90> file should be located under the helloWorld project folder.

The vfproj file always saves the source file in terms of relative paths. For example, for the helloWorld project, the vfproj file has a line like below to show the source code is located under the project directory:

<File RelativePath=".\main.f90"/></Filter></Files>

Likewise, if the source code is located outside the project directory, the paths in the vfproj file will have a lot of "..\". For example if the source code is saved under C:\BRBCVS\ArrayTools\Fortran\FORTRAN source\ClassComparison and the VS2010 project is located under C:\Users\$USERNAME\Documents\Visual Studio 2010\Projects\ClassComparison\Comparison.

<File RelativePath="..\..\..\..\..\..\..\BRBCVS\ArrayTools\Fortran\FORTRAN source\ClassComparison\rank.f90"/>

Windows 10

Don't install VS 2010 onto Windows 10.

Using IMSL library

The Fortran code includes

USE Numerical_Libraries

My IMSL library is installed under C:\Program Files (x86)\VNI\imsl\fnl600 directory.

Using MKL Lapack library

I have installed Visual Studio 2010 and Intel Fortran Compiler XE 12.0.

For some reason, I need to follow this instruction to make it work.

MS VS -> Project -> Properties -> Fortran -> General -> Additional Include Directories (C:\Program Files (x86)\Intel\ComposerXE-2011\mkl\include\ia32)

MS VS -> Project -> Properties -> Linker -> Input -> Additional Dependencies (mkl_lapack95.lib for w32 and mkl_lapack95_lp64.lib for x64)

I also ALREADY have set up MS VS -> Tools -> Options -> Intel Visual Fortran -> Compilers.

  • Libraries
$(IFortInstallDir)compiler\lib\ia32
$(IFortInstallDir)mkl\lib\ia32
$(VCInstallDir)atlmfc\lib
$(VCInstallDir)lib
$(WindowsSdkDir)lib
$(FrameworkSDKDir)\lib
$(FNL_DIR)\IA32\lib
  • Includes
$(IFortInstallDir)compiler\include
$(IFortInstallDir)compiler\include\ia32
$(IFortInstallDir)mkl\include\ia32
$(VCInstallDir)atlmfc\include
$(VCInstallDir)include
$(WindowsSdkDir)include
$(FrameworkSDKDir)\include
$(FNL_DIR)\IA32\include\dll

The Fortran code does NOT even need to include the following line (??)

USE MKL95_LAPACK

and in fact, including the following line will result in an error.

USE MKL95_LAPACK, only : DGESVD

The mkl\include folder contains *.mod files and mkl\lib folder include *.lib files.

Misc

source control

The .gitignore file for the visual studio project can be found on github. See this post.

Run 64bit program on 32-bit OS

It will pop up a window saying XXX.exe is not a valid Win32 application.

libiomp5md.dll is missing

Get the following message when I build a x64 executable and then run it on another PC (w/o intel compiler).

The program can't start because libiomp5md.dll is missing from your computer. 
Try reinstalling the program to fix this problem.

Stack and Heap

  • Automatic objects (eg array with variable size) are stored in stack
subroutine foo(a, b)
   real, dimension(:), intent(inout) :: a, b
   real, dimension(size(a))          :: temp
   temp = a
   a = b
   b = temp
end subroutine foo
  • Allocable arrays are stored in heap
real, dimension(:, :), allocatable :: a
allocate(a(n, 0:n+1))

Change stack size

In Compaq Visual Fortran, go to Project Settings -> Win32 Release -> Link. In the Project Options text box, add something like /stack:0x989680 (the decimal value is 10000000 or 10MB).

Timing

system_clock tells the elapsed wall time between two successive calls.

integer(kind=8):: tclock1, tclock2, clock_rate
real(kind=8):: elapse_time

call system_clock(tclock1)

<code to be timed>

call system_clock(tclock2, clock_rate)
elapse_time = float(tclock2 - tclock1) / float(clock_rate)

cpu_time tells the CPU time used between two successive calls

real(kind=8):: t1, t2, elapsed_cpu_time
call cpu_time(t1)

<code to be timed>

call cpu_time(t2)
elapsed_cpu_time = t2 - t1

Since Unix provides a timing command called time, we can compare the system time and cpu time reported by Fortran's functions and Unix's time command; e.g. time ./a.out where a.out is the executable file written by a Fortran code. See an example from the High Performance Scientific Computing (University of Washington); the web lecture and the video lecture.