{"id":19434477,"url":"https://github.com/mlin/forkwork","last_synced_at":"2025-04-24T20:32:07.570Z","repository":{"id":5956199,"uuid":"7177304","full_name":"mlin/forkwork","owner":"mlin","description":"OCaml library for forking child processes to perform work on multiple cores","archived":false,"fork":false,"pushed_at":"2019-09-09T03:48:32.000Z","size":240,"stargazers_count":19,"open_issues_count":4,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-03T10:37:50.806Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mlin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-12-15T08:17:38.000Z","updated_at":"2023-07-28T10:44:39.000Z","dependencies_parsed_at":"2022-09-11T12:22:06.009Z","dependency_job_id":null,"html_url":"https://github.com/mlin/forkwork","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlin%2Fforkwork","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlin%2Fforkwork/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlin%2Fforkwork/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlin%2Fforkwork/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mlin","download_url":"https://codeload.github.com/mlin/forkwork/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250704831,"owners_count":21473769,"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":[],"created_at":"2024-11-10T14:46:33.988Z","updated_at":"2025-04-24T20:32:07.300Z","avatar_url":"https://github.com/mlin.png","language":"OCaml","funding_links":[],"categories":["Parallelism"],"sub_categories":[],"readme":"# [ForkWork](https://github.com/mlin/forkwork)\n\nA simple OCaml library for forking child processes to perform work on multiple cores.\n\nForkWork is intended for workloads that a master process can partition into independent jobs, each of which will typically take a while to execute (several seconds, or more). Also, the resulting values should not be too massive, since they must be marshalled for transmission back to the master process.\n\nAmong the numerous tools for multicore parallelism available in the OCaml ecosystem, ForkWork fits somewhere in between [Netmcore](http://projects.camlcity.org/projects/dl/ocamlnet-3.6.1/doc/html-main/Netmcore.html) and [Parmap](http://www.dicosmo.org/code/parmap/). It's a bit easier to use than the former, and a bit more flexible than the latter.\n\n## API documentation\n\nSee [ocamldoc:ForkWork](http://mlin.github.com/forkwork/ForkWork.html)\n\n## Installation\n\nForkWork is mainly tested on Linux and Mac OS X with OCaml 3.12 and above. It should work on most flavors of Unix. The easiest way to install it is by using [OPAM](http://opam.ocamlpro.com):\n`opam install forkwork`.\n\nIf you don't use OPAM, set up [findlib](http://projects.camlcity.org/projects/findlib.html),\ndefine the `OCAMLFIND_DESTDIR` environment variable if necessary and\n\n```git clone https://github.com/mlin/forkwork.git \u0026\u0026 cd forkwork \u0026\u0026 make \u0026\u0026 make install```\n\n[![Build Status](https://travis-ci.org/mlin/forkwork.png)](https://travis-ci.org/mlin/forkwork)\n\nYou can then use `ocamlfind` as usual to include the `forkwork` package when\ncompiling your program (making sure `OCAMLPATH` includes `OCAMLFIND_DESTDIR` if\nyou changed it).\n\n## High-level example\n\nForkWork provides a high-level interface consisting of parallel map functions for lists and arrays. Here's a program that forks four worker processes to compute a Monte Carlo estimate of π:\n\n```\n(* Worker: sample k points uniformly at random from the unit square; return\n   how many fall inside and outside of the unit circle *)\nlet worker k =\n  Random.self_init ();\n  let inside = ref 0 in\n  let outside = ref 0 in begin\n    for i = 1 to k do\n      let x = Random.float 1.0 in\n      let y = Random.float 1.0 in\n      incr (if x *. x +. y *. y \u003c= 1.0 then inside else outside)\n    done;\n    (!inside,!outside)\n  end\n;;\n\nlet estimate_pi n k =\n  (* Fork n parallel worker processes to collect samples *)\n  let results = ForkWork.map_array worker (Array.make n k) in\n  (* Combine the results and derive the estimate *)\n  let insides, outsides = List.split (Array.to_list results) in\n  let inside = float (List.fold_left (+) 0 insides) in\n  let outside = float (List.fold_left (+) 0 outsides) in\n  4.0 *. (inside /. (inside +. outside))\n;;\n\nlet n = 30 and k = 25_000_000 in\nPrintf.printf \"Based on %.1e samples, π ≈ %f\\n\" (float (n*k)) (estimate_pi n k)\n;;\n```\n\nRun this like so:\n\n```\n$ ocamlfind ocamlopt -o estimate_pi -package forkwork -linkpkg estimate_pi.ml \u0026\u0026 time ./estimate_pi\nBased on 7.5e+08 samples, π ≈ 3.141497\n\nreal  0m51.119s\nuser  3m16.268s\nsys   0m1.084s\n```\n\nOne other salient feature of ForkWork's high-level interface is that it tries to deal with worker exceptions in a reasonable way, which is difficult because exceptions [cannot be marshalled reliably](http://caml.inria.fr/mantis/view.php?id=1961). There's a mechanism for workers to cause ForkWork to both abort the parallel computation and also raise an OCaml exception to the caller with specifc information about the problem. The author was motivated to write ForkWork in part because similar existing libraries did not handle this well, at the time.\n\n## Lower-level example\n\nThere is also a lower-level interface providing much more control over the scheduling of child processes and retrieval of their results. For example, the master process can do other things while worker processes are running, including launch more worker processes, and the result of any individual child process can be retrieved as soon as it finishes.\n\nA [fancier version of the estimate_pi example](https://github.com/mlin/forkwork/blob/master/examples/estimate_pi_interval.ml) uses the lower-level interface to run the Monte Carlo sampling until the estimate reaches a certain theoretical accuracy threshold, using the available processors continuously and terminating the outstanding workers when done.\n\n## Running tests\n\nThe tests use [kaputt](http://kaputt.x9c.fr). To run them, `./configure --enable-tests` and `make test`.\n\nThey also run on Travis CI: [![Build Status](https://travis-ci.org/mlin/forkwork.png)](https://travis-ci.org/mlin/forkwork)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlin%2Fforkwork","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmlin%2Fforkwork","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlin%2Fforkwork/lists"}