Skip to content

Commit 919422b

Browse files
committed
Initial commit of MPI bindings for Haskell.
0 parents  commit 919422b

File tree

11 files changed

+348
-0
lines changed

11 files changed

+348
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist/

LICENSE

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright (c) 2009-2010 Bernard James Pope (also known as Bernie Pope).
2+
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions
7+
are met:
8+
1. Redistributions of source code must retain the above copyright
9+
notice, this list of conditions and the following disclaimer.
10+
2. Redistributions in binary form must reproduce the above copyright
11+
notice, this list of conditions and the following disclaimer in the
12+
documentation and/or other materials provided with the distribution.
13+
3. Neither the name of the author nor the names of his contributors
14+
may be used to endorse or promote products derived from this software
15+
without specific prior written permission.
16+
17+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.txt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Bindings-MPI, Haskell bindings to the MPI library
2+
------------------------------------------------
3+
4+
License and Copyright
5+
---------------------
6+
7+
Bindings-MPI is distributed as open source software under the terms of the BSD
8+
License (see the file LICENSE in the top directory).
9+
10+
Author: Bernie Pope, copyright 2010.
11+
12+
Contact information
13+
-------------------
14+
15+
Email Bernie Pope:
16+
17+
florbitous <at> gmail <dot> com
18+

Setup.lhs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env runhaskell
2+
> import Distribution.Simple
3+
> main = defaultMain

bindings-mpi.cabal

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: bindings-mpi
2+
version: 0.0.1
3+
cabal-version: >= 1.6
4+
synopsis: Haskell bindings to the MPI library.
5+
description: Haskell bindings to the MPI library.
6+
category: FFI, Distributed Computing
7+
license: BSD3
8+
license-file: LICENSE
9+
copyright: (c) 2010 Bernard James Pope
10+
author: Bernard James Pope (Bernie Pope)
11+
maintainer: [email protected]
12+
homepage: http://wiki.github.com/bjpop/berp/
13+
build-type: Simple
14+
stability: experimental
15+
tested-with: GHC==6.10.4
16+
extra-source-files: src/cbits, src/include
17+
18+
Library
19+
extra-libraries: mpi
20+
build-tools: c2hs
21+
ghc-options: -Wall -fno-warn-name-shadowing -fno-warn-orphans
22+
c-sources:
23+
src/cbits/init_wrapper.c
24+
include-dirs:
25+
src/include
26+
hs-source-dirs:
27+
src
28+
build-depends:
29+
base,
30+
haskell98
31+
exposed-modules:
32+
Bindings.MPI.Internal
33+
other-modules:
34+
C2HS

