{"id":17791889,"url":"https://github.com/twesterhout/halide-haskell","last_synced_at":"2025-03-16T16:31:43.958Z","repository":{"id":114169547,"uuid":"372287961","full_name":"twesterhout/halide-haskell","owner":"twesterhout","description":"Haskell bindings to Halide","archived":false,"fork":false,"pushed_at":"2024-03-18T11:32:04.000Z","size":731,"stargazers_count":20,"open_issues_count":4,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-27T11:41:22.921Z","etag":null,"topics":["gpu","halide","haskell","high-performance-computing","jit"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/twesterhout.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2021-05-30T18:28:52.000Z","updated_at":"2024-04-09T01:22:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"668dc6f2-b10d-427e-93be-ff77ae1fa9b3","html_url":"https://github.com/twesterhout/halide-haskell","commit_stats":{"total_commits":133,"total_committers":2,"mean_commits":66.5,"dds":"0.022556390977443663","last_synced_commit":"7240b4fd6ce74e1df327e303b060dcc09e37d44f"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twesterhout%2Fhalide-haskell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twesterhout%2Fhalide-haskell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twesterhout%2Fhalide-haskell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twesterhout%2Fhalide-haskell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/twesterhout","download_url":"https://codeload.github.com/twesterhout/halide-haskell/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243822295,"owners_count":20353500,"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":["gpu","halide","haskell","high-performance-computing","jit"],"created_at":"2024-10-27T10:56:26.984Z","updated_at":"2025-03-16T16:31:43.504Z","avatar_url":"https://github.com/twesterhout.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\nhalide-haskell\n\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"assets/construction_1f6a7.png\" width=\"32\"\u003eThis project is still under heavy development and might not be production-ready\u003cimg src=\"assets/construction_1f6a7.png\" width=\"32\"\u003e\u003cbr\u003e\nWe encourage experimenting with it and reporting any issues you run into via\n[Github issues](https://github.com/twesterhout/halide-haskell/issues).\n\n\u003cbr /\u003e\n\n[**Tutorials**](https://github.com/twesterhout/halide-haskell/tree/master/tutorials) | [**Documentation**](https://hackage.haskell.org/package/halide-haskell-0.0.1.0) | [**Showcases**](https://github.com/twesterhout/halide-haskell-examples)\n\n[![license](https://img.shields.io/github/license/twesterhout/halide-haskell.svg?style=flat-square)](LICENSE)\n[![build](https://img.shields.io/github/actions/workflow/status/twesterhout/halide-haskell/ci.yml?style=flat-square)](https://github.com/twesterhout/halide-haskell/actions/workflows/ci.yml)\n[![Hackage](https://img.shields.io/hackage/v/halide-haskell?style=flat-square)](https://hackage.haskell.org/package/halide-haskell)\n\n\u003c/div\u003e\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n[Halide](https://halide-lang.org/) is a programming language designed to make\nit easier to write high-performance image and array processing code on modern\nmachines. Rather than being a standalone programming language, Halide is\nembedded in C++. This means you write C++ code that builds an in-memory\nrepresentation of a Halide pipeline using Halide's C++ API. You can then\ncompile this representation to an object file, or JIT-compile it and run it in\nthe same process.\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003ch4 align=\"center\" \u003e\nThis package provides Haskell bindings that allow to write Halide embedded in\nHaskell without C++ 😋.\n\u003c/h4\u003e\n\n  - [Example usage](#-example-usage)\n  - [Installing](#-installing)\n  - [Motivation](#-motivation)\n  - [Contributing](#-contributing)\n\n\n## 🚀 Example usage\n\nAs a simple example, here's how you could implement array addition with halide-haskell:\n\n```haskell\n{-# LANGUAGE AllowAmbiguousTypes, DataKinds, OverloadedStrings, ViewPatterns #-}\nimport Language.Halide\n\n-- The algorithm\nmkArrayPlus = compile $ \\(buffer \"a\" -\u003e a) (buffer \"b\" -\u003e b) -\u003e do\n  -- Create an index variable\n  i \u003c- mkVar \"i\"\n  -- Define the resulting function. We call it \"out\".\n  -- In pseudocode it's equivalent to the following: out[i] = a[i] + b[i]\n  out \u003c- define \"out\" i $ a ! i + b ! i\n  -- Perform a fancy optimization and use SIMD: we split the loop over i into\n  -- an inner and an outer loop and then vectorize the inner loop\n  inner \u003c- mkVar \"inner\"\n  split TailAuto i (i, inner) 4 out \u003e\u003e= vectorize inner\n\n-- Example usage of our Halide pipeline\nmain :: IO ()\nmain = do\n  let a, b :: [Float]\n      a = [1, 2, 3, 4, 5]\n      b = [6, 7, 8, 9, 10]\n  -- Compile the code\n  arrayPlus \u003c- mkArrayPlus\n  -- We tell Halide to treat our list as a one-dimensional buffer\n  withHalideBuffer @1 @Float a $ \\a' -\u003e\n    withHalideBuffer b $ \\b' -\u003e\n      -- allocate a temporary buffer for the output\n      allocaCpuBuffer [length a] $ \\out' -\u003e do\n        -- execute the kernel -- it is a normal function call!\n        arrayPlus a' b' out'\n        -- print the result\n        print =\u003c\u003c peekToList out'\n```\n\nFor more examples, have a look at the [tutorials](https://github.com/twesterhout/halide-haskell/tree/master/tutorials).\n\n## 💻 Installing\n\nThe library is avaiable on Hackage, so you can just add `halide-haskell` to the\n`build-depends` field in your Cabal file. However, halide-haskell depends on Halide,\nso you need to make sure it's available.\n\n### ❄️ Nix\n\nNo need to do anything 😃, Nix will make Halide avaiable automatically.\n\nIf you just want to hack on the library, after `git clone`ing, type\n\n```sh\nnix build\n```\n\nand to run an example, try\n\n```sh\nnix run\nnix run .#ghc928-intel-ocl.halide-haskell # for Intel OpenCL support\nnix run .#ghc928-cuda.halide-haskell      # for CUDA support\nnix run .#ghc945.halide-haskell           # to build with GHC 9.4.5 instead\nnix run .#ghc945.halide-tutorial01        # to run the first tutorial\n```\n\n### non-Nix\n\nThis set up is not tested in CI... but\n\n- Download a pre-built Halide for your system from [their releases page](https://github.com/halide/Halide/releases/).\n- Pass `--extra-include-dirs` and `--extra-lib-dirs` options to Cabal on the command line or add them to your `cabal.project.local` file.\n\n## 🤩 Motivation\n\nThe availability of Deep Learning frameworks such as\n[PyTorch](https://pytorch.org/) or [JAX](https://github.com/google/jax) has\nrevolutionized array processing, independently of whether one works on Machine\nLearning tasks or other numerical algorithms. The ecosystem in Haskell has been\ncatching up as well, and there are now multiple good array\nlibraries ([hmatrix](https://github.com/haskell-numerics/hmatrix),\n[massiv](https://github.com/lehins/massiv),\n[Accelerate](https://www.acceleratehs.org/),\n[arrayfire-haskell](https://github.com/arrayfire/arrayfire-haskell),\n[Hasktorch](https://github.com/hasktorch/hasktorch), are all high-quality\nlibraries). To accommodate multiple domains, such libraries\nhave to support hundreds if not thousands of operations (e.g. there are more\nthan 3.5 thousand of so called [“native” functions in PyTorch](https://github.com/pytorch/pytorch/blob/6a09847c42bf7d33ba0aea5b083eebd846661ce1/aten/src/ATen/native/native_functions.yaml)),\nand this count does not include specializations for different device and data\ntypes).\n\nTo overcome this difficulty, we propose to build a common extension mechanism\nfor Haskell array libraries. The mechanism is based on embedding the\n[Halide](https://halide-lang.org/) language into Haskell that allows to\njust-in-time (JIT) compile computational kernels for various hardware.\n\n### 🤨 Why not Accelerate?\n\nOne might wonder, why write another package instead of relying on\n[Accelerate](https://www.acceleratehs.org/) for the JIT compilation of the\nkernels. Accelerate is a Haskell eDSL (embedded Domain Specific Language) for\ncollective operations on dense multi-dimensional arrays. It relies on\n[LLVM](https://llvm.org/) to JIT compile the computational kernels for the\ntarget architecture including multicore CPUs and GPUs. Users have to rely on\nAccelerate to generate high-performance kernels and have no way to force some\nlow-level optimizations. For example, [Trevor L. McDonell et\nal.](https://doi.org/10.1145/2887747.2804313) explain that the reason why\nhand-written [CUDA](https://www.nvidia.com/en-gb/geforce/technologies/cuda/)\nimplementation of the [N-body\nproblem](https://en.wikipedia.org/wiki/N-body_problem) outperforms Accelerate\nis the use of on-chip shared memory. Another example would be the matrix-matrix\nproduct where achieving maximal performance requires writing no fewer than six\nnested loops instead of the naive three ([ACM Trans. Math. Softw. 34, 3,\nArticle 12 (May 2008)](https://doi.org/10.1145/1356052.1356053)).\nAccelerate has no way of knowing that such optimizations have to be applied and\ncannot perform them automatically, and this is precisely the gap that we are\ntrying to fill by embedding Halide into Haskell.\n\nHalide is a C++ eDSL for high-performance image and array processing. Its core\nidea is to decouple the *algorithm* (i.e. what is computed) from the *schedule*\n(i.e. where and when it is computed). The eDSL allows to quickly prototype and\ntest the algorithm and then move on to the optimization. Optimizations such as\nfusion, tiling, parallelism and vectorization can be freely explored without\nthe risk of breaking the original algorithm definition. Schedulers can also be\ngenerated automatically by [advanced optimization\nalgorithms](https://halide-lang.org/papers/autoscheduler2019.html)\n\nHalide provides a lower level interface than Accelerate and thus does not aim\nto replace it. Instead, Halide can be used to extend Accelerate, and later on\none might even think about using Halide as a backend for Accelerate.\n\n## 🔨 Contributing\n\nCurrently, the best way to get started is to use Nix:\n\n```sh\nnix develop\n```\n\nThis will drop you into a shell with all the necessary tools to build the code\nsuch that you can do\n\n```sh\ncabal build\n```\n\nand\n\n```sh\ncabal test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwesterhout%2Fhalide-haskell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwesterhout%2Fhalide-haskell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwesterhout%2Fhalide-haskell/lists"}