# Runtime Dispatch

> StringZilla for Go

Every call runs on the CPU and dispatches to the best kernel of its enabled capabilities, those it executes and this binary contains:

```go
cpu := sz.CPU()
enabled, _ := cpu.CapabilitiesEnabled() // what dispatch uses: detected on this CPU and compiled in
fmt.Println(enabled)                    // like "serial,neon,neonaes,neonsha"
fmt.Println(enabled.Has(sz.CapNEON))    // test one capability
```

```go
func CPU() Device
func CountDevices(kind DeviceKind) (int, error)
func NewDevice(kind DeviceKind, ordinal int) (Device, error)
func (d Device) CapabilitiesDetected() (Capability, error)
func (d Device) CapabilitiesCompiled() Capability
func (d Device) CapabilitiesEnabled() (Capability, error)
func (d Device) ConfigureThread(capabilities Capability) (func(), error)
func (c Capability) Has(capability Capability) bool
func (c Capability) String() string
```

A `Device` is the host CPU or one GPU of a runtime, `DeviceCUDA`, `DeviceROCm` or `DeviceMetal`, named by that runtime's own ordinal.
`CountDevices` counts them and fails without a GPU of that kind, and `NewDevice` fails past the last one.
`CapabilitiesDetected` and `CapabilitiesCompiled` report the two raw axes, what the device executes and what this binary contains for its kind.
`CapabilitiesEnabled` is both at once, and on the CPU always keeps `CapSerial`.
`ConfigureThread` pins the goroutine to an OS thread and prepares it for the kernels of its argument, returning the function that unpins it; it fails on a GPU, which has no thread state to configure.
Every capability is a typed `Capability` constant, like `CapSerial`, `CapHaswell`, `CapNEON`, `CapSVE2` or `CapCUDA`, and `CapCPUs`, `CapGPUs` and `CapAny` group them.
A call that reports a failure status returns it as an `error` where the function has one, and panics otherwise.

`import "github.com/ashvardanian/stringzilla/golang"`

## DeviceKind

DeviceKind is the runtime a device belongs to, as the `sz_<kind>_\*` C functions name it.

```go
type DeviceKind int
```

- `DeviceCPU` = `iota`
- `DeviceCUDA`
- `DeviceROCm`
- `DeviceMetal`

## Capability

Capability is one capability of a CPU or a GPU, or a set of them.

```go
type Capability uint64
```

- `CapSerial`: Always: Fallback
- `CapWestmere`: 2010: Intel SSE4.2, AES-NI
- `CapGoldmont`: 2016: Intel SHA-NI
- `CapHaswell`: 2013: Intel AVX2
- `CapSkylake`: 2017: Intel AVX-512
- `CapIceLake`: 2019: Intel AVX-512 VBMI2, VAES
- `CapNEON`: 2013: ARM NEON
- `CapNEONAES`: 2013: ARM NEON AES
- `CapNEONSHA`: 2013: ARM NEON SHA
- `CapSVE`: 2020: ARM SVE
- `CapSVE2`: 2022: ARM SVE2
- `CapSVE2AES`: 2022: ARM SVE2 AES
- `CapRVV`: 2023: RISC-V Vector
- `CapRVVCrypto`: RISC-V Vector Crypto
- `CapV128`: 2021: WASM SIMD128
- `CapV128Relaxed`: 2022: WASM Relaxed SIMD
- `CapLoongsonASX`: LoongArch LASX 256-bit SIMD
- `CapPowerVSX`: Power VSX 128-bit SIMD
- `CapCUDA`: Any CUDA device
- `CapHopper`: CUDA clusters, from compute capability 9.0
- `CapBlackwell`: CUDA cluster launch control, from compute capability 10.0
- `CapROCm`: Any ROCm device
- `CapMetal`: Any Metal device
- `CapCPUs`: Every CPU capability
- `CapGPUs`: Every GPU capability
- `CapAny` = `^Capability(0)`: Every capability

## Has

Has reports whether any bit of capability is in c.

```go
func (c Capability) Has(capability Capability) bool
```

## String

String names the capabilities in c, comma-separated, like "serial,haswell".

```go
func (c Capability) String() string
```

## Device

Device is one device StringZilla knows: 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.

```go
type Device struct {
    Kind    DeviceKind
    Ordinal int
}
```

Every call of this package runs on the CPU, so a GPU device only reports its capabilities here.

## CPU

CPU returns the host CPU, which every build has.

```go
func CPU() Device
```

## NewDevice

NewDevice returns device ordinal of kind, failing past the last one.

```go
func NewDevice(kind DeviceKind, ordinal int) (Device, error)
```

## CapabilitiesCompiled

CapabilitiesCompiled returns the capabilities whose kernels were compiled in for devices of d's kind, whether or not d runs them.

```go
func (d Device) CapabilitiesCompiled() Capability
```

## CapabilitiesDetected

CapabilitiesDetected returns the capabilities d runs, whether or not they were compiled in.

```go
func (d Device) CapabilitiesDetected() (Capability, error)
```

## CapabilitiesEnabled

CapabilitiesEnabled returns the mask for d's calls: [Device.CapabilitiesDetected](#CapabilitiesDetected) and [Device.CapabilitiesCompiled](#CapabilitiesCompiled) at once.

```go
func (d Device) CapabilitiesEnabled() (Capability, error)
```

On the CPU it always has [CapSerial](#CapSerial).

## ConfigureThread

ConfigureThread pins the goroutine to an OS thread, configures it for capabilities, usually the CPU's [Device.CapabilitiesEnabled](#CapabilitiesEnabled), and returns the unlock function.

```go
func (d Device) ConfigureThread(
    capabilities Capability,
) (func(), error)
```

Call it, typically via defer, once the work is done. GPUs have no thread state to configure.

## CountDevices

CountDevices returns how many devices of kind the process sees: one CPU, or the GPUs its runtime counts, failing without one.

```go
func CountDevices(kind DeviceKind) (int, error)
```

