class Capability(enum.IntFlag) Values
SERIAL | ||
|---|---|---|
WESTMERE | ||
GOLDMONT | ||
HASWELL | ||
SKYLAKE | ||
ICELAKE | ||
NEON | ||
NEONAES | ||
NEONSHA | ||
SVE | ||
SVE2 | ||
SVE2AES | ||
RVV | ||
RVVCRYPTO | ||
V128 | ||
V128RELAXED | ||
LOONGSONASX | ||
POWERVSX |
StringZilla detects the running CPU’s SIMD features and routes every kernel to the fastest capability both the CPU and this build have, without recompilation.
Capabilities are sz.Capability flags, one member per CPU capability, like sz.Capability.HASWELL or sz.Capability.NEON; GPU bits sit above every member, so a GPU mask prints as a number.
The producers report capabilities for the CPU, or for one GPU by its runtime’s ordinal, or make a stream on that GPU, and are the only calls taking an ordinal.
sz.__version__ — the package version string.sz.cpu_capabilities_detected(), sz.cuda_capabilities_detected(ordinal) — what the device can execute, whether or not its kernels were compiled in.sz.cpu_capabilities_compiled(), sz.cuda_capabilities_compiled() — what this build holds kernels for, whether or not the device runs them.sz.cpu_capabilities_enabled(), sz.cuda_capabilities_enabled(ordinal) — what calls dispatch with, both of the above; on the CPU it always has SERIAL.sz.cuda_count_devices() — the number of CUDA devices; it raises RuntimeError when none answers, as when this build lacks its kernels, and so does an ordinal past the last device.sz.cpu_configure_thread(capabilities) — prepare the calling thread for the kernels of capabilities; call it on every thread that runs kernels.sz.cuda_stream_init(ordinal), sz.cuda_stream_free(stream) — make a stream on one device, as the integer every stream= takes, and free it once nothing queued on it remains.sz.synchronize(capabilities, stream=None) — wait for one stream of the vendor capabilities names, or its default one.ROCm and Metal have the same rocm_ and metal_ producers.
Every function that runs kernels also takes a keyword-only capabilities=, narrowing that one call and leaving every other call alone.
The keyword keeps no serial fallback, so a mask with no kernel for the call raises LookupError.
import stringzilla as sz
sz.cpu_capabilities_enabled() # e.g. <Capability.SERIAL|NEON|NEONAES|NEONSHA: 449>
sz.find("haystack", "st", capabilities=sz.Capability.SERIAL) # one call on the scalar kernel
sz.cpu_configure_thread(sz.cpu_capabilities_enabled()) # on a thread that runs kernels
[sz.cuda_capabilities_enabled(ordinal) for ordinal in range(sz.cuda_count_devices())] # raises without CUDAEngines and the stateful objects, like Hasher, Sha256 and the AES keys, dispatch every call with the capabilities they were constructed with.
Capabilityclass Capability(enum.IntFlag) SERIAL | ||
|---|---|---|
WESTMERE | ||
GOLDMONT | ||
HASWELL | ||
SKYLAKE | ||
ICELAKE | ||
NEON | ||
NEONAES | ||
NEONSHA | ||
SVE | ||
SVE2 | ||
SVE2AES | ||
RVV | ||
RVVCRYPTO | ||
V128 | ||
V128RELAXED | ||
LOONGSONASX | ||
POWERVSX |
cpu_capabilities_detectedGet the capabilities this CPU can execute.def cpu_capabilities_detected() -> Capability Detected from CPUID or HWCAP. Says nothing about whether the kernels were compiled in, which
cpu_capabilities_compiled reports.
cpu_capabilities_compiledGet the CPU capabilities whose kernels were compiled into this binary.def cpu_capabilities_compiled() -> Capability Decided at build time. Independent of the hardware: a binary built with a broken probe toolchain still detects this machine's full set while containing no SIMD kernels at all, which is what makes a scalar build hard to spot.
cpu_capabilities_enabledGet the CPU capabilities kernels run with, unless a call passes capabilities=.def cpu_capabilities_enabled() -> Capability It is cpu_capabilities_detected() & cpu_capabilities_compiled(), and always has SERIAL.
cpu_configure_threadPrepare the calling thread for kernels of capabilities.def cpu_configure_thread(capabilities: Capability, /) -> None Call it on every thread that runs kernels, before the first of them.
capabilitiesCapability | The mask kernels on this thread run with. |
|---|
*_count_devices× 3Count the devices of one GPU vendor this process sees: cuda_count_devices, and the rocm_ and metal_ ones alike.def cuda_count_devices() -> int | Symbol |
|---|
cuda_count_devices |
rocm_count_devices |
metal_count_devices |
RuntimeError: No device of that vendor answers, or this build lacks its kernels.*_capabilities_detected× 3Get the capabilities a GPU can execute, by its runtime's ordinal, whether or not the kernels were compiled in: cuda_capabilities_detected, and the rocm_ and metal_ ones alike.def cuda_capabilities_detected(ordinal: int, /) -> Capability | Symbol |
|---|
cuda_capabilities_detected |
rocm_capabilities_detected |
metal_capabilities_detected |
RuntimeError: No device with that ordinal answers.*_capabilities_compiled× 3Get the capabilities of one GPU vendor whose kernels were compiled into this binary, whether or not a device runs them: cuda_capabilities_compiled, and the rocm_ and metal_ ones alike.def cuda_capabilities_compiled() -> Capability | Symbol |
|---|
cuda_capabilities_compiled |
rocm_capabilities_compiled |
metal_capabilities_compiled |
*_capabilities_enabled× 3Get the capabilities kernels run with on a GPU, by its runtime's ordinal, both detected and compiled: cuda_capabilities_enabled, and the rocm_ and metal_ ones alike.def cuda_capabilities_enabled(ordinal: int, /) -> Capability | Symbol |
|---|
cuda_capabilities_enabled |
rocm_capabilities_enabled |
metal_capabilities_enabled |
Engines, Strings.copy and synchronize take this mask, which names the vendor, and a stream, which names the device.
RuntimeError: No device with that ordinal answers.*_stream_init× 3Create a stream on a GPU, by its runtime's ordinal, which names that device to the engines, Strings.copy and synchronize it is passed to: cuda_stream_init, and the rocm_ and metal_ ones alike.def cuda_stream_init(ordinal: int, /) -> int | Symbol |
|---|
cuda_stream_init |
rocm_stream_init |
metal_stream_init |
Free it with the matching *_stream_free once its work is synchronized.
cudaStream_t, hipStream_t or id<MTLCommandQueue> handle.RuntimeError: No device with that ordinal answers, or this build lacks its vendor.*_stream_free× 3Free a stream cuda_stream_init made, and the rocm_ and metal_ ones alike, once synchronize joined whatever was queued on it; nothing may use the stream afterwards.def cuda_stream_free(stream: int, /) -> None | Symbol |
|---|
cuda_stream_free |
rocm_stream_free |
metal_stream_free |
synchronizeWait for everything enqueued on one stream, releasing the GIL meanwhile.def synchronize(
capabilities: Capability,
stream: int | None = None,
) -> None A GPU engine's verbs enqueue and return, so their outputs are read, and their inputs freed, only after this returns. Returns at once for CPU capabilities.
capabilitiesCapability | A producer's mask, which names the vendor. | |
|---|---|---|
streamint | None | A stream of that vendor as an integer, or None for the default. |
BufferError: The stream belongs to another device.RuntimeError: A launch on the stream failed, or the device does not answer.