Fortran MPI using Cygwin64 - fortran

I am using Codeblock IDE to write and compile my Fortran program. Right now I want to include MPI to my GNU Fortran Compiler. After following some guides on GNU GCC Compiler, it occurs to me that I need to set up the following for MPICH2 (there are two guides about that):
(1) add mpi.lib to the linker setting
(2) add include file to the search directory
However, these setting won’t compile due to error on this line below, and saying that it has an unexpected EoF:
use mpi
So, then I tried to use Cygwin include file (with mpi.lib from MPICH2), strangely, it compiles fine, even with the:
call mpi_init (ierr)
call mpi_comm_rank (mpi_comm_world,rank,ierr)
call mpi_finalize (ierr)
However, when I tried to run the program. It won’t perform pass the:
call mpi_init (ierr)
Then I tried to manually compile the program, and it shows:
C:\Users\7931\AppData\Local\Temp\cclYnhYq.o:main.f90:(.text+0x18c): undefined reference to mpi_init_' C:\Users\7931\AppData\Local\Temp\cclYnhYq.o:main.f90:(.text+0x1fd): undefined reference to mpi_comm_rank_’
C:\Users\7931\AppData\Local\Temp\cclYnhYq.o:main.f90:(.text+0x276): undefined reference to `mpi_finalize_’
collect2.exe: error: ld returned 1 exit status
Maybe there is a setting that I have not set up yet for the MPI environment, or I need to get the Cygwin mpi.lib, which I can’t found after installing the complete MPI package from the Cygwin.
After trying many other things, I realized that, why there is no "include" folder on Cygwin64
Maybe what I need is a guide how to set up linker/search directories/path for MPI within Cygwin64 environment?
Anyone can please help me here?
Many thanks for your help
Edit: I have performed the solution from last chance. It seems there is an error during linking. Below is the command window response:
C:\Windows\system32>cd C:\Batch
C:\Batch>do_intel test
C:\Batch>rem ifort -c test.f90 /traceback /check:all /Qparallel
-I"C:\Program Files (x86)\Microsoft SDKs\MPI\Include\intel
C:\Batch>ifort -c test.f90 /Qparallel /O3 -I"C:\Program Files
(x86)\Microsoft SDKs\MPI\Include\intel Intel(R) Fortran Intel(R) 64
Compiler Classic for applications running on IA-32, Version 2021.6.0
Build 20220226_000000 Copyright (C) 1985-2022 Intel Corporation. All
rights reserved.
C:\Batch>ifort test.obj -o test.exe "C:\Program Files (x86)\Microsoft
SDKs\MPI\Lib\x64\msmpi.lib" "C:\Program Files (x86)\Microsoft
SDKs\MPI\Lib\x64\msmpifec.lib" Intel(R) Fortran Intel(R) 64 Compiler
Classic for applications running on IA-32, Version 2021.6.0 Build
20220226_000000 Copyright (C) 1985-2022 Intel Corporation. All rights
reserved.
link: unknown option -- s Try 'link --help' for more information.
C:\Batch>runmpi test.exe 2
C:\Batch>set OPT="C:\Program Files\Microsoft MPI\bin"
C:\Batch>"C:\Program Files\Microsoft MPI\bin"\mpiexec -n 2 test.exe
C:\Batch>link --help Usage: link FILE1 FILE2 or: link OPTION Call
the link function to create a link named FILE2 to an existing FILE1.
--help display this help and exit
--version output version information and exit
GNU coreutils online help: https://www.gnu.org/software/coreutils/
Report any translation bugs to https://translationproject.org/team/
Full documentation https://www.gnu.org/software/coreutils/link or
available locally via: info '(coreutils) link invocation'
C:\Batch>
Thanks for your help~

You can do the following with:
Windows 10 command line (NOT Cygwin)
Intel Fortran compiler (ifort)
Microsoft MPI
(1) Install and be able to use the Intel compiler in a Windows command window (your problem).
(2) Install Microsoft MPI by downloading it from https://www.microsoft.com/en-us/download/details.aspx?id=100593
You will need to download - and then install - both msmpisetup.exe and msmpisdk.msi
(3) You will need to compile mpi.f90 with your compiler (ifort) in the MS-MPI include directory (for which you will need administrator rights).
(i) Type "cmd" into the Windows search bar and choose (RHS) "Run as administrator". You will need to ensure that you can still run the ifort compiler in this state: one alternative is to start the command window from the options in the Windows start menu for the compiler, but make sure that you use right-click and run as administrator here.
(ii) In this Administrator command window, navigate to the MS-MPI include directory (e.g. C:\Program Files (x86)\Microsoft SDKs\MPI\Include)
and create a new subdirectory "intel".
(iii) Copy the file mpi.f90 from the include directory into the .\intel subdirectory. Also copy the file mpifptr.h from the .\x64 subdirectory into the .\intel subdirectory.
(iv) In this command window, navigate into the .\intel subdirectory and type the command "ifort -c mpi.f90". You should now have the relevant mpi module file available.
(4) Create a normal directory somewhere on your C-drive and put the following batch files and MPI/fortran source file in it:
do_intel.bat
rem ifort -c %1.f90 /traceback /check:all /Qparallel -I"C:\Program Files (x86)\Microsoft SDKs\MPI\Include\intel
ifort -c %1.f90 /Qparallel /O3 -I"C:\Program Files (x86)\Microsoft SDKs\MPI\Include\intel
ifort %1.obj -o %1.exe "C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\msmpi.lib" "C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\msmpifec.lib"
runmpi.bat
set OPT="C:\Program Files\Microsoft MPI\bin"
%OPT%\mpiexec -n %2 %1
test.f90
program main
use mpi
implicit none
integer size, rank, tag
integer stat(mpi_status_size), ierr
integer I
real R
call mpi_init( ierr )
call mpi_comm_size( mpi_comm_world, size, ierr )
call mpi_comm_rank( mpi_comm_world, rank, ierr )
write( *, * ) "Processor ", rank, " of ", size, " is alive"
tag = 0
if ( rank == 0 ) then
I = 42
R = 3.14152
call mpi_send( I, 1, mpi_integer, 1, tag, mpi_comm_world, ierr )
write( *, * ) "Processor ", rank, " sent integer ", I
call mpi_send( R, 1, mpi_real , 1, tag, mpi_comm_world, ierr )
write( *, * ) "Processor ", rank, " sent real ", R
else if ( rank == 1 ) then
call mpi_recv( I, 1, mpi_integer, 0, tag, mpi_comm_world, stat, ierr )
write( *, * ) "Processor ", rank, " received integer ", I
call mpi_recv( R, 1, mpi_real, 0, tag, mpi_comm_world, stat, ierr )
write( *, * ) "Processor ", rank, " received real ", R
end if
call mpi_finalize( ierr )
end program main
(5) Using a command window, and in the directory where do_intel.bat, runmpi.bat and test.f90 live, type
do_intel test
which should (hopefully!) compile and link the test file.
(6) If all compiled correctly then type
runmpi test.exe 2
to run the test program with two processors.
gfortran can also be made to run with Microsoft MPI, although it is harder work to get it going and I have found it "unreliable".
The following command is needed to compile the mpi.f90 file (assumed to be in a .\gfortran subdirector of the MS-MPI include directory):
gfortran -c -fallow-invalid-boz -fno-range-check mpi.f90
and the following batch file can compile and link the test file:
rem gfortran -c %1.f90 -Wall -Wextra -I"C:\Program Files (x86)\Microsoft SDKs\MPI\Include\gfortran" -fallow-argument-mismatch -ff2c
gfortran -c %1.f90 -O3 -I"C:\Program Files (x86)\Microsoft SDKs\MPI\Include\gfortran" -fallow-argument-mismatch -ff2c
gfortran -o %1.exe %1.o "C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\msmpi.lib" "C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\msmpifec.lib"
For many of my more complex processes, gfortran with MS-MPI works OK for a small number of processors and then either hangs or crashes with more; I have been unable to find out why, as the problem works fine with the intel compiler.

Related

I get "gcc.exe: fatal error: cannot execute 'cc1plus'" when I try to compile a program in C++ in Windows

I get the error "gcc.exe: fatal error: cannot execute 'cc1plus'" when I want to compile any program in C++. I didn't installed the compiler Mingw-w64, downloaded the zip from winlibs.com and I copied it to "C:". Then I added to the environment variable Path.
I tried to move the library cc1plus.exe.o to the lib folder of Mingw, and used the commands gcc test.cpp -o test.exe and gcc.exe test.cpp -o text.exe.
The OS is Windows.
Thank you.

warning #10145 no action performed for file 'A.obj'

I am under windows (as the obj extension shows).
I have two valid .f90 files A.f90 and B.f90 (placed in the same folder) provided to me, where B.f90 uses A.f90, the code of B.f90 being :
module B
use A
! ... stuff
The code of A.f90 is
module A
! ... stuff
I compile A.f90 with :
ifort -c -fpp A.f90
Now I would like to compile B.f90 "while taking accound of" A.f90, that is, of its .obj file.
So I tried :
ifort -c B.f90 A.obj
which throws
ifort: warning #10145: no action performed for file 'A.obj'
at me.
Is the command
ifort -c B.f90
proper to compile B.f90 "while taking accound of" A.f90, that is, of its .obj file ?
I would like B.f90 it to be compiled "as A.f90 is", as in fact I have a third C.f90 (containing a use B) and that at the end I must run the command :
ifort -dll toto.dll A.o B.o C.o
to compile a dll while linking to all object files from A, B, C.
The information about module A that the compiler needs in order to compile file B.f90 is not in file A.f90 but in file A.mod (name of the module followed by .mod extension). The default is that .mod files are created in and read from the directory where ifort is run from. Therefore, if you compile files in the right order (as you are doing), and run ifort from the same directory when you compile all these files, it will have access to the previously compiled module files, and everything will work fine with simple commands such as
ifort -c B.f90
If, at compilation time, a compiler does not have access to the module file of a module that is used in the file currently compiled, an error will be isued and compilation will abort.

"Fortran runtime error: End of file" while writing

I have written a piece of code, compiled with GNU Fortran (GCC) 7.2.1 20171128 on Arch Linux, that tries to write to a file. The unit is opened with the newunit=... Fortran 2008-feature
When trying to write to the file, the code crashes, raising the error Fortran runtime error: End of file.
Non working code
Here's a minimal non-working version of the code. If the file does not exist, the code crashes with gfortran 7.2.1
program foo
implicit none
character(len=80) :: filename
character(len=5) :: nchar
integer :: ilun=1
call title(1, nchar)
! nchar = '00001'
filename = trim(nchar)//'.txt'
write(*, '(a, "<", a, ">")') 'filename ', trim(filename)
open(newunit=ilun, file=trim(filename), form='formatted', status='replace')
write(ilun, '(a1,a12,a10)') '#', 'Family', 'Count'
close(ilun)
end program foo
subroutine title(n, nchar)
implicit none
integer, intent(in) :: n
character(len=5), intent(out) :: nchar
write(nchar, '(i0.5)') n
end subroutine title
Here the command I'm using rm -f 00001.txt; gfortran foo.f90 -o a.out && ./a.out.
Working code
By comparison, the following code compiles and works perfectly on the same machine
program foo
implicit none
character(len=80) :: filename
character(len=5) :: nchar
integer :: ilun=1
! call title(1, nchar)
nchar = '00001'
filename = trim(nchar)//'.txt'
write(*, '(a, "<", a, ">")') 'filename ', trim(filename)
open(newunit=ilun, file=trim(filename), form='formatted', status='replace')
write(ilun, '(a1,a12,a10)') '#', 'Family', 'Count'
close(ilun)
end program foo
Here's the command I'm using rm -f 00001.txt; gfortran foo.f90 -o a.out && ./a.out.
Important note
Both codes work well when compiled using ifort (any version tried between ifort15 and ifort18) as well as GNU Fortran (GCC) 6.4.1 20171003 and GNU Fortran (GCC) 7.2.0, so there seems to be an issue introduced in version 7.2.1 of gfortran or on the version bundled with Arch Linux.
A few comments
If you uncomment nchar = '00001' in the non-working example, it still doesn't work.
If you change newunit=ilun to unit=ilun, with e.g. ilun=10 before, it works in any case
System details
OS: GNU Linux
Distribution: Arch Linux (up-to-date as of 15-12-2017)
$ uname -a
Linux manchot 4.14.4-1-ARCH #1 SMP PREEMPT Tue Dec 5 19:10:06 UTC 2017 x86_64 GNU/Linux
$ gfortran --version
GNU Fortran (GCC) 7.2.1 20171128
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This issue is related to the Arch Linux distribution of Gfortran 7.2.1. It has now been fixed (see https://bugs.archlinux.org/task/56768).
If you encounter the issue, you should update your installation using
pacman -Syu gcc-fortran

Scons - build order of Fortran files

Building modules in Fortran needs to be done in a specific order, e.g. if a file A.f needs module defined in B.f, then B.f needs to be compiled first. How can I impose such build order in Scons? If I provide it with a list of source files, it arranges them alphabetically (so A.f is compiled before B.f). I read about Requires() and Depends() functions, but wasn't able to get them to work for me.
I would be happy with just listing source files in order I need them compiled (so disabling reshuffling them in alphabetical order), but any other method would be welcomed as well.
As per Kyle's request, here's my Sconscript and a build log:
# Main program building script
Import('env')
PROGRAM = 'main.exe'
SRC_PREFIX = './src/'
SRC = [ 'array_1D_module.f',
'array_2D_module.f',
'array_3D_module.f',
'thomas_algorithm_module.f',
'histogram_module.f',
'histogram_computer_module.f',
'density_parameters_module.f',
'diffusion3D_aos_z_sub_solver_module.f',
'diffusion3D_aos_y_sub_solver_module.f',
'diffusion3D_aos_x_sub_solver_module.f',
'diffusion3D_aos_solver_module.f',
'nonlinear_diffusion_utilities_module.f',
'nonlinear_diffusion_parameters_module.f',
'derivative_magnitude_computer_module.f',
'nonlinear_diffusion_module.f',
'main_module.f',
'main.f' ]
# Attach prefix to each source file
for i in range( len(SRC) ) :
SRC[i] = SRC_PREFIX + SRC[i]
env.Program(target = PROGRAM, source = SRC)
This produced:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
ifort -o src/array_1D_module.o -c src/array_1D_module.f
ifort -o src/array_2D_module.o -c src/array_2D_module.f
ifort -o src/array_3D_module.o -c src/array_3D_module.f
ifort -o src/density_parameters_module.o -c src/density_parameters_module.f
ifort -o src/derivative_magnitude_computer_module.o -c src/derivative_magnitude_computer_module.f
ifort -o src/diffusion3D_aos_solver_module.o -c src/diffusion3D_aos_solver_module.f
src/diffusion3D_aos_solver_module.f(7): error #7002: Error in opening the compiled module file. Check INCLUDE paths. [DIFFUSION3D_AOS_Z_SUB_SOLVER_MODULE]
use diffusion3D_aos_z_sub_solver_module, only :
------------^
So density_parameters_module.f was compiled before thomas_algorithm_module.f, even though it comes after it in my list.
Is your program (as suggested) using modules? There's a couple of gotchas there:
FORTRANMODDIR needs defining: See http://scons.tigris.org/ds/viewMessage.do?dsForumId=1272&dsMessageId=82725 for a discussion on that.
I found that having source files containing a mixture of module definitions and source code caused a certain amount of confusion.

providing the path to a library for ifort

Disclaimer: This is not my field and I don't know the Jargon.
I'm trying to compile and run some code on a computation server. The machine have intel compiler installed on. When I try to compile the code using
ifort src.f -o mem
Everything works. If I try to optimize things:
ifort -fast src.f. -o mem
I first get messages:
ipo: remark #11001: performing single-file optimizations
ipo: remark #11006: generating object file /tmp/ipo_ifortYepD4m.o
Which seem logical. When I run the out file I get an error:
./mem: error while loading shared libraries: libgfortran.so.1: cannot open shared object file: No such file or directory
I searched for libgfortran:
avityo#admin:~/prog/mn270.161> locate libgfortran
/home/MATLAB/R2011b/sys/os/glnxa64/libgfortran.so.3
/home/MATLAB/R2011b/sys/os/glnxa64/libgfortran.so.3.0.0
/opt/matlab/r2012b/sys/os/glnxa64/libgfortran.so.3
/opt/matlab/r2012b/sys/os/glnxa64/libgfortran.so.3.0.0
/usr/lib64/gcc/x86_64-suse-linux/4.3/libgfortran.a
/usr/lib64/gcc/x86_64-suse-linux/4.3/libgfortran.so
/usr/lib64/gcc/x86_64-suse-linux/4.3/libgfortranbegin.a
/usr/lib64/libgfortran.so.3
/usr/lib64/libgfortran.so.3.0.0
Is there a way to tell ifort the available libgfort library?
I agree with Vladimir that it is a strange dependency between gfortran & ifort. However, it appears that ifort is looking for libgfortran.so.1 and you have libgfortran.so.3 listed there. You should be able link the former to the latter via ln -s [target] [shortcut]. That is,
ln -s /usr/lib64/libgfortran.so.3 /usr/lib64/libgfortran.so.1