C · Quickstart

Quickstart

#include <numkong/types.h> 8.0.0-rc.1 · b1f866ab

#include <numkong/numkong.h>
#include <stdio.h>

int main(void) {
    nk_f32_t a[] = {1, 2, 3};
    nk_f32_t b[] = {4, 5, 6};
    nk_f64_t dot = 0;
    nk_capability_t capabilities = nk_cap_serial_k;
    nk_cpu_capabilities_enabled(&capabilities); // the capabilities this CPU runs and this build holds
    nk_cpu_configure_thread(capabilities);
    nk_status_t status = nk_dot_f32_best(a, b, 3, &dot, capabilities, NULL); // widened f32 → f64 output
    printf("dot=%f, %s\n", dot, nk_status_name(status));
    return status != nk_success_k;
}

Every operation has one such dispatch point, named with _best, which runs the best capability in the mask it gets; the root README describes the dispatch model once.

§ The C ABI

The C ABI keeps the operation family, input dtype, and output policy visible in the symbol name. That makes widening obvious at the call site.

#include <numkong/numkong.h>

nk_i8_t a[1536];
nk_i8_t b[1536];
nk_i32_t dot = 0;     // widened from int8 storage
nk_f32_t l2 = 0;      // widened from int8 storage

nk_dot_i8_best(a, b, 1536, &dot, capabilities, NULL);
nk_euclidean_i8_best(a, b, 1536, &l2, capabilities, NULL);

The examples below pass the capabilities of the Quickstart and a null stream, as every CPU call does. Each capability kernel, like nk_dot_i8_haswell, is also callable directly with the same arguments short of the mask. To resolve a kernel once and call it many times without naming a capability, library builds provide the punned finder:

nk_metric_dense_punned_t angular = 0;
nk_capability_t capability = 0;
nk_find_kernel_punned(nk_kernel_angular_k, nk_f32_k, capabilities, (nk_kernel_punned_t *)&angular, &capability);

nk_f32_t a[768], b[768];
nk_f64_t result = 0; // widened f32 → f64 output
angular(a, b, 768, &result, NULL);

That is the lowest-level dynamic path. The typed C++ wrappers usually read better unless you are building your own dispatch layer.

API

Types

nk_status_tOutcome of every NumKong call that can fail: zero on success, negative when nothing was written.
types.h:1408 ↗
enum nk_status_t

Positive values are reserved for results written with a caveat.

Statuses fall into three categories, with no interruptions or defects to report. Resources: nk_bad_alloc_k, nk_missing_gpu_k, nk_device_code_mismatch_k, nk_missing_kernel_k and nk_missing_library_k. Input: nk_unexpected_dimensions_k, nk_device_memory_mismatch_k and nk_misaligned_k. State: nk_pack_mismatch_k. Any verb that allocates, binds a device or touches a file may also return a Resources status. A verb's own block lists only what its contract adds.

Values

nk_success_k0Scheduled, or finished, without error.
nk_bad_alloc_k-10The queue could not take more memory, or record another block.
nk_unexpected_dimensions_k-15Operand shapes contradict each other, like head counts that don't divide.
nk_missing_gpu_k-16No GPU of the vendor this build targets answers.
nk_device_code_mismatch_k-17The device code lacks the kernel, or it failed to build, launch or finish.
nk_device_memory_mismatch_k-18An operand lies in memory the device cannot address.
nk_missing_kernel_k-19No capability in the capability mask has this kernel.
nk_misaligned_k-20An operand or stride breaks the alignment contract.
nk_pack_mismatch_k-21The buffer was packed by another capability or layout than the one reading it.
nk_missing_library_k-22A dispatch point or finder called from a header-only build, which links no library.

Spellings

char const * nk_status_name(nk_status_t status);