Thursday, April 19, 2012

Exploring FORTRAN DLL

Environment Intel Fortran 11.1

1. How to create a FORTRAN DLL in visual studio with INTEL FORTRAN compiler:

http://sukhbinder.wordpress.com/2011/04/14/how-to-create-fortran-dll-in-visual-studio-with-intel-fortran-compiler/

Simple to follow, worked.

2. How to call FORTRAN DLL in visual studio with INTEL FORTRAN compiler:
http://www.eng-tips.com/viewthread.cfm?qid=117348


Another method:
http://www.tek-tips.com/viewthread.cfm?qid=1572697

Calling DLL from C#
http://software.intel.com/en-us/articles/calling-fortran-function-or-subroutine-in-dll-from-c-code/

Parallel Programming 101 - Fortran OpenMP for dummies

These content are obtained from the internet, I only extracted the most useful information and tested them.  I do not claim any authorship.

1. Compiler Settings
Compaq Visual Fortran compiler does not support parallel programming feature.
If you are using Intel Visual Fortran to compile your parallel code, you have to do the following in order to have it run correctly:
Right click on project
Choose properties -> Fortran -> Preprocesor -> OpenMP->Conditional Compilation -> Yes
Choose properties -> Fortran -> Language -> Process->OpenMP Directives -> Generate Parallell Code(/Qopenmp)

(- I have to do these in my intel fortran compiler to compile! Also it is best to use free format Fortran)


2. To convert a serial code into a parallel code, you will need to use OpenMP directives
Basic format of OpenMP directives:
A typical OpenMP directive looks like this (Fortran is not case-sensitive):
!$OMP PARALLEL DO
OpenMP directives must start with a sentinel !$OMP
!$OMP can appear in any column, but must be preceded by white space only
Continuation lines must have an ampersand as the last non-blank character in a line.
!$OMP PARALLEL PRIVATE(TID)can be written as
!$OMP PARALLEL &
!$OMP PRIVATE (TID)
(Although directives start with an ! sign, it is not a comment, as in Fortran)


3. Parallel Region Construct
Parallel region: a block of code that will be executed by multiple threads.
When a thread reaches a parallel region, it creates a team of threads. The code within the parallel region is duplicated and all threads will execute the code.
The format of the parallel construct is
!$OMP PARALLEL
[Code Block]
!$OMP END PARALLEL

Example Code 1

PROGRAM Hello
!$OMP PARALLEL
print*, 'Hello World!'
!$OMP END PARALLEL
END PROGRAM

If the above example is running on a duo core computer, then
the output will be:
Hello World!
Hello World!

(but this is not useful at all so far, as we do not want to repeat the same task on all threads)

Here is my first OpenMP program, it runs, but when I wanted to loop through the threads, error occurred. So I went to study a bit more. Note that you need to include omp_lib.h in this program. This has not touched so far.
  
!----------------------------
program ompHelloWorld
#ifdef _OPENMP
   include 'omp_lib.h'  !needed for OMP_GET_NUM_THREADS()
#endif

integer TID

!$omp parallel    
   TID = OMP_GET_THREAD_NUM()
   PRINT *, 'Hello World from thread = ', TID  
!$omp end parallel
continue
end program ompHelloWorld
!--------------------

Increasing the complexity
!--------------------
 program ompHelloWorld

#ifdef _OPENMP
   include 'omp_lib.h'  !needed for OMP_GET_NUM_THREADS()
#endif

integer nthr
integer NTHREADS, TID

TID=-999
NTHREADS=-999

!$omp parallel  
  
   TID = OMP_GET_THREAD_NUM()
   PRINT *, 'Hello World from thread = ', TID

   IF (TID .EQ. 0) THEN
       NTHREADS = OMP_GET_NUM_THREADS()
       PRINT *, 'Master computer report:'
       PRINT *, 'Number of threads = ', NTHREADS
   ELSE
       PRINT *, 'Slave computer report:'
       PRINT *, 'I am on vacation.'
   END IF     
!$omp end parallel

continue

end program ompHelloWorld
!--------------------

(Note that there is an issue with using F10 to step through the code or using F5 to debug the code. It appears that F10 stepping results are not correct. Also, inserting breakpoints into the code seems to cause issue too. I have to visit this issue!!!)

4. Work-Sharing Construct
A work-sharing construct does not create new threads. It divides the execution of the enclosed code among the existing threads.
Three types of work-sharing construct
  1. DO directive:
  2. SECTIONS directive
  3. SINGLE directive
