Go · Runtime Dispatch

Runtime Dispatch

import "github.com/ashvardanian/stringzilla/golang" 6.0.0-rc.1 · 91a27bdd

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

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

API

Types

DeviceKindDeviceKind is the runtime a device belongs to, as the sz_<kind>_\* C functions name it.
capabilities.go:52 ↗
type DeviceKind int

Values

DeviceCPUiota
DeviceCUDA
DeviceROCm
DeviceMetal
EnumCapabilityCapability is one capability of a CPU or a GPU, or a set of them.2
capabilities.go:17 ↗
type Capability uint64

Values

CapSerialAlways: Fallback
CapWestmere2010: Intel SSE4.2, AES-NI
CapGoldmont2016: Intel SHA-NI
CapHaswell2013: Intel AVX2
CapSkylake2017: Intel AVX-512
CapIceLake2019: Intel AVX-512 VBMI2, VAES
CapNEON2013: ARM NEON
CapNEONAES2013: ARM NEON AES
CapNEONSHA2013: ARM NEON SHA
CapSVE2020: ARM SVE
CapSVE22022: ARM SVE2
CapSVE2AES2022: ARM SVE2 AES
CapRVV2023: RISC-V Vector
CapRVVCryptoRISC-V Vector Crypto
CapV1282021: WASM SIMD128
CapV128Relaxed2022: WASM Relaxed SIMD
CapLoongsonASXLoongArch LASX 256-bit SIMD
CapPowerVSXPower VSX 128-bit SIMD
CapCUDAAny CUDA device
CapHopperCUDA clusters, from compute capability 9.0
CapBlackwellCUDA cluster launch control, from compute capability 10.0
CapROCmAny ROCm device
CapMetalAny Metal device
CapCPUsEvery CPU capability
CapGPUsEvery GPU capability
CapAny^Capability(0)Every capability
HasHas reports whether any bit of capability is in c.
capabilities.go:187 ↗
func (c Capability) Has(capability Capability) bool
StringString names the capabilities in c, comma-separated, like "serial,haswell".
capabilities.go:190 ↗
func (c Capability) String() string
StructDeviceDevice 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.6
capabilities.go:65 ↗
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.

CPUCPU returns the host CPU, which every build has.
capabilities.go:71 ↗
func CPU() Device
NewDeviceNewDevice returns device ordinal of kind, failing past the last one.
capabilities.go:93 ↗
func NewDevice(kind DeviceKind, ordinal int) (Device, error)
CapabilitiesCompiledCapabilitiesCompiled returns the capabilities whose kernels were compiled in for devices of d's kind, whether or not d runs them.
capabilities.go:123 ↗
func (d Device) CapabilitiesCompiled() Capability
CapabilitiesDetectedCapabilitiesDetected returns the capabilities d runs, whether or not they were compiled in.
capabilities.go:102 ↗
func (d Device) CapabilitiesDetected() (Capability, error)
CapabilitiesEnabledCapabilitiesEnabled returns the mask for d's calls: Device.CapabilitiesDetected and Device.CapabilitiesCompiled at once.
capabilities.go:140 ↗
func (d Device) CapabilitiesEnabled() (Capability, error)

On the CPU it always has CapSerial.

ConfigureThreadConfigureThread pins the goroutine to an OS thread, configures it for capabilities, usually the CPU's Device.CapabilitiesEnabled, and returns the unlock function.
capabilities.go:162 ↗
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.

Functions

CountDevicesCountDevices returns how many devices of kind the process sees: one CPU, or the GPUs its runtime counts, failing without one.
sz.go:75 ↗
func CountDevices(kind DeviceKind) (int, error)