Library / SDK
ddemidov/vexcl avatar
ddemidov/vexcl

VexCL: C++ expression templates that generate OpenCL and CUDA kernels for you

VexCL is a C++ vector expression template library for OpenCL/CUDA/OpenMP

722 stars88 forksC++MIT

At a glance

What is it?
VexCL is a header style C++ library that lets you write vector arithmetic, reductions and sparse matrix vector products as ordinary expressions and compiles them down to OpenCL or CUDA at runtime. It targets GPGPU development where the boilerplate of kernel plumbing usually eats the time, and the repository ships a set of example programs that double as a map of what the library covers.
Who is it for?
VexCL fits a C++ developer who has a working OpenCL or CUDA kernel and wants the arithmetic moved into readable host code, or a numerical package that wants to fan one expression across several devices. It does not fit a team that needs a released, versioned package with a published changelog, because the newest tagged release is 1.4.3 from 2021-11-09 while the last push was on 2026-10-09, so you would be tracking the master branch.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The goal is to stop writing kernels for every arithmetic expression

VexCL is a vector expression template library for OpenCL and CUDA, and the README states its purpose in plain terms: it was created for ease of GPGPU development with C++, and it strives to reduce the amount of boilerplate code needed to develop GPGPU applications. The mechanism is the familiar one from numerical C++, expression templates, applied to accelerator code. You write arithmetic on vector objects in host code, the library fuses those operations into a single generated kernel instead of launching one kernel per operator, and the same expression can then be evaluated on several devices. The library provides convenient notation for vector arithmetic, reduction and sparse matrix vector products, and multi-device and even multi-platform computations are supported. The trade is the one that comes with any expression template system: the code you write no longer maps one to one onto the code that runs, so debugging means looking at generated source rather than at your own statements.

Multi-device and multi-platform is the capability that shapes the API

Two words in the README summary carry most of the weight: multi-device and multi-platform. A single expression can be evaluated across several OpenCL or CUDA devices, which is what you want when a single machine has more than one accelerator, and the library targets more than one compute platform, so the same host code can run against OpenCL, CUDA and OpenMP. This is the part that shapes the interface. If the library were limited to one device and one backend, the API would be a thin wrapper over kernel launches. Because it has to schedule and combine work across devices, the surrounding machinery, context and queue management, device lists, and the reduction and matrix operations, becomes the bulk of what the library provides. The examples directory in the repository reinforces that reading: there is a devlist.cpp program whose name alone suggests a device enumeration utility, and a benchmark.cpp that reads as the performance baseline for the rest of the suite.

The example programs are the real feature documentation

The examples directory is unusually broad for a research oriented library, and the file list reads like a capability map. There are simple programs such as complex_simple.cpp and complex_spmv.cpp, the second covering a sparse matrix vector product for complex valued data. exclusive.cpp is the exclusive scan, the classic building block for a parallel prefix operation, and symbolic.cpp is a separate program rather than a mode of another one, which suggests it deals with symbolic work in the sparse linear algebra sense. Then there is the FFT material: fft_benchmark.cpp, fft_profile.cpp and show_profiling_data.m, a MATLAB script that reads profiling output, so the FFT path is treated as a case worth profiling rather than just running. Two more files stand out for a different reason. thrust-sort.cpp, thrust-sort.cu and thrust-sort.hpp show the library being compared against a different C++ GPU ecosystem, and a viennacl/ directory in examples points at a second, similarly shaped numerical library.

A CMake project with the build expectations written down separately

The repository layout is conventional and tells you where to look. The library itself lives in the vexcl/ directory, and the CL/ directory holds the OpenCL side of the project. Builds are driven by CMake, with a top level CMakeLists.txt and a cmake/ directory of modules, and the examples have their own examples/CMakeLists.txt so you can configure the library without the sample programs. Two documents at the root are worth reading before anything else: INSTALL.md for the build and installation expectations, and DEPENDS.md for what the project expects to find on the system. Documentation lives in docs/, and the published site is at vexcl.readthedocs.io, which the README points to as the place to start. The tests/ directory is present, and the repository root also carries continuous integration configuration for both Linux style and Windows style pipelines, which tells you that a working build recipe is expected to be reproducible on more than one platform.

