Skip to content

Native CUDA mesh SDF backend + prebuilt CUDA wheels (0.0.2)#1

Merged
Asixa merged 3 commits into
mainfrom
codex/mesh-sdf-native-cuda
Jul 9, 2026
Merged

Native CUDA mesh SDF backend + prebuilt CUDA wheels (0.0.2)#1
Asixa merged 3 commits into
mainfrom
codex/mesh-sdf-native-cuda

Conversation

@Asixa

@Asixa Asixa commented Jul 9, 2026

Copy link
Copy Markdown
Member

Replace the SlangTorch mesh_sdf module with a native CUDA extension
(torch.utils.cpp_extension), mirroring the maxwell FDTD CUDA backend.
Removes intermittent SlangTorch load failures on non-UTF-8 Windows
consoles and ships prebuilt per-platform wheels so installs never
invoke nvcc/MSVC.

  • geometry/cuda/: six kernels (brute/BVH unsigned distance,
    distance+winding, BVH ray-parity sign, hand-derived backward
    gradients) + pybind extension + JIT/packaged-prebuilt loader.
  • mesh_sdf.py: load native module instead of Slang; Torch fallback kept.
  • Packaging: hatch hook marks wheel platform-specific and ships
    prebuilt/*.pyd + CUDA sources; publish workflow builds a CUDA wheel
    matrix (ubuntu-22.04 + windows-2022, py3.10-3.12) + sdist.
  • Bump version to 0.0.2.

CI: all 6 CUDA wheel builds + sdist green on the branch; each build
smoke-loads the packaged prebuilt without compiling.

🤖 Generated with Claude Code

Asixa and others added 3 commits March 28, 2026 12:16
Replace the SlangTorch mesh_sdf module with a native CUDA extension
(torch.utils.cpp_extension), mirroring the maxwell FDTD CUDA backend.
This removes the intermittent SlangTorch load failures on non-UTF-8
Windows consoles and ships prebuilt per-platform wheels so installs
never invoke nvcc/MSVC.

- geometry/cuda/: six mesh SDF kernels (brute/BVH unsigned distance,
  distance+winding, BVH ray-parity sign, and hand-derived backward
  gradients) plus a pybind extension and a JIT/packaged-prebuilt loader.
- mesh_sdf.py: load the native module instead of Slang; keep the
  Torch-native fallback when CUDA/toolchain is unavailable.
- Packaging: hatch build hook marks the wheel platform-specific and
  ships prebuilt/*.pyd plus the CUDA sources; publish workflow builds a
  CUDA wheel matrix (ubuntu-22.04 + windows-2022, py3.10-3.12) and sdist.
- Bump version to 0.0.2.
Copilot AI review requested due to automatic review settings July 9, 2026 08:01
@Asixa
Asixa merged commit 897ee1c into main Jul 9, 2026
18 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the SlangTorch-based mesh SDF implementation with a native PyTorch CUDA extension (via torch.utils.cpp_extension), adds infrastructure for shipping/loading prebuilt CUDA binaries in wheels, and expands geometry/material utilities (including new polygon-extrusion primitives).

Changes:

  • Replaced the Slang mesh SDF backend with a native CUDA extension + Python loader/fallback path.
  • Added new polygon-based primitives (PolySlab, ComplexPolySlab) with signed-distance + mesh export support (where applicable) and accompanying tests.
  • Updated packaging/build automation to include CUDA sources + prebuilt binaries in wheels and to build/publish a CUDA wheel matrix.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
witwin/core/mesh_sdf.slang Removes the old Slang kernel implementation (now superseded by the native CUDA extension).
witwin/core/material.py Adds DifferentiableMaterial and helper coercion utilities for differentiable material parameters.
witwin/core/geometry/primitives.py Adds polygon-loop signed distance helpers and new extruded polygon primitives (PolySlab, ComplexPolySlab).
witwin/core/geometry/mesh_sdf.py Switches mesh SDF dispatch from SlangTorch to the native CUDA extension with caching + Torch fallback.
witwin/core/geometry/cuda/mesh_sdf_kernels.cu Implements the native CUDA kernels (forward + analytic backward) for mesh SDF queries.
witwin/core/geometry/cuda/extension.cpp Defines the PyBind entry points for the CUDA extension.
witwin/core/geometry/cuda/build.py Adds a JIT + packaged-prebuilt loader/build wrapper (including Windows toolchain probing).
witwin/core/geometry/cuda/backend.py Provides a SlangTorch-compatible “module-like” kernel launcher shim over the compiled extension.
witwin/core/geometry/cuda/init.py Exposes the native CUDA backend entry points from the package.
witwin/core/geometry/init.py Exports PolySlab / ComplexPolySlab and includes them in the Geometry union.
witwin/core/init.py Re-exports DifferentiableMaterial at the top-level witwin.core API.
tests/test_geometry_smoke.py Adds smoke coverage for PolySlab construction/to-mesh/to-mask.
tests/test_geometry_sdf.py Adds signed-distance and gradient tests covering polygon slab primitives; updates CUDA SDF skip logic to the native backend.
scripts/build_mesh_sdf_cuda_prebuilt.py Adds a helper script to build and stage a prebuilt extension into cuda/prebuilt/.
pyproject.toml Bumps version to 0.0.2 and configures wheel artifacts + custom hatch hook.
hatch_build.py Marks wheels as non-pure/infer-tagged when a prebuilt extension is present.
.gitignore Ignores prebuilt native extension binaries under witwin/core/geometry/cuda/prebuilt/.
.github/workflows/publish-witwin.yml Adds a CUDA wheel build matrix (Linux/Windows, Py3.10–3.12), sdist build, and release-gated publish flow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread witwin/core/material.py
Comment on lines +23 to +44
def _coerce_differentiable_scalar(value: Any, *, name: str) -> Any:
try:
return float(value)
except (TypeError, ValueError):
return value


def _coerce_differentiable_nonnegative(value: Any, *, name: str) -> Any:
try:
scalar = float(value)
except (TypeError, ValueError):
return value
if scalar < 0.0:
raise ValueError(f"{name} must be >= 0.")
return scalar


def _is_numeric_close(value: Any, target: float) -> bool:
try:
return bool(np.isclose(float(value), target))
except (TypeError, ValueError):
return False
Comment thread witwin/core/material.py
Comment on lines +179 to +191
if resolved_frequency == 0.0:
if not _is_numeric_close(self.sigma_e, 0.0):
try:
scalar_sigma = float(self.sigma_e)
except (TypeError, ValueError):
scalar_sigma = None
if scalar_sigma is not None:
raise ValueError("Conductive materials require frequency > 0.")
return FrequencyMaterialSample(
eps_r=self.eps_r,
mu_r=self.mu_r,
sigma_e=self.sigma_e,
)
Comment thread witwin/core/material.py
Comment on lines +193 to +204
try:
eps_r = complex(
float(self.eps_r),
-float(self.sigma_e) / (2.0 * np.pi * resolved_frequency * VACUUM_PERMITTIVITY),
)
mu_r = float(self.mu_r)
sigma_e = float(self.sigma_e)
except (TypeError, ValueError):
eps_r = self.eps_r
mu_r = self.mu_r
sigma_e = self.sigma_e
return FrequencyMaterialSample(
Comment thread witwin/core/__init__.py
@@ -3,6 +3,7 @@
__version__ = "0.0.1"
Comment on lines +237 to +256
const float N = vdot(a, vcross(b, c));
const float D = la * lb * lc + ab * lc + bc * la + ca * lb;
const float scale = 2.0f * grad_output / fmaxf(N * N + D * D, eps);

// dN/dA = b x c, dN/dB = c x a, dN/dC = a x b.
const float3 dN_da = vcross(b, c);
const float3 dN_db = vcross(c, a);
const float3 dN_dc = vcross(a, b);
const float3 a_hat = vscale(a, 1.0f / la);
const float3 b_hat = vscale(b, 1.0f / lb);
const float3 c_hat = vscale(c, 1.0f / lc);
// dD/dA = (lb*lc + b.c) a_hat + lc*b + lb*c, and cyclic variants.
const float3 dD_da = vadd(vadd(vscale(a_hat, lb * lc + bc), vscale(b, lc)), vscale(c, lb));
const float3 dD_db = vadd(vadd(vscale(b_hat, la * lc + ca), vscale(a, lc)), vscale(c, la));
const float3 dD_dc = vadd(vadd(vscale(c_hat, la * lb + ab), vscale(b, la)), vscale(a, lb));

// d(atan2(N, D)) = (D dN - N dD) / (N^2 + D^2); grad = scale * that.
const float3 gA = vscale(vsub(vscale(dN_da, D), vscale(dD_da, N)), scale);
const float3 gB = vscale(vsub(vscale(dN_db, D), vscale(dD_db, N)), scale);
const float3 gC = vscale(vsub(vscale(dN_dc, D), vscale(dD_dc, N)), scale);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants