Commit c393ede5 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: leanMeasure - drop the just-added JCuda Java-oracle fallback branch...

CLAUDE: leanMeasure - drop the just-added JCuda Java-oracle fallback branch (Andrey's ruling: fallbacks only where free)

The dual-path else-branch added earlier today (f8df8dce) would silently run
a second implementation on the JCuda backend - the exact divergence the
JNA-migration-keep-it-clean policy avoids. Now: no GPU peak kernel -> loud
'requires the JNA backend' message, scene returns null. NOT a JCuda purge:
all pre-existing JCuda code stays (base execCorr2DPeaks null-return, the
consolidation CPU bridge, legacy paths); the double kernel and the Java
oracle remain as VALIDATION tiers in tests/export capture.

mvn package OK.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent f8df8dce
......@@ -445,12 +445,12 @@ public class CuasPoseRT {
// 6. peak + eigen per tile - the frozen 15-arg getMaxXYCmEig contract (Andrey's
// rulings 07/13-14/2026: closed-form 2x2 eigen; recentering + envelope de-bias as
// runtime params; FLOAT kernel in production - real-case float-vs-double dx/dy
// <= 7.2e-7 px, ratified 07/14). PRODUCTION PATH (JNA): corr2D_peak_eig_f measures
// on the GPU and only [n_corr][8] peak floats cross D2H - the PD download happens
// ONLY for debug rendering, the pose_corr capture, or the JCuda fallback (the
// original Java-oracle loop, results equal to the float kernel within validation
// tiers). By Claude on 07/14/2026 (was the unconditional PD D2H + Java loop).
final int corr_width = 2 * GPUTileProcessorDttSize() - 1;
// <= 7.2e-7 px, ratified 07/14). corr2D_peak_eig_f measures on the GPU and only
// [n_corr][8] peak floats cross D2H - the PD download happens ONLY for debug
// rendering or the pose_corr capture. NO JCuda fallback (Andrey's ruling 07/14:
// keep fallbacks only where free) - a backend without the kernel fails loudly;
// the double kernel + the Java oracle remain as VALIDATION tiers (tests/export).
// By Claude on 07/14/2026 (was the unconditional PD D2H + Java loop).
final double [] debias = (clt_parameters.curt.pose_debias > 0) ?
windowAutocorrDebias(GPUTileProcessorDttSize(), clt_parameters.curt.pose_debias) : null;
float [] fdebias = null;
......@@ -470,7 +470,12 @@ public class CuasPoseRT {
clt_parameters.imp.eig_scale_axes,// recenter window: scale eigen-ellipse half-axes
clt_parameters.imp.eig_inc_axes, // recenter window: add to half-axes, pix
true); // float = production (double stays the validation tier)
if ((gpu_peaks != null) && !peaks_path_reported) {
if (gpu_peaks == null) { // no fallback by ruling - fail loudly, not silently slower
System.out.println("leanMeasure(): GPU peak kernel unavailable (JCuda backend?) - "+
"the lean pose chain requires the JNA backend (-Dtp.backend=jna)");
return null;
}
if (!peaks_path_reported) {
peaks_path_reported = true;
System.out.println("CuasPoseRT: GPU peak kernel active (corr2D_peak_eig_f, float; "+
"recenter="+clt_parameters.curt.pose_recenter+", debias="+clt_parameters.curt.pose_debias+
......@@ -478,7 +483,7 @@ public class CuasPoseRT {
}
// PD crosses only when actually consumed
double [][] corr_pd = null;
if ((gpu_peaks == null) || (corr_pd_out != null) || PoseCorrExport.isArmed()) {
if ((corr_pd_out != null) || PoseCorrExport.isArmed()) {
corr_pd = TDCorrTile.fetchNormalizedPD(gpuQuad, corr_indices);
if (corr_pd == null) {
System.out.println("leanMeasure(): fetchNormalizedPD returned null for scene "+scene.getImageName());
......@@ -496,57 +501,20 @@ public class CuasPoseRT {
final double [][] vector_XYS = new double [num_pix][];
final double [][] eigen = new double [num_pix][];
int num_meas = 0;
if (gpu_peaks != null) {
// production path: peak rows align 1:1 with corr_indices; sum slots carry the
// measurement, valid==0 = kernel reject (weak/NaN/degenerate, as the oracle null)
for (int n = 0; n < corr_indices.length; n++) {
if ((corr_indices[n] & ((1 << GPUTileProcessor.CORR_NTILE_SHIFT) - 1)) != 0xff) continue;
final int i = corr_indices[n] >> GPUTileProcessor.CORR_NTILE_SHIFT;
if ((i < 0) || (i >= num_pix) || (pXpYD_center[i] == null)) continue;
final int row = n * GpuQuad.PEAK_ROW_FLOATS;
if (gpu_peaks[row + GpuQuad.PEAK_ROW_FLOATS - 1] == 0.0f) continue; // rejected
centers[i] = pXpYD_center[i];
vector_XYS[i] = new double [] {gpu_peaks[row], gpu_peaks[row + 1], gpu_peaks[row + 2]};
eigen[i] = new double [] {gpu_peaks[row + 3], gpu_peaks[row + 4],
gpu_peaks[row + 5], gpu_peaks[row + 6]};
num_meas++;
}
} else {
// JCuda fallback: the original Java-oracle loop (identical contract, double math)
for (int i = 0; i < num_pix; i++) {
if ((i >= corr_pd.length) || (corr_pd[i] == null) || (pXpYD_center[i] == null)) continue;
double [] corr_tile = corr_pd[i]; // not modified by getMaxXYCmEig (fpn_mask == null)
if (debias != null) { // per-tile copy: corr_pd stays raw for -POSE-RT-CORR2D // By Claude on 07/13/2026
corr_tile = new double [corr_pd[i].length];
for (int k = 0; k < corr_tile.length; k++) {
corr_tile[k] = corr_pd[i][k] * debias[k];
}
}
final double [] r = Correlation2d.getMaxXYCmEig(
corr_tile,
corr_width,
clt_parameters.imp.eig_min_abs, // abs_min
clt_parameters.imp.eig_min_rel, // rel_min
clt_parameters.imp.min_str_sum, // min_peak (single channel = the "sum")
clt_parameters.imp.eig_sub_frac, // pedestal suppression - was hardcoded 0.0: pedestal-inflated
// eigen lambdas -> sqrt(l) hits eig_max_sqrt -> setEigenTransform
// k=max(0,1/sqrt(l)-1/max) ZEROES wide-peak tiles (the eigen-ON
// 3x slow convergence). By Claude on 07/12/2026, Andrey's go.
clt_parameters.curt.pose_recenter,// recentering passes (0 = baseline single-pass) // By Claude on 07/13/2026
clt_parameters.imp.eig_sub_frac1, // pedestal suppression during recentering
clt_parameters.imp.eig_scale_axes,// recenter window: scale eigen-ellipse half-axes
clt_parameters.imp.eig_inc_axes, // recenter window: add to half-axes, pix
null, // fpn_mask (input is FPN-subtracted)
false, // ignore_border
null, // debug_data
true, // eig_fast2x2 FROZEN true: the closed-form eigen IS the contract
false); // debug
if (r == null) continue;
centers[i] = pXpYD_center[i];
vector_XYS[i] = new double [] {r[0], r[1], r[2]};
eigen[i] = new double [] {r[3], r[4], r[5], r[6]};
num_meas++;
}
// peak rows align 1:1 with corr_indices; sum slots carry the measurement,
// valid==0 = kernel reject (weak/NaN/degenerate, as the oracle null). The float
// values are widened to double ONCE here (exact) - the LMA solver stays double.
for (int n = 0; n < corr_indices.length; n++) {
if ((corr_indices[n] & ((1 << GPUTileProcessor.CORR_NTILE_SHIFT) - 1)) != 0xff) continue;
final int i = corr_indices[n] >> GPUTileProcessor.CORR_NTILE_SHIFT;
if ((i < 0) || (i >= num_pix) || (pXpYD_center[i] == null)) continue;
final int row = n * GpuQuad.PEAK_ROW_FLOATS;
if (gpu_peaks[row + GpuQuad.PEAK_ROW_FLOATS - 1] == 0.0f) continue; // rejected
centers[i] = pXpYD_center[i];
vector_XYS[i] = new double [] {gpu_peaks[row], gpu_peaks[row + 1], gpu_peaks[row + 2]};
eigen[i] = new double [] {gpu_peaks[row + 3], gpu_peaks[row + 4],
gpu_peaks[row + 5], gpu_peaks[row + 6]};
num_meas++;
}
if (debugLevel > -2) {
System.out.println("leanMeasure(): scene "+scene.getImageName()+" measured "+num_meas+" tiles");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment