Commit c673a448 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: DP rung D4 - Java switch: ONE pose_scene_dp entry per scene

Binds the D3-validated tp_proc_exec_pose_scene_dp in TpJna/GpuQuadJna
(+ base GpuQuad stubs, non-throwing negative return = the FAIL-safe
hook) and adds the one-entry-per-scene branch to the lean pose path:

- new saved curt.pose_scene_dp (default ON, 'Pose scene as ONE GPU DP
  entry'): eligibility = frozen lean shape only (fixed cycles, 1-inner
  cap, freeze 0, 3-angle lma_use_R, uniform MB, JNA backend, no armed
  capture, no debug-save holders); everything else falls back to the
  host-driven (B3) loop automatically.
- scene 0 (per template/sequence) always runs the host-driven loop -
  it seeds the resident per-sequence state through the production
  C1/C2 register path - then is REPLAYED through the DP entry as the
  one-shot oracle: per-cycle packed rows vs the captured resident-step
  results, the final anchor vs the fitted angles, and the last-cycle
  peak rows keyed by packed index (the B3 order-independence rule),
  all bit-compared. PASS arms DP from scene 1; FAIL (or any mid-run
  native failure) disables DP for the run and prints why.
- DP scenes reconstruct the scene bookkeeping from the returned trace
  by the exact leanFitScene/IntersceneLma double rules (candidate =
  packed[16..18] widened, dATR in double, RMS = packed[19..22],
  rejected step == the legacy runLma -1 -> coast), fetch/unpack the
  resident last-cycle peaks exactly like leanMeasure, and print the
  same QC/cycles/Done-line fields - the real-scene gate is 497 Done
  lines byte-identical to the 07/16 22:52 saves-OFF record.
- gpuTaskBuild steps 1-5 extracted verbatim into poseMeasureSetup()
  (shared with the DP entry); new 'scene DP entry' profile stage;
  Stage0 kernel count synced 36 -> 40 (the native-only D1-D3 sessions
  added the DP kernels but could not touch the Java constant).

