Zero to "all tests pass" on a fresh Mac. Or on a Linux box if you only want the portable CPU backend.
xcode-select --install
xcrun --show-sdk-version # should be 14.0+ at minimum; 26.0+ unlocks Metal 4If you're on macOS 26 (Tahoe) and the SDK version reports 14.x, run
sudo xcode-select -s /Applications/Xcode.app so the full Xcode is the
selected toolchain — the CLT-only path doesn't ship the macOS 26 SDK.
brew install cmake
cmake --versionFor the python_basic CTest target and the Python binding:
brew install python@3.13 # or whatever 3.10+ your Brew has
python3 -m pip install --upgrade pip
python3 -m pip install numpyIf you prefer pyenv / asdf / system Python, any 3.10+ works. NumPy is the only runtime dependency.
git clone https://github.com/tsotchke/tensorcore.git
cd tensorcore
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j8
ctest --test-dir build --output-on-failureExpected: 31/31 tests pass in roughly 5-15 seconds on a local Apple build.
If ctest shows fewer than 31 tests, your Python or NumPy may not be
visible to CMake -- python_basic skips, dropping the count by one.
./build/examples/hello_gemmExpected first line: [tensorcore] loaded metallib: …/build/tensorcore.metallib.
Then [tensorcore] device="Apple M2 Ultra" (or whatever chip), then
tc_gemm: ok backend=simdgroup_matrix. If you see
backend=simdgroup_matrix, your fast path is wired correctly.
./build/bench/bench_gemm
./build/bench/bench_attention
./build/bench/bench_inference_7bSee benchmarks.md for expected numbers per chip.
For Linux CPU nodes or Intel Macs participating in a hybrid mesh:
cmake -B build -DCMAKE_BUILD_TYPE=Release -DTC_ENABLE_METAL=OFF
cmake --build build -j8
ctest --test-dir build --output-on-failureThis builds only the portable CPU backend: pure C/C++17, no Metal, no
Apple frameworks. The C ABI is identical to the Metal-enabled build;
ops that still depend on an external backend return
TC_ERR_UNSUPPORTED_FAMILY cleanly.
What works on the portable CPU build:
tc_init/tc_shutdown/tc_device_info_gettc_buffer_alloc/tc_buffer_free/tc_buffer_map/tc_buffer_sizetc_stream_create/tc_stream_sync/tc_stream_destroytc_gemm(all dtypes, transpose flags, batched, async)tc_attention_forward/tc_attention_backwardtc_rmsnorm_*,tc_layernorm_*,tc_rope_*,tc_swiglu_*,tc_softmax_*,tc_adamw_step,tc_fused_rmsnorm_gemv,tc_fused_layernorm_gemvtc_conv2d_forward,tc_conv2d_backward_input,tc_conv2d_backward_weighttc_quantize_weights/tc_gemv_quantized(Q4_0, Q8_0)tc_gguf_*(full reader surface)tc_dist_*withTC_DIST_SINGLEbackend (world_size=1no-ops)tc_dist_*withTC_DIST_GLOOon default Apple and portable CPU builds: TCP rendezvous, fp32 SUM/AVG/MIN/MAX all-reduce, fp16 SUM/AVG all-reduce, byte-level broadcast, allgather, and barrier- DiLoCo single-rank, dense multi-rank, and sparse TOPK multi-rank outer
steps over
TC_DIST_GLOO - opt-in CPU GEMM variants via
TC_USE_AVX2_GEMM=1,TC_USE_AVX2_GEMM=1 TC_AVX2_THREADS=1,TC_USE_NEON_GEMM=1, andTC_USE_AMX_GEMM=1; the portable CI script smokes these in isolated Python subprocesses. Direct AMX C regressions also build in portable CPU mode but skip unlessTC_RUN_AMX_GEMM_TEST=1is set on known-good Apple-Silicon hardware.test_amx_proberuns everywhere because it checks only non-trapping AMX metadata/stub paths. - shared-library AVX2 throughput via
build/bench/bench_gemm_shared, which linkslibtensorcore.soso OpenMP tile fanout is present without making the static SDK archive depend on OpenMP. - sparse top-k compression helpers
- memory-tier stub baseline and portable CPU activation-checkpointing discard/realize
- HIP and CUDA backend diagnostics with deterministic unsupported stubs
tc_status_string/tc_dtype_name/tc_backend_name
What doesn't (returns TC_ERR_UNSUPPORTED_FAMILY):
tc_dist_*withTC_DIST_RINGtc_dist_*withTC_DIST_GLOObf16/int8 reductions and public generic sparse packed wire-format APIs- HIP/chipStar execution
- CUDA execution
- DiLoCo dropout tolerance and non-shipped compression modes
tc_last_backend() reports portable_cpu for every served call on
this build.
Windows is a portable CPU target today. It builds the same public C ABI and
Python ctypes surface, installs tensorcore.dll or libtensorcore.dll
depending on the generator, and runs a Winsock-backed TC_DIST_GLOO
loopback split-rank smoke. POSIX-only forked GLOO tests remain Unix-only.
Jack's Windows machine is reachable over Tailscale/SSH; use tailscale status
to confirm its current MagicDNS name or 100.x address. The expected toolchain
on that machine is:
- Visual Studio Build Tools 2022 with Desktop development with C++ (MSVC, Windows SDK, and CMake tools).
- Git for Windows.
- Python 3.11 or 3.12 for the Python binding smoke.
- Optional Ninja; otherwise use the Visual Studio generator from a Developer PowerShell or x64 Native Tools prompt.
The bootstrap script checks this state, installs Python for the current user when requested, installs Visual Studio Build Tools when run from an elevated PowerShell, and then runs the same Windows smoke used in CI:
cd "$env:USERPROFILE\src\tensorcore"
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\bootstrap_windows_cpu.ps1
# First-time toolchain install, from an Administrator PowerShell:
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\bootstrap_windows_cpu.ps1 -InstallOn Jack's machine:
git clone https://github.com/tsotchke/tensorcore.git
cd tensorcore
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\ci_windows_cpu.ps1From a Unix controller on the same tailnet, use the SSH orchestrator to keep the Windows host reproducible:
mkdir -p ~/.config/tensorcore
printf '%s\n' 'TC_WINDOWS_SSH=builder@windows-host.example' \
> ~/.config/tensorcore/windows-host.env
TC_WINDOWS_SSH_KEY="$HOME/.ssh/id_ed25519_jack" scripts/run_windows_host_smoke.sh
TC_WINDOWS_EVIDENCE_PATH=/tmp/windows-host.json \
TC_WINDOWS_SSH_KEY="$HOME/.ssh/id_ed25519_jack" \
scripts/run_windows_host_smoke.shBy default the script clones the repo if missing, then uses git pull --ff-only on master before running bootstrap_windows_cpu.ps1. Set
TC_WINDOWS_RESET=1 only for a clean operational gate where it is acceptable
to hard-reset the remote checkout to origin/master. Set
TC_WINDOWS_EVIDENCE_PATH to capture JSON evidence for
scripts/check_windows_host_smoke_evidence.py and
scripts/check_operational_evidence.py.
For an explicit Visual Studio x64 build:
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\ci_windows_cpu.ps1 `
-Generator "Visual Studio 17 2022" -Platform x64 `
-BuildDir build-windows-cpu -Prefix "$env:TEMP\tensorcore-install"The script configures TC_ENABLE_METAL=OFF, builds the portable CPU library
and CTest suite, installs the native SDK, verifies the installed public
headers, then imports Python against the produced tensorcore.dll with
TENSORCORE_LIB set explicitly.
The direct NVIDIA CUDA and chipStar HIP backends are opt-in build paths:
cmake -S . -B build-cuda -DTC_ENABLE_METAL=OFF -DTC_ENABLE_CUDA=ON
cmake -S . -B build-hip -DTC_ENABLE_METAL=OFF -DTC_ENABLE_HIP=ONTC_ENABLE_CUDA=ON requires CMake's CUDAToolkit package with
CUDA::cudart and CUDA::cublas. TC_ENABLE_HIP=ON requires HIP runtime
targets for device diagnostics; hipBLAS is detected separately and enables
HIP GEMM when present. If runtime dependencies are missing, configure
prints a warning and falls back to the deterministic unsupported stubs used
by default builds. Installed CMake packages preserve the effective backend
flags and rediscover CUDA/HIP dependencies before loading exported targets.
Use scripts/ci_cuda_smoke.sh and scripts/ci_hip_smoke.sh for the
runtime proof on machines that have those backends installed.
The portable build does not build or install tensorcore.metallib.
Consumers should treat the metallib as a Metal-backend artifact and skip
that lookup when TC_ENABLE_METAL=OFF.
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON is on by default (see
CMakeLists.txt:41). After cmake -B build, a compile_commands.json
sits at build/compile_commands.json. Symlink or copy to the repo
root if your editor needs it there:
ln -sf build/compile_commands.json .clangd, VSCode's C/C++ extension, and Xcode's bridge support all read
this file. Metal files use clangd's metal mode (the file extension is
enough).
For Python development, point your IDE at python/tensorcore/__init__.py
(the binding) and python/tests/test_basic.py (the test suite).
The deepest pre-release check. ~30 seconds on M2 Ultra:
cmake --install build --prefix .scratch/release-smoke/install
REQUIRE_GPU=1 scripts/release_smoke.shOn macOS this builds the wheel and native SDK archive, verifies the install via
CMake find_package and pkg-config, runs the full ctest, and writes a
JSON evidence file to build/release_smoke_runtime_evidence.json. See
ci_and_scripts.md § release_smoke.sh for the
schema. Use scripts/ci_portable_cpu.sh plus the shell archive scripts on
Linux, and scripts/ci_windows_cpu.ps1 plus the PowerShell archive scripts on
Windows; the release workflow requires all three platform gates.
Build-time:
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DTC_ENABLE_METAL=ON # OFF for portable CPU
-DTC_ENABLE_TENSOROPS=ON # M5 mpp::tensor_ops dispatch (SDK 26+)
-DTC_BUILD_TESTS=ON
-DTC_BUILD_BENCH=ON
-DTC_BUILD_EXAMPLES=ONRuntime:
export TENSORCORE_LIB=/opt/tensorcore/lib/libtensorcore.dylib
export TC_METALLIB=/opt/tensorcore/lib/tensorcore.metallib
export TC_USE_128_TILE=1 # opt into 128×128 GEMM tile (regresses on M2)
export TC_Q4_USE_V1=1 # revert to original Q4_0 GEMV kernelSee observability.md for the complete list.
The repo ships a developer Makefile. From the repo root:
make build # cmake -B build && cmake --build build -j
make test # the 22 ctest cases
make bench # GEMM + attention + 7B Q4_0 benches
make hello # ./build/examples/hello_gemm
make decode # ./build/examples/decode_step
make train # ./build/examples/training_step
make smoke # release_smoke.sh with REQUIRE_GPU=1
make install # cmake --install to .scratch/dev/install
make wheel # build + install + reimport the wheel
make check-version # version triple consistency
make docs-check # docs/ link integrity
make icc-audit # ICC index + doc-coverage + shell-hardening
make all # build + testSee make help for the full menu.
- MLX. Optional; tensorcore is independent. If you want to compare
fp16 GEMM TFLOPS against MLX, install separately:
pip install mlx. - PyTorch / TensorFlow. Tensorcore's core build only needs the C ABI.
An experimental PyTorch bridge lives in
bindings/pytorchfor fp32/bf16 CPU and PrivateUse1 host-memory matmul plus opt-intorch.matmuldispatch experiments. It uses zero-copy tensor wrappers when the runtime accepts the tensor pointer and falls back to staged buffers otherwise. Importingtensorcore_torchregisters PyTorch's PrivateUse1 name astensorcore, exposes a smalltorch.tensorcoreruntime module, and enables direct host-memory tensor allocation ondevice="tensorcore". Usetensorcore_torch.pytorch_backend_state()ortorch.tensorcore.backend_state()to inspect that capability state from training/deployment scripts;tensorcore_torch.matmul_eligibility()reports the exact dispatcher reason for tensorcore versus ATen fallback.tensorcore_torch.execution_state()reports which native backend served each high-value operation, whether the binding copied buffers or used zero-copy memory, and any intentional fallback reason. The AMP policy is available throughtensorcore_torch.pytorch_amp_supported_dtypes()andtorch.tensorcore.get_amp_supported_dtype(). When PyTorch is installed, runREQUIRE_PYTORCH=1 REQUIRE_PYTORCH_BACKEND=1 scripts/ci_pytorch_smoke.shto force-build the bridge and validate fp32/bf16, empty matmul, dispatcher, autograd fallback, PrivateUse1 allocation, and registration/backend-state behavior. - CUDA. Obviously.
- Real GGUF model. The bench harness uses synthetic Q4_0 weights; full inference against a real GGUF is a v0.2 deliverable.
- GitHub auth. Cloning is anonymous; only the
ghCLI in release_process.md needs auth.
If cmake -B build fails with find_library(METAL_FRAMEWORK) errors,
your Xcode CLT install is incomplete:
sudo xcode-select -s /Applications/Xcode.app
xcrun --show-sdk-path # should print a path under /Applications/Xcode.appIf cmake --build build fails on .metal compilation with
error: unknown intrinsic 'air.…', your Xcode is 17+ and you have stale
CMake cache from an earlier 16.x configure. Wipe and reconfigure:
rm -rf build
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j8If ctest shows python_basic failing with a NumPy error, run with
PYTHONPATH=$PWD/python TENSORCORE_LIB=$PWD/build/libtensorcore.dylib python3 python/tests/test_basic.py directly to see the error.
See troubleshooting.md for runtime issues after the build succeeds.
- integrating_tensorcore.md — once tensorcore works locally, this is how you wire it into another project.
- ci_and_scripts.md — what the CI workflows + helper scripts do.
- release_process.md — from version bump to published wheel.
- observability.md — runtime introspection knobs.