Consider the following set of Fortran module files:

(These files are actually part of the ParaMonte library). These modules depend on each other:

  • Math_mod uses Constants_mod and String_mod,
  • String_mod uses Constants_mod and JaggedArray_mod,
  • JaggedArray_mod uses Constants_mod,

Problem Part 1: calling the String_mod as a DLL

Fortran

Write a main Fortran program that uses the String_mod compiled as an external DLL library file named string. The program calls the replaceStr() function in String_mod to replace "FORTRAN" with "Fortran" in the following sentence,

sentence = "FORTRAN is a highly flexible expressive natively-parallel programming language for numerical computing."

such that the output of the main program is the following,

mainCallString.exe
Fortran, not FORTRAN, is a highly flexible expressive natively-parallel programming language for numerical computing.

Solution Part 1: calling the String_mod as a DLL

Fortran

Here is an implementation of this Fortran main program,

program mainCallString

    use, intrinsic :: iso_fortran_env, only: output_unit
    use String_mod, only: replaceStr
    implicit none
    character(:), allocatable :: sentence, sentenceModified

    sentence = "FORTRAN is a highly flexible expressive natively-parallel programming language for numerical computing."
    sentenceModified = replaceStr(string = sentence, search = "FORTRAN", substitute = "Fortran, not FORTRAN,") 

    write(output_unit,"(A)") sentenceModified

end program mainCallString

and here is a Windows Batch script to compile and link and generate the executable for this program

:: silence cmd output
@echo off

setlocal EnableDelayedExpansion

REM del *.mod *.obj *.pdb *.ilk *.smod *.lib

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: set up the compiler flags
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

REM compiler flags to generate code in debug mode
REM SET OPTIMIZATION_FLAGS=/debug:full /CB /Od /standard-semantics /Qinit:snan /Qdiag-error-limit:10 /debug-parameters:all /warn:all,nounused /warn:interfaces /traceback /check:all /check:stack /libs:dll /threads /dbglibs

REM compiler flags to generate fast code
SET OPTIMIZATION_FLAGS=/O3 /Qipo /fpe:0 /standard-semantics

REM define the preprocessor flag to include the Intel specific directives to export the procedure names
set FPP_FLAGS=/fpp /define:DLL_ENABLED

REM DLL library flags
set LIB_FLAGS=/libs:dll /threads

echo.
echo. -- Build Script -         optimization flags: OPTIMIZATION_FLAGS=!OPTIMIZATION_FLAGS!
echo. -- Build Script - Fortran preprocessor flags:          FPP_FLAGS=!FPP_FLAGS!
echo. -- Build Script -      Fortran library flags:          LIB_FLAGS=!LIB_FLAGS!
echo.

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: generate executable that uses the String module
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

REM generate the string dynamic (DLL) library

ifort /dll !LIB_FLAGS! !OPTIMIZATION_FLAGS! !FPP_FLAGS! Constants_mod.f90 JaggedArray_mod.f90 String_mod.f90 /exe:string

REM it is essential to pass the same compiler and library flags as the ones used for compiling the DLL

ifort !LIB_FLAGS! !OPTIMIZATION_FLAGS! mainCallString.f90 string.lib /exe:mainCallString.exe

Running this Batch script file on the Windows Intel command prompt, will create an executable named mainCallString.exe which can be called to print the requested message,

mainCallString.bat
 -- Build Script -         optimization flags: OPTIMIZATION_FLAGS=/O3 /Qipo /fpe:0 /standard-semantics
 -- Build Script - Fortran preprocessor flags:          FPP_FLAGS=/fpp /define:DLL_ENABLED
 -- Build Script -      Fortran library flags:          LIB_FLAGS=/libs:dll /threads

Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.4.245 Build 20190417
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.24.28314.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:string.dll
-dll
-implib:string.lib
C:\Users\shahmoradia\AppData\Local\Temp\ipo_3816428.obj
   Creating library string.lib and object string.exp
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.4.245 Build 20190417
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.24.28314.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:mainCallString.exe
-subsystem:console
C:\Users\shahmoradia\AppData\Local\Temp\ipo_1472013.obj
string.lib
mainCallString.exe
Fortran, not FORTRAN, is a highly flexible expressive natively-parallel programming language for numerical computing.

