diff --git a/README.md b/README.md index 92a8792..8e68dee 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,36 @@ -# OpenCL wrappers for Go +# OpenCL wrapper libraries for Go -This respoistory is the central entry point for OpenCL wrappers for Go. +This repository is the central entry point for [OpenCL](https://www.khronos.org/opencl/) wrapper libraries for [Go](https://go.dev). It serves as the central information source, issue tracker, and discussion space. + +> This GitHub organization is an open-source project and has no affiliation with Khronos Group. + +## Motivation + +The goal of this project is to maintain OpenCL wrapper libraries that + +* Provide the full functionality of main OpenCL API +* Provide documentation to help in the usage of the API +* Handle the most low-level properties of the API to expose a more Go-idiomatic approach +* Allow extensibility via OpenCL extensions +* Are also available for newer API versions (OpenCL 2.2, 3.0) + +## Further links + +* [Overview on GitHub](https://github.com/opencl-go) +* [Discussions and questions](https://github.com/opencl-go/opencl-go.github.io/discussions) +* [Issue tracker](https://github.com/opencl-go/opencl-go.github.io/issues) +* Versioned OpenCL wrappers: + * [OpenCL 3.0](https://github.com/opencl-go/cl30) + * [OpenCL 2.2](https://github.com/opencl-go/cl22) + * [OpenCL 1.2](https://github.com/opencl-go/cl12) +* [This page](https://opencl-go.github.io/) + +## How-To guides + +* [How to install the OpenCL SDK](how-to-install-sdk.md) + +## Questions and general information + +* [Design principles](faq-design-principles.md) +* [Alternative wrapper libraries](faq-alternatives.md) diff --git a/faq-alternatives.md b/faq-alternatives.md new file mode 100644 index 0000000..fe291f3 --- /dev/null +++ b/faq-alternatives.md @@ -0,0 +1,74 @@ +# Alternatives to opencl-go + +This page collects alternatives to the provided wrappers of [opencl-go](https://github.com/opencl-go). + +Listed properties may become out-of date, so double-check with the linked projects about their current state. + +> As a general observation, unless otherwise noted, the found projects appeared in an incomplete state and apparently abandoned. + +## samuel/go-opencl + +* URL: https://github.com/samuel/go-opencl +* Last check of properties: 2022-08 +* Last update of project: 2017-11 +* Supported OpenCL version(s): 1.1 and 1.2 (one repository, build tags) + +This repository comes up high in search results. With over 60 forks and 140 stars, it seems to be a common go-to repository. + +Object-details such as properties during creation or info-query are not supported. Several TODO marker in the source base. + +> This page will ignore most of the forks, unless they have a particular new property. + + +## microo8/blackcl + +* URL: https://gitlab.com/microo8/blackcl +* Last check of properties: 2022-08 +* Last update of project: 2019-02 +* Supported OpenCL version(s): ? + +Originally on [GitHub](https://github.com/microo8/blackcl) and derived from samuel/go-opencl, this is a project with "highly opinionated OpenCL bindings for Go with some black magic". + +This project is a more high-level wrapper as it hides some of OpenCL's concepts (such as Platform, Context, or Queue), to provide a more simplified approach. + +## MasterOfBinary/go-opencl + +* URL: https://github.com/MasterOfBinary/go-opencl +* Last check of properties: 2022-08 +* Last update of project: 2016-12 +* Supported OpenCL version(s): 2.0 + +Event waitList / return objects are not supported for `Enqueue*` calls; +`EnqueueNDRangeKernel()` does not support specification of global offsets or local work sizes. + +## rainliu/gocl + +* URL: https://github.com/rainliu/gocl +* Last check of properties: 2022-08 +* Last update of project: 2016-09 +* Supported OpenCL version(s): 1.1, 1.2, 2.0 (one repository, build tags) + +On one hand a low-level wrapper that matches closely the C-API, yet also performs parameter checks on its own. +As such, extensions may not be supported. + +TODO marker in the source as some features are not implemented, for example pipes. + +It contains several examples and demo applications. + +## Patagonicus/opencl + +* URL: https://github.com/Patagonicus/opencl +* Last check of properties: 2022-08 +* Last update of project: 2017-03 +* Supported OpenCL version(s): 1.2 + +A low-level wrapper. The readme shows a list of intended functions, which is about half finished. + +## go-gl/cl + +* URL: https://github.com/go-gl/cl +* Last check of properties: 2022-08 +* Last update of project: 2016-04 +* Supported OpenCL version(s): 1.0, 1.1, 1.2 (one repository, different sub-packages) + +This wrapper seems to be based on some auto-generated code that directly forwards pointers to the Go-API. diff --git a/faq-design-principles.md b/faq-design-principles.md new file mode 100644 index 0000000..18726a6 --- /dev/null +++ b/faq-design-principles.md @@ -0,0 +1,113 @@ +# Design principles + +This page collects answers and guides to "why" some things are as they are in this project. +The details should help to re-evaluate them in the future, should conditions change. + +## Allow targeting of different OpenCL versions + +It shall be possible to develop against a particular version of the OpenCL API, and also stay compatible +to be integrated with a library or application that targets a different version of the OpenCL API. + +Use-case here can be that a library developer implements a particular algorithm using the API surface of +OpenCL 1.2 for maximum portability. And an application that requires OpenCL 3.0 functionality +while making use of that extra library. +The application developer in this case wants to be able to build in version 3.0 and also build that library. + +## Why separate repositories per OpenCL version? + +Here the user-experience was the primary driving factor. The two main components are: +* Go documentation +* Ease of compilation + +As an added point for consideration is the previous one, the demand that they can be combined in a single +application in different versions. + +[Alternative wrapper libraries](faq-alternatives.md) typically come in two flavours: those using build tags to separate API level and +those having different sub-folders. +Those with separate folders demand that a user has an SDK that supports all the API levels in order to build the entire project. +This also causes a longer compilation time. + +In contrast, when using build tags, then there is only "one" version visible - depending on this tag is selected, and which is the default. +The default tag(s) then also govern which Go documentation is visible, possibly limiting or giving wrong impressions. + +Considering deprecated APIs, the library that only needs OpenCL 1.2 is free to work on this API level - despite some +used function or constants are deprecated in future versions. + +A further factor is the future extensibility: If a future OpenCL API version is released, how shall the "default" level of one repository be affected? +Should it stay at the level that was used when the project was created, or shall it update? +This then also has consequences on the Go versioning. + +With separate repositories, it is possible to have specific documentation per API level, and compilation is focused on only that level. + +This is also in line with Go module versioning: Instead of making it difficult to hide different versions within +one repository (through branches, paths, or tags), create a dedicated repository that lives independently. + +## Support extensions from external sources + +It shall be possible to implement extensions without the need to extend a repository. + +This has implications on the provided API: To stay consistent, all the functions should be available as functions that take +the affected objects as a parameter. + +For example, there is `ReleaseContext(Context)` instead of (only) `Context.Release()`. +This is then in line with the `cl_khr_terminate_context` extension: It provides a function `TerminateContext(Context)`. +If that extension is external (a separate repository), it would not be able to add a `Context.Terminate()` function. + +> Even if the `cl_khr_terminate_context` extension is part of the repository, the potentially exported `Context.Terminate()` +> function may be misleading if the extension is not available on the system. + +As a result, the exposed types, such as `Context` or `CommandQueue` must be usable in a way to expose the underlying +C-API type for external functions to work. + +This also supports in the compatibility between the different version repositories: Through a cast, a type +can be converted from a 1.2 domain to a 3.0 domain and the other way back. + +## OpenCL 1.2 is the baseline + +At the time of creation of this project, OpenCL 3.0 was already released. As part of this release, version 1.2 +has been declared as the mandatory baseline for functionality. + +This project follows this decision to ignore versions 1.0 and 1.1. + +## The exported API shall be documented + +In contrast to all the other wrappers, have a library that provides helpful documentation. + +However, it is not necessary to copy the entire official Khronos OpenCL documentation. +Instead, have all the APIs refer to the full documentation, and provide an abstract of the general behaviour. +This documentation shall also take into account any Go-specific wrapping that took place. + +Refer to the Creative Commons licensed asciidoctor files from https://github.com/KhronosGroup/OpenCL-Docs when creating the abstract. + +## Level of abstraction (wrapping) + +There is no precise definition whether an abstraction should be provided, or not. +The following points help in deciding to which degree the API stays true to the definition of OpenCL: + +* Avoid restricting an API in its capabilities. + For example, the function `SetKernelArg()` still allows to receive an arbitrary `unsafe.Pointer()` and the + caller needs to take care for the proper size. This is to ensure any future type can also be provided. + (Some alternative wrappers perform reflection on the given argument type to set the size.) +* Handle and wrap C-memory/-pointer magic. + If the low-level API makes it too easy to perform memory-access-violations or mistakes, provide a convenience helper. + For example, the function `EnqueueNDRangeKernel()` takes a `[]WorkDimension` argument instead of one number-of-dimensions value and + three size-dependent vectors. Functions that work with callbacks are another good example - especially `EnqueueNativeKernel()`. +* When in doubt, provide the low-level API and optionally convenience functions. + Primary example: `*Info()` functions and their `*InfoString()` equivalent. +* Finally, the API requires further OpenCL-specific knowledge and cannot be used without. + A certain degree of understanding in the working with raw memory can be expected, hence also the + accepted exposure to `unsafe.Pointer()`. + +> To come back to the `SetKernelArg()` function and to stay in line with the above principles: +> There would be potential for convenience functions such as `SetKernelArgUint32()`. + +## Side effects and consequences + +Because of the taken decisions, the following side effects and consequences are the result: + +* C-helper functions must all be prefixed with the version of the repository they are for. + Otherwise, the linker would fail in case a project combines multiple projects. + This prefix can be seen as the C-equivalent of the Go package. +* Deprecated APIs must be available by default. In case a library or application wants to upgrade to a higher + version, it should still compile, and ideally provide "deprecation" messages where suitable. + With OpenCL 1.2 being the baseline, versions 1.0 and 1.1 are ignored. diff --git a/how-to-install-sdk.md b/how-to-install-sdk.md new file mode 100644 index 0000000..b30a79a --- /dev/null +++ b/how-to-install-sdk.md @@ -0,0 +1,52 @@ +# How to install the OpenCL SDK + +In general, refer to common practices for your platform. This page here collects first pointers and common guides. + +It is possible that SDKs come with the runtimes of various vendors. However, development is tested +against the official [Khronos OpenCL SDK](https://github.com/KhronosGroup/OpenCL-SDK). + +For all approaches, the repositories expect to find the headers in system include folder `CL/` (and `OpenCL/` for Apple); for example, `#include `. +Linkage is performed against library (or Apple framework) `OpenCL`. + +## Microsoft Windows + +For Microsoft Windows, use to the released packages from [Khronos OpenCL SDK](https://github.com/KhronosGroup/OpenCL-SDK). + +* Download the latest binary release from [the list of releases](https://github.com/KhronosGroup/OpenCL-SDK/releases). + * It is either the `OpenCL-SDK-vYYYY.MM.DD-Win-x64.zip` or `OpenCL-SDK-vYYYY.MM.DD-Win-x32.zip` - depending on your intended architecture. +* Unpack the contained header and library files into a dedicated directory. For example `D:\OpenCL\Khronos\...` +* Ensure the header and library files can be found by the compiler and linker. + * For example, use `Edit the system environment variables` in Windows to extend the "User variables". For example: + * `CGO_CFLAGS=-ID:\OpenCL\Khronos\include` + * `CGO_CPPFLAGS=-ID:\OpenCL\Khronos\include` + * `CGO_CXXFLAGS=-ID:\OpenCL\Khronos\include` + * `CGO_LDFLAGS=-LD:\OpenCL\Khronos\lib` + +## Linux + +For Linux, it depends on the distribution. + +For Debian-based systems, there are readily-available packages for the official SDKs. +On Ubuntu-22.04 (or later), you can run the following commands: +``` +sudo apt-get update +sudo apt-get install opencl-headers ocl-icd-opencl-dev +``` + +> The GitHub workflow CI scripts of the repositories perform the steps on such a system. + +> Earlier distribution versions may also provide these packages, yet in an older version. +> This will then decide which OpenCL API level - and Go wrapper - you can use and develop against. + +## Apple MacOS + +Apple has discontinued support for OpenCL after version 1.2. +As such, only the [opencl-go/cl12](https://github.com/opencl-go/cl12) repository is compatible with such a system. + +However, the OpenCL SDK should be pre-installed on a system. Which version is available may be dependent on the machine. + +Refer to these links for further details: + +* General overview: https://developer.apple.com/opencl/ +* Version overview: https://support.apple.com/en-gb/HT202823 (no longer maintained) +* Programming guide: https://developer.apple.com/library/archive/documentation/Performance/Conceptual/OpenCL_MacProgGuide/Introduction/Introduction.html