src/Bindings/MPI/Internal.chs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{-# LANGUAGE ForeignFunctionInterface #-}
2+
3+
#include <mpi.h>
4+
#include "init_wrapper.h"
5+
#include "constants.h"
6+
7+
module Bindings.MPI.Internal (init, finalize, send, recv, Comm, Datatype, commWorld, int) where
8+
9+
import Prelude hiding (init)
10+
import C2HS
11+
12+
type Comm = {# type MPI_Comm #}
13+
type Datatype = {# type MPI_Datatype #}
14+
15+
foreign import ccall "mpi_comm_world" commWorld :: Comm
16+
foreign import ccall "mpi_int" int :: Datatype
17+
18+
init = {# call init_wrapper as ^ #}
19+
20+
-- int MPI_Finalize(void)
21+
finalize = {# call MPI_Finalize as ^ #}
22+
23+
-- int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
24+
send = {# call MPI_Send as ^ #}
25+
26+
-- int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)
27+
recv = {# call MPI_Recv as ^ #}

src/C2HS.hs

+220
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
-- C->Haskell Compiler: Marshalling library
2+
--
3+
-- Copyright (c) [1999...2005] Manuel M T Chakravarty
4+
--
5+
-- Redistribution and use in source and binary forms, with or without
6+
-- modification, are permitted provided that the following conditions are met:
7+
--
8+
-- 1. Redistributions of source code must retain the above copyright notice,
9+
-- this list of conditions and the following disclaimer.
10+
-- 2. Redistributions in binary form must reproduce the above copyright
11+
-- notice, this list of conditions and the following disclaimer in the
12+
-- documentation and/or other materials provided with the distribution.
13+
-- 3. The name of the author may not be used to endorse or promote products
14+
-- derived from this software without specific prior written permission.
15+
--
16+
-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17+
-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18+
-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19+
-- NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20+
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21+
-- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22+
-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23+
-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24+
-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
--
27+
--- Description ---------------------------------------------------------------
28+
--
29+
-- Language: Haskell 98
30+
--
31+
-- This module provides the marshaling routines for Haskell files produced by
32+
-- C->Haskell for binding to C library interfaces. It exports all of the
33+
-- low-level FFI (language-independent plus the C-specific parts) together
34+
-- with the C->HS-specific higher-level marshalling routines.
35+
--
36+
37+
module C2HS (
38+
39+
-- * Re-export the language-independent component of the FFI
40+
module Foreign,
41+
42+
-- * Re-export the C language component of the FFI
43+
module CForeign,
44+
45+
-- * Composite marshalling functions
46+
withCStringLenIntConv, peekCStringLenIntConv, withIntConv, withFloatConv,
47+
peekIntConv, peekFloatConv, withBool, peekBool, withEnum, peekEnum,
48+
49+
-- * Conditional results using 'Maybe'
50+
nothingIf, nothingIfNull,
51+
52+
-- * Bit masks
53+
combineBitMasks, containsBitMask, extractBitMasks,
54+
55+
-- * Conversion between C and Haskell types
56+
cIntConv, cFloatConv, cToBool, cFromBool, cToEnum, cFromEnum
57+
) where
58+
59+
60+
import Foreign
61+
hiding (Word)
62+
-- Should also hide the Foreign.Marshal.Pool exports in
63+
-- compilers that export them
64+
import CForeign
65+
66+
import Monad (when, liftM)
67+
68+
69+
-- Composite marshalling functions
70+
-- -------------------------------
71+
72+
-- Strings with explicit length
73+
--
74+
withCStringLenIntConv s f = withCStringLen s $ \(p, n) -> f (p, cIntConv n)
75+
peekCStringLenIntConv (s, n) = peekCStringLen (s, cIntConv n)
76+
77+
-- Marshalling of numerals
78+
--
79+
80+
withIntConv :: (Storable b, Integral a, Integral b)
81+
=> a -> (Ptr b -> IO c) -> IO c
82+
withIntConv = with . cIntConv
83+
84+
withFloatConv :: (Storable b, RealFloat a, RealFloat b)
85+
=> a -> (Ptr b -> IO c) -> IO c
86+
withFloatConv = with . cFloatConv
87+
88+
peekIntConv :: (Storable a, Integral a, Integral b)
89+
=> Ptr a -> IO b
90+
peekIntConv = liftM cIntConv . peek
91+
92+
peekFloatConv :: (Storable a, RealFloat a, RealFloat b)
93+
=> Ptr a -> IO b
94+
peekFloatConv = liftM cFloatConv . peek
95+
96+
-- Passing Booleans by reference
97+
--
98+
99+
withBool :: (Integral a, Storable a) => Bool -> (Ptr a -> IO b) -> IO b
100+
withBool = with . fromBool
101+
102+
peekBool :: (Integral a, Storable a) => Ptr a -> IO Bool
103+
peekBool = liftM toBool . peek
104+
105+
106+
-- Passing enums by reference
107+
--
108+
109+
withEnum :: (Enum a, Integral b, Storable b) => a -> (Ptr b -> IO c) -> IO c
110+
withEnum = with . cFromEnum
111+
112+
peekEnum :: (Enum a, Integral b, Storable b) => Ptr b -> IO a
113+
peekEnum = liftM cToEnum . peek
114+
115+
116+
-- Storing of 'Maybe' values
117+
-- -------------------------
118+
119+
instance Storable a => Storable (Maybe a) where
120+
sizeOf _ = sizeOf (undefined :: Ptr ())
121+
alignment _ = alignment (undefined :: Ptr ())
122+
123+
peek p = do
124+
ptr <- peek (castPtr p)
125+
if ptr == nullPtr
126+
then return Nothing
127+
else liftM Just $ peek ptr
128+
129+
poke p v = do
130+
ptr <- case v of
131+
Nothing -> return nullPtr
132+
Just v' -> new v'
133+
poke (castPtr p) ptr
134+
135+
136+
-- Conditional results using 'Maybe'
137+
-- ---------------------------------
138+
139+
-- Wrap the result into a 'Maybe' type.
140+
--
141+
-- * the predicate determines when the result is considered to be non-existing,
142+
-- ie, it is represented by `Nothing'
143+
--
144+
-- * the second argument allows to map a result wrapped into `Just' to some
145+
-- other domain
146+
--
147+
nothingIf :: (a -> Bool) -> (a -> b) -> a -> Maybe b
148+
nothingIf p f x = if p x then Nothing else Just $ f x
149+
150+
-- |Instance for special casing null pointers.
151+
--
152+
nothingIfNull :: (Ptr a -> b) -> Ptr a -> Maybe b
153+
nothingIfNull = nothingIf (== nullPtr)
154+
155+
156+
-- Support for bit masks
157+
-- ---------------------
158+
159+
-- Given a list of enumeration values that represent bit masks, combine these
160+
-- masks using bitwise disjunction.
161+
--
162+
combineBitMasks :: (Enum a, Bits b) => [a] -> b
163+
combineBitMasks = foldl (.|.) 0 . map (fromIntegral . fromEnum)
164+
165+
-- Tests whether the given bit mask is contained in the given bit pattern
166+
-- (i.e., all bits set in the mask are also set in the pattern).
167+
--
168+
containsBitMask :: (Bits a, Enum b) => a -> b -> Bool
169+
bits `containsBitMask` bm = let bm' = fromIntegral . fromEnum $ bm
170+
in
171+
bm' .&. bits == bm'
172+
173+
-- |Given a bit pattern, yield all bit masks that it contains.
174+
--
175+
-- * This does *not* attempt to compute a minimal set of bit masks that when
176+
-- combined yield the bit pattern, instead all contained bit masks are
177+
-- produced.
178+
--
179+
extractBitMasks :: (Bits a, Enum b, Bounded b) => a -> [b]
180+
extractBitMasks bits =
181+
[bm | bm <- [minBound..maxBound], bits `containsBitMask` bm]
182+
183+
184+
-- Conversion routines
185+
-- -------------------
186+
187+
-- |Integral conversion
188+
--
189+
cIntConv :: (Integral a, Integral b) => a -> b
190+
cIntConv = fromIntegral
191+
192+
-- |Floating conversion
193+
--
194+
cFloatConv :: (RealFloat a, RealFloat b) => a -> b
195+
cFloatConv = realToFrac
196+
-- As this conversion by default goes via `Rational', it can be very slow...
197+
{-# RULES
198+
"cFloatConv/Float->Float" forall (x::Float). cFloatConv x = x;
199+
"cFloatConv/Double->Double" forall (x::Double). cFloatConv x = x
200+
#-}
201+
202+
-- |Obtain C value from Haskell 'Bool'.
203+
--
204+
cFromBool :: Num a => Bool -> a
205+
cFromBool = fromBool
206+
207+
-- |Obtain Haskell 'Bool' from C value.
208+
--
209+
cToBool :: Num a => a -> Bool
210+
cToBool = toBool
211+
212+
-- |Convert a C enumeration to Haskell.
213+
--
214+
cToEnum :: (Integral i, Enum e) => i -> e
215+
cToEnum = toEnum . cIntConv
216+
217+
-- |Convert a Haskell enumeration to C.
218+
--
219+
cFromEnum :: (Enum e, Integral i) => e -> i
220+
cFromEnum = cIntConv . fromEnum

src/cbits/constants.c

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include "constants.h"
2+
3+
mpi_comm_world = MPI_COMM_WORLD;
4+
mpi_int = MPI_INT;

src/cbits/init_wrapper.c

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <mpi.h>
2+
#include "init_wrapper.h"
3+
4+
/* the following is taken from includes/Stg.h of the GHC distribution */
5+
6+
extern char **prog_argv;
7+
extern int prog_argc;
8+
9+
int init_wrapper (void) { return MPI_Init (&prog_argc, &prog_argv); }

src/include/constants.h

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include <mpi.h>
2+
3+
extern MPI_Comm mpi_comm_world;
4+
extern MPI_Datatype mpi_int;

src/include/init_wrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extern int init_wrapper (void);

0 commit comments

Comments
 (0)