Describe the bug
compute_average_mesh_edge_length in warp/native/mesh.cu unconditionally indexes sum_edge_lengths[n - 1] and divides by 3 * n:
__global__ void compute_average_mesh_edge_length(int n, float* sum_edge_lengths, Mesh* m)
{
m->average_edge_length = sum_edge_lengths[n - 1] / (3 * n);
}
For an empty mesh (n == 0, i.e. no triangles), this reads sum_edge_lengths[-1] — an out-of-bounds device read (and sum_edge_lengths may itself be a zero-length / null buffer) — and divides by zero, producing a NaN average_edge_length, which is then used as the welding epsilon.
Location
warp/native/mesh.cu, compute_average_mesh_edge_length (≈ lines 57–60).
Reachability
Constructing a wp.Mesh with empty indices on a CUDA device.
Suggested fix
Guard the empty case — either skip the three launches when num_tris == 0 on the host side, or in-kernel:
m->average_edge_length = (n > 0) ? sum_edge_lengths[n - 1] / (3.0f * n) : 0.0f;
This removes the out-of-bounds read and the divide-by-zero, and aligns the CUDA path with the CPU path for a degenerate (empty) mesh.
Note on verification
Found by static analysis; I don't have a Warp build locally, so I have not reproduced the OOB at runtime. A maintainer could confirm by creating a wp.Mesh with empty indices on CUDA under compute-sanitizer --tool memcheck. Filing in case it's useful; happy to open a PR if the suggested fix looks right.
Describe the bug
compute_average_mesh_edge_lengthinwarp/native/mesh.cuunconditionally indexessum_edge_lengths[n - 1]and divides by3 * n:For an empty mesh (
n == 0, i.e. no triangles), this readssum_edge_lengths[-1]— an out-of-bounds device read (andsum_edge_lengthsmay itself be a zero-length / null buffer) — and divides by zero, producing a NaNaverage_edge_length, which is then used as the welding epsilon.Location
warp/native/mesh.cu,compute_average_mesh_edge_length(≈ lines 57–60).Reachability
Constructing a
wp.Meshwith emptyindiceson a CUDA device.Suggested fix
Guard the empty case — either skip the three launches when
num_tris == 0on the host side, or in-kernel:This removes the out-of-bounds read and the divide-by-zero, and aligns the CUDA path with the CPU path for a degenerate (empty) mesh.
Note on verification
Found by static analysis; I don't have a Warp build locally, so I have not reproduced the OOB at runtime. A maintainer could confirm by creating a
wp.Meshwith emptyindiceson CUDA undercompute-sanitizer --tool memcheck. Filing in case it's useful; happy to open a PR if the suggested fix looks right.