{"id":22159194,"url":"https://github.com/roldak/adacompute","last_synced_at":"2025-03-24T15:12:37.923Z","repository":{"id":85677317,"uuid":"271119331","full_name":"Roldak/AdaCompute","owner":"Roldak","description":"An experimental Ada-hosted, statically-checked, high-level DSL that compiles to OpenCL kernels.","archived":false,"fork":false,"pushed_at":"2020-06-15T08:13:02.000Z","size":52,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-29T20:20:49.043Z","etag":null,"topics":["ada","ada-language","dsl","gpu","opencl","statically-typed"],"latest_commit_sha":null,"homepage":"","language":"Ada","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/Roldak.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-09T22:05:36.000Z","updated_at":"2020-09-16T07:42:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"efc5a2ba-1e4b-4370-9e84-3d4d1b7b5a8c","html_url":"https://github.com/Roldak/AdaCompute","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roldak%2FAdaCompute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roldak%2FAdaCompute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roldak%2FAdaCompute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roldak%2FAdaCompute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Roldak","download_url":"https://codeload.github.com/Roldak/AdaCompute/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245294775,"owners_count":20591909,"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":["ada","ada-language","dsl","gpu","opencl","statically-typed"],"created_at":"2024-12-02T03:44:38.579Z","updated_at":"2025-03-24T15:12:37.901Z","avatar_url":"https://github.com/Roldak.png","language":"Ada","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AdaCompute\nAn *experimental* Ada-hosted, statically-checked, high-level DSL that compiles to OpenCL kernels.\n\n## Example\n\nHere is a simple program that doubles each value in the provided buffer. This transformation will be executed on the GPU but any type/range error will be reported at compile time.\n\n```ada\nprocedure Double is\n   --  Declare a GPU-allocated buffer of 10 integers\n   package Buf is new Buffer (Integer, 10);\n   \n   --  Declare the integer constant \"2\"\n   package Two is new Const (Integer, 2);\n   \n   --  Declare the partial operation \"multiply by two\"\n   package Op is new BinOps.Arithmetic_1 (BinOps.Multiply, Two.E);\n   \n   --  Map the values of the given buffer to the operation defined above\n   package Trsf is new Map (Op.Op, Buf.I);\n   \n   --  Copy the transformed values back in the buffer\n   package Kernel is new Store_All (Trsf.I, Buf.A);\n\n   Ctx : constant CLContexts.Context := CLContexts.Default;\nbegin\n   --  Write a random array to the GPU buffer\n   Buf.Write (Ctx, (5, 4, 1, 6, 3, 6, 8, 2, 2, 5));\n   \n   --  Execute the kernel\n   Kernel.Execute (Ctx);\n   \n   --  Read back the values from the GPU and print them\n   Buf.Dump (Ctx);\nend Double;\n```\nThis prints:\n\n```\n[10, 8, 2, 12, 6, 12, 16, 4, 4, 10]\n```\n\nThe generated kernel is\n\n```c\n__kernel main(__global int* buffer_1) {\n   int id = get_global_id (0);\n   buffer_1[id] = buffer_1[id] * 2;\n}\n```\n\n## Features\n\n*Disclaimer: everything is still work in progress.*\n\n### Static checking\n\nOne of the main added value of this DSL is that it is statically checked. That is, any error made while designing the kernel will be reported at compile-time by your Ada compiler.\n\nIn comparison, the basic OpenCL workflow is to write your kernel in a `.cl` file, then to load it and compile it at runtime, meaning that any error would be catched at runtime only, or not catched at all and result in undefined behavior during execution.\n\nTo illustrate this, consider the following buggy kernel definition:\n```ada\n--  declare a GPU-allocated buffer of 10 Natural integers\npackage Buf is new Buffer (Natural, 10);\n\n--  Create a Range expression from -5 to 5 (both ends included)\npackage Rng is new Int_Range (Integer, -5, 5);\n\n--  Copy this range to the buffer\npackage Kernel is new Store_All (Rng.I, Buf.A);\n```\n\nFortunately, this program will not even compile! First, the compiler will complain that you are trying to assign integer\nvalues to a buffer of natural numbers. Once you fix this (replace `Natural` by `Integer` in the definition of `Buf`), the compiler will now complain that you cannot assign a range of 11 elements to a buffer of 10 elements. Modify the declaration of `Buf` to `package Buf is new Buffer (Integer, 11);` and it will now compile correctly.\n\n### High-level description of kernels\n\nAnother big feature is that the programs are written using high-level functional-style constructs. These are then compiled to low-level OpenCL kernels, as shown in the introductory example. Such constructs include `Zip`, `Map`, `Reduce`, etc. \n\n## Build Steps\n\n- Clone and build [OpenCLAda](https://github.com/flyx/OpenCLAda) (GL support not required), make sure `opencl.gpr` is in your `GPR_PROJECT_PATH` environment variable.\n- Run `sh make`\n- Check out the examples in the `./bin` directory!\n\n## More complex example\n\nHere is how to describe 1D convolution:\n\n```ada\n--  The input and output buffer\npackage Buf is new Buffer (Integer, 10);\n\n--  Declare some constants\npackage Rng_1 is new Int_Range (Integer, 0, 9);\npackage Rng_2 is new Int_Range (Integer, -1, 1);\npackage Zero is new Const (Integer, 0);\n\n--  Create the operation `(i, j) =\u003e buffer[i + j]` (with bound checks)\npackage Add is new BinOps.Arithmetic_2 (BinOps.Add, Integer);\npackage Buf_Get is new Buf.Safe_Get (Zero.E);\npackage Buf_Add_Get is new Operations.Combine_2_1 (Add.Op, Buf_Get.Op);\n\n--  Compute the convolution\npackage Trf is new Map_2 (Buf_Add_Get.Op, Rng_1.I, Rng_2.I);\npackage Red is new Reduce_2 (Zero.E, Add.Op, Trf.I);\n\n--  Store the convolution of each element back in the buffer.\npackage Kernel is new Store_All (Red.I, Buf.A);\n```\n\nThis generates the following OpenCL kernel:\n\n```c\n__kernel void main(__global int* buffer_1) {\n   size_t i = get_global_id(0);\n   int reduce_2 =  0;\n   for (int r = 0; r \u003c  3; ++r) {\n      int idx = i + r - 1;\n      reduce_2 = reduce_2 + ((idx \u003c 0 || idx \u003e=  10) ? 0 : buffer_1[idx]);\n   }\n   buffer_1[i] = reduce_2;\n}\n```\n\nApplied to a buffer containing `[ 1,  6,  4,  2,  5,  7,  2,  1,  7,  3]`, it yields `[ 7,  11,  12,  11,  14,  14,  10,  10,  11,  10]`. You can find the source code for this example in the `examples` directory.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froldak%2Fadacompute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froldak%2Fadacompute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froldak%2Fadacompute/lists"}