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.

After another test, I found the key is

  1. Add the IMSL Include and Library directories to the list of directories searched. This is not project specific. Tools -> Options -> Intel Fortran -> under Project directories, click ... for Libraries and Include.
  2. add INCLUDE 'link_fnl_static.h' to your source code. This needs to be specified only once per application. There is no need to add USE Numerical_Libraries.
  3. One of the following
    • (first choice) We can include a line !DEC$ OBJCOMMENT LIB:'libiomp5md.lib' in the source code
    • Ensure that the following project properties are set to ensure correct operation with the IMSL libraries:, Fortran>Language>Process OpenMP Directives>Generate Parallel Code.

A sample test code is

!  This free-form example demonstrates how to call
!  IMSL routines from Intel Visual Fortran.
!
  PROGRAM SHOWIMSL
  INCLUDE 'link_fnl_static.h'
  USE AMACH_INT
  USE UMACH_INT
  INTEGER NOUT
  REAL RINFP
! The AMACH function and UMACH subroutine are
! declared in the AMACH_INT and UMACH_INT modules
  CALL UMACH(2,NOUT)
  RINFP = AMACH(7)
  WRITE(NOUT,*) 'REAL POSITIVE MACHINE INFINITY = ',RINFP
  END PROGRAM

Note that for some reason, the 32-bit of exe file created using this method cannot be run on another 64-bit Windows 7 (“The Application was unable to start correctly (0xc00007b). Click OK to close the Application”)??? I need to create a 64-bit of exe file in order to run it on another 64-bit Windows 7.

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.

Mix C/C++ and Fortran

My old code based on VS6 and Compaq fortran cannot be build successfully. The Cpp subroutine cannot be found in Fortran when I build the solution in IDE. The command line way works however.

cl /nologo /c /D_CRT_SECURE_NO_DEPRECATE mysvm.cpp
ifort /nologo *.f90 mysvm.obj

The 2nd line may need to run again since it requires mod 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

The default stack size is only 1MB.

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).

On Windows, we can use /Fn compile option where n is the number of bytes in the command line. For example, /F100000000.

Check an executable 32 or 64-bit

http://superuser.com/questions/358434/how-to-check-if-a-binary-is-32-or-64-bit-on-windows

Open a Visual Studio command prompt,

C:\>dumpbin /headers ClassPrediction3_5.exe
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file ClassPrediction3_5.exe

PE signature found

File Type: EXECUTABLE IMAGE

FILE HEADER VALUES
             14C machine (x86)
...

And we will get a keyword (x64) on a 64-bit executable.

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.