# Runtime Dispatch

> NumKong for JavaScript

Capability detection is explicit, one `Device` at a time:

```ts
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.

`import * as numkong from 'numkong';`

`import { Device } from 'numkong';`

## DeviceKind

Which runtime a device belongs to, as the `nk_<kind>_*` C functions name it.

```typescript
type DeviceKind = 'cpu' | 'cuda' | 'rocm' | 'metal'
```

## Device

One 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.

```typescript
class Device
```

Prefer [`Device.capabilitiesEnabled`](#capabilitiesEnabled) unless you specifically mean one of the raw axes:
[`Device.capabilitiesDetected`](#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

```typescript
new Device(kind: DeviceKind, ordinal: number = 0)
```

- `kind`: The runtime the device belongs to.
- `ordinal`: The runtime's own index of the device, below [`Device.count`](#count).

Throws: Without a device of `kind`, or past the last one.

## cpu

The host CPU, which every build has.

```typescript
static cpu(): Device
```

## count

How many devices of `kind` the process sees: one CPU, or the GPUs its runtime counts.

```typescript
static count(kind: DeviceKind): number
```

Throws: Without a GPU of `kind`.

## capabilitiesDetected

The capabilities this device runs, compiled in or not, as a bitmask.

```typescript
capabilitiesDetected(): bigint
```

## capabilitiesCompiled

The capabilities compiled into this build for devices of this kind, as a bitmask.

```typescript
capabilitiesCompiled(): bigint
```

## capabilitiesEnabled

The capabilities this device's kernel calls run within: detected and compiled at once, as a bitmask.

```typescript
capabilitiesEnabled(): bigint
```

On the CPU the library settles it as it loads, and it always includes [`Capability.serial`](#Capability).

## outputDType

Determines the output dtype for a given kernel family and input dtype, mirroring `nk_kernel_output_dtype` from C.

```typescript
function outputDType(family: KernelFamily, input: DType): DType
```

## Capability

Lowercase capability names, like `haswell`, `neon` or `ampere`, mapped to their bits, and the `cpus`, `gpus` and `any` groups to theirs.

```typescript
const Capability: Readonly<Record<string, bigint>>
```

