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