2

我正在通过重写绑定来弄清楚 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

主要.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_

生成文件:

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文件

 typedef int MPI_Comm;
 #define MPI_COMM_WORLD ((MPI_Comm)0x44000000)
 #define MPI_COMM_SELF  ((MPI_Comm)0x44000001)
4

2 回答 2

3
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 有一些魔法可以为你做到这一点。

于 2015-05-06T16:04:52.337 回答
1

我刚刚了解到,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上的文档。

于 2015-06-02T18:27:03.313 回答