A work-sharing construct assumes a parallel region has already been initiated, otherwise it executes in serial on a single processor.
(Now it is getting interesting!)

4.1 SINGLE Directive
The SINGLE directive speci…es that the enclosed code is to be executed by only one thread in the team.
Useful when dealing with sections of code that are not thread safe (such as I/O)
Example
!$OMP PARALLEL
    !$OMP SINGLE

    !$OMP END SINGLE
!$OMP END PARALLEL


4.2 DO directives
The DO directive specifi…es that the iterations of the loop immediately following it must be executed in parallel by the team.
The format of the DO directive is
!$OMP DO
[Code Block]
!$OMP END DO
Example Code
!$OMP PARALLEL
   !$OMP DO
   DO i = 1,n
      z(i) = a*x(i) + y
   END DO
   !$OMP END DO
!$OMP END PARALLEL

For convenience, there is
PARALLEL DO
We can replace the above code with
!$OMP PARALLEL DO
DO i = 1,n
z(i) = a*x(i) + y
END DO
Note that PARALLEL DO does not need an END PARALLEL DO.



4.3 SECTION directives
The SECTIONS directive divides the enclosed sections of code among the existing threads.
The format of the SECTIONS directive is
!$OMP SECTIONS
   !$OMP SECTION
     [Code Block 1]
   !$OMP SECTION
     [Code Block 2]
   !$OMP SECTION
     [Code Block 3]
!$OMP END SECTIONS
Example Code
!$OMP PARALLEL SHARED(A,B,C,D), PRIVATE(I)
   !$OMP SECTIONS
   !$OMP SECTION
     DO I = 1, N
        C(I) = A(I) + B(I)
     ENDDO
   !$OMP SECTION
     DO I = 1, N
        D(I) = A(I) * B(I)
     ENDDO
   !$OMP END SECTIONS
!$OMP END PARALLEL

For convenience, there is
PARALLEL SECTIONS
We can replace the above code with
!$OMP PARALLEL SECTIONS
!$OMP SECTION
[Code Block 1]
!$OMP SECTION
[Code Block 2]
!$OMP END PARALLEL SECTIONS

With the above work-share construct, I can construct some simple yet useful program.
----------------------------------------------------------------------------
Trouble 1: 
When I compile the program and sent my executable to a lab computer with 8 cores to run, it failed with an error message: 
libiomp5md.dll is missing

This is the most useful answer I found on the internet

Even when static libraries are selected, the OpenMP library is linked dynamically - this can be overridden by adding /Qopenmp-link:static under Fortran > Command Line > Additional Options.

OMP libary
!$omp parallel num_threads(3)   !use three threads for this program


Directives for Sychronization



CRITICAL contains the codes that will be executed in serial, no longer parallel, this is to avoid data comfliction


!$OMP CRITICAL
...
!$OMP END CRITICAL 

Example (I did not test this, probably should)
! Look for the largest element in an array
currentMax = -1.E10
!$OMP PARALLEL DO
    DO i = 1, n
        IF( a(i) < currentMax) THEN
           !$OMP CRITICAL
           
              IF( a(i) < currentMax) THEN 
                 currentMax = a(i)
            ENDIF
           !$OMP END CRITICAL 
        END IF
END DO

!$OMP END PARALLEL DO


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

I am running out of time for another project. This will be put on hold.

References:

  • A comprehensive Book:

http://www.amazon.com/Parallel-Programming-OpenMP-Rohit-Chandra/dp/1558606718#reader_1558606718

  • A simple to follow yet in-depth ppt (in C)

http://openmp.org/mp-documents/omp-hands-on-SC08.pdf

  • Useful table summaries of directives

http://www.cita.utoronto.ca/MISC/computing_guide/docs/Intel_Fortran_v8.1/f_ug2/index.htm#par_dirs.htm

http://www.cita.utoronto.ca/MISC/computing_guide/docs/Intel_Fortran_v8.1/f_ug2/par_dirs.htm

  • OpenMP training workshop of Llnl

https://computing.llnl.gov/tutorials/openMP/#RunTimeLibrary

https://computing.llnl.gov/tutorials/openMP/exercise.html

https://computing.llnl.gov/?set=training&page=index#training_materials

https://computing.llnl.gov/tutorials/openMP/exercise.html

Tuesday, April 17, 2012

Map a program modules

dependency walker
http://www.dependencywalker.com/