...
| Code Block |
|---|
% cat hello1.c #include <stdio.h> #include <mpi.h> extern int printhello (int *, int *) ; int main(int argc, char *argv[]) { int ierror, rank, size; char hname[64]; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) printf ("Hello world!\n"); MPI_Comm_size(MPI_COMM_WORLD, &size); (void) printhello (&rank, &size); MPI_Finalize(); return 0; } % cat utils.c #include <stdio.h> int printhello (int *rank, int *size) { char hname[64]; if (gethostname (hname, 32) != 0) hname[0] = 0; hname[31] = 0; /* gethostname() may omit trailing 0 if hostname >31 chars */ printf("I am %d out of %d on %s.\n", *rank, *size, hname); return 0; } % /usr/local/pkg/gcc/4.7.0/bin/gcc -c -I/usr/lpp/ppe.poe/include hello1.c |
...
% /usr/local/pkg/gcc/4.7.0/bin/gcc -c utils.c |
...
% mpcc utils.o hello. |
...
o
|
Mixing FORTRAN code
| Code Block |
|---|
% cat parhello1.f
PROGRAM HelloWorld
include 'mpif.h'
call mpi_init(ierr)
call mpi_comm_size(MPI_COMM_WORLD,npes, ierr)
call mpi_comm_rank(MPI_COMM_WORLD,irank,ierr)
call printhello (irank, npes)
call mpi_finalize(ierr)
END PROGRAM
% cat utils.f
SUBROUTINE printhello(my_irank,my_npes)
INTEGER my_irank,my_npes
print*,'Hello World! I am ',my_irank,' of ',my_npes
RETURN
END |
...
% gfortran -c -I/usr/lpp/ppe.poe/include/thread parhello1.f |
...
% gfortran -c utils.f |
...
% mpxlf utils.o parhello1.o -L/usr/local/pkg/gcc/4.7.0/lib -lgfortran |
Mixing C and FORTRAN code
...
| Code Block |
|---|
% gfortran -fno-underscoring -c utils.f % xlf -c -I/usr/lpp/ppe.poe/include/thread parhello1.f % mpcc parhello1.o utils.o -L /lib/threads -lxlf90 -L/usr/local/pkg/gcc/4.7.0/lib -lgfortran |
Mixing C and FORTRAN code with underscores
This is more tricky with gcc because you can't persuade gcc to put underscores in the right place! All it has is -fleading-underscore which is just the wrong thing. Note that the gnu linker has -demangle to strip leading underscores, and demangle C++ name mangling if you run into a library full of underscores.
Hence, you must compile your FORTRAN code with no underscores if you want to link FORTRAN against gcc-compiled C code, or have special C code that explicitly appends underscores in the source (which some libraries do).
...
| Code Block |
|---|
% gfortran -fno-underscoring -c -I/usr/lpp/ppe.poe/include/thread parhello1.f % xlc -c utils.c % mpcc parhello1.o utils.o -L /lib/threads -lxlf90 -L/usr/local/pkg/gcc/4.7.0/lib -lgfortran |
And so on...
| Code Block |
|---|
% gcc -c -I/usr/lpp/ppe.poe/include hello1.c
% xlf -c utils.f
% mpcc hello1.o utils.o -L /lib/threads -lxlf90
% xlc -c -I/usr/lpp/ppe.poe/include hello1.c
% gfortran -fno-underscoring -c utils.f
% mpcc hello1.o utils.o -L/usr/local/pkg/gcc/4.7.0/lib -lgfortran |
On the BlueGene L
Often this mixing C and FORTRAN is straightforward if you make sure you use the IBM XL compilers by invoking blrts_<compiler name>. Make sure you add -qextname to your fortran compile flags, at least. When you mix C++ and Fortran you must use the C++ compiler to do the linking, otherwise name mangling won't work. When you add in libxlf90 (as you often have to) then you can end up with undefined references to omp_get_thread_num (and there is no threading on the BG/L) - there is a special verson of libxlsmp to fix this in /opt/ibmcmp/xlsmp/bg/1.7/bglib.
...