Problem Part 2: calling the Matho_mod DLL which depends on String_mod DLL

Fortran

Now, write a main Fortran program which calls the getDistanceSq() function of Math_mod from the math DLL (that you will have to build). Note that this Math_mod will depend on the string DLL file from the previous problem in the above.

Solution Part 2: calling the Matho_mod DLL which depends on String_mod DLL

Fortran

Here is an implementation of this Fortran main program,

program mainCallMath

    use, intrinsic :: iso_fortran_env, only: output_unit, IK => int32, RK => real64
    use Math_mod, only: getDistanceSq
    implicit none
    integer(IK) :: ndim, i
    real(RK), allocatable :: point1(:), point2(:)
    real(RK) :: distanceSq

    ndim = 3_IK
    point1 = [ (0_IK, i = 1, ndim)]
    point2 = [ (i, i = 1, ndim)]

    ! call Math module from the math DLL library 

    distanceSq = getDistanceSq  ( nd = ndim &
                                , point1 = point1 &
                                , point2 = point2 &
                                )

end program mainCallMath

and here is a Windows Batch script to compile and link and generate the executable for this program

:: silence cmd output
@echo off

setlocal EnableDelayedExpansion

REM del *.mod *.obj *.pdb *.ilk *.smod *.lib

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: set up the compiler flags
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

REM compiler flags to generate code in debug mode
REM SET OPTIMIZATION_FLAGS=/debug:full /CB /Od /standard-semantics /Qinit:snan /Qdiag-error-limit:10 /debug-parameters:all /warn:all,nounused /warn:interfaces /traceback /check:all /check:stack /libs:dll /threads /dbglibs

REM compiler flags to generate fast code
SET OPTIMIZATION_FLAGS=/O3 /Qipo /fpe:0 /standard-semantics

REM define the preprocessor flag to include the Intel specific directives to export the procedure names
set FPP_FLAGS=/fpp /define:DLL_ENABLED

REM DLL library flags
set LIB_FLAGS=/libs:dll /threads

echo.
echo. -- Build Script -         optimization flags: OPTIMIZATION_FLAGS=!OPTIMIZATION_FLAGS!
echo. -- Build Script - Fortran preprocessor flags:          FPP_FLAGS=!FPP_FLAGS!
echo. -- Build Script -      Fortran library flags:          LIB_FLAGS=!LIB_FLAGS!
echo.

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: generate executable that uses the Math module, which uses the String module
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

REM generate the math dynamic (DLL) library

ifort /dll !LIB_FLAGS! !OPTIMIZATION_FLAGS! !FPP_FLAGS! Constants_mod.f90 Math_mod.f90 string.lib /exe:math

REM it is essential to pass the same compiler and library flags as the ones used for compiling the DLL

ifort !LIB_FLAGS! !OPTIMIZATION_FLAGS! mainCallMath.f90 math.lib /exe:mainCallMath.exe

Running this Batch script file on the Windows Intel command prompt, will create an executable named mainCallMath.exe which can be called to print the requested message,

mainCallMath.bat
 -- Build Script -         optimization flags: OPTIMIZATION_FLAGS=/O3 /Qipo /fpe:0 /standard-semantics
 -- Build Script - Fortran preprocessor flags:          FPP_FLAGS=/fpp /define:DLL_ENABLED
 -- Build Script -      Fortran library flags:          LIB_FLAGS=/libs:dll /threads

Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.4.245 Build 20190417
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.24.28314.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:math.dll
-dll
-implib:math.lib
C:\Users\shahmoradia\AppData\Local\Temp\ipo_2920424.obj
string.lib
   Creating library math.lib and object math.exp
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.4.245 Build 20190417
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.24.28314.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:mainCallMath.exe
-subsystem:console
C:\Users\shahmoradia\AppData\Local\Temp\ipo_1954413.obj
math.lib
mainCallMath.exe
The distance between the two 3-dimensional points is 14.00000000000000

Comments