Gates: mvn clean package PASS; Stage0 PASS 40/40; native run_cases.sh
ALL PASS (pose_corr @tol 0 + dp_cycles + measure_dp + scene_dp).
Real-scene gate = Andrey's next routine run: expect the D4 oracle PASS
line after scene 0, 'DP scene entry active' from scene 1, poses/QC
byte-identical, post ~19.5 -> ~8-10 ms/scene.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent 6edca7c6
......@@ -237,7 +237,8 @@ public class CuasPoseRT {
static final int FX_JNA = 26; // cross-cutting: poseFxProvider JNA roundtrip, all lean fx sites // By Claude on 07/17/2026
static final int FX_SETUPERS = 27; // cross-cutting: setupERS pair, lean fx sites
static final int B3_CHAIN = 28; // 3-B rung B3: single-entry batched measure chain (replaces stages 6-13 on batched cycles) // By Claude on 07/16/2026
static final int NUM_STAGES = 29;
static final int DP_SCENE = 29; // DP rung D4: ONE tp_proc_exec_pose_scene_dp entry per scene (replaces the whole measure<->solve loop on DP scenes) // By Claude on 07/17/2026
static final int NUM_STAGES = 30;
static final String [] LABELS = {
"post-conditioning total",
" motion-blur setup",
......@@ -267,7 +268,8 @@ public class CuasPoseRT {
" pose update/QC",
" fx JNA roundtrip (all sites)", // By Claude on 07/17/2026 (rung C0)
" setupERS pair (all lean sites)",
" batched measure chain (B3)" // By Claude on 07/16/2026 (rung B3; a leanMeasure child, printed last)
" batched measure chain (B3)", // By Claude on 07/16/2026 (rung B3; a leanMeasure child, printed last)
" scene DP entry (one JNA call)" // By Claude on 07/17/2026 (rung D4; a lean-fit child on DP scenes)
};
final int scenesExpected;
......@@ -363,8 +365,9 @@ public class CuasPoseRT {
printStage(LMA_GPU_PRODUCTS, postSum);
printStage(LMA_CPU_REMAINDER, postSum);
printStage(POSE_UPDATE, postSum);
printStage(DP_SCENE, postSum); // rung D4: DP scenes (replaces measure/prepare/run/update above) // By Claude on 07/17/2026
printDerived(" lean-fit other",
sum(LEAN_FIT) - sum(MEASURE_TOTAL) - sum(LMA_PREPARE) - sum(LMA_RUN) - sum(POSE_UPDATE), postSum);
sum(LEAN_FIT) - sum(MEASURE_TOTAL) - sum(LMA_PREPARE) - sum(LMA_RUN) - sum(POSE_UPDATE) - sum(DP_SCENE), postSum);
// Cross-cutting boundaries (rung C0): overlap LMA prepare/run above - not
// part of any remainder arithmetic. By Claude on 07/17/2026.
printStage(FX_JNA, postSum);
......@@ -1183,38 +1186,33 @@ public class CuasPoseRT {
private static GpuTaskTemplate gpu_task_template = null;
/**
* 3-B rung B1 (design 2026-07-16): build the correlation tasks ON-DEVICE.
* Verifies the MB vectors are uniform (the pose_mb_uniform broadcast), builds/
* caches the per-sequence template + skeleton, refreshes the per-scene
* configuration registers (scene camera block after setupERS + skeleton
* re-upload, guarding against other pipeline stages having used the task
* slots between scenes), computes the per-scene 6-float uniform-MB descriptor
* with the EXACT setInterTasksMotionBlur double math, and launches
* pose_task_update to rewrite both resident task slots from the current pose.
* Zero per-cycle H2D beyond the 12-float pose vector.
*
* @return the Java-side skeleton TpTask[2][count] to use as cons_tasks, or
* null to fall back to the legacy CPU build (non-uniform/NaN MB).
* By Claude on 07/16/2026.
* Shared per-scene measure setup of the resident GPU task build (rung B1
* steps 1-5, extracted verbatim for the D4 scene-DP entry): uniform-MB
* verification, per-sequence template/skeleton, per-scene configuration
* registers (camera capture + skeleton slots), the 6-float uniform-MB
* descriptor (exact setInterTasksMotionBlur double math) and the margin
* gate bounds. Returns null = fall back to the legacy CPU build.
* By Claude on 07/17/2026.
*/
private static TpTask [][] gpuTaskBuild(
final CLTParameters clt_parameters,
final ImageDtt image_dtt,
private static final class PoseMeasureSetup {
GpuTaskTemplate tpl;
IntersceneLmaFloat.Camera sceneCamera; // non-null only when the scene camera block needs upload
boolean newScene;
boolean newTemplate;
int taskCodeMain, taskCodeSub;
double dxm, dym, dxs, dys, gain, gainSub;
float minPx, maxPx, minPy, maxPy;
}
private static PoseMeasureSetup poseMeasureSetup(
final QuadCLT center_CLT,
final QuadCLT scene,
final double [] center_disparity,
final double [][] pXpYD_center,
final boolean [] selection,
final double [] scene_xyz,
final double [] scene_atr,
final int margin,
final double [][] mb_vectors,
final double mb_tau,
final double mb_max_gain,
final double disparity_corr,
final GpuQuad gpuQuad,
final int [] b3_stats, // rung B3: non-null = run the BATCHED single-entry chain (fills consolidation stats) // By Claude on 07/16/2026
final int debugLevel) {
final int margin,
final GpuQuad gpuQuad) {
// 1. uniform-MB verification: the descriptor is per-scene ONLY if every
// selected tile carries the same (broadcast) vector; the degenerate
// per-tile fallback of uniformMotionBlur() goes back to the CPU build.
......@@ -1267,12 +1265,13 @@ public class CuasPoseRT {
// 3. per-scene configuration registers: camera block (after setupERS) +
// skeleton slots (re-uploaded per scene: other pipeline stages may have
// replaced the task slots between scenes; ~120 KB, once per scene)
final boolean new_scene = !scene.getImageName().equals(tpl.uploadedScene);
final boolean new_template = (tpl.uploadedScene == null);
IntersceneLmaFloat.Camera scene_camera = null;
if (new_scene) {
final PoseMeasureSetup ms = new PoseMeasureSetup();
ms.tpl = tpl;
ms.newScene = !scene.getImageName().equals(tpl.uploadedScene);
ms.newTemplate = (tpl.uploadedScene == null);
if (ms.newScene) {
scene.getErsCorrection().setupERS(); // per-scene ERS line tables (transformToScenePxPyD parity)
scene_camera = IntersceneLmaFloat.Camera.capture(scene.getErsCorrection());
ms.sceneCamera = IntersceneLmaFloat.Camera.capture(scene.getErsCorrection());
gpuQuad.setTasks(tpl.skeleton[0], false, false, 0); // sizes slots + |511 task words
gpuQuad.setTasks(tpl.skeleton[1], false, false, 1);
}
......@@ -1283,16 +1282,14 @@ public class CuasPoseRT {
final int task_code_or = ((1 << GPUTileProcessor.TASK_CORR_EN) | (1 << GPUTileProcessor.TASK_INTER_EN)) | 511;
final double min_sub = 1e-12;
final double min_len = 0.001; // pix
double dxm, dym, dxs, dys, gain, gain_sub;
int task_code_sub;
double dx = mb0;
double dy = mb1;
double mb_len = Math.sqrt(dx * dx + dy * dy);
if (mb_len < min_len) { // no-MB: sub set disabled (task 0 -> |511 = 511)
dxm = 0.0; dym = 0.0; dxs = 0.0; dys = 0.0;
gain = 1.0;
gain_sub = -min_sub;
task_code_sub = 511;
ms.dxm = 0.0; ms.dym = 0.0; ms.dxs = 0.0; ms.dys = 0.0;
ms.gain = 1.0;
ms.gainSub = -min_sub;
ms.taskCodeSub = 511;
} else {
dx /= mb_len; // unit vector
dy /= mb_len;
......@@ -1307,23 +1304,78 @@ public class CuasPoseRT {
dy *= mb_offs;
final double exp_offs = Math.exp(-mb_offs / mb_len);
final double rel_cent = mb_len * (1.0 - (mb_offs / mb_len + 1.0) * exp_offs) / (mb_offs * (1 - exp_offs));
dxm = -rel_cent * dx; // centerXY(main) = projected - rel_cent*d
dym = -rel_cent * dy;
dxs = dxm + (1 - rel_cent) * dx; // centerXY(sub) = main + (1-rel_cent)*d (Java order preserved)
dys = dym + (1 - rel_cent) * dy;
gain = 1.0 / (1.0 - exp_offs);
gain_sub = -gain * exp_offs;
if (gain_sub > -min_sub) {
gain_sub = -min_sub;
}
task_code_sub = task_code_or;
}
ms.dxm = -rel_cent * dx; // centerXY(main) = projected - rel_cent*d
ms.dym = -rel_cent * dy;
ms.dxs = ms.dxm + (1 - rel_cent) * dx; // centerXY(sub) = main + (1-rel_cent)*d (Java order preserved)
ms.dys = ms.dym + (1 - rel_cent) * dy;
ms.gain = 1.0 / (1.0 - exp_offs);
ms.gainSub = -ms.gain * exp_offs;
if (ms.gainSub > -min_sub) {
ms.gainSub = -min_sub;
}
ms.taskCodeSub = task_code_or;
}
ms.taskCodeMain = task_code_or;
// 5. margin gate bounds - GPU port-coords mode Java bounds (no WOI tops)
final int [] wh = scene.getGeometryCorrection().getSensorWH();
final float min_px = margin;
final float max_px = wh[0] - 1 - margin;
final float min_py = margin;
final float max_py = wh[1] - 1 - margin;
ms.minPx = margin;
ms.maxPx = wh[0] - 1 - margin;
ms.minPy = margin;
ms.maxPy = wh[1] - 1 - margin;
return ms;
}
/**
* 3-B rung B1 (design 2026-07-16): build the correlation tasks ON-DEVICE.
* Verifies the MB vectors are uniform (the pose_mb_uniform broadcast), builds/
* caches the per-sequence template + skeleton, refreshes the per-scene
* configuration registers (scene camera block after setupERS + skeleton
* re-upload, guarding against other pipeline stages having used the task
* slots between scenes), computes the per-scene 6-float uniform-MB descriptor
* with the EXACT setInterTasksMotionBlur double math, and launches
* pose_task_update to rewrite both resident task slots from the current pose.
* Zero per-cycle H2D beyond the 12-float pose vector.
*
* @return the Java-side skeleton TpTask[2][count] to use as cons_tasks, or
* null to fall back to the legacy CPU build (non-uniform/NaN MB).
* By Claude on 07/16/2026.
*/
private static TpTask [][] gpuTaskBuild(
final CLTParameters clt_parameters,
final ImageDtt image_dtt,
final QuadCLT center_CLT,
final QuadCLT scene,
final double [] center_disparity,
final double [][] pXpYD_center,
final boolean [] selection,
final double [] scene_xyz,
final double [] scene_atr,
final int margin,
final double [][] mb_vectors,
final double mb_tau,
final double mb_max_gain,
final double disparity_corr,
final GpuQuad gpuQuad,
final int [] b3_stats, // rung B3: non-null = run the BATCHED single-entry chain (fills consolidation stats) // By Claude on 07/16/2026
final int debugLevel) {
// Steps 1-5 extracted to poseMeasureSetup() (shared with the D4 scene-DP
// entry): uniform-MB check, template/skeleton, per-scene registers, the
// uniform-MB descriptor and the margin bounds. By Claude on 07/17/2026.
final PoseMeasureSetup ms = poseMeasureSetup(center_CLT, scene, pXpYD_center,
selection, mb_vectors, mb_tau, mb_max_gain, margin, gpuQuad);
if (ms == null) return null;
final GpuTaskTemplate tpl = ms.tpl;
final boolean new_scene = ms.newScene;
final boolean new_template = ms.newTemplate;
final IntersceneLmaFloat.Camera scene_camera = ms.sceneCamera;
final int task_code_or = ms.taskCodeMain;
final int task_code_sub = ms.taskCodeSub;
final double dxm = ms.dxm, dym = ms.dym, dxs = ms.dxs, dys = ms.dys;
final double gain = ms.gain, gain_sub = ms.gainSub;
final float min_px = ms.minPx;
final float max_px = ms.maxPx;
final float min_py = ms.minPy;
final float max_py = ms.maxPy;
// 6. launch: template on rebuild, camera block per scene, pose every call
// (48 B - the Java-tracked measure pose; B3/DP chain will drop it)
final float [] ref_xyz = IntersceneLmaFloat.toFloat3(ZERO3);
......@@ -1506,6 +1558,413 @@ public class CuasPoseRT {
max_d_float, hole_mismatch));
}
// ---- DP rung D4 (ladder ratified 07/16/2026): the whole per-scene pose solve
// as ONE device entry. Scene 0 (per template/sequence) always runs the
// host-driven loop - it seeds the resident per-sequence state (camera blocks,
// task template, LMA centers) through the production C1/C2 register path -
// and is then REPLAYED through the DP entry as the one-shot oracle: per-cycle
// packed rows, the final anchor and the last-cycle peak rows (keyed by packed
// index, the B3 rule) must all match BIT-EXACT. PASS -> scenes 1+ run one
// tp_proc_exec_pose_scene_dp call each; FAIL -> DP disabled for the run
// (fail-safe: a real divergence must never drive production).
// By Claude on 07/17/2026.
private static final int DP_PACKED = 25; // POSE_LMA_RESIDENT_RESULT: {valid,H[9],b[3],delta[3],candidate[3],rms4,accepted,stop}
private static final int DP_MSTATS = 5; // POSE_MEASURE_STATUS_INTS: {npk,pairs,surviving,misaligned,corr_rows}
private static boolean dp_path_reported = false; // once-per-program "path active" note
private static boolean dp_oracle_failed = false; // fail-safe: FAIL (or a mid-run entry failure) keeps the run host-driven
private static Object dp_seeded_key = null; // the GpuTaskTemplate whose scene-0 legacy pass seeded + validated DP
/** One DP scene entry's readbacks (the single end-of-scene D2H). */
private static final class DpSceneResult {
int npk; // last-cycle corr-row count (>0)
float [] trace; // [num_cycles*DP_PACKED] per-cycle packed rows
int [] mstats; // [num_cycles*DP_MSTATS] per-cycle measure counts
float [] result; // final packed [DP_PACKED]
float [] vector; // final anchor [3]
float [] prep; // last full prepare [8]
int [] stats; // last-cycle {pairs, surviving, misaligned}
}
/**
* Run ONE pose_scene_dp entry for a scene: refresh the per-scene descriptor
* (the exact b3CycleSetup bytes), build the full-prepare objective rows (the
* exact IntersceneLma.residentPrepare floats: pull = the predicted/pull ATR,
* regweights = param_regweights at the 3-angle indices) and launch. Camera/
* task/centers groups follow the C2 register contract (resident unless new).
* Returns null on a native failure (message printed - the FAIL-safe hook).
* By Claude on 07/17/2026.
*/
private static DpSceneResult dpSceneEntry(
final CLTParameters clt_parameters,
final ImageDtt image_dtt,
final QuadCLT center_CLT,
final QuadCLT scene,
final PoseMeasureSetup ms,
final GpuQuad gpuQuad,
final int num_tiles, // full-grid LMA tile count (pXpYD_center.length; corr indices carry full-grid tile numbers)
final double [][] entry_pose, // {xyz, atr} at chain entry (the prediction)
final double [][] pull_pose, // the pull pose (same prediction on the lean path)
final double [] reg_weights, // ilp.ilma_regularization_weights (full-length)
final double lma_lambda,
final int num_cycles) {
final double disparity_corr = clt_parameters.imp.disparity_corr + center_CLT.getDispInfinityRef();
b3CycleSetup(clt_parameters, image_dtt, scene, gpuQuad,
ms.tpl.count, ms.tpl.skeleton[0][0].getSize(),
disparity_corr, ms.minPx, ms.maxPx, ms.minPy, ms.maxPy,
ms.taskCodeMain, ms.taskCodeSub,
ms.dxm, ms.dym, ms.dxs, ms.dys, ms.gain, ms.gainSub);
final float [] pull = new float [IntersceneLmaFloat.NUM_PARAMS];
final float [] regw = new float [IntersceneLmaFloat.NUM_PARAMS];
for (int par = 0; par < IntersceneLmaFloat.NUM_PARAMS; par++) {
pull[par] = (float) pull_pose[1][par];
regw[par] = (float) reg_weights[ErsCorrection.DP_DSAZ + par];
}
final DpSceneResult r = new DpSceneResult();
r.trace = new float [num_cycles * DP_PACKED];
r.mstats = new int [num_cycles * DP_MSTATS];
r.result = new float [DP_PACKED];
r.vector = new float [IntersceneLmaFloat.NUM_PARAMS];
r.prep = new float [8]; // POSE_LMA_PREP_RESULT
r.stats = new int [3];
r.npk = gpuQuad.execPoseSceneDp(
ms.newTemplate ? ms.tpl.refCamera : null,
ms.sceneCamera, // null = keep resident (same scene)
IntersceneLmaFloat.toFloat3(ZERO3), // reference pose = zeros (virtual center)
IntersceneLmaFloat.toFloat3(ZERO3),
IntersceneLmaFloat.toFloat3(entry_pose[0]),
IntersceneLmaFloat.toFloat3(entry_pose[1]),
ms.newTemplate ? ms.tpl.map : null,
ms.newTemplate ? ms.tpl.centers : null,
num_cycles,
(float) lma_lambda,
0.0f, // pure_weight: full prepare reads it LIVE on-device
(float) clt_parameters.ilp.ilma_rms_diff,
num_tiles,
0xff, // the sum slot (the consolidated average x center)
GPUTileProcessor.CORR_NTILE_SHIFT,
IntersceneLmaFloat.NUM_COMPONENTS,
!clt_parameters.imp.eig_xy_lma, // use_eigen (prepareLMA passes eigen=null only when eig_xy_lma)
(float) clt_parameters.imp.eig_min_sqrt,
(float) clt_parameters.imp.eig_max_sqrt,
0.0f, // min_confidence (tiles pre-calibrated)
false, // same_weights
false, // prepare_light: production = per-cycle FULL prepare (pose_freeze_cycle==0)
null, // LMA centers: resident (seeded by the scene-0 legacy pass)
pull, regw,
IntersceneLmaFloat.toFloat3(entry_pose[1]), // entry anchor = the 3-angle parameter vector
r.trace, r.mstats, r.result, r.vector, r.prep, r.stats);
if (r.npk <= 0) {
System.out.println("CuasPoseRT: DP scene entry FAILED for scene "+scene.getImageName()+
" rc="+r.npk+" ("+gpuQuad.poseLastError()+")");
return null;
}
return r;
}
/**
* D4 production path: ONE DP entry replaces the whole measure<->solve loop,
* then the scene bookkeeping/reporting is reconstructed from the per-cycle
* trace by the EXACT leanFitScene/IntersceneLma double rules (all Java-side
* state is derived from the same widened GPU floats, so the printed records
* stay byte-identical to the host-driven loop):
* - per-cycle: candidate = packed[16..18]; accepted = packed[23]; a rejected
* step == the legacy runLma() -1 (scene failed, caller coasts);
* - dATR = L2(candidate - cycle-entry vector) in double; inner iterations =
* stop ? 0 : 1 (the validated 1-inner static shape);
* - RMS: measured = packed[20], solved = packed[22]; the scene RMS = the
* last cycle's candidate pair (all cycles must accept to get here);
* - the last-cycle measurement (peaks) stays resident - fetched and unpacked
* exactly like leanMeasure() for -POSE-RT-HYPER and the weight/num fields.
* @return fitted {xyz,atr}, or null with dp_fallback[0]=false = scene failed
* (coast), or null with dp_fallback[0]=true = run the host-driven loop.
* By Claude on 07/17/2026.
*/
private static double [][] leanFitSceneDp(
final CLTParameters clt_parameters,
final ImageDtt image_dtt,
final QuadCLT center_CLT,
final QuadCLT scene,
final double [][] pXpYD_center,
final boolean [] selection,
final double [][] predicted,
final double [] reg_weights,
final int margin,
final double [][] mb_vectors,
final double mb_tau,
final double mb_max_gain,
final double [] lma_rms,
final double [][][] coord_motion_rslt,
final int [] ncyc_out,
final boolean [] dp_fallback, // out: [0]=true -> caller runs the host-driven loop
final int debugLevel) {
final RtPoseProfile rtProfile = RT_POSE_PROFILE.get();
final GpuQuad gpuQuad = center_CLT.getGPUQuad();
final PoseMeasureSetup ms = poseMeasureSetup(center_CLT, scene, pXpYD_center,
selection, mb_vectors, mb_tau, mb_max_gain, margin, gpuQuad);
if ((ms == null) || (ms.tpl != dp_seeded_key)) {
// degenerate MB this scene, or a NEW template/sequence (bootstrap second
// pass, next sequence) - the host-driven loop re-seeds and re-validates
dp_fallback[0] = true;
return null;
}
final int K = clt_parameters.curt.pose_cycles;
final double lma_lambda = (clt_parameters.curt.pose_lambda > 0) ?
clt_parameters.curt.pose_lambda : clt_parameters.ilp.ilma_lambda;
final long profileStart = (rtProfile != null) ? rtProfile.start() : 0L;
final DpSceneResult r = dpSceneEntry(clt_parameters, image_dtt, center_CLT, scene,
ms, gpuQuad, pXpYD_center.length, predicted, predicted, reg_weights,
lma_lambda, K);
if (rtProfile != null) rtProfile.addElapsed(RtPoseProfile.DP_SCENE, profileStart);
if (r == null) { // FAIL-safe: a mid-run native failure degrades to the host-driven loop
dp_oracle_failed = true;
System.out.println("CuasPoseRT: DP scene entry DISABLED for this run - host-driven loop takes over");
dp_fallback[0] = true;
return null;
}
if (ms.newScene) ms.tpl.uploadedScene = scene.getImageName();
if (!dp_path_reported) {
dp_path_reported = true;
System.out.println("CuasPoseRT: DP scene entry active (ONE tp_proc_exec_pose_scene_dp "+
"per scene: "+K+" x [measure chain -> full prepare -> resident LMA step -> commit] "+
"self-chained on-device; per-scene D2H = per-cycle trace + final packed + last-cycle peaks)");
}
// consolidation warning parity (the B3 per-cycle print)
for (int cyc = 0; cyc < K; cyc++) {
final int mis = r.mstats[cyc * DP_MSTATS + 3];
if (mis != 0) {
System.out.println("CuasPoseRT B3 measure cycle: WARNING - "+mis+
" misaligned MB pairs, "+r.mstats[cyc * DP_MSTATS + 1]+" pairs -> "+
r.mstats[cyc * DP_MSTATS + 2]+" tiles");
}
}
// per-cycle bookkeeping (the leanFitScene/IntersceneLma double rules)
final double [] vec = predicted[1].clone();
final double [] cycle_datr = new double [K];
final int [] cycle_inner = new int [K];
final double [] cycle_rms_meas = new double [K];
final double [] cycle_rms_solved = new double [K];
double last_full_rms = Double.NaN, last_pure_rms = Double.NaN;
int failed_cycle = -1;
for (int cyc = 0; cyc < K; cyc++) {
final int row = cyc * DP_PACKED;
cycle_rms_meas[cyc] = r.trace[row + 20]; // re-measured pure RMS at this cycle's pose
if (r.trace[row + 23] != 1.0f) { // rejected step == the legacy runLma() -1
failed_cycle = cyc;
break;
}
double d2 = 0.0;
for (int par = 0; par < IntersceneLmaFloat.NUM_PARAMS; par++) {
final double cand = r.trace[row + 16 + par]; // widened exactly, like the Java state machine
final double d = cand - vec[par];
d2 += d * d;
vec[par] = cand;
}
cycle_datr[cyc] = Math.sqrt(d2);
cycle_inner[cyc] = (r.trace[row + 24] == 1.0f) ? 0 : 1; // runLma() iter with the 1-inner cap
cycle_rms_solved[cyc] = r.trace[row + 22]; // model-predicted pure RMS after the solve
last_full_rms = r.trace[row + 21];
last_pure_rms = r.trace[row + 22];
}
if (failed_cycle >= 0) {
// The host-driven loop cannot be re-entered mid-scene (the interleave
// already advanced) - report like its runLma() failure and coast.
System.out.println("leanFitScene(): LMA failed, lmaResult=-1"+
" (DP: GPU step rejected at cycle "+failed_cycle+" of "+K+")");
return null; // dp_fallback stays false: scene failed, caller coasts the prediction
}
// QC diagnostic (fixed-cycle mode) - the exact leanFitScene line
final double last_diff_atr = cycle_datr[K - 1];
if (!(last_diff_atr < clt_parameters.imp.exit_change_atr) && (debugLevel > -4)) {
System.out.println("CuasPoseRT QC: scene "+scene.getImageName()+" pose NOT settled after "+
K+" fixed cycles: last ATR change "+last_diff_atr+
" >= exit_change_atr "+clt_parameters.imp.exit_change_atr);
}
if (ncyc_out != null) ncyc_out[0] = K;
if ((clt_parameters.curt.pose_lma_debug >= 1) && (debugLevel > -4)) { // the per-scene cycles trace line
final StringBuilder tsb = new StringBuilder();
for (int i = 0; i < K; i++) tsb.append(String.format(" %.3g", cycle_datr[i]));
final StringBuilder isb = new StringBuilder();
for (int i = 0; i < K; i++) isb.append(" "+cycle_inner[i]);
final StringBuilder rsb = new StringBuilder();
for (int i = 0; i < K; i++) rsb.append(String.format(" %.4f>%.4f",
cycle_rms_meas[i], cycle_rms_solved[i]));
System.out.println("CuasPoseRT cycles: scene "+scene.getImageName()+
" ("+K+" of max "+K+", lambda0 "+lma_lambda+") dATR/cycle ="+tsb+
"; innerLMA ="+isb+"; RMS meas>solved ="+rsb);
}
// last-cycle measurement: peaks/corr indices stayed resident - fetch and
// unpack EXACTLY like leanMeasure() (the -POSE-RT-HYPER + weight/num source)
final int [] corr_indices = gpuQuad.getCorrIndices();
final float [] gpu_peaks = (corr_indices != null) ?
gpuQuad.fetchCorr2DPeaks(corr_indices.length) : null;
if (gpu_peaks == null) {
dp_oracle_failed = true;
System.out.println("CuasPoseRT: DP scene entry peak fetch FAILED for scene "+
scene.getImageName()+" - DP DISABLED, host-driven loop takes over");
dp_fallback[0] = true;
return null;
}
final int num_pix = pXpYD_center.length;
final double [][] centers = new double [num_pix][];
final double [][] vector_XYS = new double [num_pix][];
final double [][] eigen = new double [num_pix][];
int num_meas = 0;
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 (num_meas == 0) return null; // the leanMeasure() failure semantics (coast)
if (lma_rms != null) {
lma_rms[0] = last_full_rms;
if (lma_rms.length > 1) lma_rms[1] = last_pure_rms;
double sw = 0; int nm = 0;
for (double [] v : vector_XYS) if (v != null) { sw += v[2]; nm++; }
if (lma_rms.length > 2) lma_rms[2] = sw;
if (lma_rms.length > 3) lma_rms[3] = nm;
}
if (coord_motion_rslt != null) {
final double [][][] cm = {centers, vector_XYS, eigen};
for (int i = 0; (i < coord_motion_rslt.length) && (i < cm.length); i++) {
coord_motion_rslt[i] = cm[i];
}
}
if (debugLevel > -3) { // the leanFitScene exit line (same widened-float double)
System.out.println("Adjusted interscene, iteration="+K+", last RMS = "+
last_full_rms+" (lean)");
}
return new double [][] {predicted[0].clone(), vec};
}
/**
* D4 one-shot first-scene oracle: the host-driven loop just fitted this scene
* (its per-cycle resident-step results are in {@code capture}); replay the
* WHOLE scene through the DP entry from the same entry pose and compare
* bit-exact - per-cycle candidate/RMS/decision rows, the final anchor, and
* the last-cycle peak rows keyed by packed index (correlate2D_inter row order
* is legitimately nondeterministic - the B3 lesson). PASS arms the DP path
* for this template; FAIL (or a native failure) disables DP for the run.
* By Claude on 07/17/2026.
*/
private static void dpFirstSceneOracle(
final CLTParameters clt_parameters,
final ImageDtt image_dtt,
final QuadCLT center_CLT,
final QuadCLT scene,
final double [][] pXpYD_center,
final boolean [] selection,
final double [][] predicted,
final double [] reg_weights,
final int margin,
final double [][] mb_vectors,
final double mb_tau,
final double mb_max_gain,
final double lma_lambda,
final ArrayList<IntersceneLmaFloat.ResidentLmaStepResult> capture,
final double [] final_atr, // the host-driven loop's fitted angles
final GpuQuad gpuQuad) {
final int K = clt_parameters.curt.pose_cycles;
if (capture.size() != K) {
// A SUCCESSFUL scene without K resident-step results = the resident LMA
// machinery is inactive (persistent config, not a transient) - disable.
// (A failed scene never reaches the oracle and retries naturally.)
dp_oracle_failed = true;
System.out.println("CuasPoseRT D4 oracle: captured "+capture.size()+
" resident steps (need "+K+") - resident LMA machinery inactive, "+
"DP scene entry DISABLED for this run");
return;
}
// the host-driven loop's last-cycle rows, BEFORE the replay overwrites them
final int [] legacy_idx = gpuQuad.getCorrIndices();
final float [] legacy_peaks = (legacy_idx != null) ?
gpuQuad.fetchCorr2DPeaks(legacy_idx.length) : null;
if (legacy_peaks == null) {
System.out.println("CuasPoseRT D4 oracle: legacy peak fetch failed - retrying on the next scene");
return;
}
final PoseMeasureSetup ms = poseMeasureSetup(center_CLT, scene, pXpYD_center,
selection, mb_vectors, mb_tau, mb_max_gain, margin, gpuQuad);
if (ms == null) {
System.out.println("CuasPoseRT D4 oracle: measure setup degenerate - retrying on the next scene");
return;
}
final DpSceneResult r = dpSceneEntry(clt_parameters, image_dtt, center_CLT, scene,
ms, gpuQuad, pXpYD_center.length, predicted, predicted, reg_weights,
lma_lambda, K);
if (r == null) {
dp_oracle_failed = true;
System.out.println("CuasPoseRT: DP scene entry DISABLED for this run (oracle replay failed) - staying host-driven");
return;
}
// per-cycle packed rows vs the captured resident-step results (bit compare)
long step_mism = 0;
for (int cyc = 0; cyc < K; cyc++) {
final IntersceneLmaFloat.ResidentLmaStepResult s = capture.get(cyc);
final int row = cyc * DP_PACKED;
if ((s.step == null) || (s.step.candidate == null) ||
(s.step.candidate.length != IntersceneLmaFloat.NUM_PARAMS)) { step_mism++; continue; }
for (int par = 0; par < IntersceneLmaFloat.NUM_PARAMS; par++) {
if (Float.floatToRawIntBits(r.trace[row + 16 + par]) !=
Float.floatToRawIntBits(s.step.candidate[par])) step_mism++;
}
if (Float.floatToRawIntBits(r.trace[row + 19]) != Float.floatToRawIntBits(s.currentRms)) step_mism++;
if (Float.floatToRawIntBits(r.trace[row + 20]) != Float.floatToRawIntBits(s.currentPureRms)) step_mism++;
if (Float.floatToRawIntBits(r.trace[row + 21]) != Float.floatToRawIntBits(s.candidateRms)) step_mism++;
if (Float.floatToRawIntBits(r.trace[row + 22]) != Float.floatToRawIntBits(s.candidatePureRms)) step_mism++;
if ((r.trace[row + 23] == 1.0f) != s.accepted) step_mism++;
if ((r.trace[row + 24] == 1.0f) != s.stop) step_mism++;
}
// final anchor vs the host-driven fitted angles (widen/narrow is exact)
int anchor_mism = 0;
for (int par = 0; par < IntersceneLmaFloat.NUM_PARAMS; par++) {
if (Float.floatToRawIntBits(r.vector[par]) !=
Float.floatToRawIntBits((float) final_atr[par])) anchor_mism++;
}
// last-cycle rows, order-independent by packed index (the B3 rule)
final int [] dp_idx = gpuQuad.getCorrIndices();
final float [] dp_peaks = (dp_idx != null) ? gpuQuad.fetchCorr2DPeaks(dp_idx.length) : null;
int missing = 0, extra = 0;
long row_mism = 0;
if (dp_peaks == null) {
missing = legacy_idx.length; // fetch failure counts as a full mismatch
} else {
final java.util.HashMap<Integer, Integer> legacy_rows = new java.util.HashMap<>();
for (int n = 0; n < legacy_idx.length; n++) legacy_rows.put(legacy_idx[n], n);
final int row_floats = GpuQuad.PEAK_ROW_FLOATS;
for (int n = 0; n < dp_idx.length; n++) {
final Integer on = legacy_rows.remove(dp_idx[n]);
if (on == null) { extra++; continue; }
for (int k = 0; k < row_floats; k++) {
if (Float.floatToRawIntBits(dp_peaks[n * row_floats + k]) !=
Float.floatToRawIntBits(legacy_peaks[on * row_floats + k])) row_mism++;
}
}
missing = legacy_rows.size();
}
final boolean pass = (step_mism == 0) && (anchor_mism == 0) &&
(missing == 0) && (extra == 0) && (row_mism == 0);
System.out.println(String.format(
"CuasPoseRT D4 DP-vs-host oracle (one-shot, scene %s, %d cycles):"+
" step-row bit-mismatches=%d, final-anchor mismatches=%d;"+
" last-cycle peaks (order-independent by packed index): %d rows,"+
" unmatched host=%d dp=%d, bit-mismatches=%d -> %s",
scene.getImageName(), K, step_mism, anchor_mism,
legacy_idx.length, missing, extra, row_mism, pass ? "PASS" : "FAIL"));
if (pass) {
dp_seeded_key = ms.tpl; // scenes on this template now take the ONE-entry DP path
} else { // fail-safe: a REAL divergence must never drive production
dp_oracle_failed = true;
System.out.println("CuasPoseRT: DP scene entry DISABLED for this run (oracle FAIL) - staying host-driven");
}
}
private static int GPUTileProcessorDttSize() {
return com.elphel.imagej.gpu.GPUTileProcessor.DTT_SIZE;
}
......@@ -1697,10 +2156,38 @@ public class CuasPoseRT {
final int [] ncyc_out, // null or [1]: outer cycles executed (for the one-line scene report) // By Claude on 07/13/2026
final int debugLevel) {
final RtPoseProfile rtProfile = RT_POSE_PROFILE.get();
// DP rung D4 (ladder ratified 07/16/2026): eligibility for the ONE-entry-per-
// scene path. The frozen lean shape only: fixed cycles, 1-inner cap, per-cycle
// full prepare (freeze 0), uniform MB, JNA backend, no armed capture and no
// debug-save holders (their fetches read mid-loop state). By Claude on 07/17/2026.
final GpuQuad lmaGpu = center_CLT.getGPUQuad();
final boolean dp_config = clt_parameters.curt.pose_scene_dp && !dp_oracle_failed &&
(clt_parameters.curt.pose_cycles > 0) &&
(clt_parameters.curt.pose_max_lma == 1) &&
(clt_parameters.curt.pose_freeze_cycle == 0) &&
clt_parameters.imp.lma_use_R && // the frozen 3-angle shape (2-angle = no resident machinery)
clt_parameters.curt.pose_mb_uniform && (mb_vectors != null) &&
lmaGpu.supportsPoseSceneDp() && lmaGpu.supportsResidentTaskSlots() &&
!PoseCorrExport.isArmed() &&
(corr_pd_out == null) && (img_out == null);
if (dp_config && (dp_seeded_key != null) && (dp_seeded_key == gpu_task_template)) {
// production DP branch: the oracle passed on this template's scene 0
final boolean [] dp_fallback = {false};
final double [][] dp_pose = leanFitSceneDp(clt_parameters, image_dtt, center_CLT,
scene, pXpYD_center, selection, predicted, reg_weights, margin,
mb_vectors, mb_tau, mb_max_gain, lma_rms, coord_motion_rslt, ncyc_out,
dp_fallback, debugLevel);
if (!dp_fallback[0]) return dp_pose; // fitted, or null = scene failed (caller coasts)
// fall through: the host-driven loop re-seeds/re-validates or finishes the run
}
// scene-0 (per template) oracle arm: capture every resident-step result of the
// host-driven loop for the end-of-scene DP replay compare. By Claude on 07/17/2026.
final ArrayList<IntersceneLmaFloat.ResidentLmaStepResult> dp_capture =
(dp_config && (dp_seeded_key != gpu_task_template)) ?
new ArrayList<IntersceneLmaFloat.ResidentLmaStepResult>() : null;
final IntersceneLma intersceneLma = new IntersceneLma(
clt_parameters.ilp.ilma_thread_invariant,
0.0); // no disparity weight (2D only)
final GpuQuad lmaGpu = center_CLT.getGPUQuad();
intersceneLma.setPoseFxProvider((
reference, sceneCamera,
referenceXyz, referenceAtr, sceneXyz, sceneAtr,
......@@ -1722,6 +2209,7 @@ public class CuasPoseRT {
lmaGpu.execPoseLmaResidentStep(
lambda, weights, y, eigen, vector, pureWeight, rmsDiff,
numTiles, capturePrepared);
if ((dp_capture != null) && (result != null)) dp_capture.add(result); // D4 oracle arm // By Claude on 07/17/2026
if ((result != null) && !pose_lma_step_path_reported) {
pose_lma_step_path_reported = true;
// Rung B (design 2026-07-16): GPU decision promoted to authoritative. By Claude on 07/16/2026.
......@@ -1992,6 +2480,16 @@ public class CuasPoseRT {
System.out.println("Adjusted interscene, iteration="+nlma+", last RMS = "+
intersceneLma.getLastRms()[0]+" (lean)");
}
// D4 one-shot oracle: this scene just ran the host-driven loop with the
// resident-step results captured - replay it through the DP entry and
// bit-compare; PASS arms the ONE-entry path from the next scene on.
// By Claude on 07/17/2026.
if (dp_capture != null) {
dpFirstSceneOracle(clt_parameters, image_dtt, center_CLT, scene,
pXpYD_center, selection, predicted, reg_weights, margin,
mb_vectors, mb_tau, mb_max_gain, lma_lambda,
dp_capture, scene_xyzatr0[1], lmaGpu);
}
// 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);
......
......@@ -3080,6 +3080,60 @@ public class GpuQuad{ // quad camera description
/** Upload gc + cv once per scene for the batched chain (the granular path re-uploads them every cycle). */
public void uploadPoseCycleGeometry() {
}
/**
* DP rung D4 (ladder ratified 2026-07-16): the FULL per-scene pose solve as ONE
* device entry (num_cycles x [measure chain -> prepare -> resident step -> commit],
* self-chained on-device). Base/JCuda has no DP chain - the host-driven lean loop
* stays the fallback. By Claude on 07/17/2026.
*/
public boolean supportsPoseSceneDp() {
return false;
}
/**
* ONE JNA crossing per SCENE: the D3-validated pose_scene_dp parent. Nullable
* camera/task/centers groups follow the C2 configuration-register contract;
* readback arrays (trace/mstats/result/vector_out/prep_out/stats) are filled when
* non-null. Returns the last cycle's corr-row count (>0) or a negative.
*/
public int execPoseSceneDp(
IntersceneLmaFloat.Camera reference,
IntersceneLmaFloat.Camera scene,
float [] reference_xyz,
float [] reference_atr,
float [] scene_xyz,
float [] scene_atr,
int [] task_map,
float [] task_centers,
int num_cycles,
float lambda,
float pure_weight, // prepare_light only (frozen conditioning)
float rms_diff,
int num_tiles,
int corr_slot,
int ntile_shift,
int num_components,
boolean use_eigen,
float eig_min_sqrt,
float eig_max_sqrt,
float min_confidence,
boolean same_weights,
boolean prepare_light,
float [] centers, // null = keep resident (per-sequence)
float [] pull_targets, // full mode; null = keep resident
float [] param_regweights, // full mode; null = keep resident
float [] vector, // entry anchor [3]
float [] trace, // [num_cycles*25] or null
int [] mstats, // [num_cycles*5] or null
float [] result, // final packed [25]
float [] vector_out, // final anchor [3] or null
float [] prep_out, // last full prepare [8] or null
int [] stats) { // last-cycle {pairs, surviving, misaligned} or null
return -1;
}
/** Backend error string for a failed pose entry (the D4 FAIL-safe prints it instead of throwing). */
public String poseLastError() {
return "no native backend";
}
public void execRBGA(
double [] color_weights,
......
......@@ -876,6 +876,81 @@ public class GpuQuadJna extends GpuQuad {
final float [] peaks = new float [num_rows * PEAK_ROW_FLOATS];
return (lib.tp_proc_get_peaks(proc, peaks) == num_rows) ? peaks : null;
}
// ---- DP rung D4: the full per-scene pose solve as ONE device entry (design 2026-07-16) ---- // By Claude on 07/17/2026
@Override public boolean supportsPoseSceneDp() { return !rectilinear; }
@Override public int execPoseSceneDp(
final IntersceneLmaFloat.Camera reference,
final IntersceneLmaFloat.Camera scene,
final float [] reference_xyz,
final float [] reference_atr,
final float [] scene_xyz,
final float [] scene_atr,
final int [] task_map,
final float [] task_centers,
final int num_cycles,
final float lambda,
final float pure_weight,
final float rms_diff,
final int num_tiles,
final int corr_slot,
final int ntile_shift,
final int num_components,
final boolean use_eigen,
final float eig_min_sqrt,
final float eig_max_sqrt,
final float min_confidence,
final boolean same_weights,
final boolean prepare_light,
final float [] centers,
final float [] pull_targets,
final float [] param_regweights,
final float [] vector,
final float [] trace,
final int [] mstats,
final float [] result,
final float [] vector_out,
final float [] prep_out,
final int [] stats) {
final boolean have_pose = (scene_xyz != null) || (scene_atr != null) ||
(reference_xyz != null) || (reference_atr != null);
float[] poseVectors = null;
if (have_pose) {
poseVectors = new float[12];
copyPoseVector3(reference_xyz, poseVectors, 0);
copyPoseVector3(reference_atr, poseVectors, 3);
copyPoseVector3(scene_xyz, poseVectors, 6);
copyPoseVector3(scene_atr, poseVectors, 9);
}
final int n = lib.tp_proc_exec_pose_scene_dp(
proc,
(reference != null) ? poseCameraMeta(reference) : null,
(reference != null) ? reference.radial : null,
(reference != null) ? reference.rByRDist : null,
(reference != null) ? reference.rByRDist.length : 0,
(reference != null) ? reference.ers : null,
(reference != null) ? reference.ers.length : 0,
(scene != null) ? poseCameraMeta(scene) : null,
(scene != null) ? scene.radial : null,
(scene != null) ? scene.rByRDist : null,
(scene != null) ? scene.rByRDist.length : 0,
(scene != null) ? scene.ers : null,
(scene != null) ? scene.ers.length : 0,
poseVectors, task_map, task_centers,
num_cycles, lambda, pure_weight, rms_diff,
num_tiles, corr_slot, ntile_shift,
num_components, use_eigen ? 1 : 0,
eig_min_sqrt, eig_max_sqrt,
min_confidence, same_weights ? 1 : 0,
prepare_light ? 1 : 0,
centers, pull_targets, param_regweights,
vector,
trace, mstats, result, vector_out, prep_out, stats);
// A negative return is the D4 FAIL-safe hook: the caller prints tp_last_error()
// and falls back to the host-driven loop - do NOT throw here (unlike the B3
// entry, mid-run DP failure must degrade, not abort). By Claude on 07/17/2026.
return n;
}
@Override public String poseLastError() { return lib.tp_last_error(); }
@Override public void uploadPoseCycleGeometry() {
setGeometryCorrection(); // gc (resets rbr_ready -> one in-chain rebuild, same bits)
setExtrinsicsVector(quadCLT.getGeometryCorrection().expandSensors(
......
......@@ -10,7 +10,7 @@ import com.sun.jna.Pointer;
* com.elphel.imagej.gpu.jna.Stage0 [kernel_src_dir] [libcudadevrt.a]
*/
public class Stage0 {
private static final int EXPECTED_KERNELS = 36; // 19 base + 2 conditioning + 4 consolidate + 2 peak + pose fx/J + 4 pose LMA + products + 3 resident prepare (rung C1) // By Claude on 07/17/2026
private static final int EXPECTED_KERNELS = 40; // 36 (through rung C1) + 2 DP-cycles (D1: pose_lma_dp_cycles/commit) + measure-chain DP (D2: pose_measure_dp + launch helpers) + scene DP parent family (D3: pose_scene_dp lma/step/commit) - the native D1-D3 sessions could not touch this Java constant, synced at D4 // By Claude on 07/17/2026
public static void main(String[] args) {
String srcdir = (args.length > 0) ? args[0] : "/home/elphel/git/tile_processor_gpu/src";
String devrt = (args.length > 1) ? args[1] : "/usr/local/cuda/targets/x86_64-linux/lib/libcudadevrt.a";
......
......@@ -243,6 +243,34 @@ public interface TpJna extends Library {
float[] sceneRbr, int sceneRbrLen, float[] sceneErs, int sceneErsLen,
float[] poseVectors, int[] taskMap, float[] taskCenters,
int[] stats);
/** DP rung D4 (ladder ratified 2026-07-16): the FULL per-scene pose solve as ONE
* device entry - numCycles x [D2 measure chain -> full/light prepare -> six-stage
* resident step -> commit], self-chained on-device with zero interior host round
* trips. Camera/task/centers groups follow the C2 configuration-register contract
* (null = keep resident). pull/regw are the full-prepare objective rows (null =
* keep resident); vector = the entry anchor [3]. Readbacks: trace [numCycles*25]
* per-cycle packed rows, mstats [numCycles*5] per-cycle measure counts, result =
* final packed [25], vectorOut = final anchor [3], prepOut = last full prepare [8],
* stats = last-cycle {pairs, surviving, misaligned} (each nullable). Peaks/corr
* indices stay resident for the unchanged fetch calls. Returns the LAST cycle's
* corr-row count (>0) or a negative (host -1xx / device guard codes).
* By Claude on 07/17/2026. */
int tp_proc_exec_pose_scene_dp(Pointer proc,
float[] refMeta, float[] refRadial,
float[] refRbr, int refRbrLen, float[] refErs, int refErsLen,
float[] sceneMeta, float[] sceneRadial,
float[] sceneRbr, int sceneRbrLen, float[] sceneErs, int sceneErsLen,
float[] poseVectors, int[] taskMap, float[] taskCenters,
int numCycles, float lambda, float pureWeight, float rmsDiff,
int numTiles, int corrSlot, int ntileShift,
int numComponents, int useEigen,
float eigMinSqrt, float eigMaxSqrt,
float minConfidence, int sameWeights,
int prepareLight,
float[] centers, float[] pullTargets, float[] paramRegweights,
float[] vector,
float[] trace, int[] mstats, float[] result,
float[] vectorOut, float[] prepOut, int[] stats);
/** Deterministic double normal-equation products for the lean pose LMA.
* jt is parameter-major [numParams][numValues]; out is row-major H followed by b.
* Damping and the small solve remain in Java. 0 on success. */
......
......@@ -38,6 +38,7 @@ public class CuasRtParameters {
public double pose_debias = 0.0; // rung-2 optional envelope de-bias hook (Andrey's ruling 07/13/2026, default OFF): fraction of the MCLT window-autocorr envelope divided out of the pixel-domain correlation BEFORE peak extraction (corr *= envelope^-frac, envelope normalized 1.0 at center). The envelope multiplies the true correlation peak and pulls the centroid toward center - argmax under-reports offsets by alpha ~0.75-0.9 (probed 07/13, the residual per-cycle convergence tax). 0 = off (bit-identical to no hook); 1 = full divide. GPU kernel contract: optional precomputed de-bias array pointer, NULL = off. Enabling needs its own A/B run. // By Claude on 07/13/2026
public int pose_lma_debug = 0; // inner-LMA debug level, passed to the inner runLma (max with the run's own debugLevel): 0 = quiet (default; ALSO gates the per-scene "CuasPoseRT cycles:" trace line - >=1 to print it); 2 = one line PER INNER STEP ("LMA step N: {good,done} full RMS= ... pure RMS= ... + lambda=...") - the convergence trajectory INSIDE each outer cycle; 3-4 = progressively deeper solver dumps (parameter vectors, matrices). VERBOSE at >=2 - use for short investigation runs, not production. // By Claude on 07/12/2026, trace gate 07/13
public int pose_freeze_cycle = 0; // rung C3/C3b FALSIFIED 07/16 (freeze@1: az +48% roll +100%; freeze@2: az +30% roll +54%, NOT-settled 51->228): conditioning re-derivation matters through ALL cycles. 0 = never freeze = per-cycle (DEFAULT, restores C2 quality). Mechanism kept validated (bit-exact light path) for DP-era experiments (e.g. previous-scene conditioning). Was: freeze the lean-pose LMA conditioning (weights/eigen/selection/pull/reg) at this FULL prepare count; later cycles run light (fresh offsets only). 0 = never freeze = re-derive every cycle (highest accuracy, the pre-C3 behavior); 1 = freeze at cycle 1 (FAILED its gate: blurriest-pose conditioning, azimuth +48%); 2 = freeze at cycle 2 (post-first-correction measurement ~= converged). Keeps the high-accuracy opportunity selectable at runtime (Andrey 07/16). // By Claude on 07/16/2026
public boolean pose_scene_dp = true; // DP rung D4 (ladder ratified 07/16/2026): run the FULL per-scene lean pose solve as ONE device entry (pose_scene_dp parent: pose_cycles x [measure chain -> full prepare -> resident LMA step -> commit], self-chained on-device, one end-of-scene readback). Scene 0 always runs the host-driven (B3) loop to seed the resident per-sequence state AND is replayed through the DP entry as a one-shot bit-exact oracle; FAIL disables DP for the run (fail-safe). Requires JNA backend + uniform MB + fixed cycles + inner cap 1 + freeze 0; ineligible scenes/configs fall back to the host-driven loop automatically. OFF = the validated B3 host-driven loop (the A/B knob). // By Claude on 07/17/2026
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
......@@ -170,6 +171,8 @@ public class CuasRtParameters {
"0 = quiet (also hides the per-scene 'CuasPoseRT cycles:' trace; >=1 shows it); 2 = one line per INNER LMA step (good/done flags, full/pure RMS, lambda); 3-4 = deeper solver dumps. VERBOSE at >=2 - for short investigation runs.");
gd.addNumericField("Pose freeze conditioning at cycle", this.pose_freeze_cycle, 0,3,"", // By Claude on 07/16/2026
"Freeze lean-pose LMA weights/eigen at this full-prepare count; later cycles reuse them (light prepare). 0 = never (re-derive every cycle, highest accuracy); 2 = recommended (post-first-correction measurement); 1 = falsified (blurry cycle-1 conditioning).");
gd.addCheckbox ("Pose scene as ONE GPU DP entry", this.pose_scene_dp, // By Claude on 07/17/2026
"DP rung D4: the whole per-scene pose solve (cycles x measure+prepare+LMA step) as ONE device entry, one end-of-scene readback. Scene 0 runs the host-driven loop and is replayed through the DP entry as a one-shot bit-exact oracle; FAIL disables DP for the run. Ineligible configs (JCuda, non-uniform MB, convergence exit, inner cap != 1, freeze != 0, debug saves) fall back automatically. OFF = the host-driven (B3) loop.");
gd.addMessage("=== RT render diagnostics ==="); // By Codex on 07/15/2026
gd.addCheckbox ("CUAS RT render (full product)", this.rend_test, // By Claude on 07/05/2026
......@@ -365,6 +368,7 @@ public class CuasRtParameters {
this.pose_debias = gd.getNextNumber(); // By Claude on 07/13/2026
this.pose_lma_debug =(int) gd.getNextNumber(); // By Claude on 07/12/2026
this.pose_freeze_cycle =(int) gd.getNextNumber(); // By Claude on 07/16/2026
this.pose_scene_dp = gd.getNextBoolean(); // By Claude on 07/17/2026
this.rend_test = gd.getNextBoolean(); // By Claude on 07/05/2026
this.log_test = gd.getNextBoolean(); // By Claude on 07/06/2026
this.log_ident = gd.getNextBoolean(); // By Claude on 07/06/2026
......@@ -474,6 +478,7 @@ public class CuasRtParameters {
properties.setProperty(prefix+"pose_debias", this.pose_debias+""); // double // By Claude on 07/13/2026
properties.setProperty(prefix+"pose_lma_debug", this.pose_lma_debug+""); // int // By Claude on 07/12/2026
properties.setProperty(prefix+"pose_freeze_cycle", this.pose_freeze_cycle+""); // int // By Claude on 07/16/2026
properties.setProperty(prefix+"pose_scene_dp", this.pose_scene_dp+""); // boolean // By Claude on 07/17/2026
properties.setProperty(prefix+"rend_test", this.rend_test+""); // boolean // By Claude on 07/05/2026
properties.setProperty(prefix+"log_test", this.log_test+""); // boolean // By Claude on 07/06/2026
properties.setProperty(prefix+"log_ident", this.log_ident+""); // boolean // By Claude on 07/06/2026
......@@ -583,6 +588,7 @@ public class CuasRtParameters {
if (properties.getProperty(prefix+"pose_debias")!=null) this.pose_debias=Double.parseDouble(properties.getProperty(prefix+"pose_debias")); // By Claude on 07/13/2026
if (properties.getProperty(prefix+"pose_lma_debug")!=null) this.pose_lma_debug=Integer.parseInt(properties.getProperty(prefix+"pose_lma_debug")); // By Claude on 07/12/2026
if (properties.getProperty(prefix+"pose_freeze_cycle")!=null) this.pose_freeze_cycle=Integer.parseInt(properties.getProperty(prefix+"pose_freeze_cycle")); // By Claude on 07/16/2026
if (properties.getProperty(prefix+"pose_scene_dp")!=null) this.pose_scene_dp=Boolean.parseBoolean(properties.getProperty(prefix+"pose_scene_dp")); // By Claude on 07/17/2026
if (properties.getProperty(prefix+"rend_test")!=null) this.rend_test=Boolean.parseBoolean(properties.getProperty(prefix+"rend_test")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"log_test")!=null) this.log_test=Boolean.parseBoolean(properties.getProperty(prefix+"log_test")); // By Claude on 07/06/2026
if (properties.getProperty(prefix+"log_ident")!=null) this.log_ident=Boolean.parseBoolean(properties.getProperty(prefix+"log_ident")); // By Claude on 07/06/2026
......@@ -695,6 +701,7 @@ public class CuasRtParameters {
cp.pose_debias = this.pose_debias; // By Claude on 07/13/2026
cp.pose_lma_debug = this.pose_lma_debug; // By Claude on 07/12/2026
cp.pose_freeze_cycle = this.pose_freeze_cycle; // By Claude on 07/16/2026
cp.pose_scene_dp = this.pose_scene_dp; // By Claude on 07/17/2026
cp.rend_test = this.rend_test; // By Claude on 07/05/2026
cp.log_test = this.log_test; // By Claude on 07/06/2026
cp.log_ident = this.log_ident; // By Claude on 07/06/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