This guide will walk you through installing checkasm and writing your first test.
Installation
You can either load checkasm as a library (e.g. via pkg-config), or include it directly in your project's build system.
Meson using wrap files (recommended)
First, create subprojects/checkasm.wrap:
[wrap-git]
url = https://code.videolan.org/videolan/checkasm.git
revision = release # or a specific tag/release
directory = checkasm
Then integrate it into your build system:
# This first attempts loading checkasm as an external dependency using the
# appropriate platform-specific method (e.g. pkg-config on POSIX systems),
# and falls back to using the bundled version inside `subprojects/checkasm`
# otherwise.
checkasm_dependency = dependency('checkasm',
# Extracts the `checkasm_dep` variable from the `checkasm` subproject.
fallback: ['checkasm', 'checkasm_dep'],
required: false
)
# Alternatively, you can directly force use of the bundled version:
# checkasm_dependency = subproject('checkasm').get_variable('checkasm_dep')
if checkasm_dependency.found()
checkasm = executable('checkasm',
checkasm_sources,
dependencies: checkasm_dependency,
)
test('checkasm', checkasm, suite: 'checkasm')
benchmark('checkasm', checkasm, suite: 'checkasm', args: '--bench')
endif
Meson using submodules (alternative)
As an alternative, you may use git submodules to include checkasm as a subproject. This may be preferred in some environments where the build system cannot access the internet during configuration time, or if you're already using submodules in your project.
git submodule init
git submodule add -b release https://code.videolan.org/videolan/checkasm subprojects/checkasm
# or checkout a specific tag/release
Then declare the dependency in your meson.build as usual. (See the previous section)
Manual Installation
You can also build and install checkasm manually:
git clone https://github.com/videolan/checkasm.git && cd checkasm
meson setup builddir -Dprefix=$PREFIX # (set optional build prefix)
meson compile -C builddir
meson install -C builddir
This is discouraged in favor of using Meson subprojects or distribution packages, but may be useful inside containerized environments, CI systems or custom build roots.
Quick Start Example
Let's create a simple test for a vector addition function that operates on buffers.
1. Prerequisites
Let's assume you have a reference implementation and an optimized version, alongside a way of detecting CPU features and choosing the implementation based on that:
#include <stdint.h>
enum {
CPU_FLAG_AVX = 1 << 0,
};
unsigned detect_cpu_flags(void);
typedef void (*add8_func_t)(uint16_t *dst, const uint8_t *src1,
const uint8_t *src2, size_t len);
add8_func_t get_add8_func(unsigned cpu_flags);
#include "my_cpu.h"
static void add8_c(uint16_t *dst, const uint8_t *src1,
const uint8_t *src2, size_t len)
{
for (size_t i = 0; i < len; i++)
dst[i] = src1[i] + src2[i];
}
static void add8_avx(uint16_t *dst, const uint8_t *src1,
const uint8_t *src2, size_t len)
{
add8_c(dst, src1, src2, len);
}
add8_func_t get_add8_func(unsigned cpu_flags)
{
if (cpu_flags & CPU_FLAG_AVX)
return add8_avx;
return add8_c;
}
2. Write the Test
Create your test file:
#include "my_dsp.h"
#define WIDTH 1024
{
for (int w = 1; w <= WIDTH; w <<= 1) {
dst_a, sizeof(dst_a),
w, 1, "sum");
}
}
}
static void check_dsp(void)
{
test_add8(cpu);
}
{ "dsp", check_dsp },
{0}
};
{ "AVX", "avx", CPU_FLAG_AVX },
{0}
};
int main(int argc, const char *argv[]) {
.tests = tests,
.cpu_flags = cpu_flags,
.cpu = detect_cpu_flags(),
};
}
Main checkasm API for test suite configuration and execution.
uint64_t CheckasmCpu
Opaque type representing a set of CPU feature flags.
Definition checkasm.h:52
CHECKASM_API CheckasmCpu checkasm_get_cpu_flags(void)
Get the current active set of CPU flags.
CHECKASM_API int checkasm_main(CheckasmConfig *config, int argc, const char *argv[])
Main entry point for checkasm test programs.
#define checkasm_check(type,...)
Compare two 2D buffers and fail test if different.
Definition utils.h:480
#define CHECKASM_ALIGN(x)
Declare a variable with platform-specific alignment requirements.
Definition utils.h:408
#define CLEAR_BUF(buf)
Clear a fixed size buffer (convenience macro).
Definition utils.h:254
#define INITIALIZE_BUF(buf)
Fill a fixed size buffer with pathological test data (convenience macro).
Definition utils.h:269
Configuration structure for the checkasm test suite.
Definition checkasm.h:122
Describes a CPU feature flag/capability.
Definition checkasm.h:69
Describes a single test function.
Definition checkasm.h:81
Test writing API for checkasm.
#define checkasm_bench_new(...)
Benchmark the optimized implementation.
Definition test.h:407
#define checkasm_call_ref(...)
Call the reference implementation.
Definition test.h:327
CHECKASM_API void checkasm_report(const char *name,...) CHECKASM_PRINTF(1
Report test outcome for a named group of functions.
#define checkasm_alternate(a, b)
Alternate between two values during benchmarking.
Definition test.h:429
#define checkasm_call_new(...)
Call the implementation being tested with validation.
Definition test.h:342
#define checkasm_declare(ret,...)
Declare a function signature for testing.
Definition test.h:166
#define checkasm_check_func(func,...)
Check if a function should be tested and set up function references.
Definition test.h:76
3. Build and Run
# Compile (example using gcc directly)
gcc -o check_dsp my_dsp.c check_dsp.c $(pkg-config --cflags --libs checkasm)
# or use `meson compile` if using Meson
# Run all tests
./check_dsp
Command-Line Options
checkasm provides several useful command-line options:
# List all available functions
./checkasm --list-functions
# Run specific functions (supports wildcards)
./checkasm --function=add_*_8bpc
# Run benchmarks
./checkasm --bench
# Run specified test with higher benchmark duration (here: 10 ms)
./checkasm --test=pixel --bench --duration=10000
# Enable verbose output
./checkasm --verbose
The --help output shows all available options:
Usage: checkasm [options...] <random seed>
<random seed> Use fixed value to seed the PRNG
Options:
--affinity=<cpu> Run the process on CPU <cpu>
--bench -b Benchmark the tested functions
--csv, --tsv, --json, Choose output format for benchmarks
--html
--function=<pattern> -f Test only the functions matching <pattern>
--help -h Print this usage info
--list-cpu-flags List available cpu flags
--list-functions List available functions
--list-tests List available tests
--duration=<μs> Benchmark duration (per function) in μs
--repeat[=<N>] Repeat tests N times, on successive seeds
--test=<pattern> -t Test only <pattern>
--verbose -v Print verbose timing info and failure data
Next Steps
Now that you've set up checkasm and written your first test, learn how to integrate it properly with your project's CPU detection and dispatch mechanisms.
Next: Integration Guide