Quality signals come from static analysis and coverage, not from release notes

The README badge block is worth reading as a picture of the project's engineering practice. There is a documentation status badge pointing at the readthedocs build, a DOI badge pointing at a Zenodo record for citation, a build status badge for a Travis CI pipeline and another for AppVeyor, a codecov badge for coverage, and a Coverity Scan build status badge. That is a wide set of automated checks for a numerical library, and it is the standard practice of a research code base that has to keep working across compilers and driver versions. What the badge block does not show is a recent release. The published tags are 1.4.3 from 2021-11-09, 1.4.2 from 2021-04-27 and 1.4.1 from 2017-05-04, while the last push was on 2026-10-09. In other words, the code has moved on for years without a new tag, which tells you that users of this project are expected to work from the master branch rather than from a release.

Where the library is the wrong tool

There are two clear cases. The first is a project that has already solved this problem in a different direction. If a codebase is built around hand written kernels with an existing profiler and a tuned occupancy strategy, an expression template layer adds a compilation step in the middle of the build and a generated source file you did not write, and the usual reason people hand write kernels is precisely that they want to control that. The second is a task that is not vector arithmetic at all: irregular memory access, custom atomics, warp level primitives or anything that needs device specific intrinsics will fight the abstraction, because the library's job is to express portable arithmetic, and portability has a price. The third cost is compile time and code size, since every distinct expression is a separate generated kernel that the driver has to compile at runtime, and on a machine with an expensive JIT that cost is paid every run rather than once.

MIT licensing, permissive and simple to adopt

The source is distributed under what the README calls a very permissive MIT licence, and the repository root carries a LICENSE.md file, so the terms are the standard ones: use it, modify it, ship it inside a larger product, keep the copyright notice and the permission text with the copies. For a numerical library that you intend to embed in an application rather than just call from a script, that is the licence most commercial teams want, and there is no copyleft obligation on the code you generate with it. Two practical notes sit alongside it. First, the licence covers the library, not the OpenCL, CUDA or OpenMP runtimes it calls, which carry their own licences. Second, if you intend to pin a version, be aware of the release history described above: the tags stop at 1.4.3, so pinning to a tag means pinning to code from 2021, and tracking master means tracking a project whose compatibility with a given driver you verify for yourself.

Editorial conclusion

VexCL fits a C++ developer who has a working OpenCL or CUDA kernel and wants the arithmetic moved into readable host code, or a numerical package that wants to fan one expression across several devices. It does not fit a team that needs a released, versioned package with a published changelog, because the newest tagged release is 1.4.3 from 2021-11-09 while the last push was on 2026-10-09, so you would be tracking the master branch. Before adopting it, read INSTALL.md and DEPENDS.md in the repository root for the build and dependency expectations, and check the documentation site for which OpenCL runtime and kernel compiler your target actually needs.

Frequently asked questions

What is VexCL and what is it used for?

VexCL is a C++ vector expression template library for OpenCL, CUDA and OpenMP, created to reduce the boilerplate in GPGPU development. It provides notation for vector arithmetic, reduction and sparse matrix vector products, and supports computation across multiple devices and multiple compute platforms.

How do I build VexCL and run its examples?

The project is built with CMake, with a top level CMakeLists.txt, a cmake/ directory and a separate examples/CMakeLists.txt for the sample programs. INSTALL.md covers the installation and DEPENDS.md the dependencies, and the documentation site at vexcl.readthedocs.io is the starting point the README points to.

Which example programs ship with VexCL?

The examples directory includes complex_simple.cpp, complex_spmv.cpp, exclusive.cpp, symbolic.cpp, devlist.cpp, benchmark.cpp, fft_benchmark.cpp, fft_profile.cpp with a MATLAB script show_profiling_data.m, mba_benchmark.cpp, a simple/ subdirectory, a viennacl/ subdirectory, and thrust-sort.cpp with thrust-sort.cu and thrust-sort.hpp.

Official sources

  1. ddemidov/vexcl on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ddemidov-vexcl.svg)](https://hysenlabs.com/projects/ddemidov-vexcl)

Was this useful?