C -GHCI接头误差带有FFI Imported MPI常数(通过C2HS)



我正在通过重写绑定来弄清Haskell-MPI的工作方式。我正在尝试重新使用通过安装PETSC(工作正常)设置的MPICH安装。问题:make main在GHCI中给了我一个正确的模块,但是当我要求计算Commworld时,链接器抱怨它找不到MPI_COMM_WORLD符号(但是它在Makefile的范围中)。

我在做什么错?预先感谢

错误:

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

表示commWorld_将是变量MPI_COMM_WORLD的指针。但是实际上MPI_COMM_WORLD不是一个变量,它是CPP宏,因此根本不是一个地址的东西,这就是链接器错误告诉您的。

我可能会添加一个带有

的定义的C文件
const MPI_Comm hs_MPI_COMM_WORLD = MPI_COMM_WORLD;

并以您完成的方式导入。也许C2HS有一些魔术可以为您做到这一点。

我刚刚了解到CApiFFI扩展(自GHC 7.6)允许您不仅导入C级"函数",实际上可能是宏,而且还可以导入C级值成为宏。因此,您应该能够写

{-# LANGUAGE CApiFFI #-}
type MPIComm = {# type MPI_Comm #} 
foreign import capi "mpi.h value MPI_COMM_WORLD" :: MPIComm

无需编写其他C文件(GHC将为您做)。

请参阅https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi.html#ffi-capi。

最新更新