|
13 | 13 | from autoarray import exc |
14 | 14 |
|
15 | 15 |
|
16 | | -def _debug_host_array(name: str, x): |
17 | | - """ |
18 | | - Print shape/dtype/strides and nan/inf counts for a host-side array-like. |
19 | | - Safe to call inside pure_callback. |
20 | | - """ |
21 | | - arr = np.asarray(x) # IMPORTANT: raw view BEFORE any dtype/contiguous conversion |
22 | | - finite = np.isfinite(arr) |
23 | | - n_nan = np.isnan(arr).sum() |
24 | | - n_inf = np.isinf(arr).sum() |
25 | | - n_bad = (~finite).sum() |
26 | | - |
27 | | - print( |
28 | | - f"[pure_callback] {name}: shape={arr.shape} dtype={arr.dtype} strides={arr.strides} " |
29 | | - f"n_bad={n_bad} n_nan={n_nan} n_inf={n_inf}" |
30 | | - ) |
31 | | - |
32 | | - # Print a tiny sample for sanity (won't crash on empty) |
33 | | - flat = arr.reshape(-1) |
34 | | - head = flat[:10] if flat.size >= 10 else flat |
35 | | - print(f"[pure_callback] {name}: head={head}") |
36 | | - |
37 | | - return arr |
38 | | - |
39 | | - |
40 | | - |
41 | 16 | def scipy_delaunay(points_np, query_points_np, use_voronoi_areas, areas_factor): |
42 | 17 | """Compute Delaunay simplices (simplices_padded) and Voronoi areas in one call.""" |
43 | 18 |
|
44 | | - # --- Debug: what did the callback actually receive? --- |
45 | | - points_raw = _debug_host_array("points_raw", points_np) |
46 | | - qpts_raw = _debug_host_array("qpts_raw", query_points_np) |
47 | | - |
48 | | - # If anything is non-finite, save inputs to replay and crash immediately. |
49 | | - if (not np.isfinite(points_raw).all()) or (not np.isfinite(qpts_raw).all()): |
50 | | - np.savez("callback_bad_inputs.npz", points=points_raw, qpts=qpts_raw) |
51 | | - raise FloatingPointError( |
52 | | - "Non-finite values at pure_callback entry; saved callback_bad_inputs.npz" |
53 | | - ) |
54 | | - |
55 | | - # (Optional but helpful) enforce expected rank early: |
56 | | - if points_raw.ndim != 2 or points_raw.shape[1] != 2: |
57 | | - raise ValueError(f"points_raw unexpected shape {points_raw.shape}") |
58 | | - if qpts_raw.ndim != 2 or qpts_raw.shape[1] != 2: |
59 | | - raise ValueError(f"qpts_raw unexpected shape {qpts_raw.shape}") |
60 | | - |
61 | | - # Continue using the raw arrays |
62 | | - points_np = points_raw |
63 | | - query_points_np = qpts_raw |
64 | | - |
65 | 19 | max_simplices = 2 * points_np.shape[0] |
66 | 20 |
|
67 | 21 | # --- Delaunay mesh using source plane data grid --- |
@@ -113,6 +67,17 @@ def scipy_delaunay(points_np, query_points_np, use_voronoi_areas, areas_factor): |
113 | 67 | area_weights=split_point_areas, |
114 | 68 | ) |
115 | 69 |
|
| 70 | + # DEBUG: split_points must be finite for KDTree/query |
| 71 | + if not np.isfinite(split_points).all(): |
| 72 | + n_nan = np.isnan(split_points).sum() |
| 73 | + n_inf = np.isinf(split_points).sum() |
| 74 | + print(f"[pure_callback] split_points NON-FINITE: n_nan={n_nan} n_inf={n_inf} " |
| 75 | + f"min={np.nanmin(split_points)} max={np.nanmax(split_points)}") |
| 76 | + np.savez("callback_bad_split_points.npz", |
| 77 | + points=points_np, split_point_areas=split_point_areas, split_points=split_points) |
| 78 | + raise FloatingPointError("split_points contains NaN/inf; saved callback_bad_split_points.npz") |
| 79 | + |
| 80 | + |
116 | 81 | # ---------- find_simplex for split cross points ---------- |
117 | 82 | split_points_idx = tri.find_simplex(split_points) |
118 | 83 |
|
@@ -376,10 +341,23 @@ def pix_indexes_for_sub_slim_index_delaunay_from( |
376 | 341 | # Case 2: Outside → KDTree NN |
377 | 342 | # --------------------------- |
378 | 343 | if outside_mask.any(): |
| 344 | + x = source_plane_data_grid[outside_mask] |
| 345 | + |
| 346 | + if not np.isfinite(x).all(): |
| 347 | + n_nan = np.isnan(x).sum() |
| 348 | + n_inf = np.isinf(x).sum() |
| 349 | + print(f"[pure_callback] KDTree.query input NON-FINITE: n_nan={n_nan} n_inf={n_inf} " |
| 350 | + f"shape={x.shape} dtype={x.dtype}") |
| 351 | + np.savez("callback_bad_kdtree_x.npz", |
| 352 | + x=x, source_plane_data_grid=source_plane_data_grid, outside_mask=outside_mask, |
| 353 | + delaunay_points=delaunay_points) |
| 354 | + raise FloatingPointError("KDTree.query got NaN/inf; saved callback_bad_kdtree_x.npz") |
| 355 | + |
379 | 356 | tree = cKDTree(delaunay_points) |
380 | | - _, idx = tree.query(source_plane_data_grid[outside_mask], k=1) |
| 357 | + _, idx = tree.query(x, k=1) |
381 | 358 | out[outside_mask, 0] = idx.astype(np.int32) |
382 | 359 |
|
| 360 | + |
383 | 361 | out = out.astype(np.int32) |
384 | 362 |
|
385 | 363 | return out |
|
0 commit comments