Commit 98e4ee98 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: 3-C rung 1 - pose_corr kernel-test export (checkpoint 1 = raw TD corr...

CLAUDE: 3-C rung 1 - pose_corr kernel-test export (checkpoint 1 = raw TD corr after correlate2D_inter)

curt.kernel_test dropdown entry pose_corr: runs the normal lean pose sequence
with a static armed capture (PoseCorrExport) that records, for the FIRST
fitted scene, every LMA iteration's task streams exactly as the GPU received
them (pre-offsets, task|511) and as the consolidation flattened them
(post-offsets, disp_dist tail zero), the conditioned 16-sensor images exactly
as uploaded (hook in conditionSceneToGpuInner - the data never lands in
QuadCLT), geometry/correction-vector floats, aberration-kernel flatten, the
four LPF/HPF constant payloads, the resident center TD (gpu_clt_ref cam 0)
and the expected packed corr indices + raw TD correlation (captured right
after execCorr2D_inter_TD, before FZ-normalize = the rung-2 boundary).
The sequence stops early once the case is written; the TILE-CALIB save is
additionally gated on !captureDone() so a truncated max-over-scenes
calibration can never be written, and kernelTest refuses to run without an
existing -POSE-RT-TILE-CALIB (the bootstrap FULL pass must never be capture-
truncated). Requires pose_lean+pose_raw ON, pose_stored/pose_full OFF.
C++ side: tile_processor_gpu tests_bin/test_pose_corr --data <case> --tol 0
(newly exercises calculate_tiles_offsets + correlate2D_inter; results/ are
saved reordered into oracle index order for the Java round-trip compare).
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent 2f0611e3
......@@ -281,6 +281,10 @@ public class CuasConditioning {
scene.saveQuadClt(); // bind this scene (conditional; resets bayer guard on switch)
scene.setHasNewImageData(false); // the guard's other re-pull trigger - must be clear
gpuQuad.setBayerImages(data, true); // force H2D; sets bayer_set -> pipeline skips its pull
// pose_corr kernel-test capture: the conditioned data is uploaded directly (never
// stored in the QuadCLT), so the exporter takes its bit-exact copy here. No-op
// unless the curt.kernel_test=pose_corr run armed it. By Claude on 07/13/2026.
com.elphel.imagej.gpu.testdata.PoseCorrExport.offerImages(scene, data);
return true;
}
......
......@@ -32,6 +32,7 @@ import java.util.Arrays;
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.gpu.GpuQuad;
import com.elphel.imagej.gpu.TpTask;
import com.elphel.imagej.gpu.testdata.PoseCorrExport; // pose_corr kernel-test capture // By Claude on 07/13/2026
import com.elphel.imagej.tileprocessor.Correlation2d;
import com.elphel.imagej.tileprocessor.ErsCorrection;
import com.elphel.imagej.tileprocessor.ImageDtt;
......@@ -335,6 +336,10 @@ public class CuasPoseRT {
sortTasksByTile(tp_tasks2[0]); // fixed task-stream order (3-A3, GPU static shape) // By Claude on 07/13/2026
sortTasksByTile(tp_tasks2[1]);
cons_tasks = tp_tasks2; // By Claude on 07/12/2026
// pose_corr kernel-test capture (checkpoint 1, roadmap 3-C rung 1): the task
// streams exactly as handed to the GPU, BEFORE setTasks/updateTasks mutate them.
// No-op unless the curt.kernel_test=pose_corr run armed it. By Claude on 07/13/2026.
PoseCorrExport.iterTasksPre(clt_parameters, image_dtt, gpuQuad, scene, cons_tasks);
image_dtt.interCorrTDMotionBlur(
clt_parameters.img_dtt,
1, // erase_clt_first: NaN outside the task set
......@@ -370,6 +375,7 @@ public class CuasPoseRT {
}
sortTasksByTile(tp_tasks); // fixed task-stream order (3-A3, GPU static shape) // By Claude on 07/13/2026
cons_tasks = new TpTask [][] {tp_tasks, null}; // no-MB: single set, [1] = null // By Claude on 07/12/2026
PoseCorrExport.iterTasksPre(clt_parameters, image_dtt, gpuQuad, scene, cons_tasks); // pose_corr capture (armed only) // By Claude on 07/13/2026
// 2. convert only: LPFs + tasks + offsets + convert_direct, NO correlation (mask=0)
image_dtt.interCorrTD(
clt_parameters.img_dtt,
......@@ -405,6 +411,9 @@ public class CuasPoseRT {
// dominated, not fz-dominated (NOMB oracle 3.58 ~ lean 3.22 at 16x different
// amplitude); the fat zero regularizes usefully at the average's operating point.
// By Claude on 07/04/2026, falsified-and-reverted per LEAN-07.
// pose_corr capture: the SAME arrays after updateTasks() filled the GPU-computed
// offsets - the exact stream the consolidation flattens. By Claude on 07/13/2026.
PoseCorrExport.iterTasksPost(scene, cons_tasks);
CuasTD.consolidateToSlot0(gpuQuad, cons_tasks, // By Claude on 07/12/2026
clt_parameters.curt.oob_soft, clt_parameters.curt.oob_hard);
// DEBUG (img_out): render the composite the correlator sees (the weighted average)
......@@ -419,6 +428,9 @@ public class CuasPoseRT {
1.0/(1.0+clt_parameters.corr_red+clt_parameters.corr_blue)});
gpuQuad.setSensorMaskInter(1);
gpuQuad.execCorr2D_inter_TD(col_weights);
// pose_corr capture: checkpoint 1 = the raw TD correlation + packed indices right
// here, BEFORE fat-zero normalization (rung 2's boundary). By Claude on 07/13/2026.
PoseCorrExport.iterCorr(gpuQuad, scene, col_weights);
// 5. TD tiles -> FZ-normalize -> pixel domain (the JNA-validated TDCorrTile path)
final TDCorrTile [] td_tiles = TDCorrTile.getFromGpu(gpuQuad);
final double [][] corr_pd = TDCorrTile.convertTDtoPD(
......@@ -637,7 +649,10 @@ public class CuasPoseRT {
center_disparity, pXpYD_center, selection,
scene_xyzatr0[0], scene_xyzatr0[1], margin,
mb_vectors, mb_tau, mb_max_gain, corr_pd_out, img_out, debugLevel);
if (cm == null) return null;
if (cm == null) {
PoseCorrExport.sceneFailed(scene); // drop a partial pose_corr capture (armed only) // By Claude on 07/13/2026
return null;
}
final double [][] eigen_masked = clt_parameters.imp.eig_xy_lma ? null : cm[2];
intersceneLma.prepareLMA(
scene_xyzatr0, // scene_xyzatr0
......@@ -681,6 +696,7 @@ public class CuasPoseRT {
lma_debug); // curt.pose_lma_debug boost (inner solver only) // By Claude on 07/12/2026
if (lmaResult < 0) {
System.out.println("leanFitScene(): LMA failed, lmaResult="+lmaResult);
PoseCorrExport.sceneFailed(scene); // drop a partial pose_corr capture (armed only) // By Claude on 07/13/2026
return null;
}
scene_xyzatr0 = intersceneLma.getSceneXYZATR(false);
......@@ -746,6 +762,9 @@ public class CuasPoseRT {
System.out.println("Adjusted interscene, iteration="+nlma+", last RMS = "+
intersceneLma.getLastRms()[0]+" (lean)");
}
// pose_corr capture complete: all measure<->solve iterations of this scene are
// recorded - write the test case (armed only). By Claude on 07/13/2026.
PoseCorrExport.sceneDone(scene);
return scene_xyzatr0;
}
......@@ -1340,6 +1359,14 @@ public class CuasPoseRT {
prev_pose = predicted;
prev_ts = ts;
predicted = new double [][] {fitted[nscene][0].clone(), fitted[nscene][1].clone()};
// pose_corr kernel-test run (roadmap 3-C rung 1): the case is written once the
// first fitted scene completes - the exclusive diagnostic needs no more scenes
// (this run's CSV/products are partial and disposable). By Claude on 07/13/2026.
if (PoseCorrExport.captureDone()) {
System.out.println("CuasPoseRT: pose_corr kernel-test case captured after scene "+
nscene+" ("+ts_name+") - stopping the sequence early");
break;
}
}
// ---- Output ----
......@@ -1364,7 +1391,8 @@ public class CuasPoseRT {
// not selected/measured. Saved only from a FULL-selection run so a filtered run
// never shrinks the calibration coverage. The derived boolean selection is also
// saved (-POSE-RT-RELIABLE-FILT) for visualization.
if (full_selection && !clt_parameters.curt.pose_full && !hyper_scenes.isEmpty()) { // pose_full: never write the calibration // By Claude on 07/04/2026
if (full_selection && !clt_parameters.curt.pose_full && !hyper_scenes.isEmpty()
&& !PoseCorrExport.captureDone()) { // pose_full: never write the calibration // By Claude on 07/04/2026; a pose_corr capture stops the sequence early - a truncated max-over-scenes calibration must never be saved // By Claude on 07/13/2026
final float [] fmax = new float [num_pix];
Arrays.fill(fmax, Float.NaN);
for (int i = 0; i < num_pix; i++) if (reliable_ref[i]) {
......
......@@ -28,6 +28,7 @@ import java.util.Arrays;
import com.elphel.imagej.cuas.CuasMotion;
import com.elphel.imagej.gpu.testdata.AvgTdExport; // By Claude on 07/12/2026
import com.elphel.imagej.gpu.testdata.PoseCorrExport; // pose_corr kernel test (roadmap 3-C rung 1) // By Claude on 07/13/2026
import com.elphel.imagej.cuas.CuasRanging;
import com.elphel.imagej.gpu.GpuQuad;
import com.elphel.imagej.gpu.TpTask;
......@@ -358,7 +359,7 @@ public class CuasRT {
// exports ONE kernel's testdata case; nothing else runs, so a saved config
// can't accidentally mix a kernel test into other diagnostics/production.
// By Claude on 07/12/2026, from Andrey's design.
kernelTest(clt_parameters, master_CLT, debugLevel);
kernelTest(clt_parameters, master_CLT, quadCLTs, debugLevel); // quadCLTs: pose_corr runs the pose sequence // By Claude on 07/13/2026
return true;
}
if (clt_parameters.curt.pose_test) {
......@@ -431,6 +432,7 @@ public class CuasRT {
private static void kernelTest(
final CLTParameters clt_parameters,
final QuadCLT master_CLT,
final QuadCLT [] quadCLTs, // scene sequence (pose_corr runs the pose flow) // By Claude on 07/13/2026
final int debugLevel) {
final String kernel = clt_parameters.curt.kernel_test;
System.out.println("===== CUAS RT GPU-kernel test (curt_kernel_test): "+kernel+" =====");
......@@ -475,6 +477,42 @@ public class CuasRT {
dir_path, phys.getImageName(), debugLevel);
break;
}
case "pose_corr": {
// Lean pose chain CHECKPOINT 1 (roadmap 3-C rung 1): run the NORMAL pose
// sequence with the PoseCorrExport capture armed - the first fitted scene's
// per-LMA-iteration task streams, the resident center TD and the expected raw
// TD correlation (after correlate2D_inter, before FZ-normalize) become the
// case; the sequence then stops early (products of this run are disposable).
// C++ side: tests_bin/test_pose_corr (newly exercises calculate_tiles_offsets
// + correlate2D_inter @ tol 0). By Claude on 07/13/2026, from Andrey's plan.
if (!clt_parameters.curt.pose_lean || !clt_parameters.curt.pose_raw ||
clt_parameters.curt.pose_stored || clt_parameters.curt.pose_full) {
System.out.println("kernelTest(pose_corr): requires pose_lean + pose_raw ON, "+
"pose_stored + pose_full OFF (the production lean chain) - skipping");
return;
}
if (quadCLTs == null) {
System.out.println("kernelTest(pose_corr): no scene sequence - skipping");
return;
}
// the tile calibration must exist: a missing file would trigger the
// FULL-selection bootstrap pass, which the capture's early stop would truncate
if (master_CLT.readImagePlusFromModelDirectory(CuasPoseRT.TILE_CALIB_SUFFIX) == null) {
System.out.println("kernelTest(pose_corr): "+CuasPoseRT.TILE_CALIB_SUFFIX+
" not found - run a normal pose_test once (TILE-CALIB bootstrap), then re-run");
return;
}
PoseCorrExport.arm(dir_path, debugLevel);
try {
CuasPoseRT.testPoseSequence(clt_parameters, master_CLT, quadCLTs, debugLevel);
} finally {
if (!PoseCorrExport.captureDone()) {
System.out.println("kernelTest(pose_corr): capture did NOT complete - no case written");
}
PoseCorrExport.disarm();
}
break;
}
default:
System.out.println("kernelTest(): unknown kernel test '"+kernel+
"' - update CuasRT.kernelTest() to match CuasRtParameters.KERNEL_TESTS");
......@@ -482,6 +520,9 @@ public class CuasRT {
}
if (new File(dir_path, "results").isDirectory()) { // C++ results from a previous run of THIS case
System.out.println("kernelTest("+kernel+"): NOTE - results/ predate this export if the case just changed");
if ("pose_corr".equals(kernel)) { // per-iteration corr_td_it<k> results // By Claude on 07/13/2026
PoseCorrExport.compareResults(dir_path, debugLevel);
} else
AvgTdExport.compareResults(dir_path, debugLevel);
} else {
System.out.println("kernelTest("+kernel+"): now run (tile_processor_gpu): tests_bin/test_"+
......
......@@ -37,7 +37,7 @@ public class CuasRtParameters {
public boolean rend_test = false; // RT full-render product (CuasRender.testRenderSequence): per scene raw /jp4/ -> conditionSceneToGpu -> virtual-grid render at BORROWED stored pose+ERS rates -> -CUAS-RT-RENDER hyperstack [s00..s15, merged][scenes], comparable to -CUAS-INDIVIDUAL/MERGED-CUAS-DBG. NON-exclusive: runs AFTER the pose stage when both are ON (the pose stage is part of the RT cycle - Andrey 07/06/2026). // By Claude on 07/05/2026
public boolean log_test = false; // LoG A/B with the RT render (CuasRender): also save -CUAS-RT-RENDER-LOG-ORACLE (product convolved with the EXISTING pre-DNN pixel LoG, LINEAR alpha=1) and -CUAS-RT-RENDER-LOG-FOLDED (same render, LoG folded into the GPU aberration kernels via CuasLogFold - no pixel convolution; originals restored). The aberration+LoG kernel-fold validation (RT-seed step 1b). // By Claude on 07/06/2026
public boolean log_ident = false; // LoG ISOLATION test with the RT render (CuasRender): render with IDENTITY kernels (-CUAS-RT-RENDER-ID, aberrations skipped), pixel-LoG it (-ID-LOG-ORACLE), and render with PURE-LoG kernels (-LOG-ONLY). If -LOG-ONLY vs -ID-LOG-ORACLE residual persists, the fold/L0 is wrong; if it collapses to the wrap floor, the aberration-kernel interaction was responsible (Andrey 07/06/2026). // By Claude on 07/06/2026
public static final String[] KERNEL_TESTS = {"none", "avg_td", "avg_td_oob"}; // GPU-kernel test registry: one dropdown entry per CUDA kernel under oracle validation (roadmap kernel ladder); add one name here + one case in CuasRT.kernelTest() per new kernel. // By Claude on 07/12/2026
public static final String[] KERNEL_TESTS = {"none", "avg_td", "avg_td_oob", "pose_corr"}; // GPU-kernel test registry: one dropdown entry per CUDA kernel under oracle validation (roadmap kernel ladder); add one name here + one case in CuasRT.kernelTest() per new kernel. pose_corr = lean pose-chain checkpoint 1 (roadmap 3-C rung 1): per-LMA-iteration task streams + resident center TD + expected raw TD correlation after correlate2D_inter, captured from the first fitted scene of a normal pose run (requires pose_lean + pose_raw, existing -POSE-RT-TILE-CALIB, pose_stored OFF). // By Claude on 07/12/2026, pose_corr 07/13/2026
public String kernel_test = KERNEL_TESTS[0]; // GPU-kernel test to run this pass (EXCLUSIVE diagnostic, ONE kernel per Java run - Andrey 07/12/2026): run the kernel's CPU oracle on live GPU data and export a self-describing testdata case for the standalone NSight-debuggable CUDA test (tile_processor_gpu tests_bin/test_<kernel> --data <case> --tol 0). "none" = normal operation. // By Claude on 07/12/2026
public boolean show_kernels = false; // show selected convolution kernel
public boolean dbg_fpixels = true; // save the ORACLE debug renders during ingest (prepareFpixels): -CUAS-INDIVIDUAL-CUAS-DBG (an EXTRA per-sensor render pass, ~11GB) + -CUAS-MERGED-CUAS-DBG (save only - the merged render is the production input regardless). Was hardcoded. Turn OFF to save the render time and disk once the RT chain (-CUAS-RT-RENDER) is the trusted full render. // By Claude on 07/05/2026
......
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