packages feed

mpi-hs 0.6.0.0 → 0.7.0.0

raw patch · 15 files changed

+358/−99 lines, 15 filesdep −criteriondep ~basenew-component:exe:example1new-component:exe:example2new-component:exe:versionPVP ok

version bump matches the API change (PVP)

Dependencies removed: criterion

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Control.Distributed.MPI: datatypeLongLong :: Datatype
+ Control.Distributed.MPI: datatypeUnsignedLongLong :: Datatype
+ Control.Distributed.MPI: instance Control.Distributed.MPI.HasDatatype Foreign.C.Types.CULLong
+ Control.Distributed.MPI: instance Control.Distributed.MPI.HasDatatype GHC.Int.Int16
+ Control.Distributed.MPI: instance Control.Distributed.MPI.HasDatatype GHC.Int.Int32
+ Control.Distributed.MPI: instance Control.Distributed.MPI.HasDatatype GHC.Int.Int64
+ Control.Distributed.MPI: instance Control.Distributed.MPI.HasDatatype GHC.Int.Int8
+ Control.Distributed.MPI: instance Control.Distributed.MPI.HasDatatype GHC.Word.Word16
+ Control.Distributed.MPI: instance Control.Distributed.MPI.HasDatatype GHC.Word.Word32
+ Control.Distributed.MPI: instance Control.Distributed.MPI.HasDatatype GHC.Word.Word64
+ Control.Distributed.MPI: instance Control.Distributed.MPI.HasDatatype GHC.Word.Word8
+ Control.Distributed.MPI.Storable: bcast :: CanSerialize a => Maybe a -> Rank -> Comm -> IO a
+ Control.Distributed.MPI.Storable: bcastSend_ :: CanSerialize a => a -> Rank -> Comm -> IO ()
+ Control.Distributed.MPI.Storable: ibcast :: CanSerialize a => Maybe a -> Rank -> Comm -> IO (Request a)
+ Control.Distributed.MPI.Storable: ibcastSend_ :: CanSerialize a => a -> Rank -> Comm -> IO (Request ())
- Control.Distributed.MPI.Storable: bcastSend :: CanSerialize a => a -> Rank -> Comm -> IO ()
+ Control.Distributed.MPI.Storable: bcastSend :: CanSerialize a => a -> Rank -> Comm -> IO a
- Control.Distributed.MPI.Storable: ibcastSend :: CanSerialize a => a -> Rank -> Comm -> IO (Request ())
+ Control.Distributed.MPI.Storable: ibcastSend :: CanSerialize a => a -> Rank -> Comm -> IO (Request a)

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright 2018 Erik Schnetter+Copyright 2018, 2019, 2020 Erik Schnetter  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
README.md view
@@ -7,10 +7,9 @@   package and documentation * [Stackage](https://www.stackage.org/package/mpi-hs): Stackage   snapshots-* [Azure-  Pipelines](https://dev.azure.com/schnetter/mpi-hs/_build):+* [Azure Pipelines](https://dev.azure.com/schnetter/mpi-hs/_build):   Build Status [![Build-  Status](https://dev.azure.com/schnetter/mpi-hs/_apis/build/status/eschnett.mpi-hs?branchName=master)](https://dev.azure.com/schnetter/mpi-hs/_build/latest&branchName=master)+  Status](https://dev.azure.com/schnetter/mpi-hs/_apis/build/status/eschnett.mpi-hs?branchName=master)](https://dev.azure.com/schnetter/mpi-hs/_build/latest?definitionId=8&branchName=master)   @@ -40,7 +39,7 @@   -## Programming Example+## Example  This is a typical MPI C code: ```C@@ -53,6 +52,9 @@   MPI_Comm_rank(MPI_COMM_WORLD, &rank);   MPI_Comm_size(MPI_COMM_WORLD, &size);   printf("This is process %d of %d\n", rank, size);+  int msg = rank;+  MPI_Bcast(&msg, 1, MPI_INT, 0, MPI_COMM_WORLD):+  printf("Process %d says hi\n", msg);   MPI_Finalize();   return 0; }@@ -60,7 +62,11 @@  The Haskell equivalent looks like this: ```Haskell+{-# LANGUAGE TypeApplications #-}+ import qualified Control.Distributed.MPI as MPI+import Foreign+import Foreign.C.Types  main :: IO () main = do@@ -68,11 +74,35 @@   rank <- MPI.commRank MPI.commWorld   size <- MPI.commSize MPI.commWorld   putStrLn $ "This is process " ++ show rank ++ " of " ++ show size+  let msg = MPI.fromRank rank+  buf <- mallocForeignPtr @CInt+  withForeignPtr buf $ \ptr -> poke ptr msg+  MPI.bcast (buf, 1::Int) MPI.rootRank MPI.commWorld+  msg' <- withForeignPtr buf peek+  putStrLn $ "Process " ++ show msg' ++ " says hi"   MPI.finalize ``` +The high-level API simplifies exchanging data; no need to allocate a+buffer nor to use poke or peek:+```+{-# LANGUAGE TypeApplications #-} +import qualified Control.Distributed.MPI as MPI+import qualified Control.Distributed.MPI.Storable as MPI +main :: IO ()+main = MPI.mainMPI $ do+  rank <- MPI.commRank MPI.commWorld+  size <- MPI.commSize MPI.commWorld+  putStrLn $ "This is process " ++ show rank ++ " of " ++ show size+  let msg = MPI.fromRank rank :: Int+  msg' <- MPI.bcast (Just msg) MPI.rootRank MPI.commWorld+  putStrLn $ "Process " ++ show msg' ++ " says hi"+```+++ ## Installing  `mpi-hs` requires an external MPI library to be available on the@@ -165,11 +195,13 @@  ### Running the example -To run the example provided in `src/Main.hs`:+To run the example provided in the `src` directory:  ``` stack build-mpiexec -n 3 stack exec example+mpiexec stack exec versionn+mpiexec -n 3 stack exec example1+mpiexec -n 3 stack exec example2 ```  ### Running the tests@@ -186,16 +218,17 @@   -<!--- ## Related packages  There are three companion packages that provide the same high-level API via different serialization packages. These are separate packages to reduce the number of dependencies of `mpi-hs`:-- `mpi-hs-binary`, based on `Data.Binary` from-  [`binary`](https://hackage.haskell.org/package/binary)-- `mpi-hs-serialize`, based on `Data.Serialize` from-  [`cereal`](https://hackage.haskell.org/package/cereal)-- `mpi-hs-store`, based on `Data.Store` from-  [`store`](https://hackage.haskell.org/package/store)--->+- [`mpi-hs-binary`](https://github.com/eschnett/mpi-hs-binary), based+  on `Data.Binary` in the+  [`binary`](https://hackage.haskell.org/package/binary) package+- [`mpi-hs-cereal`](https://github.com/eschnett/mpi-hs-cereal), based+  on `Data.Serialize` in the+  [`cereal`](https://hackage.haskell.org/package/cereal) package+- [`mpi-hs-store`](https://github.com/eschnett/mpi-hs-store), based on+  `Data.Store` in the+  [`store`](https://hackage.haskell.org/package/store) package
− bench/Main.hs
@@ -1,6 +0,0 @@--- You can benchmark your code quickly and effectively with Criterion. See its--- website for help: <http://www.serpentine.com/criterion/>.-import Criterion.Main--main :: IO ()-main = defaultMain [bench "const" (whnf const ())]
c/include/mpihs.h view
@@ -35,11 +35,13 @@ void mpihs_get_int(MPI_Datatype *datatype); void mpihs_get_long(MPI_Datatype *datatype); void mpihs_get_long_double(MPI_Datatype *datatype);+void mpihs_get_long_long(MPI_Datatype *datatype); void mpihs_get_long_long_int(MPI_Datatype *datatype); void mpihs_get_short(MPI_Datatype *datatype); void mpihs_get_unsigned(MPI_Datatype *datatype); void mpihs_get_unsigned_char(MPI_Datatype *datatype); void mpihs_get_unsigned_long(MPI_Datatype *datatype);+void mpihs_get_unsigned_long_long(MPI_Datatype *datatype); void mpihs_get_unsigned_short(MPI_Datatype *datatype);  // Op
c/src/mpihs.c view
@@ -23,6 +23,7 @@ void mpihs_get_long_double(MPI_Datatype *datatype) {   *datatype = MPI_LONG_DOUBLE; }+void mpihs_get_long_long(MPI_Datatype *datatype) { *datatype = MPI_LONG_LONG; } void mpihs_get_long_long_int(MPI_Datatype *datatype) {   *datatype = MPI_LONG_LONG_INT; }@@ -33,6 +34,9 @@ } void mpihs_get_unsigned_long(MPI_Datatype *datatype) {   *datatype = MPI_UNSIGNED_LONG;+}+void mpihs_get_unsigned_long_long(MPI_Datatype *datatype) {+  *datatype = MPI_UNSIGNED_LONG_LONG; } void mpihs_get_unsigned_short(MPI_Datatype *datatype) {   *datatype = MPI_UNSIGNED_SHORT;
lib/Control/Distributed/MPI.chs view
@@ -20,7 +20,7 @@  -- | Module: Control.Distributed.MPI -- Description: MPI bindings for Haskell--- Copyright: (C) 2018 Erik Schnetter+-- Copyright: (C) 2018, 2019, 2020 Erik Schnetter -- License: Apache-2.0 -- Maintainer: Erik Schnetter <schnetter@gmail.com> -- Stability: experimental@@ -114,11 +114,13 @@   , datatypeInt   , datatypeLong   , datatypeLongDouble+  , datatypeLongLong   , datatypeLongLongInt   , datatypeShort   , datatypeUnsigned   , datatypeUnsignedChar   , datatypeUnsignedLong+  , datatypeUnsignedLongLong   , datatypeUnsignedShort   , HasDatatype(..) @@ -680,8 +682,12 @@     { alloca- `Datatype' peekDatatype*     } -> `()'#} --- | MPI datatype for 'CLLong' (@MPI_LONG_LONG_INT@). (There is no MPI--- datatype for 'CULLong@).+-- | MPI datatype for 'CLLong' (@MPI_LONG_LONG@).+{#fun pure mpihs_get_long_long as datatypeLongLong+    { alloca- `Datatype' peekDatatype*+    } -> `()'#}++-- | MPI datatype for 'CLLong' (@MPI_LONG_LONG_INT@). {#fun pure mpihs_get_long_long_int as datatypeLongLongInt     { alloca- `Datatype' peekDatatype*     } -> `()'#}@@ -706,6 +712,11 @@     { alloca- `Datatype' peekDatatype*     } -> `()'#} +-- | MPI datatype for 'CULLong' (@MPI_UNSIGNED_LONG_LONG@).+{#fun pure mpihs_get_unsigned_long_long as datatypeUnsignedLongLong+    { alloca- `Datatype' peekDatatype*+    } -> `()'#}+ -- | MPI datatype for 'CUShort' (@MPI_UNSIGNED_SHORT@). {#fun pure mpihs_get_unsigned_short as datatypeUnsignedShort     { alloca- `Datatype' peekDatatype*@@ -719,13 +730,22 @@ instance HasDatatype CDouble where getDatatype = datatypeDouble instance HasDatatype CFloat where getDatatype = datatypeFloat instance HasDatatype CInt where getDatatype = datatypeInt-instance HasDatatype CLLong where getDatatype = datatypeLongLongInt+instance HasDatatype CLLong where getDatatype = datatypeLongLong instance HasDatatype CLong where getDatatype = datatypeLong instance HasDatatype CShort where getDatatype = datatypeShort instance HasDatatype CUChar where getDatatype = datatypeUnsignedChar instance HasDatatype CUInt where getDatatype = datatypeUnsigned+instance HasDatatype CULLong where getDatatype = datatypeUnsignedLongLong instance HasDatatype CULong where getDatatype = datatypeUnsignedLong instance HasDatatype CUShort where getDatatype = datatypeUnsignedShort+instance HasDatatype Int8 where getDatatype = datatypeChar+instance HasDatatype Int16 where getDatatype = datatypeShort+instance HasDatatype Int32 where getDatatype = datatypeInt+instance HasDatatype Int64 where getDatatype = datatypeLongLong+instance HasDatatype Word8 where getDatatype = datatypeByte+instance HasDatatype Word16 where getDatatype = datatypeUnsignedShort+instance HasDatatype Word32 where getDatatype = datatypeUnsigned+instance HasDatatype Word64 where getDatatype = datatypeUnsignedLongLong   @@ -1715,6 +1735,24 @@   scatterTyped (castPtr sendptr) sendcount senddatatype                (castPtr recvptr) recvcount recvdatatype                root comm++-- -- | Scatter data from the root process to all processes, allowing+-- -- varying send counts to each process (collective,+-- -- @[MPI_Scatterv](https://www.open-mpi.org/doc/current/man3/MPI_Scatterv.3.php)@).+-- -- The MPI datatypes are determined automatically from the buffer+-- -- pointer types.+-- scatterv :: (Buffer sb, Buffer rb)+--          => sb        -- ^ Source buffer (only used on the root process)+--          -> rb                   -- ^ Destination buffer+--          -> Rank                 -- ^ Root rank+--          -> Comm                 -- ^ Communicator+--          -> IO ()+-- scatterv sendbuf recvbuf root comm =+--   withPtrLenType sendbuf $ \sendptr sendcount senddatatype ->+--   withPtrLenType recvbuf $ \recvptr recvcount recvdatatype ->+--   scatterTyped (castPtr sendptr) sendcount senddatatype+--                (castPtr recvptr) recvcount recvdatatype+--                root comm  {#fun Send as sendTyped     { id `Ptr ()'
lib/Control/Distributed/MPI/Storable.hs view
@@ -68,13 +68,17 @@      -- ** Collective (blocking)   , barrier+  , bcast   , bcastRecv   , bcastSend+  , bcastSend_      -- ** Collective (non-blocking)   , ibarrier+  , ibcast   , ibcastRecv   , ibcastSend+  , ibcastSend_   ) where  import Prelude hiding (init)@@ -85,6 +89,7 @@ import Control.Monad.Loops import qualified Data.ByteString as B import qualified Data.ByteString.Unsafe as B+import Data.Maybe import Data.Typeable import Foreign import Foreign.C.Types@@ -322,6 +327,21 @@   -- | Broadcast a message from one process (the "root") to all other+-- processes in the communicator. The send object must be present+-- (`Just`) on the root, and is ignored on all non-root processes.+bcast :: CanSerialize a+      => Maybe a+      -> Rank+      -> Comm+      -> IO a+bcast sendobj root comm =+  do rank <- MPI.commRank comm+     if rank == root+       then do mpiAssert (isJust sendobj) "bcast: expected send object on root"+               bcastSend (fromJust sendobj) root comm+       else bcastRecv root comm++-- | Broadcast a message from one process (the "root") to all other -- processes in the communicator. Call this function on all non-root -- processes. Call 'bcastSend' instead on the root process. bcastRecv :: CanSerialize a@@ -331,7 +351,7 @@ bcastRecv root comm =   do rank <- MPI.commRank comm      mpiAssert (rank /= root) "bcastRecv: expected rank /= root"-     lenbuf <- mallocForeignPtr @CLong+     lenbuf <- mallocForeignPtr @CInt      lenreq <- MPI.ibcast (lenbuf, 1::Int) root comm      whileM_ (not <$> MPI.test_ lenreq) yield      len <- withForeignPtr lenbuf peek@@ -345,22 +365,58 @@ -- | Broadcast a message from one process (the "root") to all other -- processes in the communicator. Call this function on the root -- process. Call 'bcastRecv' instead on all non-root processes.-bcastSend :: CanSerialize a-          => a-          -> Rank-          -> Comm-          -> IO ()-bcastSend sendobj root comm =+bcastSend_ :: CanSerialize a+           => a+           -> Rank+           -> Comm+           -> IO ()+bcastSend_ sendobj root comm =   do rank <- MPI.commRank comm      mpiAssert (rank == root) "bcastSend: expected rank == root"      sendbuf <- serialize sendobj-     lenbuf <- mallocForeignPtr @CLong+     lenbuf <- mallocForeignPtr @CInt      withForeignPtr lenbuf $ \ptr -> poke ptr (fromIntegral (B.length sendbuf))      lenreq <- MPI.ibcast (lenbuf, 1::Int) root comm      whileM_ (not <$> MPI.test_ lenreq) yield      req <- MPI.ibcast sendbuf root comm      whileM_ (not <$> MPI.test_ req) yield +-- | Broadcast a message from one process (the "root") to all other+-- processes in the communicator. Call this function on the root+-- process. Call 'bcastRecv' instead on all non-root processes.+bcastSend :: CanSerialize a+          => a+          -> Rank+          -> Comm+          -> IO a+bcastSend sendobj root comm =+  do bcastSend_ sendobj root comm+     return sendobj++-- | Begin a barrier. Call 'test' or 'wait' to finish the+-- communication.+ibarrier :: Comm+         -> IO (Request ())+ibarrier comm =+  do result <- newEmptyMVar+     _ <- forkIO $+       do req <- MPI.ibarrier comm+          whileM_ (not <$> MPI.test_ req) yield+          putMVar result (Status MPI.anySource MPI.anyTag, ())+     return (Request result)++ibcast :: CanSerialize a+       => Maybe a+       -> Rank+       -> Comm+       -> IO (Request a)+ibcast sendobj root comm =+  do rank <- MPI.commRank comm+     if rank == root+       then do mpiAssert (isJust sendobj) "ibcast: expected send object on root"+               ibcastSend (fromJust sendobj) root comm+       else ibcastRecv root comm+ ibcastRecv :: CanSerialize a            => Rank            -> Comm@@ -376,22 +432,52 @@            => a            -> Rank            -> Comm-           -> IO (Request ())+           -> IO (Request a) ibcastSend sendobj root comm =   do result <- newEmptyMVar      _ <- forkIO $-       do bcastSend sendobj root comm-          putMVar result (Status root MPI.anyTag, ())+       do bcastSend_ sendobj root comm+          putMVar result (Status root MPI.anyTag, sendobj)      return (Request result) --- | Begin a barrier. Call 'test' or 'wait' to finish the--- communication.-ibarrier :: Comm-         -> IO (Request ())-ibarrier comm =+ibcastSend_ :: CanSerialize a+            => a+            -> Rank+            -> Comm+            -> IO (Request ())+ibcastSend_ sendobj root comm =   do result <- newEmptyMVar      _ <- forkIO $-       do req <- MPI.ibarrier comm-          whileM_ (not <$> MPI.test_ req) yield-          putMVar result (Status MPI.anySource MPI.anyTag, ())+       do bcastSend_ sendobj root comm+          putMVar result (Status root MPI.anyTag, ())      return (Request result)++-- scatter :: CanSerialize a+--         => Maybe a+--         -> Rank+--         -> Comm+--         -> IO (Request a)+-- scatter msendobj root comm =+--   do rank <- commRank comm+--      sendbuf <-+--        if (rank == root)+--        then do mpiAssert (isJust msendobj)+--                serialize (fromJust sendobj)+--        else return nullPtr+--      lenbuf <- mallocForeignPtr @CInt+--      withForeignPtr lenbuf $ \ptr -> poke ptr (fromIntegral (B.length sendbuf))+--      lenreq <- MPI.ibcast (lenbuf, 1::Int) root comm+--      whileM_ (not <$> MPI.test_ lenreq) yield+--      req <- MPI.iscatterv sendbuf root comm+--      whileM_ (not <$> MPI.test_ req) yield+-- +-- scatterRecv :: CanSerialize a+--             => Rank+--             -> Comm+--             -> IO (Request a)+-- +-- scatterSend :: CanSerialize a+--             => a+--             -> Rank+--             -> Comm+--             -> IO (Request a)
mpi-hs.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 11b62fed3be3a0f857f2e02c4f51e8d2161fe465d5ef830539f21ba83ba7fb5d+-- hash: 538426701e8b2b17467e84727926d3787dccae19f2208fab5e05afde41654712  name:           mpi-hs-version:        0.6.0.0+version:        0.7.0.0 synopsis:       MPI bindings for Haskell description:    MPI (the [Message Passinag Interface](https://www.mpi-forum.org)) is                 a widely used standard for distributed-memory programming on HPC@@ -42,6 +42,7 @@ bug-reports:    https://github.com/eschnett/mpi-hs/issues author:         Erik Schnetter <schnetter@gmail.com> maintainer:     Erik Schnetter <schnetter@gmail.com>+copyright:      2018, 2019, 2020 Erik Schnetter <schnetter@gmail.com> license:        Apache-2.0 license-file:   LICENSE build-type:     Simple@@ -50,6 +51,7 @@     README.md     package.yaml     stack.yaml+    stack.yaml.lock     c/include/mpihs.h     c/src/mpihs.c @@ -132,14 +134,16 @@   if flag(mpich-ubuntu)     include-dirs:         /usr/lib/mpich/include+        /usr/include/x86_64-linux-gnu/mpich     extra-lib-dirs:         /usr/lib/mpich/lib+        /usr/lib/x86_64-linux-gnu     extra-libraries:         mpich   default-language: Haskell2010 -executable example-  main-is: Main.hs+executable example1+  main-is: example1.hs   other-modules:       Paths_mpi_hs   hs-source-dirs:@@ -179,23 +183,23 @@   if flag(mpich-ubuntu)     include-dirs:         /usr/lib/mpich/include+        /usr/include/x86_64-linux-gnu/mpich     extra-lib-dirs:         /usr/lib/mpich/lib+        /usr/lib/x86_64-linux-gnu     extra-libraries:         mpich   default-language: Haskell2010 -test-suite mpi-test-  type: exitcode-stdio-1.0-  main-is: Main.hs+executable example2+  main-is: example2.hs   other-modules:       Paths_mpi_hs   hs-source-dirs:-      tests/mpi+      src   ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N   build-depends:       base-    , monad-loops     , mpi-hs   if flag(openmpi-debian)     include-dirs:@@ -228,22 +232,74 @@   if flag(mpich-ubuntu)     include-dirs:         /usr/lib/mpich/include+        /usr/include/x86_64-linux-gnu/mpich     extra-lib-dirs:         /usr/lib/mpich/lib+        /usr/lib/x86_64-linux-gnu     extra-libraries:         mpich   default-language: Haskell2010 -test-suite mpi-test-storable+executable version+  main-is: version.hs+  other-modules:+      Paths_mpi_hs+  hs-source-dirs:+      src+  ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N+  build-depends:+      base+    , mpi-hs+  if flag(openmpi-debian)+    include-dirs:+        /usr/lib/x86_64-linux-gnu/openmpi/include+    extra-lib-dirs:+        /usr/lib/x86_64-linux-gnu/openmpi/lib+    extra-libraries:+        mpi+  if flag(openmpi-macports)+    include-dirs:+        /opt/local/include/openmpi-mp+    extra-lib-dirs:+        /opt/local/lib/openmpi-mp+    extra-libraries:+        mpi+  if flag(openmpi-ubuntu)+    include-dirs:+        /usr/lib/openmpi/include+    extra-lib-dirs:+        /usr/lib/openmpi/lib+    extra-libraries:+        mpi+  if flag(mpich-macports)+    include-dirs:+        /opt/local/include/mpich-gcc9+    extra-lib-dirs:+        /opt/local/lib/mpich-gcc9+    extra-libraries:+        mpi+  if flag(mpich-ubuntu)+    include-dirs:+        /usr/lib/mpich/include+        /usr/include/x86_64-linux-gnu/mpich+    extra-lib-dirs:+        /usr/lib/mpich/lib+        /usr/lib/x86_64-linux-gnu+    extra-libraries:+        mpich+  default-language: Haskell2010++test-suite mpi-test   type: exitcode-stdio-1.0   main-is: Main.hs   other-modules:       Paths_mpi_hs   hs-source-dirs:-      tests/storable+      tests/mpi   ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N   build-depends:       base+    , monad-loops     , mpi-hs   if flag(openmpi-debian)     include-dirs:@@ -276,23 +332,24 @@   if flag(mpich-ubuntu)     include-dirs:         /usr/lib/mpich/include+        /usr/include/x86_64-linux-gnu/mpich     extra-lib-dirs:         /usr/lib/mpich/lib+        /usr/lib/x86_64-linux-gnu     extra-libraries:         mpich   default-language: Haskell2010 -benchmark mpi-hs-benchmarks+test-suite mpi-test-storable   type: exitcode-stdio-1.0   main-is: Main.hs   other-modules:       Paths_mpi_hs   hs-source-dirs:-      bench+      tests/storable   ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N   build-depends:       base-    , criterion     , mpi-hs   if flag(openmpi-debian)     include-dirs:@@ -325,8 +382,10 @@   if flag(mpich-ubuntu)     include-dirs:         /usr/lib/mpich/include+        /usr/include/x86_64-linux-gnu/mpich     extra-lib-dirs:         /usr/lib/mpich/lib+        /usr/lib/x86_64-linux-gnu     extra-libraries:         mpich   default-language: Haskell2010
package.yaml view
@@ -1,9 +1,10 @@ name: mpi-hs-version: '0.6.0.0'+version: '0.7.0.0' github: "eschnett/mpi-hs" license: Apache-2.0 author: "Erik Schnetter <schnetter@gmail.com>" maintainer: "Erik Schnetter <schnetter@gmail.com>"+copyright: "2018, 2019, 2020 Erik Schnetter <schnetter@gmail.com>" category: Distributed Computing synopsis: MPI bindings for Haskell description: |@@ -63,6 +64,7 @@   - README.md   - package.yaml   - stack.yaml+  - stack.yaml.lock   - c/include/mpihs.h   - c/src/mpihs.c @@ -114,15 +116,17 @@   - condition: flag(mpich-ubuntu)     include-dirs:       - /usr/lib/mpich/include+      - /usr/include/x86_64-linux-gnu/mpich     extra-lib-dirs:       - /usr/lib/mpich/lib+      - /usr/lib/x86_64-linux-gnu     extra-libraries:       - mpich  executables:-  example:+  version:     source-dirs: src-    main: Main.hs+    main: version.hs     dependencies:       - base       - mpi-hs@@ -130,15 +134,22 @@       - -rtsopts       - -threaded       - -with-rtsopts=-N--benchmarks:-  mpi-hs-benchmarks:-    source-dirs: bench-    main: Main.hs+  example1:+    source-dirs: src+    main: example1.hs     dependencies:       - base       - mpi-hs-      - criterion+    ghc-options:+      - -rtsopts+      - -threaded+      - -with-rtsopts=-N+  example2:+    source-dirs: src+    main: example2.hs+    dependencies:+      - base+      - mpi-hs     ghc-options:       - -rtsopts       - -threaded
− src/Main.hs
@@ -1,18 +0,0 @@-import Control.Exception-import Data.Version--import qualified Control.Distributed.MPI as MPI--main :: IO ()-main = bracket-  MPI.init-  (\_ ->  MPI.finalize) $-  \_ -> do library <- MPI.getLibraryVersion-           putStrLn $ "MPI library " ++ library-           version <- MPI.getVersion-           putStrLn $ "MPI standard " ++ showVersion version-           processor <- MPI.getProcessorName-           rank <- MPI.commRank MPI.commWorld-           size <- MPI.commSize MPI.commWorld-           putStrLn $ "MPI processor " ++ processor ++-             " (" ++ show rank ++ "/" ++ show size ++ ")"
+ src/example1.hs view
@@ -0,0 +1,19 @@+{-# LANGUAGE TypeApplications #-}++import qualified Control.Distributed.MPI as MPI+import Foreign+import Foreign.C.Types++main :: IO ()+main = do+  MPI.init+  rank <- MPI.commRank MPI.commWorld+  size <- MPI.commSize MPI.commWorld+  putStrLn $ "This is process " ++ show rank ++ " of " ++ show size+  let msg = MPI.fromRank rank+  buf <- mallocForeignPtr @CInt+  withForeignPtr buf $ \ptr -> poke ptr msg+  MPI.bcast (buf, 1::Int) MPI.rootRank MPI.commWorld+  msg' <- withForeignPtr buf peek+  putStrLn $ "Process " ++ show msg' ++ " says hi"+  MPI.finalize
+ src/example2.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE TypeApplications #-}++import qualified Control.Distributed.MPI.Storable as MPI++main :: IO ()+main = MPI.mainMPI $ do+  rank <- MPI.commRank MPI.commWorld+  size <- MPI.commSize MPI.commWorld+  putStrLn $ "This is process " ++ show rank ++ " of " ++ show size+  let msg = MPI.fromRank rank :: Int+  msg' <- MPI.bcast (Just msg) MPI.rootRank MPI.commWorld+  putStrLn $ "Process " ++ show msg' ++ " says hi"
+ src/version.hs view
@@ -0,0 +1,16 @@+import Control.Exception+import Data.Version++import qualified Control.Distributed.MPI as MPI++main :: IO ()+main = bracket_ MPI.init MPI.finalize $ do+  library <- MPI.getLibraryVersion+  putStrLn $ "MPI library " ++ library+  version <- MPI.getVersion+  putStrLn $ "MPI standard " ++ showVersion version+  processor <- MPI.getProcessorName+  rank <- MPI.commRank MPI.commWorld+  size <- MPI.commSize MPI.commWorld+  putStrLn $ "MPI processor " ++ processor+    ++ " (" ++ show rank ++ "/" ++ show size ++ ")"
+ stack.yaml.lock view
@@ -0,0 +1,12 @@+# This file was autogenerated by Stack.+# You should not edit this file by hand.+# For more information, please see the documentation at:+#   https://docs.haskellstack.org/en/stable/lock_files++packages: []+snapshots:+- completed:+    size: 491372+    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/15/5.yaml+    sha256: 1b549cfff328040c382a70a84a2087aac8dab6d778bf92f32a93a771a1980dfc+  original: lts-15.5
tests/storable/Main.hs view
@@ -190,13 +190,9 @@   [ testCase "barrier" $     do MPI.barrier MPI.commWorld   , testCase "bcast" $-    do rank <- MPI.commRank MPI.commWorld-       let sendmsg :: FixedString = "Hello, World!"+    do let sendmsg :: FixedString = "Hello, World!"        recvmsg :: FixedString <--         if rank == MPI.rootRank-         then do MPI.bcastSend sendmsg MPI.rootRank MPI.commWorld-                 return sendmsg-         else do MPI.bcastRecv MPI.rootRank MPI.commWorld+         MPI.bcast (Just sendmsg) MPI.rootRank MPI.commWorld        recvmsg == sendmsg @? ""   ] @@ -208,14 +204,9 @@     do req <- MPI.ibarrier MPI.commWorld        MPI.wait_ req   , testCase "bcast" $-    do rank <- MPI.commRank MPI.commWorld-       let sendmsg :: FixedString = "Hello, World!"+    do let sendmsg :: FixedString = "Hello, World!"        recvmsg :: FixedString <--         if rank == MPI.rootRank-         then do req <- MPI.ibcastSend sendmsg MPI.rootRank MPI.commWorld-                 MPI.wait_ req-                 return sendmsg-         else do req <- MPI.ibcastRecv MPI.rootRank MPI.commWorld-                 MPI.wait_ req+         do req <- MPI.ibcast (Just sendmsg) MPI.rootRank MPI.commWorld+            MPI.wait_ req        recvmsg == sendmsg @? ""   ]