I'm figuring out how haskell-mpi works by rewriting the binding. I'm trying to re-use the MPICH installation that was set up by installing PETSc (which is working fine).
Question: make main
gives me a correct module in GHCi, but when I request to compute commWorld, the linker complains that it can't find the MPI_COMM_WORLD symbol (which however is in scope of the makefile).
What am I doing wrong? Thanks in advance
error:
ByteCodeLink: can't find label
During interactive linking, GHCi couldn't find the following symbol:
MPI_COMM_WORLD
Main.chs :
type MPIComm = {# type MPI_Comm #}
newtype Comm = MkComm { fromComm :: MPIComm } deriving (Eq, Show)
foreign import ccall "&MPI_COMM_WORLD" commWorld_ :: Ptr MPIComm
foreign import ccall "&MPI_COMM_SELF" commSelf_ :: Ptr MPIComm
commWorld, commSelf :: Comm
commWorld = MkComm <$> unsafePerformIO $ peek commWorld_
commSelf = MkComm <$> unsafePerformIO $ peek commSelf_
makefile:
PETSC_DIR_ARCH = ${PETSC_DIR}/arch-darwin-c-debug
PETSC_DIR_ARCH_INCLUDE = ${PETSC_DIR_ARCH}/include
main :
c2hs Main.chs -C -I${PETSC_DIR_ARCH}/include -C -I${PETSC_DIR}/include
ghci Main.hs -L${PETSC_DIR_ARCH}/lib -lpetsc -lmpich
mpi.h
typedef int MPI_Comm;
#define MPI_COMM_WORLD ((MPI_Comm)0x44000000)
#define MPI_COMM_SELF ((MPI_Comm)0x44000001)
foreign import ccall "&MPI_COMM_WORLD" commWorld_ :: Ptr MPIComm
means that commWorld_
will be a pointer to the variable MPI_COMM_WORLD
. But in fact MPI_COMM_WORLD
is not a variable, it's a CPP macro, so it's not the kind of thing that has an address at all, and this is what the linker error is telling you.
I would probably add a C file with a definition like
const MPI_Comm hs_MPI_COMM_WORLD = MPI_COMM_WORLD;
and import that in the way that you have done. Perhaps c2hs has some magic that will do this for you.