# OpenCL.jl

[![][buildkite-img]][buildkite-url]
[![Test](https://github.com/JuliaGPU/OpenCL.jl/actions/workflows/Test.yml/badge.svg)](https://github.com/JuliaGPU/OpenCL.jl/actions/workflows/Test.yml)
[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliagpu.github.io/OpenCL.jl/stable)
[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliagpu.github.io/OpenCL.jl/dev)

[buildkite-img]: https://badge.buildkite.com/6b2a46bff67692115dea3ad5a275d2f80777a5a99ffe42adb0.svg?branch=main
[buildkite-url]: https://buildkite.com/julialang/opencl-dot-jl

*Julia interface for the OpenCL parallel computation API*

This package aims to be a complete solution for OpenCL programming in Julia, similar in
scope to [PyOpenCL](http://mathema.tician.de/software/pyopencl/) for Python. It provides a high level API for OpenCL to make programing
hardware accelerators, such as GPUs, FPGAs, and DSPs, as well as multicore CPUs much less
onerous.

**OpenCL.jl needs your help! If you can help maintaining this package, please reach out on
the [JuliaLang Slack](https://julialang.org/slack/) #gpu channel**

**Also note: OpenCL.jl is currently undergoing major changes. If you have old code,
developed for OpenCL.jl v0.9, please check [`NEWS.md`](NEWS.md) for an overview of the
changes.**


## Installation

1. Install an OpenCL driver. You can install one system-wide, i.e., using your package
   manager, or use `pocl_jll.jl` for a CPU back-end.
2. Add OpenCL to your Julia environment:

```julia
using Pkg
Pkg.add("OpenCL")
```

3. Test your installation:

```julia-repl
julia> OpenCL.versioninfo()
OpenCL.jl version 0.10.0

Toolchain:
 - Julia v1.10.5
 - OpenCL_jll v2024.5.8+1

Available platforms: 3
 - Portable Computing Language
   version: OpenCL 3.0 PoCL 6.0  Linux, Release, RELOC, SPIR-V, LLVM 15.0.7jl, SLEEF, DISTRO, POCL_DEBUG
   · cpu-haswell-AMD Ryzen 9 5950X 16-Core Processor (fp64, il)
 - NVIDIA CUDA
   version: OpenCL 3.0 CUDA 12.6.65
   · NVIDIA RTX 6000 Ada Generation (fp64)
 - Intel(R) OpenCL Graphics
   version: OpenCL 3.0
   · Intel(R) Arc(TM) A770 Graphics (fp16, il)
```

> [!WARNING]
> OpenCL is only computing the list of platforms [once](https://github.com/KhronosGroup/OpenCL-ICD-Loader/blob/d547426c32f9af274ec1369acd1adcfd8fe0ee40/loader/linux/icd_linux.c#L234-L238).
> Therefore if `using pocl_jll` is executed after `OpenCL.versioninfo()` or other calls to the OpenCL API
> then it won't affect the list of platforms available and you will need to restart the Julia session
> and run `using pocl_jll` before `OpenCL` is used.

## Basic example: vector add

The traditional way of using OpenCL is by writing kernel source code in OpenCL C. For
example, a simple vector addition:

```julia
using OpenCL, pocl_jll

const source = """
   __kernel void vadd(__global const float *a,
                      __global const float *b,
                      __global float *c) {
      int gid = get_global_id(0);
      c[gid] = a[gid] + b[gid];
    }"""

a = rand(Float32, 50_000)
b = rand(Float32, 50_000)

d_a = CLArray(a)
d_b = CLArray(b)
d_c = similar(d_a)

p = cl.Program(; source) |> cl.build!
k = cl.Kernel(p, "vadd")

clcall(k, Tuple{CLPtr{Float32}, CLPtr{Float32}, CLPtr{Float32}},
       d_a, d_b, d_c; global_size=size(a))

c = Array(d_c)

@assert a + b ≈ c
```


## Native example: vector add

If your platform supports SPIR-V, it's possible to use Julia functions as kernels:

```julia
using OpenCL, pocl_jll

function vadd(a, b, c)
    gid = get_global_id(1)
    @inbounds c[gid] = a[gid] + b[gid]
    return
end

a = rand(Float32, 50_000)
b = rand(Float32, 50_000)

d_a = CLArray(a)
d_b = CLArray(b)
d_c = similar(d_a)

@opencl global_size=size(a) vadd(d_a, d_b, d_c)

c = Array(d_c)

@assert a + b ≈ c
```


## More examples

You may want to check out the `examples` folder. Either `git clone` the repository to your
local machine or navigate to the OpenCL.jl install directory via:

```julia
using OpenCL
cd(joinpath(dirname(pathof(OpenCL)), ".."))
```

Otherwise, feel free to take a look at the Jupyter notebooks below:

  * [Julia set fractals](https://github.com/JuliaGPU/OpenCL.jl/blob/main/examples/notebooks/julia_set_fractal.ipynb)
  * [Mandlebrot fractal](https://github.com/JuliaGPU/OpenCL.jl/blob/main/examples/notebooks/mandelbrot_fractal.ipynb)
  * [Transpose bandwidth](https://github.com/JuliaGPU/OpenCL.jl/blob/main/examples/notebooks/Transpose.ipynb)


## Credit

This package is heavily influenced by the work of others:

  * [PyOpenCL](http://mathema.tician.de/software/pyopencl/) by Andreas Klockner
  * [oclpb](https://github.com/srossross/oclpb) by Sean Ross
  * [Boost.Compute](https://github.com/kylelutz/compute) by Kyle Lutz
  * [rust-opencl](https://github.com/luqmana/rust-opencl)
