hyperfold
hyperfold is a modern C++23 high-performance computing library for dense and
structured linear algebra. It provides solver pipelines and accelerator-aware
numerical kernels for CPU and CUDA backends, with an emphasis on numerical
correctness, predictable performance, and explicit resource ownership.
Usage
Hyperfold Python bindings
Hyperfold provides two mutually exclusive wheel variants with the same
hyperfold import name:
python -m pip install hyperfold
# Linux x86_64 with a compatible NVIDIA driver:
python -m pip install hyperfold-cuda
The CPU wheel requires NumPy 1.26 or newer. The CUDA wheel additionally installs
the tested CUDA 13.0 runtime (nvidia-cuda-runtime==13.0.96), cuBLAS
(nvidia-cublas==13.1.1.3) and cuSOLVER
(nvidia-cusolver==12.0.4.66) packages. CuPy and PyTorch are optional and
are never installed by Hyperfold. The two Hyperfold distributions must not be
installed together.
NumPy quickstart:
import numpy as np
import hyperfold
a = np.array([[1, 2], [3, 4]], dtype=np.float32)
b = np.array([[5, 6], [7, 8]], dtype=np.float32)
system = np.array([[4, 1-1j], [1+1j, 3]], dtype=np.complex64)
rhs = np.array([1+2j, 3-1j], dtype=np.complex64)
product = hyperfold.matmul(a, b)
solution = hyperfold.solve(system, rhs)
CuPy and PyTorch use the same functions and preserve their framework through zero-copy DLPack interchange when arrays are contiguous and on one CUDA device:
import cupy as cp
import torch
import hyperfold
x_cp = cp.arange(8, dtype=cp.float32)
y_cp = hyperfold.add(x_cp, x_cp)
x_pt = torch.arange(8, dtype=torch.float32, device="cuda")
y_pt = hyperfold.scale(x_pt, 2.0)
assert isinstance(y_cp, cp.ndarray)
assert isinstance(y_pt, torch.Tensor)
Python sequences infer float32 or complex64. Existing arrays retain their
dtype: common unsupported dtypes are rejected with the exact explicit
astype(...) or framework conversion needed, rather than being silently
rounded. Inputs are limited to vectors and matrices; v1 has no batching or
broadcasting.
| API group | float32 |
complex64 |
CPU | CUDA |
|---|---|---|---|---|
add, subtract, multiply, sum, scale |
yes | yes | yes | yes |
sqrt, conjugate, divide, inner, norm, vector_equal |
no | yes | yes | yes |
matmul |
yes | yes | yes | yes |
other matrix operations and eye |
no | yes | yes | yes |
solve, eigensolvers, partial_trace, is_unitary |
no | yes | yes | yes |
This table is derived from the currently registered CPU and CUDA backends. An
unsupported combination raises hyperfold.BackendError; Python does not
replace missing Hyperfold kernels with NumPy computations.
Reusable factorisations keep the solve operation on the factor itself:
factor = hyperfold.lu_factor(system)
first = factor.solve(rhs)
second = factor.solve(2 * rhs)
copy=None borrows aligned C-contiguous storage and otherwise creates a fresh
same-device contiguous input. copy=False forbids those Python-boundary copies;
copy=True always normalises through fresh storage. Internal algorithmic
scratch and interleaved-complex to split-complex adaptation remain possible in
all three modes. out= must have the same framework, dtype, device and exact
shape, be writable and C-contiguous, and must not overlap an input.
ctx = hyperfold.Context(cpu_threads=8, parallel_work_threshold=65536,
numa_policy="auto", pinning_policy="auto")
y = hyperfold.matmul(a, a, context=ctx)
cuda_ctx = hyperfold.Context(cuda_devices=0, stream_pool_size=32,
scheduling="auto", cross_device="reject")
CUDA calls pass Hyperfold's actual execution stream to each producer's
__dlpack__ method, execute directly into framework-owned output memory, and
complete synchronously before returning. An external stream can be supplied as
Context(external_stream=<CUDA stream pointer>); it remains caller-owned and
must outlive each call. A non-default external stream binds the context to the
first CUDA device on which it is used. Cross-device operands and implicit
host/device transfers are rejected. CUDA reductions return zero-dimensional
CuPy or PyTorch arrays; NumPy reductions return NumPy scalars.
Public wheels target CPython 3.11–3.14 (excluding PyPy and free-threaded builds):
- Linux x86_64 CPU wheels use an AVX2 baseline and fail at import with a clear diagnostic on older CPUs.
- macOS arm64 CPU wheels use NEON and Accelerate.
- Linux x86_64 CUDA wheels use CUDA 13 and include the AVX2 CPU backend; only a compatible system NVIDIA driver is required outside the virtual environment.
Source builds on macOS use Xcode's Apple Clang by default because Accelerate's
headers must match the active Apple SDK. Set HYPERFOLD_MACOS_CXX to an
alternative compatible C++ compiler path when an explicit override is needed.
Known v1 limitations are synchronous CUDA execution, non-negative signed 32-bit
matrix_power exponents, no JAX framework preservation, no futures, and no
__array_ufunc__ or __array_function__ integration. Compiled extensions need
one wheel for every supported Python/platform combination.
Operation and kernel extensions
Python is the primary numerical API. Hyperfold deliberately provides three extension paths with different distribution and dispatch contracts:
| Path | Intended use | Dispatch | Distribution |
|---|---|---|---|
| Python callbacks | Prototypes and orchestration | Exact Python signature match | Python source |
| Typed C++ registration | Source-integrated high-performance kernels | Native dispatch and adaptation | Rebuild the native host |
| C ABI plug-ins | Independently compiled CPU/CUDA kernel packages | Native dispatch and adaptation | Explicitly loaded shared library |
HyperfoldContextBuilder is the typed C++ registration boundary. Operation
identifiers use canonical dotted names and non-zero major versions
(acme.copy@1). Operand roles are library-defined: input index N is encoded
as N, while output index N is encoded as 0x80000000 | N. Valid indices
are 0…0x7fffffff. Input0–Input2 and Output0–Output2 are convenience
constants, Output aliases Output0, and input_role(N)/output_role(N)
support larger arities.
using Input = Hyperfold::CpuDenseRealVectorArg<
float, Hyperfold::OperandRole::Input0, Hyperfold::OperandAccess::Read>;
using Output = Hyperfold::CpuDenseRealVectorArg<
float, Hyperfold::OperandRole::Output, Hyperfold::OperandAccess::Write>;
const Hyperfold::OperationId copy{"acme.copy", 1};
Hyperfold::HyperfoldContextBuilder builder;
auto acme = builder.extension("acme");
acme.register_operation({
copy,
{{Hyperfold::OperandRole::Input0, Hyperfold::OperandAccess::Read,
Hyperfold::OperandKind::Vector},
{Hyperfold::OperandRole::Output, Hyperfold::OperandAccess::Write,
Hyperfold::OperandKind::Vector}}});
acme.register_cpu_kernel<Input, Output>(
copy, Hyperfold::BackendKind::CpuScalar,
[](Input::View input, Output::View output) {
std::copy(input.data(), input.data() + input.size(), output.data());
});
Hyperfold::HyperfoldContext context = std::move(builder).build();
The complete authoring, lifetime, concurrency, CUDA stream, packaging, and
ABI-compatibility contracts are documented in
docs/extensions.md. A buildable CPU plug-in with an
optional CUDA implementation is provided under examples/plugin.
Installed Python packages expose the two ABI headers through
hyperfold.get_include(); full C++ development artefacts remain part of the
native CMake installation rather than the wheel.
The operation contract is zero or more contiguous read-only inputs followed by one or more contiguous write or read-write outputs. Every declared output is mandatory and caller-owned. Python execution returns the caller-supplied object for one output and an ordered tuple of those objects for multiple outputs. Custom operand/backend kinds, automatic plug-in discovery, and automatic Python output allocation are not supported.
Sealed Python contexts also provide deterministic operation introspection.
Context.operations() lists the available versioned operation IDs, while
Context.describe() reports each structural contract, its exact registered
backend/dtype/layout signatures, built-in or extension provenance, and optional
declarative shape and numerical metadata. The latter reports requirements,
direct algorithms, qualitative stability, asymptotic complexity, precision
behaviour, parameters, and explicit uncertainty without changing validation,
dispatch, or numerical execution.
Native wheels for the active Python interpreter can be built locally without a container:
bash scripts/python/build_wheels.sh cpu wheelhouse
bash scripts/python/build_wheels.sh cuda wheelhouse
The CUDA build requires CUDA Toolkit 13.0 or newer. These native wheels are for
local testing and are not repaired portable distribution artefacts. Build the
CPython 3.11-3.14 distribution matrix with matrix mode, which requires
cibuildwheel==4.1.0 and Docker on Linux:
bash scripts/python/build_wheels.sh cpu wheelhouse matrix
bash scripts/python/build_wheels.sh cuda wheelhouse matrix
Hyperfold is distributed under the proprietary Hyperfold Freeware Licence, copyright Lorenzo Fritzsch. Both wheel variants include the licence and third-party notices. See PyPI publishing for account setup, portable wheel builds, validation, and uploads. CI does not build or publish wheel artefacts.
CI workers
The macOS arm64 job dispatches a workflow in a private GitHub helper repository after the containerised Linux C++ and Python tests pass. It fetches the exact GitLab commit, builds and runs the C++ unit and integration tests, installs the private Python package, and runs the Python tests. GitLab waits for that run, downloads its diagnostic artefacts, and fails unless the run succeeds. The macOS job uses Apple Silicon with NEON and Accelerate and is CPU-only. See the macOS bridge setup for the workflow, credentials, timeouts, cancellation behaviour, and hosting limitations.
The Linux CUDA test job uses a fresh Scaleway GPU machine only after the macOS
job succeeds. Both jobs belong to the platform-test stage and require
GITHUB_MACOS_REPOSITORY to be configured. It pulls a versioned CUDA 13.0
build-and-test image from a private
Scaleway Container Registry namespace, mounts the checked-out commit into that
container, and then cleans up. The image already contains the CUDA compiler
and libraries, Compute Sanitizer, build tools, and Python test dependencies;
the fresh worker does not reinstall them. No wheel matrix, Docker manylinux
image, or wheel artefact is produced. Pipelines are created only for merge
requests. The paid GPU job runs automatically for same-project merge requests
and is not available to fork merge requests. The CPU jobs do not require
Scaleway credentials and are eligible to run for fork merge requests, subject
to hosted-runner availability in the source namespace. A newer commit
automatically cancels the replaceable jobs from an older pipeline on the same
merge-request branch. The GPU test job owns both provisioning and cleanup of
its Scaleway resources.
The Windows job remains disabled; its retained configuration requires GitLab's
saas-windows-medium-amd64 hosted runner. The macOS bridge is enabled by setting
GITHUB_MACOS_REPOSITORY and runs only for same-project merge requests.
Enable Auto-cancel redundant pipelines under Settings > CI/CD > General Pipelines in GitLab. The committed workflow then cancels every interruptible job from an older pipeline when a newer commit is pushed to the same branch.
Configure these GitLab CI/CD variables:
SCW_ACCESS_KEYandSCW_SECRET_KEY, masked and hidden, for a dedicated Scaleway IAM application;SCW_ORGANIZATION_IDandSCW_PROJECT_ID, masked and hidden, for a dedicated CI project;SCW_SSH_PRIVATE_KEYas a file variable containing a dedicated ED25519 private key whose public key is registered with Scaleway. GitLab requires multiline SSH keys to use visible rather than masked visibility; the job receives the path to the temporary file and does not print its contents;SCW_GPU_CI_IMAGE_REPOSITORY, visible and non-secret, set to the image repository without a tag, for examplerg.fr-par.scw.cloud/example/hyperfold-ci;SCW_REGISTRY_PUSH_SECRET_KEY, masked and hidden, for a dedicated IAM application withContainerRegistryFullAccesson the CI project;SCW_REGISTRY_PULL_SECRET_KEY, masked and hidden, for a separate dedicated IAM application withContainerRegistryReadOnlyon the CI project.
Both registry variables contain only the relevant API secret key. Docker uses
the fixed username nologin; neither registry application's access-key ID is
required by the pipeline.
The image publisher uses rootless BuildKit and does not require privileged
Docker-in-Docker. The GitLab runner must allow the user namespaces and mount
operations required by rootless BuildKit. The image is tagged with a digest of
docker/gpu-ci/; its build runs automatically when that definition changes
and remains available as a manual merge-request job for recovery. The first
merge request that adds or changes the definition publishes the new image.
Pipelines for later merge requests that do not change it only pull that image;
additional pipelines in the image-changing merge request reuse the registry
build cache and the same content-derived tag.
Also configure SCW_GPU_IMAGE with the Marketplace label
ubuntu_noble_gpu_os_13_nvidia.
Marketplace catalogue UUIDs and zone-local image UUIDs are also accepted: the
job resolves and validates the configured value against the selected GPU type
and zone before creating an instance.
The committed defaults use L4-1-24G in fr-par-1, a 125 GB GPU root volume,
CUDA 13.0, compute capability 8.9, and Scaleway CLI 2.60.0. The Marketplace
image supplies the host-side NVIDIA driver and Docker environment; the private
container supplies the user-space CUDA toolchain. GPU types, zones, volume
settings, readiness timeouts, and architectures remain overridable through the
corresponding variables in .gitlab-ci.yml. Update docker/gpu-ci/Dockerfile
or its requirements file to change a containerised tool version.
SCW_CLEANUP_ATTEMPTS and SCW_CLEANUP_RETRY_SECONDS control the bounded
cleanup retry window and default to 30 attempts five seconds apart.
Scope the control-plane IAM application to the dedicated CI project with
InstancesFullAccess, BlockStorageFullAccess, and SSHKeysReadOnly. Block
Storage access is required to create and remove the GPU instance's SBS root
volume. Keep that project free of unrelated resources, cap its GPU quota, and
treat same-project contributors as trusted:
merge-request pipeline configuration can read even masked variables. The
remote source and test processes never receive the Scaleway control-plane or
registry credentials. The ephemeral host uses the read-only registry secret
through standard input, removes its temporary Docker configuration immediately
after the pull, and does not pass it into the test container.
GPU instances are force-deleted immediately with their IP and all attached
volumes. Every server, flexible IP, and tagged Block Storage volume carries
both hyperfold-ci and hyperfold-ci-gpu; cleanup requires both tags before it
reclaims a resource discovered outside the recorded state. The
scaleway-gpu resource group serialises GPU test jobs. The explicit
bash scripts/ci/scaleway_ci.sh cleanup gpu --all-owned recovery command can
reclaim tagged orphans; run it only when no GPU test job is active.
The job also records its server, flexible-IP, and SBS root-volume IDs. Its exit
trap makes an immediate cleanup attempt, probing exact IDs before deletion and
retaining any state whose absence cannot be confirmed. The same job repeats
the idempotent cleanup in GitLab after_script, including after script failure
or cancellation. SCW_DEFER_CLEANUP_FAILURE=1 allows a successful GPU workload
to defer an unconfirmed trap cleanup to that final attempt, while
AFTER_SCRIPT_IGNORE_ERRORS=false makes an unconfirmed final cleanup fail the
owning job. Workload failures are never hidden. If the runner disappears before
either cleanup attempt completes, use the ownership-wide recovery command once
no GPU test job is active.
The CI image rebuilds its system CA bundle, logs the installed
ca-certificates version, and verifies TLS access to api.scaleway.com before
installing the Scaleway CLI. A GitLab Runner custom CA is added when supplied;
TLS verification is never disabled.
Build the library
This project can be built using make:
make build
You'll find the compiled library in the build/lib/ folder.
CUDA builds require CUDA Toolkit 13.0 or newer. By default, CUDA code is built
for Ampere, Ada, Hopper, and desktop/datacentre Blackwell architectures
(80;86;89;90;100;103;120). Override the target set when configuring a build:
cmake -S . -B build -DENABLE_CUDA=ON -DHYPERFOLD_CUDA_ARCHITECTURES="90;100;103"
NUMA host memory
NUMA-aware host allocation is controlled by HYPERFOLD_ENABLE_NUMA, which accepts
AUTO, ON, or OFF and defaults to AUTO:
cmake -S . -B build -DHYPERFOLD_ENABLE_NUMA=ON
AUTO enables Linux libnuma support when the development files are available.
ON makes missing Linux libnuma support a configure-time error. OFF keeps
host allocation on ordinary aligned storage.
Host vectors, matrices, scalars, LU factors, and eigen outputs keep the requested
NUMA node separately from the effective placement reported by their topology
descriptor. requested_numa_id() is the caller's requested node;
effective_numa_id() and numa_id() report where placement was actually
honoured. If NUMA placement cannot be proven, the effective node is unknown
(-1) and placement_guaranteed() is false.
Topology descriptors now expose placement objects as the primary contract:
host_placement() returns requested/effective NUMA placement, and
gpu_placement() returns the CUDA device id plus any resolved GPU-local NUMA
node and PCI bus id. The node can be discovered from PCI topology or explicitly
configured. The older numa_id() and gpu_id() accessors remain
convenience accessors for the current effective host node and CUDA device id.
The default host allocation policy is fallback: an unavailable node or missing
libnuma falls back to aligned host storage while preserving the requested node
for diagnostics. Strict allocation is available through
HostNumaAllocationPolicy::Strict on low-level host and pinned-host allocation
paths; it fails instead of silently losing requested placement. CPU execution
routing uses effective host placement only, so fallback allocations with unknown
effective placement do not force a NUMA-local runtime.
CUDA host staging and cuSOLVER host workspaces use NUMA-aware pinned host
allocation when CUDA is enabled. Configure this through
CudaHostMemoryOptions, exposed by CudaContext::Options::host_memory and
BackendExecutor::CudaOptions::host_memory. gpu_local_numa_node defaults to
unknown. The transfer_staging and solver_workspace HostMemoryOptions
default to unknown NUMA placement and are resolved to the GPU-local NUMA node
when Linux PCI sysfs reports one; otherwise they remain unknown and use the
configured fallback or strict allocation policy.
For a multi-device BackendExecutor, CudaOptions::host_memory is the fallback
for every device. CudaOptions::host_memory_by_device can override it for each
CUDA device in the execution scope, including systems where PCI sysfs topology
is unavailable. Overrides for devices outside the execution scope are rejected.
CUDA execution scope
CUDA execution supports an execution scope containing one or more CUDA devices.
BackendExecutor::ExecutionScope::cuda_device(device_id) creates a
single-device scope; BackendExecutor::ExecutionScope::cuda_devices(...)
creates a multi-device scope with duplicate ids removed while preserving the
first device as the primary fallback.
Each dispatched CUDA process selects one execution device. Scheduling is driven
by GpuSchedulingOptions: output-device scheduling is the default, first-input
scheduling can prefer the first GPU input, and preferred-device scheduling pins a
specific CUDA device. BackendExecutor validates the selected device and every
GPU operand against the execution scope before running process steps.
The default cross-device policy is CrossDevicePolicy::Reject, which requires
GPU operands to be colocated with the selected execution device. With
PeerCopyIfAvailable, CUDA uses peer copies when CUDA peer access is available
and rejects the operation otherwise. With StagedHostCopy, CUDA stages
cross-device transfers through pinned host memory using the configured CUDA
host staging NUMA policy.
BackendExecutor::execute completes process work through tail events recorded
on participating streams before returning. BackendExecutor::submit returns an
Execution token without adding that final wait; wait() provides the explicit
completion point, and destroying or replacing an unfinished token waits as part
of cleanup. Entity readiness events order later Hyperfold work without a
device-wide barrier, although native library operations may synchronise where
their contracts or status validation require it. A borrowed external CUDA
stream remains caller-owned and must outlive the execution token.
CUDA device resources derive their placement from the owning runtime. CUDA memory pools, stream pools, runtime contexts, and frontend CUDA factories carry the selected device placement into descriptors, including GPU-local NUMA metadata when it is known.
Full and Performance Testing
To build the tests, run:
make build-test
To build and run all the tests, run:
make test
To run benchmark smoke tests:
make test-perf
To run CPU-only coverage tests:
make test-covr-cpu
CUDA coverage and Compute Sanitizer checks are separate CUDA-machine workflows:
make test-covr-full
make test-cuda-sanitise
test-covr-full runs the complete test suite from a coverage-instrumented CUDA
build and writes reports under build-covr-cuda/. The gcovr report covers
host-side CUDA paths, including CUDA-enabled C++ code and launch/runtime paths;
it does not provide per-thread line coverage inside GPU kernels. The full
coverage target enables CUDA-language coverage by building C++ and NVCC host
code with the same compiler and by deriving the matching gcov from that
compiler. By default it probes NVCC's selected host compiler when CXX was not
explicitly set. Override CUDA_COVERAGE_CXX or standard CUDAHOSTCXX to choose
a supported host compiler. Use test-cuda-sanitise for device/runtime
correctness checks through NVIDIA Compute Sanitizer's memcheck tool. That
target registers one aggregate sanitiser test per CUDA-labelled test executable.
An aggregate is skipped when its required device test skips, including when no
CUDA device is visible; an empty GoogleTest selection and any real test or
sanitiser failure remain failures.
The test layer uses CTest labels, so focused runs are available after
make build-test:
ctest --test-dir build-test -L unit
ctest --test-dir build-test -L integration
ctest --test-dir build-test -L cuda
ctest --test-dir build-test -L numa-hardware
The numa-hardware tests are registered only on Linux builds with libnuma.
The policy test needs any allowed NUMA node, the page-residency test needs an
allowed nonzero node and permission to apply and query NUMA policy, and the
worker-affinity test needs an allowed nonzero node with at least three logical
CPUs. Missing topology skips only the affected test. A denied or unavailable
strict allocation or page-residency query also skips, while checks after a
successful strict allocation remain failures.
Benchmarks are built with -DHYPERFOLD_BUILD_BENCHMARKS=ON. make test-perf is
intentionally a short CTest smoke path. Use the benchmark targets below for
timing data:
make benchmark-local
make benchmark-full
make benchmark-full BENCHMARK_FILTER=Matmul
make benchmark-full BENCHMARK_FILTER='LuDecomp|Solve|Logdet|Eigen'
benchmark-local uses short repeated runs for quick feedback. benchmark-full
uses longer runs, 10 repetitions, aggregate reporting, tabular counters, and
JSON output under benchmark-results/. Both targets also write metadata JSON
with CPU, compiler, git revision, and CUDA/GPU details when available.
Individual Google Benchmark executables can also write machine-readable reports:
./build-perf/test/benchmark/backend_cpu/hyperfold_cpu_operation_benchmark --benchmark_filter=Matmul --benchmark_min_time=1s --benchmark_repetitions=10 --benchmark_report_aggregates_only=true --benchmark_counters_tabular=true --benchmark_out=cpu.json --benchmark_out_format=json
./build-perf/test/benchmark/backend_cuda/hyperfold_cuda_operation_benchmark --benchmark_filter=Matmul --benchmark_min_time=1s --benchmark_repetitions=10 --benchmark_report_aggregates_only=true --benchmark_counters_tabular=true --benchmark_out=cuda.json --benchmark_out_format=json
./build-perf/test/benchmark/backend_cpu/hyperfold_cpu_solver_benchmark --benchmark_filter='LuDecomp|Solve|Logdet|Eigen' --benchmark_min_time=1s --benchmark_repetitions=10 --benchmark_report_aggregates_only=true --benchmark_counters_tabular=true --benchmark_out=cpu_solver.json --benchmark_out_format=json
./build-perf/test/benchmark/backend_cuda/hyperfold_cuda_transfer_benchmark --benchmark_min_time=1s --benchmark_repetitions=10 --benchmark_report_aggregates_only=true --benchmark_counters_tabular=true --benchmark_out=cuda_transfer.json --benchmark_out_format=json
The operation benchmarks separate lowered process timing, dispatch-included
timing, direct materialiser-step timing, selected CUDA event-timed GPU regions,
and end-to-end synchronised CUDA latency. Real-time CUDA benchmark variants
explicitly wait for completion per iteration when using BackendExecutor::submit
or lower-level asynchronous paths; BackendExecutor::execute already waits
before returning. Counters include dimensions, throughput, bandwidth, and
GFLOP/s where the operation has a clear FLOP model.
Benchmark host placement can be controlled with environment variables:
HYPERFOLD_BENCHMARK_HOST_NUMA_NODE=1 make benchmark-local
HYPERFOLD_BENCHMARK_CUDA_TRANSFER_NUMA_NODE=1 make benchmark-full BENCHMARK_FILTER=CudaHostToDeviceTransfer
HYPERFOLD_BENCHMARK_CUDA_WORKSPACE_NUMA_NODE=1 make benchmark-full BENCHMARK_FILTER='LuDecomp|Solve|Logdet|Eigen'
HYPERFOLD_BENCHMARK_HOST_NUMA_POLICY=strict make benchmark-local
CPU benchmark host allocations default to requested NUMA node 0. CUDA transfer
staging and solver workspace benchmark settings default to auto, which defers
node selection to CUDA runtime placement resolution. The values auto and
unknown both defer selection; an integer requests a concrete NUMA node. A
resolved request can still fall back to unknown effective placement when the
allocation policy permits it. Set HYPERFOLD_BENCHMARK_HOST_NUMA_POLICY,
HYPERFOLD_BENCHMARK_CUDA_TRANSFER_NUMA_POLICY, or
HYPERFOLD_BENCHMARK_CUDA_WORKSPACE_NUMA_POLICY to fallback or strict to
make the allocation policy explicit.
Benchmark metadata records raw NUMA environment requests, CPU affinity, online
NUMA nodes, the raw CUDA_VISIBLE_DEVICES environment value under
visible_devices_env, CUDA-visible GPU PCI metadata under logical_gpus, and
the physical GPU inventory when available. CUDA benchmark executables currently
use logical device 0; its logical_gpus entry records the resulting physical
mapping when both CUDA and nvidia-smi expose enough information. The metadata
does not claim effective NUMA placement because only each completed allocation
can report whether its requested placement was honoured. Placement-sensitive
comparisons must use the corresponding strict policy so an unhonoured request
fails the benchmark instead of producing ambiguously placed measurements.
Benchmark JSON reports can be compared with:
make benchmark-compare BENCHMARK_BASELINE=benchmark-results/cpu_operation_full.json BENCHMARK_CANDIDATE=benchmark-results-next/cpu_operation_full.json
The make build-perf, make test-perf, and benchmark targets enable CUDA
cudaProfilerStart/cudaProfilerStop markers. CUDA benchmarks also use NVTX
ranges when the toolkit exposes NVTX, so Nsight can capture focused benchmark
regions:
make benchmark-profile BENCHMARK_FILTER=CudaComplexMatmul/Process
nsys profile --capture-range=cudaProfilerApi --trace=cuda,nvtx,osrt,cublas,cusolver ./build-perf/test/benchmark/backend_cuda/hyperfold_cuda_operation_benchmark --benchmark_filter=CudaComplexMatmul/Process --benchmark_min_time=0.1s --benchmark_repetitions=1
ncu --target-processes all ./build-perf/test/benchmark/backend_cuda/hyperfold_cuda_operation_benchmark --benchmark_filter=CudaComplexMatmulGpuTime --benchmark_min_time=0.1s --benchmark_repetitions=1
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hyperfold-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: hyperfold-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 747.3 kB
- Tags: CPython 3.14, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0be5fd4dd0d8c8616a6fb55fe76be66621e5a343d9d7d917a8cb4dbc68bd167
|
|
| MD5 |
cb97c801790c892814dc7c63a9ae26e1
|
|
| BLAKE2b-256 |
cdfe2fc24b58b05b7df1283e63d73913b2e33ddfacada595f8580e67e5fdea71
|
File details
Details for the file hyperfold-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: hyperfold-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 747.2 kB
- Tags: CPython 3.13, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1fd6d332241eebc5d5dba88b71299f143d89f98c50ff90683beb4cb9e0f19af
|
|
| MD5 |
f14379a32b8d587f9b71ab3e817eec57
|
|
| BLAKE2b-256 |
181ce1df85111b84aeeb52a3829698460c0c3d324efe6b4da49fae3a2bdbe9cd
|
File details
Details for the file hyperfold-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: hyperfold-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 747.0 kB
- Tags: CPython 3.12, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e16f5d21f5902999bbf5fcc8c67ecd62b58f1c0121c4a59f6e8e48d7f62583eb
|
|
| MD5 |
bd679f9466864427d2a2d178f8687984
|
|
| BLAKE2b-256 |
3ecfb276ff4f7855e720856c0cf79b77d54e0b67d1f553f9103fc8999c7ed18c
|
File details
Details for the file hyperfold-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: hyperfold-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 748.4 kB
- Tags: CPython 3.11, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89cdfa080ffe2aab71e795fa02f987503bf79c10e920bdd6e05f8bf680ff3ffa
|
|
| MD5 |
8712b419ee52ad928cee4e240a718d39
|
|
| BLAKE2b-256 |
5516649a7cc3bd08b5709a4472eebd03ac9f8cb02662464301ebe1b2eaa14650
|