Building OpenCoarrays on macOS
– everything from the sources – gcc-8.3.0
This article focuses on installation based on gcc-8.3.0.
There are quite a lot of perquisites for this article, but there are two, most important ones. You will need: huge cup of coffee/tea and something to do between various compilation steps (good book would be handy, maybe some movie on Netflix).
There are few steps you have to do, if you want to have everything built from the sources.
1. GCC
This part of tutorial is heavily based on this article – in fact I have stolen the whole idea: https://solarianprogrammer.com/2019/10/12/compiling-gcc-macos/. However, I have changed it a little bit to make all the places local – I want things to be installed inside my $HOME/opt. If you prefer having gcc installed system wide, proceed with the steps above.
First of all, make sure to create place where all the sources and all the compiled codes will go. Note that in case of macOS I am strongly against installing stuff inside /usr. First of all, you have no idea when and what Apple decides to do with central locations – they can protect them, remove, change name, do whatever they want. Second thing is that I prefer to keep all the things close to my $HOME so I can easily move things around and pick arbitrary location for the stuff I build.
> mkdir -p $HOME/opt/usr/local > mkdir -p $HOME/opt/src
Download gcc-8.3.0.
> cd $HOME/opt/src > mkdir gcc > cd gcc > curl -L -O https://ftpmirror.gnu.org/gcc/gcc-8.3.0/gcc-8.3.0.tar.xz > tar zxf gcc-8.3.0.tar.xz
Get all the dependencies.
> cd gcc-8.3.0 > contrib/download_prerequisites
Now, this is the step I have stolen from the page mentioned above. We have to create artificial system root. The reason here is that Apple removed /usr/include and moved it inside XCode based platforms. Note that I prefer to create everything inside my $HOME/opt.
> mkdir -p $HOME/opt/usr/local/gcc_system_root > cd $HOME/opt/usr/local/gcc_system_root > ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library . > ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System . > mkdir usr && cd usr > ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/bin . > ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib . > ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/libexec . > ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/share . > cp -r /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include include
Now, we have to alter the file Availability.h. Apply this patch (save it inside your $HOME/Availability.h.patch) (you can download it here).
--- /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/Availability.h 2019-11-07 07:07:28.000000000 +0100 +++ Availability.h 2020-01-18 12:17:58.000000000 +0100 @@ -307,6 +307,12 @@ #define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(_osxIntro, _osxDep, _iosIntro, _iosDep, _msg) #endif +#ifndef __OSX_AVAILABLE_STARTING + #define __OSX_AVAILABLE_STARTING(_osx, _ios) + #define __OSX_AVAILABLE_BUT_DEPRECATED(_osxIntro, _osxDep, _iosIntro, _iosDep) + #define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(_osxIntro, _osxDep, _iosIntro, _iosDep, _msg) +#endif + #if defined(__has_feature) #if __has_feature(attribute_availability_with_message)
apply it following way
> patch -b $HOME/opt/usr/local/gcc_system_root/usr/include/Availability.h $HOME/Availability.h.patch
Now, we can configure the build of gcc.
> cd $HOME/opt/src/gcc/gcc-8.3.0 > mkdir build && cd build > ../configure --prefix=$HOME/opt/usr/local/gcc/gcc-8.3.0 \ --enable-checking=release \ --enable-languages=c,c++,fortran \ --disable-multilib \ --with-sysroot=$HOME/opt/usr/local/gcc_system_root \ --program-suffix=-8.3.0
And, once it’s finished, we can build it and install it
> make > make install
Eventually, you can test it
> cd $HOME > echo '#include <stdio.h> \nvoid main() { printf("Hello from gcc-8.3.0\\n"); }' \ $HOME/opt/usr/local/gcc/gcc-8.3.0/bin/g++-8.3.0 -x c -o hello -; ./hello
If you want, you can update your PATH variable such way it points to this location
export PATH=$HOME/opt/usr/local/gcc/gcc-8.3.0/bin:${PATH}
2. MPICH
You need MPICH for OpenCoarrays. Note that MPICH serves as transport layer for OpenCoarrays project (it is said to work with OpenMPI as well).
> mkdir -p $HOME/opt/src/mpich > cd $HOME/opt/src/mpich > curl -L -O https://www.mpich.org/static/downloads/3.3.1/mpich-3.3.1.tar.gz > tar zxf mpich-3.3.1.tar.gz > cd mpich-3.3.1 > export CC=$HOME/opt/usr/local/gcc/gcc-8.3.0/bin/gcc-8.3.0 > export CXX=$HOME/opt/usr/local/gcc/gcc-8.3.0/bin/g++-8.3.0 > export FC=$HOME/opt/usr/local/gcc/gcc-8.3.0/bin/gfortran-8.3.0 > export FC77=$HOME/opt/usr/local/gcc/gcc-8.3.0/bin/gfortran-8.3.0 > ./configure --prefix=$HOME/opt/usr/local/mpich/mpich-3.3.1-gcc-8.3.0 > make > make install
Once you have it installed, you can test it with simple code.
program main use mpi integer error, id, p call MPI_Init ( error ) call MPI_Comm_size ( MPI_COMM_WORLD, p, error ) call MPI_Comm_rank ( MPI_COMM_WORLD, id, error ) write (*,*) 'Hello: ', id, '/', p call MPI_Finalize ( error ) end
Save it inside $HOME/tmp/hello.f90 and build it.
> cd $HOME/tmp > $HOME/opt/usr/local/mpich/mpich-3.3.1-gcc-8.3.0/bin/mpif90 -o hello hello.f90 > $HOME/opt/usr/local/mpich/mpich-3.3.1-gcc-8.3.0/bin/mpirun -np 4 ./hello Hello: 0 / 4 Hello: 1 / 4 Hello: 3 / 4 Hello: 2 / 4
You are done with MPICH. We can now move to OpenMPI.
3. OpenMPI
OpenCoarrays can also be based on OpenMPI as transport layer. Let’s build OpenMPI
> mkdir -p $HOME/opt/src/openmpi > cd $HOME/opt/src/openmpi > curl -L -O https://download.open-mpi.org/release/open-mpi/v4.0/openmpi-4.0.2.tar.gz > tar zxf openmpi-4.0.2.tar.gz > cd openmpi-4.0.2 > export CC=$HOME/opt/usr/local/gcc/gcc-8.3.0/bin/gcc-8.3.0 > export CXX=$HOME/opt/usr/local/gcc/gcc-8.3.0/bin/g++-8.3.0 > export FC=$HOME/opt/usr/local/gcc/gcc-8.3.0/bin/gfortran-8.3.0 > export FC77=$HOME/opt/usr/local/gcc/gcc-8.3.0/bin/gfortran-8.3.0 > ./configure --prefix=$HOME/opt/usr/local/openmpi/openmpi-4.0.2-gcc-8.3.0 > make > make install
Once you have OpenMPI installed, you can test it with simple code.
program main use mpi integer error, id, p call MPI_Init ( error ) call MPI_Comm_size ( MPI_COMM_WORLD, p, error ) call MPI_Comm_rank ( MPI_COMM_WORLD, id, error ) write (*,*) 'Hello: ', id, '/', p call MPI_Finalize ( error ) end
Save it inside $HOME/tmp/hello.f90 and build it.
> cd $HOME/tmp > $HOME/opt/usr/local/openmpi/openmpi-4.0.2-gcc-8.3.0/bin/mpif90 -o hello hello.f90 > $HOME/opt/usr/local/openmpi/openmpi-4.0.2-gcc-8.3.0/bin/mpirun -np 4 ./hello Hello: 0 / 4 Hello: 1 / 4 Hello: 3 / 4 Hello: 2 / 4
You are done with OpenMPI. We can now move to CMake – it is needed by OpenCoarrays.
4. CMake
You need CMake in order to build OpenCoarrays. And, again, I prefer to have it installed my way.
> mkdir -p $HOME/opt/src/cmake > cd $HOME/opt/src/cmake > curl -o https://github.com/Kitware/CMake/releases/download/v3.16.1/cmake-3.16.1.tar.gz > tar zxf cmake-3.16.1.tar.gz > cd cmake-3.16.1 > ./bootstrap --prefix=$HOME/opt/usr/local/cmake/cmake-3.16.1 > make > make install
You can test whether it works following way
> $HOME/opt/usr/local/cmake/cmake-3.16.1/bin/cmake --version cmake version 3.16.1 CMake suite maintained and supported by Kitware (kitware.com/cmake).
5. OpenCoarrays – MPICH flavour
Now, let’s install OpenCoarrays witm MPICH as a transport layer.
> cd $HOME/opt/src/OpenCoarrays > cd $HOME/opt/src/OpenCoarrays > curl -L -O \ https://github.com/sourceryinstitute/OpenCoarrays/releases/download/2.8.0/OpenCoarrays-2.8.0.tar.gz > tar zxf OpenCoarrays-2.8.0.tar.gz > cd OpenCoarrays-2.8.0 > mkdir opencoarrays-build-mpich > cd opencoarrays-build-mpich > $HOME/opt/usr/local/cmake/cmake-3.16.1/bin/cmake \ $HOME/opt/src/OpenCoarrays/OpenCoarrays-2.8.0 \ -DMPI_Fortran_COMPILER=$HOME/opt/usr/local/mpich/mpich-3.3.1-gcc-8.3.0/bin/mpif90 \ -DMPI_C_COMPILER=$HOME/opt/usr/local/mpich/mpich-3.3.1-gcc-8.3.0/bin/mpicc \ -DMPIEXEC_EXECUTABLE=$HOME/opt/usr/local/mpich/mpich-3.3.1-gcc-8.3.0/bin/mpiexec \ -DCMAKE_INSTALL_PREFIX=$HOME/opt/usr/local/OpenCoarrays/OpenCoarrays-2.8.0-mpich-3.3.1-gcc-8.3.0 > make > make test > make install
6. OpenCoarrays – OpenMPI flavour
Now, let’s install OpenCoarrays witm OpenMPI as a transport layer.
> cd $HOME/opt/src/OpenCoarrays/OpenCoarrays-2.8.0 > mkdir opencoarrays-build-openmpi > cd opencoarrays-build-openmpi > $HOME/opt/usr/local/cmake/cmake-3.16.1/bin/cmake \ $HOME/opt/src/OpenCoarrays/OpenCoarrays-2.8.0 \ -DMPI_Fortran_COMPILER=$HOME/opt/usr/local/openmpi/openmpi-4.0.2-gcc-8.3.0/bin/mpif90 \ -DMPI_C_COMPILER=$HOME/opt/usr/local/openmpi/openmpi-4.0.2-gcc-8.3.0/bin/mpicc \ -DMPIEXEC_EXECUTABLE=$HOME/opt/usr/local/openmpi/openmpi-4.0.2-gcc-8.3.0/bin/mpiexec \ -DCMAKE_INSTALL_PREFIX=$HOME/opt/usr/local/OpenCoarrays/OpenCoarrays-2.8.0-openmpi-4.0.2-gcc-8.3.0 > make > make test > make install
7. First coarray Fortran code
The time is now :) You can run your very first coarray based code.
program hello_world implicit none write(*,*) 'Hello world from ', & this_image() , 'of', num_images() end program hello_world
Save this file inside $HOME/tmp/hello_world.f90.
Let’s run it with MPICH based OpenCoarrays
> cd $HOME/tmp > $HOME/opt/usr/local/OpenCoarrays/OpenCoarrays-2.8.0-mpich-3.3.1-gcc-8.3.0/bin/caf \ -o hello_world hello_world.f90 > $HOME/opt/usr/local/OpenCoarrays/OpenCoarrays-2.8.0-mpich-3.3.1-gcc-8.3.0/bin/cafrun \ -np 2 ./hello_world Hello world from 1 of 2 Hello world from 2 of 2
Let’s run it with MPICH based OpenCoarrays
> cd $HOME/tmp > $HOME/opt/usr/local/OpenCoarrays/OpenCoarrays-2.8.0-openmpi-4.0.2-gcc-8.3.0/bin/caf \ -o hello_world hello_world.f90 > $HOME/opt/usr/local/OpenCoarrays/OpenCoarrays-2.8.0-openmpi-4.0.2-gcc-8.3.0/bin/cafrun \ -np 2 ./hello_world Hello world from 1 of 2 Hello world from 2 of 2
You did it!! You have macOS based environment for coarray based development in Fortran :)