Commit 13db0146 authored by Andrey Filippov's avatar Andrey Filippov

CODEX: Validate resident pose LMA decisions

Co-authored-by: 's avatarCodex <codex@elphel.com>
parent f7939cc0
...@@ -1035,15 +1035,16 @@ public class CuasPoseRT { ...@@ -1035,15 +1035,16 @@ public class CuasPoseRT {
return result; return result;
}); // first production gate: replace only getFxDerivs per-tile work; callers remain unchanged // By Codex on 07/15/2026 }); // first production gate: replace only getFxDerivs per-tile work; callers remain unchanged // By Codex on 07/15/2026
intersceneLma.setPoseLmaResidentStepProvider(( intersceneLma.setPoseLmaResidentStepProvider((
lambda, weights, y, eigen, vector, pureWeight, numTiles, capturePrepared) -> { lambda, weights, y, eigen, vector, pureWeight, rmsDiff, numTiles, capturePrepared) -> {
final IntersceneLmaFloat.ResidentLmaStepResult result = final IntersceneLmaFloat.ResidentLmaStepResult result =
lmaGpu.execPoseLmaResidentStep( lmaGpu.execPoseLmaResidentStep(
lambda, weights, y, eigen, vector, pureWeight, lambda, weights, y, eigen, vector, pureWeight, rmsDiff,
numTiles, capturePrepared); numTiles, capturePrepared);
if ((result != null) && !pose_lma_step_path_reported) { if ((result != null) && !pose_lma_step_path_reported) {
pose_lma_step_path_reported = true; pose_lma_step_path_reported = true;
System.out.println("CuasPoseRT: resident CUDA float LMA candidate/RMS oracle active "+ System.out.println("CuasPoseRT: resident CUDA float LMA decision/state oracle active "+
"(separate candidate fx/J buffers; Java acceptance authoritative)"); "(GPU candidate accept swaps raw buffers; reject retains current; "+
"Java acceptance authoritative)");
} }
return result; return result;
}); // production candidate: resident raw fx/J -> parallel prepare/reduce -> fixed 3x3 tail // By Codex on 07/15/2026 }); // production candidate: resident raw fx/J -> parallel prepare/reduce -> fixed 3x3 tail // By Codex on 07/15/2026
......
...@@ -2949,6 +2949,7 @@ public class GpuQuad{ // quad camera description ...@@ -2949,6 +2949,7 @@ public class GpuQuad{ // quad camera description
float [] eigen, float [] eigen,
float [] vector, float [] vector,
float pure_weight, float pure_weight,
float rms_diff,
int num_tiles, int num_tiles,
boolean capture_prepared) { boolean capture_prepared) {
return null; return null;
......
...@@ -564,6 +564,7 @@ public class GpuQuadJna extends GpuQuad { ...@@ -564,6 +564,7 @@ public class GpuQuadJna extends GpuQuad {
final float[] eigen, final float[] eigen,
final float[] vector, final float[] vector,
final float pureWeight, final float pureWeight,
final float rmsDiff,
final int numTiles, final int numTiles,
final boolean capturePrepared) { final boolean capturePrepared) {
final int numValues = IntersceneLmaFloat.NUM_COMPONENTS * numTiles + final int numValues = IntersceneLmaFloat.NUM_COMPONENTS * numTiles +
...@@ -572,7 +573,8 @@ public class GpuQuadJna extends GpuQuad { ...@@ -572,7 +573,8 @@ public class GpuQuadJna extends GpuQuad {
(y == null) || (y.length != numValues) || (eigen == null) || (y == null) || (y.length != numValues) || (eigen == null) ||
(eigen.length != 4 * numTiles) || (vector == null) || (eigen.length != 4 * numTiles) || (vector == null) ||
(vector.length != IntersceneLmaFloat.NUM_PARAMS) || (vector.length != IntersceneLmaFloat.NUM_PARAMS) ||
!Float.isFinite(pureWeight) || !(pureWeight > 0.0f)) { !Float.isFinite(pureWeight) || !(pureWeight > 0.0f) ||
!Float.isFinite(rmsDiff)) {
throw new IllegalArgumentException("GpuQuadJna.execPoseLmaResidentStep: inconsistent inputs"); throw new IllegalArgumentException("GpuQuadJna.execPoseLmaResidentStep: inconsistent inputs");
} }
final float[] packed = new float[IntersceneLmaFloat.LMA_RESIDENT_RESULT_FLOATS]; final float[] packed = new float[IntersceneLmaFloat.LMA_RESIDENT_RESULT_FLOATS];
...@@ -580,7 +582,7 @@ public class GpuQuadJna extends GpuQuad { ...@@ -580,7 +582,7 @@ public class GpuQuadJna extends GpuQuad {
new float[IntersceneLmaFloat.NUM_PARAMS * numValues] : null; new float[IntersceneLmaFloat.NUM_PARAMS * numValues] : null;
final float[] preparedYmfx = capturePrepared ? new float[numValues] : null; final float[] preparedYmfx = capturePrepared ? new float[numValues] : null;
final int rc = lib.tp_proc_exec_pose_lma_resident_step( final int rc = lib.tp_proc_exec_pose_lma_resident_step(
proc, lambda, weights, y, eigen, vector, pureWeight, numTiles, proc, lambda, weights, y, eigen, vector, pureWeight, rmsDiff, numTiles,
capturePrepared ? 1 : 0, packed, preparedJt, preparedYmfx); capturePrepared ? 1 : 0, packed, preparedJt, preparedYmfx);
if (rc != 0) { if (rc != 0) {
throw new IllegalStateException("GpuQuadJna.execPoseLmaResidentStep rc="+rc+": "+ throw new IllegalStateException("GpuQuadJna.execPoseLmaResidentStep rc="+rc+": "+
...@@ -596,7 +598,9 @@ public class GpuQuadJna extends GpuQuad { ...@@ -596,7 +598,9 @@ public class GpuQuadJna extends GpuQuad {
packed[IntersceneLmaFloat.LMA_RESULT_FLOATS], packed[IntersceneLmaFloat.LMA_RESULT_FLOATS],
packed[IntersceneLmaFloat.LMA_RESULT_FLOATS + 1], packed[IntersceneLmaFloat.LMA_RESULT_FLOATS + 1],
packed[IntersceneLmaFloat.LMA_RESULT_FLOATS + 2], packed[IntersceneLmaFloat.LMA_RESULT_FLOATS + 2],
packed[IntersceneLmaFloat.LMA_RESULT_FLOATS + 3]); packed[IntersceneLmaFloat.LMA_RESULT_FLOATS + 3],
packed[IntersceneLmaFloat.LMA_RESULT_FLOATS + 4] != 0.0f,
packed[IntersceneLmaFloat.LMA_RESULT_FLOATS + 5] != 0.0f);
} }
private static IntersceneLmaFloat.LmaStepResult unpackPoseLmaStep(final float[] packed) { private static IntersceneLmaFloat.LmaStepResult unpackPoseLmaStep(final float[] packed) {
......
...@@ -155,12 +155,12 @@ public interface TpJna extends Library { ...@@ -155,12 +155,12 @@ public interface TpJna extends Library {
float[] ymfxWeighted, float[] vector, float[] ymfxWeighted, float[] vector,
int numValues, float[] result); int numValues, float[] result);
/** Continue from raw fx/J left by the most recent pose kernel. Result has /** Continue from raw fx/J left by the most recent pose kernel. Result has
* the 19 candidate floats followed by current and candidate full/pure RMS. Prepared * the 19 candidate floats, current/candidate full/pure RMS, then accepted/stop.
* arrays are nullable unless capturePrepared is nonzero. */ * Prepared arrays are nullable unless capturePrepared is nonzero. */
int tp_proc_exec_pose_lma_resident_step(Pointer proc, int tp_proc_exec_pose_lma_resident_step(Pointer proc,
float lambda, float[] weights, float[] y, float lambda, float[] weights, float[] y,
float[] eigen, float[] vector, float pureWeight, float[] eigen, float[] vector, float pureWeight,
int numTiles, int capturePrepared, float[] result, float rmsDiff, int numTiles, int capturePrepared, float[] result,
float[] preparedJt, float[] preparedYmfx); float[] preparedJt, float[] preparedYmfx);
/** Deterministic double normal-equation products for the lean pose LMA. /** Deterministic double normal-equation products for the lean pose LMA.
* jt is parameter-major [numParams][numValues]; out is row-major H followed by b. * jt is parameter-major [numParams][numValues]; out is row-major H followed by b.
......
...@@ -121,12 +121,14 @@ public class IntersceneLma { ...@@ -121,12 +121,14 @@ public class IntersceneLma {
float [] eigen, float [] eigen,
float [] vector, float [] vector,
float pureWeight, float pureWeight,
float rmsDiff,
int numTiles, int numTiles,
boolean capturePrepared); boolean capturePrepared);
} }
private PoseLmaResidentStepProvider poseLmaResidentStepProvider = null; private PoseLmaResidentStepProvider poseLmaResidentStepProvider = null;
private static boolean poseLmaStepOracleReported = false; private static boolean poseLmaStepOracleReported = false;
private static boolean poseLmaAcceptanceOracleReported = false; private static boolean poseLmaAcceptanceOracleReported = false;
private static boolean poseLmaAcceptanceMismatchReported = false;
private IntersceneLmaFloat.Camera poseFloatReference = null; private IntersceneLmaFloat.Camera poseFloatReference = null;
private IntersceneLmaFloat.Camera poseFloatScene = null; private IntersceneLmaFloat.Camera poseFloatScene = null;
private float [] poseFloatCenters = null; private float [] poseFloatCenters = null;
...@@ -944,7 +946,8 @@ public class IntersceneLma { ...@@ -944,7 +946,8 @@ public class IntersceneLma {
eig_trans, poseFloatLastResult.numTiles); eig_trans, poseFloatLastResult.numTiles);
residentResult = poseLmaResidentStepProvider.calculate( residentResult = poseLmaResidentStepProvider.calculate(
(float) lambda, floatWeights, floatY, floatEigen, floatVector, (float) lambda, floatWeights, floatY, floatEigen, floatVector,
(float) pure_weight, poseFloatLastResult.numTiles, captureResidentOracle); (float) pure_weight, (float) rms_diff, poseFloatLastResult.numTiles,
captureResidentOracle);
if (residentResult != null) residentPoseStep = residentResult.step; if (residentResult != null) residentPoseStep = residentResult.step;
if (captureResidentOracle && (residentPoseStep != null)) { if (captureResidentOracle && (residentPoseStep != null)) {
if (residentResult.prepared == null) { if (residentResult.prepared == null) {
...@@ -1047,9 +1050,16 @@ public class IntersceneLma { ...@@ -1047,9 +1050,16 @@ public class IntersceneLma {
if (last_ymfx == null) { if (last_ymfx == null) {
return null; // need to re-init/restart LMA return null; // need to re-init/restart LMA
} }
if (residentCandidateValid && (residentResult != null) && (debug_level >= 1) && if (residentCandidateValid && (residentResult != null) && (debug_level >= 1)) {
!poseLmaAcceptanceOracleReported) { final boolean decisionsMatch = poseRmsDecisionsMatch(
reportPoseRmsDecision(residentResult, this.last_rms, rms, rms_diff); residentResult, this.last_rms, rms, rms_diff);
if (!poseLmaAcceptanceOracleReported ||
(!decisionsMatch && !poseLmaAcceptanceMismatchReported)) {
reportPoseRmsDecision(
decisionsMatch ? "" : " MISMATCH",
residentResult, this.last_rms, rms, rms_diff);
}
if (!decisionsMatch) poseLmaAcceptanceMismatchReported = true;
poseLmaAcceptanceOracleReported = true; poseLmaAcceptanceOracleReported = true;
} }
...@@ -1934,7 +1944,23 @@ public class IntersceneLma { ...@@ -1934,7 +1944,23 @@ public class IntersceneLma {
label, poseStep.valid, maxProducts, maxDelta, maxCandidate)); label, poseStep.valid, maxProducts, maxDelta, maxCandidate));
} }
private static boolean poseRmsDecisionsMatch(
final IntersceneLmaFloat.ResidentLmaStepResult resident,
final double [] javaCurrent,
final double [] javaCandidate,
final double rmsDiff) {
final boolean doubleImproved = javaCandidate[0] < javaCurrent[0];
final boolean doubleStop = doubleImproved &&
(javaCandidate[0] >= javaCurrent[0] * (1.0 - rmsDiff));
return Float.isFinite(resident.currentRms) &&
Float.isFinite(resident.currentPureRms) &&
Float.isFinite(resident.candidateRms) &&
Float.isFinite(resident.candidatePureRms) &&
(resident.accepted == doubleImproved) && (resident.stop == doubleStop);
}
private static void reportPoseRmsDecision( private static void reportPoseRmsDecision(
final String suffix,
final IntersceneLmaFloat.ResidentLmaStepResult resident, final IntersceneLmaFloat.ResidentLmaStepResult resident,
final double [] javaCurrent, final double [] javaCurrent,
final double [] javaCandidate, final double [] javaCandidate,
...@@ -1943,21 +1969,19 @@ public class IntersceneLma { ...@@ -1943,21 +1969,19 @@ public class IntersceneLma {
Float.isFinite(resident.currentPureRms) && Float.isFinite(resident.currentPureRms) &&
Float.isFinite(resident.candidateRms) && Float.isFinite(resident.candidateRms) &&
Float.isFinite(resident.candidatePureRms); Float.isFinite(resident.candidatePureRms);
final boolean floatImproved = finite && (resident.candidateRms < resident.currentRms);
final boolean doubleImproved = javaCandidate[0] < javaCurrent[0]; final boolean doubleImproved = javaCandidate[0] < javaCurrent[0];
final boolean floatStop = floatImproved &&
(resident.candidateRms >= resident.currentRms * (1.0f - (float) rmsDiff));
final boolean doubleStop = doubleImproved && final boolean doubleStop = doubleImproved &&
(javaCandidate[0] >= javaCurrent[0] * (1.0 - rmsDiff)); (javaCandidate[0] >= javaCurrent[0] * (1.0 - rmsDiff));
System.out.println(String.format( System.out.println(String.format(
"IntersceneLma resident CUDA-float vs Java-double RMS/decision: finite=%s, |current RMS|=%g, |current pure RMS|=%g, |candidate RMS|=%g, |candidate pure RMS|=%g, improved-match=%s, stop-match=%s", "IntersceneLma resident CUDA-float vs Java-double RMS/decision%s: finite=%s, |current RMS|=%g, |current pure RMS|=%g, |candidate RMS|=%g, |candidate pure RMS|=%g, improved-match=%s, stop-match=%s",
suffix,
finite, finite,
Math.abs(resident.currentRms - javaCurrent[0]), Math.abs(resident.currentRms - javaCurrent[0]),
Math.abs(resident.currentPureRms - javaCurrent[1]), Math.abs(resident.currentPureRms - javaCurrent[1]),
Math.abs(resident.candidateRms - javaCandidate[0]), Math.abs(resident.candidateRms - javaCandidate[0]),
Math.abs(resident.candidatePureRms - javaCandidate[1]), Math.abs(resident.candidatePureRms - javaCandidate[1]),
floatImproved == doubleImproved, resident.accepted == doubleImproved,
floatStop == doubleStop)); resident.stop == doubleStop));
} }
private static final class DoubleLmaStepResult { private static final class DoubleLmaStepResult {
......
...@@ -42,7 +42,7 @@ public final class IntersceneLmaFloat { ...@@ -42,7 +42,7 @@ public final class IntersceneLmaFloat {
public static final int NUM_COMPONENTS = 2; public static final int NUM_COMPONENTS = 2;
public static final int LMA_PRODUCTS = NUM_PARAMS * NUM_PARAMS + NUM_PARAMS; public static final int LMA_PRODUCTS = NUM_PARAMS * NUM_PARAMS + NUM_PARAMS;
public static final int LMA_RESULT_FLOATS = 1 + LMA_PRODUCTS + 2 * NUM_PARAMS; public static final int LMA_RESULT_FLOATS = 1 + LMA_PRODUCTS + 2 * NUM_PARAMS;
public static final int LMA_RESIDENT_RESULT_FLOATS = LMA_RESULT_FLOATS + 4; public static final int LMA_RESIDENT_RESULT_FLOATS = LMA_RESULT_FLOATS + 6;
public static final float INFINITY_DISPARITY = 0.01f; public static final float INFINITY_DISPARITY = 0.01f;
static final int ERS_XYZ = 0; static final int ERS_XYZ = 0;
...@@ -220,6 +220,8 @@ public final class IntersceneLmaFloat { ...@@ -220,6 +220,8 @@ public final class IntersceneLmaFloat {
public final float currentPureRms; public final float currentPureRms;
public final float candidateRms; public final float candidateRms;
public final float candidatePureRms; public final float candidatePureRms;
public final boolean accepted;
public final boolean stop;
public ResidentLmaStepResult( public ResidentLmaStepResult(
final LmaStepResult step, final LmaStepResult step,
...@@ -227,13 +229,17 @@ public final class IntersceneLmaFloat { ...@@ -227,13 +229,17 @@ public final class IntersceneLmaFloat {
final float currentRms, final float currentRms,
final float currentPureRms, final float currentPureRms,
final float candidateRms, final float candidateRms,
final float candidatePureRms) { final float candidatePureRms,
final boolean accepted,
final boolean stop) {
this.step = step; this.step = step;
this.prepared = prepared; this.prepared = prepared;
this.currentRms = currentRms; this.currentRms = currentRms;
this.currentPureRms = currentPureRms; this.currentPureRms = currentPureRms;
this.candidateRms = candidateRms; this.candidateRms = candidateRms;
this.candidatePureRms = candidatePureRms; this.candidatePureRms = candidatePureRms;
this.accepted = accepted;
this.stop = stop;
} }
} }
......
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