type DeviceKind = 'cpu' | 'cuda' | 'rocm' | 'metal' Capability detection is explicit, one Device at a time:
import { Capability, Device } from "numkong";
const cpu = Device.cpu();
console.log(cpu.capabilitiesEnabled()); // what dispatch runs within
console.log((cpu.capabilitiesEnabled() & Capability.haswell) !== 0n);
const metal = new Device("metal", 0); // throws without that GPU
console.log(metal.capabilitiesEnabled() & Capability.gpus);Device.cpu() is the host CPU, and new Device(kind, ordinal) any device Device.count(kind) counts, with kind one of "cpu", "cuda", "rocm" or "metal". capabilitiesEnabled() is the one you usually want, and derives from two independent axes:
capabilitiesDetected(): what the device, like this CPU or WASM host, can execute.capabilitiesCompiled(): what this build contains for devices of its kind, from the ISA probes at build time.capabilitiesEnabled(): what dispatch runs within, both axes at once, which the library settles as it loads.
capabilitiesDetected() describes the machine and says nothing about whether a kernel was compiled in, so a prebuild whose ISA probes failed still reports your CPU’s full feature set while containing no SIMD kernels at all.
The enabled set always keeps the serial fallback, and the binding keeps no mask of its own: every kernel call passes Capability.cpus, which the library clamps to the enabled set. Capability maps each lowercase capability name, like haswell, neon, v128relaxed or ampere, to its bit, and is built at load from the C library’s own names; cpus, devices and any group them.
A WASM module has only the CPU, so Device.count throws for every GPU kind there.
The exact bitmask depends on whether you are running the native addon or a WASM runtime.
There is no configure_thread call in the JS binding.
Thread configuration is managed internally by the native addon or WASM runtime.
API
Types
DeviceKindWhich runtime a device belongs to, as the nk_<kind>_* C functions name it.
ClassDeviceOne device NumKong can run kernels on: the host CPU, or a GPU by its runtime's own ordinal, the one cudaSetDevice or hipSetDevice takes, or the position in Metal's device list.6
class Device Prefer Device.capabilitiesEnabled unless you specifically mean one of the raw axes:
Device.capabilitiesDetected describes the device and says nothing about whether a kernel
was compiled into this build, so a prebuild whose ISA probes failed still reports your CPU's
full feature set while containing no SIMD kernels at all.
Examples
import { Device, Capability } from 'numkong';
const cpu = Device.cpu();
if (cpu.capabilitiesEnabled() & Capability.haswell) console.log('AVX2 kernels in use');
Device
new Device(kind: DeviceKind, ordinal: number = 0) Parameters
kindDeviceKind | The runtime the device belongs to. | |
|---|---|---|
ordinalnumber | The runtime's own index of the device, below Device.count. |
Throws
Without a device of kind, or past the last one.
cpuThe host CPU, which every build has.
static cpu(): Device countHow many devices of kind the process sees: one CPU, or the GPUs its runtime counts.
capabilitiesDetectedThe capabilities this device runs, compiled in or not, as a bitmask.
capabilitiesDetected(): bigint capabilitiesCompiledThe capabilities compiled into this build for devices of this kind, as a bitmask.
capabilitiesCompiled(): bigint capabilitiesEnabledThe capabilities this device's kernel calls run within: detected and compiled at once, as a bitmask.
capabilitiesEnabled(): bigint On the CPU the library settles it as it loads, and it always includes Capability.serial.
Functions
outputDTypeDetermines the output dtype for a given kernel family and input dtype, mirroring nk_kernel_output_dtype from C.
function outputDType(family: KernelFamily, input: DType): DType Constants
CapabilityLowercase capability names, like haswell, neon or ampere, mapped to their bits, and the cpus, gpus and any groups to theirs.
const Capability: Readonly<Record<string, bigint>>