/tmp to store temporary
information. If /tmp fills up or information placed there
is erased the compilation may fail,
quite often with no clear indication on the cause of the
problem. For reasons outlined here, users should not normally use /tmp and
files placed on /tmp can get deleted by the
system. To avoid the compilation failing at random places in case of
the login node being very busy,
users can set the environment variable TMPDIR to a
directory in their own home or workspace. For example in ksh
typing
mkdir ~/MyTemp export TMPDIR=~/MyTempmakes the compilers use the directory
MyTemp in your home space.
Serial codes are compiled with:
The _r suffix stands for re-entrant and denotes that the compiler should generate thread safe code. This is essential if you are using OpenMP or threads, but it also helps with MPI codes, so it is always recommended. There are several reasons for this:
Please note that for Fortran code the -qsuffix flag will be needed if your Fortran files do not have a .f or .F suffix, e.g.
xlf90_r -qsuffix=f=f90 -o mycode -q64 mycode.f90
For Java codes, the -O flag may be used for optimisation. e.g.
javac -O mycode.java
To compile Fortran MPI code the basic command is mpxlf90_r, e.g.:
mpxlf90_r -qsuffix=f=f90 -q64 -o mycode mycode.f90
The mp prefix denotes that the compiler is for multi-processor (MPI) programs.
Please note the comment above (Compiling sequential code) for the -qsuffix flag.
mpcc_r is used to compile MPI C code, e.g.:
mpcc_r -q64 -o mycode mycode.c
Please have a look at the below remark on the -q64 option.
mpCC_r is used to compile MPI C++ code:
mpCC_r -q64 -o mycode mycode.C
If your code is using the C++ bindings of MPI instead of the standard
C bindings, that is utilising functions which start with
``MPI::'' instead of ``MPI_'', you need to define the
pre-processor
variable _MPI_CPP_BINDINGS. This can be achieved by using the
-D compiler flag:
mpCC_r -q64 -D_MPI_CPP_BINDINGS -o mycode mycode.C
Please have a look at the below remark on the -q64 option.
Use the -qsmp option to turn on shared-memory parallelisation. You must use the _r versions of the compilers which provide thread-safe versions of the Fortran/C/C++ compilers, e.g.
$ export OMP_NUM_THREADS=2
$ xlf90_r -qsmp=omp -qsuffix=f=f90 -o hello hello.f90
** hello === End of Compilation 1 ===
1501-510 Compilation successful for file hello.f90.
$ ./hello
hello from 0 of 2
hello from 1 of 2
-q64
By default the xlf90_r compiler uses 32-bit addressing. To
change this to
use 64-bit addressing the -q64 options can be used.
All object files
making up the same executable must be compiled and linked
with the -q64 flag.
This flag increases the amount of memory that a program can use and removes some of the restrictions on shared memory segments so the 64-bit MPI library has some additional optimisations. This flag is therefore a good choice for most codes. One possible disadvantage is that all pointers will double in size so there may be a performance impact on codes that use a lot of pointers, this mainly concerns codes written in C or C++.
If you want to make your own 64-bit object code libraries using
the ar command you will also need to set the environment variable
OBJECT_MODE=64
or use the -X 64 flag.
Setting OBJECT_MODE=64 is an alternative to specifying
-q64 as a linker option.
-qrealsize=8
It is important to note that the default size of variables declare
REAL is 4 bytes (on a Cray, for example, it is 8 bytes). The
-qrealsize option allows one to specify either 4 or 8 bytes for
the deafault size. Please also note that changing this value from 4 to 8
bytes also changes the size of COMPLEX variables to 2 x 8
bytes, DOUBLE COMPLEX variables to 2 x 16 bytes and
DOUBLE PRECISION variables from 8 bytes to 16 bytes. Integers
(and logicals) are also promoted to 8 bytes. It is up to the user to
ensure that the Fortran/C types are consistent with the MPI types, which
will not be altered automatically.
Please see the section on `Porting code' for details of Fortran, C and MPI datatypes.
Example Makefiles, batch scripts and short test programs are available at
http://www.hpcx.ac.uk/support/FAQ/template.tar
The Makefiles are also shown below.
To compile the examples, just use:
make -f Makefile.MPI.[f|f90|c] (for .[f|f90|c] MPI files)
make -f Makefile.OMP.[f|f90|c] (for .[f|f90|c] OMP files)
make -f Makefile.MIX.[f|f90|c] (for .[f|f90|c] mixed MPI/OMP files)
It is probably best to do a make -f Makefile.X.Y clean beforehand too.
These examples have deliberately been written using 2 separate files (e.g. mpihello.f90 and hello.f90) to ensure the Makefiles are not completely trivial.
Example Makefile (Makefile.MPI.f) to compile code with two MPI fixed format Fortran source files: mpihello.f and hello.f.
MF= Makefile.MPI.f
FC= mpxlf_r
FFLAGS= -q64 -O3 -qarch=pwr4 -qtune=pwr4
LFLAGS= $(FFLAGS)
EXE= mpihello
SRC= \
mpihello.f \
hello.f
#
# No need to edit below this line
#
.SUFFIXES:
.SUFFIXES: .f .o
OBJ= $(SRC:.f=.o)
.f.o:
$(FC) $(FFLAGS) -c $<
all: $(EXE)
$(EXE): $(OBJ)
$(FC) $(LFLAGS) -o $@ $(OBJ)
$(OBJ): $(MF)
tar:
tar cvf $(EXE).tar $(MF) $(SRC)
clean:
rm -f $(OBJ) $(EXE) core
Example Makefile (Makefile.MPI.f90) to compile code with two MPI Fortran 90 source files: mpihello.f90 and hello.f90.
MF= Makefile.MPI.f90
FC= mpxlf90_r
FFLAGS= -qsuffix=f=f90 -q64 -O3 -qarch=pwr4 -qtune=pwr4
LFLAGS= $(FFLAGS)
EXE= mpihello
SRC= \
mpihello.f90 \
hello.f90
#
# No need to edit below this line
#
.SUFFIXES:
.SUFFIXES: .f90 .o
OBJ= $(SRC:.f90=.o)
.f90.o:
$(FC) $(FFLAGS) -c $<
all: $(EXE)
$(EXE): $(OBJ)
$(FC) $(LFLAGS) -o $@ $(OBJ)
$(OBJ): $(MF)
tar:
tar cvf $(EXE).tar $(MF) $(SRC)
clean:
rm -f $(OBJ) $(EXE) core
Example Makefile (Makefile.MPI.c) to compile code with two C source files: mpihello.c and hello.c
MF= Makefile.MPI.c
CC= mpcc_r
CFLAGS= -q64 -O3 -qarch=pwr4 -qtune=pwr4
LFLAGS= $(CFLAGS)
EXE= mpihello
SRC= \
mpihello.c \
hello.c
#
# No need to edit below this line
#
.SUFFIXES:
.SUFFIXES: .c .o
OBJ= $(SRC:.c=.o)
.c.o:
$(CC) $(CFLAGS) -c $<
all: $(EXE)
$(EXE): $(OBJ)
$(CC) $(LFLAGS) -o $@ $(OBJ)
$(OBJ): $(MF)
tar:
tar cvf $(EXE).tar $(MF) $(SRC)
clean:
rm -f $(OBJ) $(EXE) core
Example Makefile (Makefile.OMP.f) to compile code with two OMP fixed format Fortran source files: omphello.f and hello.f.
MF= Makefile.OMP.f
FC= xlf_r
FFLAGS= -q64 -O3 -qarch=pwr4 -qtune=pwr4 -qsmp=omp,noauto
LFLAGS= $(FFLAGS)
EXE= omphello
SRC= \
omphello.f \
hello.f
#
# No need to edit below this line
#
.SUFFIXES:
.SUFFIXES: .f .o
OBJ= $(SRC:.f=.o)
.f.o:
$(FC) $(FFLAGS) -c $<
all: $(EXE)
$(EXE): $(OBJ)
$(FC) $(LFLAGS) -o $@ $(OBJ)
$(OBJ): $(MF)
tar:
tar cvf $(EXE).tar $(MF) $(SRC)
clean:
rm -f $(OBJ) $(EXE) core
Example Makefile (Makefile.OMP.f90) to compile code with two OpenMP Fortran 90 source files: omphello.f90 and hello.f90
MF= Makefile.OMP.f90
FC= xlf90_r
FFLAGS= -qsuffix=f=f90 -q64 -O3 -qarch=pwr4 -qtune=pwr4 -qsmp=omp,noauto
LFLAGS= $(FFLAGS)
EXE= omphello
SRC= \
omphello.f90 \
hello.f90
#
# No need to edit below this line
#
.SUFFIXES:
.SUFFIXES: .f90 .o
OBJ= $(SRC:.f90=.o)
.f90.o:
$(FC) $(FFLAGS) -c $<
all: $(EXE)
$(EXE): $(OBJ)
$(FC) $(LFLAGS) -o $@ $(OBJ)
$(OBJ): $(MF)
tar:
tar cvf $(EXE).tar $(MF) $(SRC)
clean:
rm -f $(OBJ) $(EXE) core
Example Makefile (Makefile.OMP.c) to compile code with two OMP C source files: omphello.c and hello.c.
MF= Makefile.OMP.c
CC= xlc_r
CFLAGS= -q64 -O3 -qarch=pwr4 -qtune=pwr4 -qsmp=omp:noauto
LFLAGS= $(CFLAGS)
EXE= omphello
SRC= \
omphello.c \
hello.c
#
# No need to edit below this line
#
.SUFFIXES:
.SUFFIXES: .c .o
OBJ= $(SRC:.c=.o)
.c.o:
$(CC) $(CFLAGS) -c $<
all: $(EXE)
$(EXE): $(OBJ)
$(CC) $(LFLAGS) -o $@ $(OBJ)
$(OBJ): $(MF)
tar:
tar cvf $(EXE).tar $(MF) $(SRC)
clean:
rm -f $(OBJ) $(EXE) core
Example Makefile (Makefile.MIC.f) to compile code with two MPI/OpenMP fixed format Fortran source files: mixhello.f and hello.f.
MF= Makefile.MIX.f
FC= mpxlf_r
FFLAGS= -q64 -O3 -qarch=pwr4 -qtune=pwr4 -qsmp=omp,noauto
LFLAGS= $(FFLAGS)
EXE= mixhello
SRC= \
mixhello.f \
hello.f
#
# No need to edit below this line
#
.SUFFIXES:
.SUFFIXES: .f .o
OBJ= $(SRC:.f=.o)
.f.o:
$(FC) $(FFLAGS) -c $<
all: $(EXE)
$(EXE): $(OBJ)
$(FC) $(LFLAGS) -o $@ $(OBJ)
$(OBJ): $(MF)
tar:
tar cvf $(EXE).tar $(MF) $(SRC)
clean:
rm -f $(OBJ) $(EXE) core
Example Makefile (Makefile.MIX.f90) to compile code with two mixed MPI/OpenMP Fortran 90 source files: mixhello.f90 and hello.f90
MF= Makefile.MIX.f90
FC= mpxlf90_r
FFLAGS= -qsuffix=f=f90 -q64 -O3 -qarch=pwr4 -qtune=pwr4 -qsmp=omp,noauto
LFLAGS= $(FFLAGS)
EXE= mixhello
SRC= \
mixhello.f90 \
hello.f90
#
# No need to edit below this line
#
.SUFFIXES:
.SUFFIXES: .f90 .o
OBJ= $(SRC:.f90=.o)
.f90.o:
$(FC) $(FFLAGS) -c $<
all: $(EXE)
$(EXE): $(OBJ)
$(FC) $(LFLAGS) -o $@ $(OBJ)
$(OBJ): $(MF)
tar:
tar cvf $(EXE).tar $(MF) $(SRC)
clean:
rm -f $(OBJ) $(EXE) core
Example Makefile (Makefile.MIX.c) to compile code with two mixed MPI/OpenMP C source files: mixhello.c and hello.c.
MF= Makefile.MIX.c
CC= mpcc_r
CFLAGS= -q64 -O3 -qarch=pwr4 -qtune=pwr4 -qsmp=omp:noauto
LFLAGS= $(CFLAGS)
EXE= mixhello
SRC= \
mixhello.c \
hello.c
#
# No need to edit below this line
#
.SUFFIXES:
.SUFFIXES: .c .o
OBJ= $(SRC:.c=.o)
.c.o:
$(CC) $(CFLAGS) -c $<
all: $(EXE)
$(EXE): $(OBJ)
$(CC) $(LFLAGS) -o $@ $(OBJ)
$(OBJ): $(MF)
tar:
tar cvf $(EXE).tar $(MF) $(SRC)
clean:
rm -f $(OBJ) $(EXE) core