メモリとエラー管理をユーザーから隠すために、FFI インターフェイスを介して Haskell から PETScライブラリ(のサブセット) を利用できるようにしたいと考えています。
- 以下に示すコマンドで共有ライブラリを使用して PETSc 3.5.3 をビルドすると、テスト スイートが正常に実行されます。
- ヘッダーのインポート、タイプ、および 2 つの外部関数インターフェイスの例を含む .hsc ファイル #2 を準備しました
- ビルドを自動化する Makefile #3 を準備しました。
make test1
ロードされたモジュールで GHCi を渡し、起動します。
ライブラリは、MPI と完全に分散されたデータ構造によって有効化された並列操作に優れているため、ほとんどの操作 (すべてのデータ アセンブリ、計算、および割り当て解除はライブラリ プリミティブによって行われる必要があります) の間、Haskell で大量のデータ トラフィックを期待する必要はありませんが、"データ準備完了」。PETSc 関連の Haskell 関数は、純粋性を保証できないため、主に IO モナドに値を持ちます (たとえば、返される C エラー コードは、プログラムの外部の理由により異なる場合があります)。
悪いアイデアunsafePerformIO
alloca
メモリとエラー管理をラップする必要があります。この考え方は正しいでしょうか?GHC でコンパイルされたバイナリは で実行できますはいmpirun
か?
私はすべての提案と発言を受け入れます。前もって感謝します
-- 注記: GHC に実行可能なバイナリを生成してもらいたい: mpirun
GHC コマンド ラインからリンカーにオプションを-optl
フラグ (参照here ) で渡すことができるため、次のような組み合わせが提案されていghc -optl-static -lmpich
ます。これについては、試してみることができ次第、追加します。
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