Commit b6a074a1 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: rung C0 - prepareLMA sub-stage + fx-boundary profiling (attribute before C1)

Design 3-A4i rung C0: IntersceneLma gains a null-safe ProfileSink (pattern-
consistent with the providers; zero overhead when unset). The production
prepareLMA overload emits setup+samples-weights / fx-pass-1 / WJtJ+reg+
normalize / fx-pass-2 samples (LMA path only - MB-vector calls excluded;
y+RMS tail = derived remainder). Two cross-cutting probes: the poseFxProvider
JNA roundtrip wall (all lean fx sites, incl. runLma's first-step
re-linearization) and the setupERS pair. CuasPoseRT routes the sink into
RtPoseProfile (6 new stages, printSummary extended).
Expected from one run of the same config: split prepare's ~16 ms/call into
JNA-roundtrip vs Java-CPU, sizing C1 honestly.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent 7665886f
...@@ -225,11 +225,17 @@ public class CuasPoseRT { ...@@ -225,11 +225,17 @@ public class CuasPoseRT {
static final int DEBUG_FETCH = 15; // debug-save data motion (PD/composite), own stage so it can never hide in "other" (rung A) // By Claude on 07/16/2026 static final int DEBUG_FETCH = 15; // debug-save data motion (PD/composite), own stage so it can never hide in "other" (rung A) // By Claude on 07/16/2026
static final int MEASURE_OTHER = 16; static final int MEASURE_OTHER = 16;
static final int LMA_PREPARE = 17; static final int LMA_PREPARE = 17;
static final int LMA_RUN = 18; static final int PREP_SETUP = 18; // rung C0 sub-stages (design 2026-07-16) // By Claude on 07/17/2026
static final int LMA_GPU_PRODUCTS = 19; static final int PREP_FX1 = 19;
static final int LMA_CPU_REMAINDER = 20; static final int PREP_WJTJ = 20;
static final int POSE_UPDATE = 21; static final int PREP_FX2 = 21;
static final int NUM_STAGES = 22; static final int LMA_RUN = 22;
static final int LMA_GPU_PRODUCTS = 23;
static final int LMA_CPU_REMAINDER = 24;
static final int POSE_UPDATE = 25;
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 NUM_STAGES = 28;
static final String [] LABELS = { static final String [] LABELS = {
"post-conditioning total", "post-conditioning total",
" motion-blur setup", " motion-blur setup",
...@@ -249,10 +255,16 @@ public class CuasPoseRT { ...@@ -249,10 +255,16 @@ public class CuasPoseRT {
" debug-save fetch (PD+img)", // By Claude on 07/16/2026 " debug-save fetch (PD+img)", // By Claude on 07/16/2026
" leanMeasure other", " leanMeasure other",
" LMA prepare (CPU)", " LMA prepare (CPU)",
" prep setup+samples weights", // By Claude on 07/17/2026 (rung C0)
" prep fx pass 1 (getFxDerivs)",
" prep WJtJ+reg+normalize",
" prep fx pass 2 (getFxDerivs)",
" LMA run total", " LMA run total",
" GPU normal products boundary", " GPU normal products boundary",
" LMA CPU remainder", " LMA CPU remainder",
" pose update/QC" " pose update/QC",
" fx JNA roundtrip (all sites)", // By Claude on 07/17/2026 (rung C0)
" setupERS pair (all lean sites)"
}; };
final int scenesExpected; final int scenesExpected;
...@@ -340,12 +352,19 @@ public class CuasPoseRT { ...@@ -340,12 +352,19 @@ public class CuasPoseRT {
printStage(MEASURE_TOTAL, postSum); printStage(MEASURE_TOTAL, postSum);
for (int stage = GRID_TRANSFORM; stage <= MEASURE_OTHER; stage++) printStage(stage, postSum); for (int stage = GRID_TRANSFORM; stage <= MEASURE_OTHER; stage++) printStage(stage, postSum);
printStage(LMA_PREPARE, postSum); printStage(LMA_PREPARE, postSum);
for (int stage = PREP_SETUP; stage <= PREP_FX2; stage++) printStage(stage, postSum); // By Claude on 07/17/2026
printDerived(" prep y+RMS/other",
sum(LMA_PREPARE) - sum(PREP_SETUP) - sum(PREP_FX1) - sum(PREP_WJTJ) - sum(PREP_FX2), postSum);
printStage(LMA_RUN, postSum); printStage(LMA_RUN, postSum);
printStage(LMA_GPU_PRODUCTS, postSum); printStage(LMA_GPU_PRODUCTS, postSum);
printStage(LMA_CPU_REMAINDER, postSum); printStage(LMA_CPU_REMAINDER, postSum);
printStage(POSE_UPDATE, postSum); printStage(POSE_UPDATE, postSum);
printDerived(" lean-fit other", 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), 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);
printStage(FX_SETUPERS, postSum);
System.out.println("PROFILE interpretation: Java wall >> later CUDA-event time means packing/JNA/synchronization waste; similar times mean device compute."); System.out.println("PROFILE interpretation: Java wall >> later CUDA-event time means packing/JNA/synchronization waste; similar times mean device compute.");
} }
} }
...@@ -1062,6 +1081,22 @@ public class CuasPoseRT { ...@@ -1062,6 +1081,22 @@ public class CuasPoseRT {
} }
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
// Rung C0 (design 2026-07-16): route IntersceneLma sub-stage samples into the
// RT profiler - attributes prepareLMA's budget and the cross-cutting fx
// boundaries (JNA roundtrip, setupERS) before C1 goes resident. Null profiler
// (non-RT callers) = zero overhead. By Claude on 07/17/2026.
intersceneLma.setProfileSink((stage, ns) -> {
final RtPoseProfile prof = RT_POSE_PROFILE.get();
if (prof == null) return;
switch (stage) {
case IntersceneLma.PROF_PREP_SETUP: prof.add(RtPoseProfile.PREP_SETUP, ns); break;
case IntersceneLma.PROF_PREP_FX1: prof.add(RtPoseProfile.PREP_FX1, ns); break;
case IntersceneLma.PROF_PREP_WJTJ: prof.add(RtPoseProfile.PREP_WJTJ, ns); break;
case IntersceneLma.PROF_PREP_FX2: prof.add(RtPoseProfile.PREP_FX2, ns); break;
case IntersceneLma.PROF_FX_JNA: prof.add(RtPoseProfile.FX_JNA, ns); break;
case IntersceneLma.PROF_FX_SETUPERS: prof.add(RtPoseProfile.FX_SETUPERS, ns); break;
}
});
intersceneLma.setNormalEquationProvider((weights, jt, ymfxWeighted) -> { intersceneLma.setNormalEquationProvider((weights, jt, ymfxWeighted) -> {
final long profileStart = (rtProfile != null) ? rtProfile.start() : 0L; final long profileStart = (rtProfile != null) ? rtProfile.start() : 0L;
final double [] products = lmaGpu.execLmaNormalProducts(weights, jt, ymfxWeighted); final double [] products = lmaGpu.execLmaNormalProducts(weights, jt, ymfxWeighted);
......
...@@ -422,6 +422,11 @@ public class IntersceneLma { ...@@ -422,6 +422,11 @@ public class IntersceneLma {
boolean first_run, boolean first_run,
String dbg_prefix, // null or image name prefix String dbg_prefix, // null or image name prefix
final int debug_level) { final int debug_level) {
// Rung C0 sub-stage attribution (design 2026-07-16); samples are emitted only
// on the LMA path (vector_XYSDS != null) so MB-vector calls do not pollute
// the LMA-prepare budget. Null sink = zero overhead. By Claude on 07/17/2026.
final ProfileSink prof_sink = profileSink;
final long prof_t0 = (prof_sink != null) ? System.nanoTime() : 0L;
// before getFxDerivs // before getFxDerivs
eig_trans = setEigenTransform( eig_trans = setEigenTransform(
eig_max_sqrt, // final double eig_max_sqrt, eig_max_sqrt, // final double eig_max_sqrt,
...@@ -494,6 +499,7 @@ public class IntersceneLma { ...@@ -494,6 +499,7 @@ public class IntersceneLma {
if (debug_level > 1) { if (debug_level > 1) {
System.out.println("prepareLMA() 1"); System.out.println("prepareLMA() 1");
} }
final long prof_t1 = (prof_sink != null) ? System.nanoTime() : 0L; // By Claude on 07/17/2026
double [] fx = getFxDerivs( double [] fx = getFxDerivs(
parameters_vector, // double [] vector, parameters_vector, // double [] vector,
last_jt, // final double [][] jt, // should be null or initialized with [vector.length][] last_jt, // final double [][] jt, // should be null or initialized with [vector.length][]
...@@ -503,7 +509,12 @@ public class IntersceneLma { ...@@ -503,7 +509,12 @@ public class IntersceneLma {
if (vector_XYSDS == null) { if (vector_XYSDS == null) {
return; // for MB vectors (noLMA) return; // for MB vectors (noLMA)
} }
long prof_t2 = 0L; // rung C0 boundaries // By Claude on 07/17/2026
if (prof_sink != null) {
prof_t2 = System.nanoTime();
prof_sink.add(PROF_PREP_SETUP, prof_t1 - prof_t0);
prof_sink.add(PROF_PREP_FX1, prof_t2 - prof_t1);
}
double [][] wjtj = getWJtJlambda( // USED in lwir all NAN double [][] wjtj = getWJtJlambda( // USED in lwir all NAN
0.0, // final double lambda, 0.0, // final double lambda,
last_jt); // final double [][] jt) all 0??? last_jt); // final double [][] jt) all 0???
...@@ -516,6 +527,11 @@ public class IntersceneLma { ...@@ -516,6 +527,11 @@ public class IntersceneLma {
} }
} }
normalizeWeights(); // make full weight == 1.0; pure_weight <= 1.0; normalizeWeights(); // make full weight == 1.0; pure_weight <= 1.0;
long prof_t3 = 0L; // By Claude on 07/17/2026
if (prof_sink != null) {
prof_t3 = System.nanoTime();
prof_sink.add(PROF_PREP_WJTJ, prof_t3 - prof_t2);
}
// remeasure fx - now with regularization terms. // remeasure fx - now with regularization terms.
if (debug_level > 1) { if (debug_level > 1) {
System.out.println("prepareLMA() 2"); System.out.println("prepareLMA() 2");
...@@ -526,7 +542,10 @@ public class IntersceneLma { ...@@ -526,7 +542,10 @@ public class IntersceneLma {
scene_QuadClt, // final QuadCLT scene_QuadClt, scene_QuadClt, // final QuadCLT scene_QuadClt,
reference_QuadClt, // final QuadCLT reference_QuadClt, reference_QuadClt, // final QuadCLT reference_QuadClt,
debug_level); // final int debug_level) debug_level); // final int debug_level)
// Why y_vector starts with initial value of fx??? if (prof_sink != null) { // y-build+RMS tail = derived remainder in the profile // By Claude on 07/17/2026
prof_sink.add(PROF_PREP_FX2, System.nanoTime() - prof_t3);
}
// Why y_vector starts with initial value of fx???
y_vector = fx.clone(); y_vector = fx.clone();
for (int i = 0; i < vector_XYSDS.length; i++) { for (int i = 0; i < vector_XYSDS.length; i++) {
if (vector_XYSDS[i] != null){ if (vector_XYSDS[i] != null){
...@@ -1717,8 +1736,14 @@ public class IntersceneLma { ...@@ -1717,8 +1736,14 @@ public class IntersceneLma {
System.out.println("getFxDerivs(): scene_xyz[0]=NaN"); System.out.println("getFxDerivs(): scene_xyz[0]=NaN");
System.out.println(); System.out.println();
} }
// Rung C0 probe: setupERS pair, lean (non-MB) sites only. By Claude on 07/17/2026.
final ProfileSink prof_sink_fx = mb_mode ? null : profileSink;
final long prof_ers_t0 = (prof_sink_fx != null) ? System.nanoTime() : 0L;
ers_scene.setupERS(); ers_scene.setupERS();
ers_ref.setupERS(); ers_ref.setupERS();
if (prof_sink_fx != null) {
prof_sink_fx.add(PROF_FX_SETUPERS, System.nanoTime() - prof_ers_t0);
}
if (!mb_mode && fillFromPoseFxProvider( if (!mb_mode && fillFromPoseFxProvider(
ers_ref, ers_scene, ers_ref, ers_scene,
reference_xyz, reference_atr, scene_xyz, scene_atr, reference_xyz, reference_atr, scene_xyz, scene_atr,
...@@ -1859,11 +1884,18 @@ public class IntersceneLma { ...@@ -1859,11 +1884,18 @@ public class IntersceneLma {
poseFloatSelection[tile] = (macrotile_centers[tile] != null) && (weights[2 * tile] > 0.0); poseFloatSelection[tile] = (macrotile_centers[tile] != null) && (weights[2 * tile] > 0.0);
} }
} }
// Rung C0 probe: the JNA fx/J roundtrip wall (camera-state H2D + kernel +
// fx/jt/valid D2H), across ALL lean fx sites. By Claude on 07/17/2026.
final ProfileSink prof_sink_jna = profileSink;
final long prof_jna_t0 = (prof_sink_jna != null) ? System.nanoTime() : 0L;
final IntersceneLmaFloat.Result result = poseFxProvider.calculate( final IntersceneLmaFloat.Result result = poseFxProvider.calculate(
poseFloatReference, poseFloatScene, poseFloatReference, poseFloatScene,
IntersceneLmaFloat.toFloat3(reference_xyz), IntersceneLmaFloat.toFloat3(reference_atr), IntersceneLmaFloat.toFloat3(reference_xyz), IntersceneLmaFloat.toFloat3(reference_atr),
IntersceneLmaFloat.toFloat3(scene_xyz), IntersceneLmaFloat.toFloat3(scene_atr), IntersceneLmaFloat.toFloat3(scene_xyz), IntersceneLmaFloat.toFloat3(scene_atr),
poseFloatCenters, poseFloatSelection, jt != null); poseFloatCenters, poseFloatSelection, jt != null);
if (prof_sink_jna != null) {
prof_sink_jna.add(PROF_FX_JNA, System.nanoTime() - prof_jna_t0);
}
if (result == null) return false; if (result == null) return false;
if ((result.fx == null) || (result.valid == null) || if ((result.fx == null) || (result.valid == null) ||
(result.numTiles != macrotile_centers.length) || (result.numTiles != macrotile_centers.length) ||
...@@ -1896,6 +1928,20 @@ public class IntersceneLma { ...@@ -1896,6 +1928,20 @@ public class IntersceneLma {
return true; return true;
} }
// Rung C0 (design 2026-07-16): lightweight profiling sink so the RT harness can
// attribute prepareLMA sub-stages and the cross-cutting fx boundaries without
// this class depending on the profiler. Null sink = zero overhead (no nanoTime).
// By Claude on 07/17/2026.
public interface ProfileSink { void add(int stage, long ns); }
public static final int PROF_PREP_SETUP = 0; // vector build + pull + setSamplesWeights
public static final int PROF_PREP_FX1 = 1; // first getFxDerivs (weight normalization input)
public static final int PROF_PREP_WJTJ = 2; // getWJtJlambda + reg weights + normalizeWeights
public static final int PROF_PREP_FX2 = 3; // second getFxDerivs (with regularization); y+RMS tail = derived
public static final int PROF_FX_JNA = 4; // poseFxProvider.calculate wall, ALL lean fx sites
public static final int PROF_FX_SETUPERS = 5; // setupERS() pair wall, lean (non-MB) fx sites
private ProfileSink profileSink = null;
public void setProfileSink(final ProfileSink sink) { profileSink = sink; }
private boolean isPoseLmaStepShape() { private boolean isPoseLmaStepShape() {
if ((num_components != 2) || (par_indices == null) || if ((num_components != 2) || (par_indices == null) ||
(par_indices.length != IntersceneLmaFloat.NUM_PARAMS) || (par_indices.length != IntersceneLmaFloat.NUM_PARAMS) ||
......
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