{"id":20247475,"url":"https://github.com/eschnett/mpi-hs","last_synced_at":"2025-06-13T13:07:11.886Z","repository":{"id":56847524,"uuid":"152750655","full_name":"eschnett/mpi-hs","owner":"eschnett","description":"MPI bindings for Haskell","archived":false,"fork":false,"pushed_at":"2024-10-16T14:13:36.000Z","size":217,"stargazers_count":16,"open_issues_count":1,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-31T00:48:41.910Z","etag":null,"topics":["distributed-computing","haskell","high-performance-computing","mpi","parallel-computing"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eschnett.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-12T12:56:50.000Z","updated_at":"2024-10-16T14:13:41.000Z","dependencies_parsed_at":"2022-09-09T06:21:56.084Z","dependency_job_id":"f51fde7c-559b-45b3-aebe-b2c75d1603d8","html_url":"https://github.com/eschnett/mpi-hs","commit_stats":{"total_commits":138,"total_committers":2,"mean_commits":69.0,"dds":"0.036231884057971064","last_synced_commit":"c8fb0581eaabbbab765103e98548ce1435f639bf"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/eschnett/mpi-hs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eschnett%2Fmpi-hs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eschnett%2Fmpi-hs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eschnett%2Fmpi-hs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eschnett%2Fmpi-hs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eschnett","download_url":"https://codeload.github.com/eschnett/mpi-hs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eschnett%2Fmpi-hs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259650958,"owners_count":22890385,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["distributed-computing","haskell","high-performance-computing","mpi","parallel-computing"],"created_at":"2024-11-14T09:37:32.517Z","updated_at":"2025-06-13T13:07:11.853Z","avatar_url":"https://github.com/eschnett.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [mpi-hs](https://github.com/eschnett/mpi-hs)\n\n[MPI](https://www.mpi-forum.org) bindings for Haskell\n\n* [GitHub](https://github.com/eschnett/mpi-hs): Source code repository\n* [Hackage](http://hackage.haskell.org/package/mpi-hs): Haskell\n  package and documentation\n* [Stackage](https://www.stackage.org/package/mpi-hs): Stackage\n  snapshots\n* [GitHub Actions](https://docs.github.com/en/actions) Build Status\n  [![.github/workflows/build.yml](https://github.com/eschnett/mpi-hs/actions/workflows/build.yml/badge.svg)](https://github.com/eschnett/mpi-hs/actions/workflows/build.yml)\n\n\n\n## Overview\n\nMPI (the Message Passing Interface) is a widely used standard for\ndistributed-memory programming on HPC (High Performance Computing)\nsystems. MPI allows exchanging data (_messages_) between programs\nrunning in parallel. There are several high-quality open source MPI\nimplementations (e.g. MPICH, MVAPICH, OpenMPI) as well as a variety of\nclosed-source implementations. These libraries can typically make use\nof high-bandwidth low-latency communication hardware such as\nInfiniBand.\n\nThis library `mpi-hs` provides Haskell bindings for MPI. It is based\non ideas taken from\n[haskell-mpi](https://github.com/bjpop/haskell-mpi),\n[Boost.MPI](https://www.boost.org/doc/libs/1_64_0/doc/html/mpi.html)\nfor C++, and [MPI for\nPython](https://mpi4py.readthedocs.io/en/stable/).\n\n`mpi-hs` provides two API levels: A low-level API gives rather direct\naccess to the actual MPI API, apart from certain \"reasonable\" mappings\nfrom C to Haskell (e.g. output arguments that are in C stored via a\npointer are in Haskell regular return values). A high-level API\nsimplifies exchanging arbitrary values that can be serialized.\n\n\n\n## Example\n\nThis is a typical MPI C code:\n```C\n#include \u003cstdio.h\u003e\n#include \u003cmpi.h\u003e\n\nint main(int argc, char** argv) {\n  MPI_Init(\u0026argc, \u0026argv);\n  int rank, size;\n  MPI_Comm_rank(MPI_COMM_WORLD, \u0026rank);\n  MPI_Comm_size(MPI_COMM_WORLD, \u0026size);\n  printf(\"This is process %d of %d\\n\", rank, size);\n  int msg = rank;\n  MPI_Bcast(\u0026msg, 1, MPI_INT, 0, MPI_COMM_WORLD):\n  printf(\"Process %d says hi\\n\", msg);\n  MPI_Finalize();\n  return 0;\n}\n```\n\nThe Haskell equivalent looks like this:\n```Haskell\n{-# LANGUAGE TypeApplications #-}\n\nimport qualified Control.Distributed.MPI as MPI\nimport Foreign\nimport Foreign.C.Types\n\nmain :: IO ()\nmain = do\n  MPI.init\n  rank \u003c- MPI.commRank MPI.commWorld\n  size \u003c- MPI.commSize MPI.commWorld\n  putStrLn $ \"This is process \" ++ show rank ++ \" of \" ++ show size\n  let msg = MPI.fromRank rank\n  buf \u003c- mallocForeignPtr @CInt\n  withForeignPtr buf $ \\ptr -\u003e poke ptr msg\n  MPI.bcast (buf, 1::Int) MPI.rootRank MPI.commWorld\n  msg' \u003c- withForeignPtr buf peek\n  putStrLn $ \"Process \" ++ show msg' ++ \" says hi\"\n  MPI.finalize\n```\n\nThe high-level API simplifies exchanging data; no need to allocate a\nbuffer nor to use poke or peek:\n```\n{-# LANGUAGE TypeApplications #-}\n\nimport qualified Control.Distributed.MPI as MPI\nimport qualified Control.Distributed.MPI.Storable as MPI\n\nmain :: IO ()\nmain = MPI.mainMPI $ do\n  rank \u003c- MPI.commRank MPI.commWorld\n  size \u003c- MPI.commSize MPI.commWorld\n  putStrLn $ \"This is process \" ++ show rank ++ \" of \" ++ show size\n  let msg = MPI.fromRank rank :: Int\n  msg' \u003c- MPI.bcast (Just msg) MPI.rootRank MPI.commWorld\n  putStrLn $ \"Process \" ++ show msg' ++ \" says hi\"\n```\n\n\n\n## Installing\n\n`mpi-hs` requires an external MPI library to be available on the\nsystem. How to install such a library is beyond the scope of these\ninstructions.\n\n`mpi-hs` uses pkg-config to find an MPI installation and supports:\n\n- OpenMPI via the `-fopenmpi` cabal flag (default)\n- MVAPICH via the `-fmvapich -f-openmpi` cabal flags\n- MPICH via the `-fmpich -f-openmpi` cabal flags\n\nAlternatively, `mpi-hs` can link against `-lmpi` an `mpi.h` generically, if all\npkg-config options are disabled via `-f-openmpi -f-mpich -f-mvapich`.\nIn this case you may need to specify `--extra-include-dirs` and `--extra-lib-dirs`\nand point them to your MPI installation directory.\n\n\n### Testing the MPI installation with a C program\n\nTo test your MPI installation independently of using Haskell, copy the\nexample MPI C code into a file `mpi-example.c`, and run these commands:\n\n```sh\nmpicc -c mpi-example.c\nmpicc -o mpi-example mpi-example.o\nmpiexec -n 3 ./mpi-example\n```\n\nAll three commands must complete without error, and the last command\nmust output something like\n\n```\nThis is process 0 of 3\nThis is process 1 of 3\nThis is process 2 of 3\n```\n\nwhere the lines will be output in a random order. (The output might\neven be jumbled, i.e. the characters in these three lines might be\nmixed up.)\n\nIf these commands do not work, then this needs to be corrected before\n`mpi-hs` can work. If additional compiler options or libraries are\nneeded, then these need to be added to the `stack.yaml` configuration\nfile (for include and library paths; see `extra-include-dirs` and\n`extra-lib-dirs` there) or the `package.yaml` configuration file (for\nadditional libraries; see `extra-libraries` there).\n\n\n\n## Examples and Tests\n\n### Running the example\n\nTo run the example provided in the `src` directory:\n\n```\nstack build\nmpiexec stack exec version\nmpiexec -n 3 stack exec example1\nmpiexec -n 3 stack exec example2\n```\n\n### Running the tests\n\nThere are two test cases provided in `tests`. The first (`mpi-test`)\ntests the low-level API, the second (`mpi-test-storable`) tests the\nhigh-level API:\n\n```\nstack build --test --no-run-tests\nmpiexec -n 3 stack exec -- $(stack path --dist-dir)/build/mpi-test/mpi-test\nmpiexec -n 3 stack exec -- $(stack path --dist-dir)/build/mpi-test-storable/mpi-test-storable\n```\n\n\n\n## Related packages\n\nThere are three companion packages that provide the same high-level\nAPI via different serialization packages. These are separate packages\nto reduce the number of dependencies of `mpi-hs`:\n- [`mpi-hs-binary`](https://github.com/eschnett/mpi-hs-binary), based\n  on `Data.Binary` in the\n  [`binary`](https://hackage.haskell.org/package/binary) package\n- [`mpi-hs-cereal`](https://github.com/eschnett/mpi-hs-cereal), based\n  on `Data.Serialize` in the\n  [`cereal`](https://hackage.haskell.org/package/cereal) package\n- [`mpi-hs-store`](https://github.com/eschnett/mpi-hs-store), based on\n  `Data.Store` in the\n  [`store`](https://hackage.haskell.org/package/store) package\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feschnett%2Fmpi-hs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feschnett%2Fmpi-hs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feschnett%2Fmpi-hs/lists"}