Commit 5f473261 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: rung B - device-visible pose current/candidate set index (no host swap)

Design 3-A4i rung B (imagej-elphel-internal 2026-07-16 handoff), DP-readiness:
- gpu_pose_* / gpu_pose_candidate_* become FIXED physical slots; the CURRENT
  set is selected by a device-authoritative int flag.
- pose_lma_reduce_rms gains a final int* current_set arg and flips it on
  accept DEVICE-SIDE (NULL = no flip, standalone tests); rejection leaves it
  unchanged so the prior current raw pose remains the fallback.
- tp_proc_exec_pose_lma_resident_step: host std::swap removed; launch
  pointers come from cur_*/cand_* accessors; the host mirror syncs with a
  4-byte D2H after each step. exec_pose_fx_jacobian uploads/reads via the
  CURRENT set. The candidate-base DtoD invariant (ref rows pose-independent)
  is now documented at the copy site.
- test_pose_lma_step: pass + assert the no-flip side (not-accepted case).
C API unchanged. Gates: direct CUDA 5120/150 PASS (products 0.000244141,
candidate 9.69e-08, same as session-40); NVRTC resident accept-carryover +
worsened-rejection PASS (flip proven behaviorally); 19-float bit-exact PASS;
fx_jacobian PASS; compute-sanitizer(12.8) 0 errors; test_pose_corr_jna
bit-exact @tol 0.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent d9b7afdb
This diff is collapsed.
...@@ -253,9 +253,17 @@ int main(int argc, char ** argv) ...@@ -253,9 +253,17 @@ int main(int argc, char ** argv)
checkCudaErrors(cudaGetLastError()); checkCudaErrors(cudaGetLastError());
pose_lma_reduce_step<<<1, 1>>>(numPartials, lambda, pureWeight, pose_lma_reduce_step<<<1, 1>>>(numPartials, lambda, pureWeight,
gpuPartials.dev(), gpuVectorResident.dev(), gpuResidentResult.dev()); gpuPartials.dev(), gpuVectorResident.dev(), gpuResidentResult.dev());
// current_set: device set index (rung B) - this case reduces the SAME partials
// as the current step, so candidate RMS == current RMS -> NOT accepted -> the
// index must stay 0 (the no-flip side of the device-side commit).
// By Claude on 07/16/2026.
GpuBuf<int> gpuCurrentSet(1);
const int zeroSet = 0;
gpuCurrentSet.upload(&zeroSet);
pose_lma_reduce_rms<<<1, 1>>>(numPartials, pureWeight, 0.001f, pose_lma_reduce_rms<<<1, 1>>>(numPartials, pureWeight, 0.001f,
gpuPartials.dev(), gpuResidentResult.dev()); gpuPartials.dev(), gpuResidentResult.dev(), gpuCurrentSet.dev());
checkCudaErrors(cudaGetLastError()); checkCudaErrors(cudaDeviceSynchronize()); checkCudaErrors(cudaGetLastError()); checkCudaErrors(cudaDeviceSynchronize());
const std::vector<int> gotCurrentSet = gpuCurrentSet.download();
const std::vector<float> gotJt = gpuPreparedJt.download(); const std::vector<float> gotJt = gpuPreparedJt.download();
const std::vector<float> gotYmfx = gpuPreparedYmfx.download(); const std::vector<float> gotYmfx = gpuPreparedYmfx.download();
const std::vector<float> gotResident = gpuResidentResult.download(); const std::vector<float> gotResident = gpuResidentResult.download();
...@@ -279,7 +287,8 @@ int main(int argc, char ** argv) ...@@ -279,7 +287,8 @@ int main(int argc, char ** argv)
(maxProducts <= 0.02f) && (maxDelta <= 2.0e-5f) && (maxProducts <= 0.02f) && (maxDelta <= 2.0e-5f) &&
(maxCandidate <= 2.0e-5f) && (maxRms <= 2.0e-6f) && (maxCandidate <= 2.0e-5f) && (maxRms <= 2.0e-6f) &&
(gotResident[POSE_LMA_ACCEPTED] == 0.0f) && (gotResident[POSE_LMA_ACCEPTED] == 0.0f) &&
(gotResident[POSE_LMA_STOP] == 0.0f); (gotResident[POSE_LMA_STOP] == 0.0f) &&
(gotCurrentSet[0] == 0); // not accepted -> no device-side flip // By Claude on 07/16/2026
std::printf("pose_lma resident 5120/150: prepared bit mismatches=%d, max products=%g, delta=%g, candidate=%g, RMS=%g -> %s\n", std::printf("pose_lma resident 5120/150: prepared bit mismatches=%d, max products=%g, delta=%g, candidate=%g, RMS=%g -> %s\n",
preparedBad, maxProducts, maxDelta, maxCandidate, maxRms, preparedBad, maxProducts, maxDelta, maxCandidate, maxRms,
residentOk ? "PASS" : "FAIL"); residentOk ? "PASS" : "FAIL");
......
...@@ -737,7 +737,8 @@ extern "C" __global__ void pose_lma_reduce_rms( ...@@ -737,7 +737,8 @@ extern "C" __global__ void pose_lma_reduce_rms(
float pure_weight, float pure_weight,
float rms_diff, float rms_diff,
const float * partials, const float * partials,
float * result) float * result,
int * current_set) // device set index, flipped on accept (NULL = no flip) // By Claude on 07/16/2026
{ {
if ((blockIdx.x != 0) || (threadIdx.x != 0)) return; if ((blockIdx.x != 0) || (threadIdx.x != 0)) return;
float pure_l2 = 0.0f; float pure_l2 = 0.0f;
...@@ -760,6 +761,12 @@ extern "C" __global__ void pose_lma_reduce_rms( ...@@ -760,6 +761,12 @@ extern "C" __global__ void pose_lma_reduce_rms(
pose_lma_sub(1.0f, rms_diff))); pose_lma_sub(1.0f, rms_diff)));
result[POSE_LMA_ACCEPTED] = accepted ? 1.0f : 0.0f; result[POSE_LMA_ACCEPTED] = accepted ? 1.0f : 0.0f;
result[POSE_LMA_STOP] = stop ? 1.0f : 0.0f; result[POSE_LMA_STOP] = stop ? 1.0f : 0.0f;
// Device-authoritative accept commit (rung B): flip the current/candidate
// buffer-set index in device memory. The host (and later a DP parent) reads
// this index instead of swapping pointers. By Claude on 07/16/2026.
if (accepted && (current_set != NULL)) {
*current_set ^= 1;
}
} }
extern "C" __global__ void lma_normal_products( extern "C" __global__ void lma_normal_products(
......
...@@ -108,12 +108,18 @@ extern "C" __global__ void pose_lma_reduce_step( ...@@ -108,12 +108,18 @@ extern "C" __global__ void pose_lma_reduce_step(
// Reduce a separately projected candidate pose to RMS only. Results append to // Reduce a separately projected candidate pose to RMS only. Results append to
// the compact resident step record without changing its candidate/normal terms. // the compact resident step record without changing its candidate/normal terms.
// On accept it also flips *current_set (0<->1) DEVICE-SIDE - the authoritative
// current/candidate buffer-set index (rung B, design 2026-07-16): a future DP
// parent resolves the raw pose buffers with no host round trip; today the host
// mirrors the flag with a 4-byte D2H after the step. NULL current_set = no flip
// (standalone kernel tests). By Claude on 07/16/2026.
extern "C" __global__ void pose_lma_reduce_rms( extern "C" __global__ void pose_lma_reduce_rms(
int num_partials, int num_partials,
float pure_weight, float pure_weight,
float rms_diff, float rms_diff,
const float * partials, const float * partials,
float * result); // candidate RMS fields in resident result float * result, // candidate RMS fields in resident result
int * current_set); // device current/candidate set index, flipped on accept
extern "C" __global__ void lma_normal_products( extern "C" __global__ void lma_normal_products(
int num_params, int 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