GPU and native runtime

Channel's CUDA-only runtime - the native extension, RayD and OptiX, supported GPU architectures, device placement, memory limits and fail-loud behavior.

Channel runs every solve on an NVIDIA GPU. The Python package is a thin layer over one compiled extension, witwin.channel._channel, which links RayD (the WiTwin GPU ray-tracing library) and uses NVIDIA OptiX for ray-triangle intersection. There is no CPU backend, no NumPy fallback and no reduced mode.

What the native extension contains#

PartRole
RayD 0.8.0Builds the bounding volume hierarchy (BVH), traces rays and finds reflection, diffraction and penetration geometry. Channel compiles it from source at a locked commit.
OptiXHardware ray tracing on RT cores. The OptiX runtime ships with the NVIDIA display driver; only the headers are needed at build time.
Channel CUDA kernelsField evaluation (Fresnel, layer stacks, UTD, Kirchhoff), accumulation into maps, Monte Carlo sampling and the backward and forward-mode companions used for gradients.

witwin.channel.build_info() reports what the loaded extension was built with. On the 0.5.0 Windows wheel:

backend: channel
channel_git_sha: f8575a01da09effe1a83d4cd0d9f46e02b5c4e9b
rayd_commit: c7a99979d0fdcc67b2ec8a12246a7df597603409
cuda_version: 12.8
torch_version: 2.10.0
cuda_architectures: 70-real, 75-real, 80-real, 86-real, 87-real, 89-real, 90-real, 100-real, 101-real, 120-real, 120-virtual
optix_available: True

GPU architectures#

The release wheels contain native code (SASS) for compute capabilities 7.0, 7.5, 8.0, 8.6, 8.7, 8.9, 9.0, 10.0, 10.1 and 12.0, plus compute_120 PTX. A GPU newer than 12.0 compiles the PTX when the extension loads, which makes the first solve slower.

Two levels of support are reported separately:

  • Built: the architectures in build_info()["cuda_architectures"].
  • Declared and verified: runtime_diagnostics()["declared_sm_architectures"] is [75, 80, 86, 89, 120], and only SM 120 (RTX 50-series) has full runtime acceptance evidence in the 0.5.0 release. On any other GPU, runtime_diagnostics()["device"]["status"] reports declared_unverified or not declared. Channel still runs there if the wheel contains code for the GPU, but the release tests did not cover it.

Devices and tensors#

Channel runs on the current CUDA device (torch.cuda.current_device()). Select another GPU with torch.cuda.set_device(i) before you solve. Inputs may be CPU or CUDA tensors; Channel moves endpoint and material values to the GPU. Tensors inside one geometry must share a device: Mesh raises ValueError if vertices and faces are on different devices. All result tensors are CUDA tensors.

Compiled scenes stay in a per-process cache until you call witwin.channel.scene.clear_compile_cache().

Memory limits#

Solvers allocate capacity for paths before they trace. When a scene needs more than the configured capacity, the solve raises instead of dropping paths:

SettingSolverDefault
workspace_limit_bytesmontecarlo.basic, montecarlo.bdpt1 GiB
max_pathsdeterministicNone (sized from the scene)
coupled_candidate_limitdeterministic, path, BDPT1,000,000

See the API pages of each solver for the full list.

Fail-loud behavior#

Channel never returns a partial result. These conditions raise before or during a solve:

  • CUDA is not available, or PyTorch is a CPU build;
  • the native extension cannot be imported (wrong Python, missing DLL, mismatched ABI);
  • the GPU has no code in the extension and no PTX can be compiled for it;
  • an unsupported combination of components, solver and AD mode;
  • a capacity overflow, or a frozen topology that no longer matches the scene.

witwin.channel.runtime_diagnostics() never raises. It collects import and device problems in its errors list, so it is the first thing to run when a solve fails. See Check the runtime.