【发布时间】:2015-06-02 03:59:58
【问题描述】:
我想通过 FFI 接口从 Haskell 提供 PETSc 库(的一个子集),以便对用户隐藏内存和错误管理;
- 使用如下所示的命令使用共享库构建 PETSc 3.5.3,测试套件运行成功
- 准备了一个 .hsc 文件 #2,其中包含头文件导入、类型和两个示例外部函数接口
- 准备了一个 Makefile #3 来自动化构建;
make test1使用加载的模块传递并启动 GHCi。
由于库在 MPI 和完全分布式数据结构支持的并行操作上大放异彩,因此在大多数操作期间不应期望使用 Haskell 进行大量数据流量(所有数据组装、计算和释放都应由库原语完成),但是仅在“数据准备就绪”时。 PETSc 相关的 Haskell 函数大多在 IO monad 中有值,因为我们无法保证纯度(例如,返回的 C 错误代码可能因程序外部原因而有所不同)
-
需要坏主意unsafePerformIO来包装内存allocation 和错误管理。这种思路正确吗? -
用 GHC 编译的二进制文件可以用是的mpirun执行吗?
我愿意接受所有建议和评论。提前谢谢你
-- 注释:
我们希望 GHC 生成mpirun 可以执行的二进制文件:由于可以使用-optl 标志(参考here)将选项从GHC 命令行传递给链接器,因此有人建议我使用@ 等组合987654329@。我会尽快添加更多关于此的内容。
1) 配置命令:
$ ./configure --with-cc=gcc --with-cxx=g++ --with-fc=gfortran --with-shared-libraries=1 --download-mpich --download-fblaslapack
2) PETSC.hsc
{-# LANGUAGE CPP, ForeignFunctionInterface, EmptyDataDecls #-}
module PETSc where
import Foreign
import Foreign.Ptr
import Foreign.C.Types
import Foreign.C.String
#include <petscksp.h>
#include <petscsys.h>
newtype PetscErrCode = PetscErrCode {unPetscErrCode :: CInt} deriving (Eq, Show)
newtype PetscInt = PetscInt {unPetscInt :: CInt} deriving (Eq, Show)
data Petsc
-- PetscErrorCode PetscInitialize(int *argc,char ***args,const char file[],const char help[])
foreign import ccall unsafe "petscsys.h PetscInitialize"
c_petscInitialize :: Ptr CInt -> Ptr (Ptr CString) -> CString -> CString -> IO PetscErrCode
-- PetscErrorCode PetscFinalize(void)
foreign import ccall unsafe "petscsys.h PetscFinalize"
c_petscFinalize :: IO PetscErrCode
3) 生成文件
PETSC_DIR_ARCH = ${PETSC_DIR}/arch-darwin-c-debug
PETSc.hs:
hsc2hs PETSc.hsc -I ${PETSC_DIR}/include -I ${PETSC_DIR_ARCH}/include
test1: PETSc.hs
ghci -dynamic PETSc.hs -L${PETSC_DIR_ARCH}/lib
【问题讨论】: