1. 18 Jul, 2026 1 commit
    • Andrey Filippov's avatar
      CLAUDE: M1 - erase-by-task-list in the pose measure chain · e1913933
      Andrey Filippov authored
      Margin rung M1 (ROADMAP 3-A4i D5 tail, item (f) - suspect CONFIRMED by code:
      erase_clt_tiles NaN-fills the full 16x5120x256-float CLT buffer (~84 MB)
      every cycle while the chain converts/reads only the 150 task tiles):
      - new erase_clt_task_tiles(_inner): poison ONLY the task-listed tiles
        (~2.4 MB) - task-tile bytes identical to the full erase (a task tile that
        fails conversion stays NaN), non-task tiles keep stale data no pose-chain
        consumer reads (consolidation/inter-corr/peaks are all task/index-driven).
      - pose_measure chain (tp_lma.cu) switches to it; the full-frame
        erase_clt_tiles stays UNCHANGED for every render/debug/legacy path.
      - module function list +1 (Java Stage0 41/41 in the main-repo commit).
      Gates: run_cases.sh ALL PASS (pose_corr @tol 0 = captured production data
      bit-identical through the list-erase chain; scene_dp/scene_dp_split/
      measure_dp bit-identical); sanitizer 0 errors. A/B microbench: chain 2.52 ->
      ~2.35 ms/cycle => ~0.6-0.8 ms/scene off the DP entry.
      Co-authored-by: 's avatarClaude Opus 4.8 <claude-opus-4-8@anthropic.com>
      Co-authored-by: 's avatarClaude Fable 5 <claude-fable-5@anthropic.com>
      e1913933
  2. 17 Jul, 2026 8 commits
    • Andrey Filippov's avatar
      CLAUDE: D5b - launch/collect split of the pose_scene_dp entry · 25ddfe30
      Andrey Filippov authored
      Overlap-ring design ratified 07/17: the blocking entry refactored into
      pose_scene_dp_submit (through the parent enqueue; fence style + sync/async
      launch switchable) + pose_scene_dp_readback (the one-end-of-scene D2H +
      status checks) - the blocking entry composes both, byte-identical ABI and
      behavior, retained for the D4 oracle + A/B. New exports:
      - tp_proc_exec_pose_scene_dp_launch: GPU-side cudaStreamWaitEvent on the
        active ring set's ready event (replaces the host-blocking bayer_fence),
        raw enqueue with NO cuCtxSynchronize, returns immediately; one chain in
        flight, want_trace/want_mstats fixed at launch.
      - tp_proc_exec_pose_scene_dp_collect: readback (first D2H = completion wait),
        returns last-cycle npk exactly like the blocking entry.
      Case scene_dp_split (test_pose_scene_dp_split_jna, rides captured pose_corr):
      4 chains launch/collect bit-identical to the host-driven B3 loop, with
      chains 2-4 running CONCURRENT ring-set-1 staged uploads + async conditioning
      during the chain (set-1 result bit-exact vs the sync-path reference).
      run_cases.sh ALL PASS incl. blocking scene_dp unchanged; sanitizer 0 errors.
      Co-authored-by: 's avatarClaude Opus 4.8 <claude-opus-4-8@anthropic.com>
      Co-authored-by: 's avatarClaude Fable 5 <claude-fable-5@anthropic.com>
      25ddfe30
    • Andrey Filippov's avatar
      CLAUDE: D5a - k-slot device image-set ring + async conditioning on the copy stream · 76266672
      Andrey Filippov authored
      Overlap-ring design ratified 07/17 (handoffs/2026-07-17_pose_d5_overlap_ring_design.md):
      - TP_MAX_IMG_SETS=4 ring; set 0 = the setup allocation, others lazy clones
        (same pitch asserted); images_h/gpu_images always alias the ACTIVE set so
        every consumer (conditioning, granular convert, pose_mchain_fill snapshot)
        follows the ring with zero call-site changes.
      - tp_proc_img_set_select / _active / _ready_record; tp_proc_exec_conditioning_async
        = float two-map kernel on the bayer copy stream, ready event after it (ONE
        event = uploaded+conditioned); bayer_fence extended to cover the active set.
      - test_img_set_ring_jna (case img_ring): sync-set0 vs async-set1 conditioning
        bit-exact + both set-independence directions; run_cases.sh ALL PASS;
        compute-sanitizer memcheck 0 errors.
      Co-authored-by: 's avatarClaude Opus 4.8 <claude-opus-4-8@anthropic.com>
      Co-authored-by: 's avatarClaude Fable 5 <claude-fable-5@anthropic.com>
      76266672
    • Andrey Filippov's avatar
      CLAUDE: DP rung D3 - full per-scene parent (K x measure+prepare+step+commit, one entry) · a727289d
      Andrey Filippov authored
      pose_scene_dp: ONE device entry per scene. Self-chaining launchers (D1
      pattern): pose_measure_dp (D2, payload unchanged; its tail launcher now
      chains onward via a new PoseMeasureChain.scene back-pointer) ->
      pose_scene_dp_lma (per-cycle prepare from LIVE corr-row count; full mode
      = production per-cycle conditioning re-derivation with clears/assemble/
      norm/fx/finish, light mode = the D1 frozen body) -> pose_scene_dp_step
      (full-mode pure_weight read LIVE from prep_result - it changes every
      cycle; the six validated spike stages) -> pose_scene_dp_commit (anchor
      update on accept, 25-float trace + 5-int measure-stats trace rows,
      self-chains the next cycle's measure). Fixed-K, no device early exit;
      guard/invalid-prepare failures stop the chain fail-safe with
      cycles-completed visible to the host.
      
      Wrapper tp_proc_exec_pose_scene_dp: C2 nullable uploads + per-scene
      policy/pull/reg/anchor, full provisioning (D2 measure provision + the
      prepare/step scratch blocks), B4 bayer fence, ONE launch, ONE
      end-of-scene readback (scene status + measure status + traces + final
      packed + final anchor + compact prep); peaks/indices stay resident for
      the unchanged fetch calls. D2 entry refactored onto shared
      pose_measure_provision/pose_mchain_fill (same bytes).
      
      GATE (cases.list scene_dp): test_pose_scene_dp_jna rides the captured
      pose_corr case at the production 5120/150 LMA shape (full-grid centers
      scattered by task txy - corr indices carry full-grid tile numbers).
      Four chains vs the host-driven B3 loop (measure -> prepare_resident ->
      resident step, host anchor bookkeeping): full accept K=3, full reject
      K=2, full post-reject K=2, light K=2 riding the conditioning frozen by
      the preceding full chain. Per-cycle trace rows, measure stats, final
      packed/anchor/prep, and last-cycle corr rows keyed by packed index ALL
      bit-identical; the measure<->LMA interleave is real (accepts move the
      pose the next cycle measures at). run_cases.sh ALL PASS incl. pose_corr
      @tol 0 + dp_cycles + measure_dp; DP spike PASS; sanitizer-12.8 memcheck
      0 errors. Native-test timing is A==B by construction (no JNA in either
      arm); the production win - killing the per-cycle Java/JNA round trips -
      lands at rung D4.
      Co-authored-by: 's avatarClaude Fable 5 <noreply@anthropic.com>
      a727289d
    • Andrey Filippov's avatar
      CLAUDE: DP rung D2 - device measure chain from ONE parent entry · 39534100
      Andrey Filippov authored
      PoseMeasureChain descriptor (tp_lma.h) = the rung-B3 per-scene pcyc_*
      union + the resident buffer pointers the granular stage functions launch
      with - the DP parent's marshalling, consumed verbatim. Geometry buffers
      stay opaque (void*) so the header remains host-compilable; tp_lma.cu
      casts at the launch sites (one NVRTC translation unit).
      
      pose_measure_dp tail-enqueues the EXACT B3 host stage sequence:
      task_update -> [slot0 rot-deriv + tile offsets + erase(NaN) + convert
      SET] -> [slot1 rot-deriv + tile offsets + convert SUBTRACT] ->
      consolidate -> inter-corr -> normalize -> peak. Payload kernels are the
      UNMODIFIED production ones (most already single-thread CDP parents -
      the pre-JNA top-DP pattern), so the chain is byte-identical BY
      CONSTRUCTION; only the interior host syncs and the mid-chain 4-byte
      count readbacks disappear. Mid-chain counts (MB pairs / surviving tiles
      / corr rows) are read by self-chaining launchers (the D1 pattern) that
      run tail-enqueued BEHIND the counting kernel and check the LIVE count
      against the descriptor's provisioned capacity (device count guards;
      static over-provisioned shapes per the ratified D2 rule). New helper
      kernels only move bytes: gather/scatter of the per-cam CLT slices and
      the 0xFF NaN-poison fill (the host DtoD memcpys/memsets).
      
      Wrapper tp_proc_exec_pose_measure_cycle_dp (B3-signature drop-in):
      host keeps the rung-C2 nullable uploads (pose_task_upload split out of
      exec_pose_task_update, same bytes), the per-sequence reverse-distortion
      build, consolidate/peak capacity provisioning (no device-side malloc),
      the B4 bayer fence, ONE parent launch, ONE end-of-chain 5-int status
      D2H (rc/pairs/surviving/misaligned/corr rows). Peaks/corr indices stay
      resident for the unchanged fetch calls.
      
      Gate: test_pose_measure_dp_jna (cases.list 'measure_dp', rides the
      captured pose_corr case for real images/kernels/geometry/center-TD;
      task template txy/centers extracted from the captured production task
      stream; camera pair synthetic per the B1/D1 two-instance rule). Three
      poses, B3 entry vs DP chain, ORDER-INDEPENDENT KEYED BY PACKED INDEX:
      counts/stats equal, index sets equal, raw-TD (256) + FZ-normalized PD
      (225) + peak (8) rows ALL memcmp-equal (300 corr rows, 150/150 tiles).
      run_cases.sh ALL PASS (pose_corr @tol 0, peak, peak_recenter, avg_td,
      avg_td_oob, bayer_staged, dp_cycles, measure_dp); DP spike test still
      PASS; compute-sanitizer 12.8 memcheck 0 errors.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      39534100
    • Andrey Filippov's avatar
      CLAUDE: DP rung D1 - K chained prepare-light+step cycles from ONE device entry · 66fc53a1
      Andrey Filippov authored
      Self-chaining launcher pose_lma_dp_cycles: each cycle's launcher reads the
      LIVE current_set (tail-enqueued behind the previous reduce_rms, so it sees
      the accept flip a single unrolled parent could not), resolves cur/cand from
      both physical sets in the PoseDpCycles descriptor, tail-enqueues the exact
      host per-cycle sequence (clear-y = light memset, assemble(light),
      fx_jacobian(current), prepare_finish(light), the six spike step stages),
      then pose_lma_dp_commit - the device-side anchor update on accept that the
      spike flagged as the multi-step gap - plus a minimal per-cycle 25-float
      trace (ruling b), and finally the next launcher. Fixed-K, no device early
      exit (ruling a). Interior cycles cross NOTHING host-side.
      
      Wrapper tp_proc_exec_pose_lma_dp_cycles: entry H2D = pose vectors + anchor
      + descriptor; one launch; D2H once = trace + final result + final anchor +
      set mirror. Preconditions: frozen conditioning (C3) + resident corr/peaks.
      
      Gate: test_pose_lma_dp_cycles_jna (new, in cases.list as dp_cycles) seeds
      resident measurement through the production chain (set_corr_indices_td ->
      normalize -> corr2D_peak_eig_f), freezes conditioning, then compares three
      chains (K=3 accept, K=2 reject, K=2 post-reject) against host-driven
      light-prepare+step cycles: per-cycle traces, final packed, final anchor,
      set index ALL BIT-IDENTICAL. run_cases.sh ALL PASS (pose_corr @tol 0,
      peak, peak_recenter, avg_td, avg_td_oob, bayer_staged, dp_cycles); DP
      spike test still PASS.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      66fc53a1
    • Andrey Filippov's avatar
      CLAUDE: 3-B rung B3 - single measure-chain entry (host-batched, descriptor + one crossing) · ee0d275f
      Andrey Filippov authored
      tp_proc_set_pose_cycle stores the per-scene descriptor = the union of the
      fixed per-cycle chain's stage arguments (task_update / consolidate /
      inter-corr / normalize / peak) - the marshalling the DP parent will
      consume verbatim (design D2). tp_proc_exec_pose_measure_cycle is ONE JNA
      crossing per measure cycle: pose_task_update -> [slot0 geometry +
      convert(erase NaN)] -> [slot1 geometry + convert(SUBTRACT)] ->
      consolidate_slots -> corr2d_inter_td -> corr2d_normalize -> corr2d_peak,
      calling the EXACT exported stage functions in the exact granular order -
      byte-identical by construction. Nullable camera/template/pose groups
      forward verbatim to pose_task_update (rung-C2 register semantics).
      Stage-tagged negative returns (-10..-20); g_err keeps the failing
      stage's message. gc/cv/LPF/debias stay caller-resident (the Java setup
      uploads them once per scene - same bytes the granular path re-sent
      every cycle).
      
      run_cases.sh ALL PASS (pose_corr @tol 0 + synthetic + bayer_staged).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      ee0d275f
    • Andrey Filippov's avatar
      CLAUDE: 3-B rung B4 - pinned double-buffered bayer staging + async per-sensor H2D · 11ccdc2d
      Andrey Filippov authored
      Legacy tp_proc_set_image is a synchronous cudaMemcpy2D from pageable
      JNA-marshalled memory (B0: 11.9 ms/scene, ~1.8 GB/s). New surface:
      tp_proc_bayer_staging(slot 0/1) lazily allocates pinned staging
      (num_cams*w*h floats) + a dedicated non-blocking copy stream + fence
      event; tp_proc_set_image_staged enqueues the pinned->device copy of one
      sensor and returns (sensor k DMAs while the host prepares k+1). All
      resident-image consumers/writers fence (bayer_fence; kernel exec paths
      already cuCtxSynchronize). Double buffer + non-blocking stream = the
      RT-service inter-scene overlap provision. tp_proc_destroy drains the
      copy stream before freeing pinned.
      
      test_bayer_staged_jna (synthetic, cases.list 'bayer_staged'): both
      slots x 16 sensors bit-exact readback + staged->legacy WAW ordering -
      PASS. Full run_cases.sh ALL PASS (incl. pose_corr @tol 0).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      11ccdc2d
    • Andrey Filippov's avatar
      CLAUDE: 3-B rung B1 - pose_task_update resident task-build kernel · ef36688d
      Andrey Filippov authored
      New NVRTC kernel pose_task_update: one thread per selected task template
      entry runs the C1-validated projection chain (pose_world_from_pixel ->
      pose_pixel_from_world) and rewrites the 6-float task headers of BOTH
      resident ftask slots in place (slot 0 = MB main, slot 1 = MB partner).
      Inputs are all resident: per-sequence template (packed txy + reference
      centers, configuration-register semantics), per-scene camera blocks
      (shared with prepare_resident via pose_prep_ready bits), the
      device-authoritative current pose set, and per-scene scalars (uniform-MB
      6-float descriptor + margins + pre-encoded |511 task words). Failed
      projection / margin-gate tiles become task=0 HOLES in both sets -
      index_direct, index_consolidate and the inter correlation all skip them
      (the Java condensed stream reached the same end by omission).
      
      JNA API: tp_proc_exec_pose_task_update (nullable groups, rung C2
      contract; task_size derived from the uploaded skeleton) +
      tp_proc_activate_tasks_slot (make a resident slot the live task stream
      with no H2D - geometry/convert consume the kernel-rewritten slots).
      
      Tests (test_avg_td_oob two-tier pairing precedent):
      - src/tests/test_pose_task_update (nvcc-direct): grid-stride body makes
        a <<<1,1>>> launch the serial float oracle - parallel launch memcmp
        bit-exact; centerXY == pose_fx_jacobian fx + descriptor at 0 px
        (bit-identical across kernels); host-replayed margin/hole logic exact;
        xy/disp_dist tails untouched. PASS.
      - jna/test_pose_task_update_jna (production NVRTC module): fx-consistent
        at 0 px, keep-resident rerun memcmp-identical, no-MB encoding
        (sub=511), activate-slot getter semantics, error paths. PASS.
      All regressions PASS: run_cases.sh (pose_corr @tol 0 replay, peak,
      peak_recenter, avg_td, avg_td_oob) + pose fx/step/resident/DP/products
      standalone tests against the rebuilt module. compute-sanitizer cannot
      run on this GPU (sm_120 "Device not supported" - environment, not code).
      
      Design: imagej-elphel-internal
      handoffs/2026-07-16_3b_measure_chain_residency_design.md (B1; gate D3).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      ef36688d
  3. 16 Jul, 2026 9 commits
    • Andrey Filippov's avatar
      CLAUDE: DP spike PASS - CDP2 device-side pose-LMA step bit-identical on Blackwell · 978c5193
      Andrey Filippov authored
      pose_lma_dp_step<<<1,1>>> tail-launches all six resident-step stages
      (cudaStreamTailLaunch, CDP2) with zero host round trips; the only new
      device work is pose_lma_dp_candidate_vector (replaces two host
      cudaMemcpyAsync). NVRTC-only (#ifdef __CUDACC_RTC__): the production
      module's --extensible-whole-program + libcudadevrt link is exactly the
      CDP2 requirement; direct nvcc test builds never see device-side launches.
      
      Feasibility verdict (the spike's deliverable): CDP2 JIT+link+run WORKS in
      the production NVRTC module on CC 12.0 - no flag changes needed.
      
      test_pose_lma_dp_jna: two TpProc instances from one module driven to the
      identical pre-step resident state (the step mutates state on accept, so
      one-instance host-then-DP would compare different starting states); host
      prepared-resident path vs DP chain memcmp-equal on packed[0..24] for
      accept (device set flip exercised under DP), reject, and post-flip reject;
      multi-block child grid (300 tiles -> 2 blocks) + 3-partial reduce.
      Wall/step always-reject microbench: host 132 us, DP 118 us (1.12x; the
      real win is removing 6 JNA launch/sync round trips per step in production).
      
      Gates: test_pose_lma_dp_jna PASS bit-identical; regressions PASS:
      pose_lma_resident, pose_fx_jacobian, lma_products, pose_lma_step (all
      NVRTC), pose_corr captured-data @tol 0.
      
      Production notes for the DP milestone: the DP entry reuses the resident
      gpu_pose_lma_vector (anchor) - the per-cycle vector update after accept
      must move device-side (from result[16..18]) before multi-step DP chains.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      978c5193
    • Andrey Filippov's avatar
      CLAUDE: rung C3 - light prepare on frozen conditioning (Andrey's ruling) · a13d1661
      Andrey Filippov authored
      Design 3-A4i rung C3 (Andrey 07/17: weights and their normalization once
      per scene, not every cycle - re-normalizing on each cycle's re-measurement
      makes the solver conditioning wobble with measurement noise while the
      information is a per-scene property):
      - pose_lma_assemble/pose_lma_prepare_finish gain a 'light' mode: cycle-1
        conditioning (weights/eigen/selection/pull/reg/pure_weight) is FROZEN;
        light cycles write only the fresh measured offsets into the frozen
        structure and add fx (a frozen-selected tile with no fresh valid peak
        abstains: y=fx, zero residual, normalization untouched).
      - tp_proc_exec_pose_lma_prepare_resident(int light): guarded by
        pose_prep_frozen_tiles (a full prepare at this tile count must precede);
        light memsets only the measured y region, skips group/pull/reg uploads,
        skips the norm tail and diag/reg/normalize, skips the compact-result D2H.
      - Direct test: new LIGHT case (fresh peaks incl. abstains + moved fx) -
        y bit-exact vs serial float oracle, weights/eigen bit-identical frozen.
      Gates: direct full+LIGHT bit-exact, NVRTC resident + 19-float, pose_corr
      @tol 0, sanitizer 0 errors.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      a13d1661
    • Andrey Filippov's avatar
      CLAUDE: rung C2 - prepare upload groups nullable (configuration registers) · c357cebc
      Andrey Filippov authored
      Design 3-A4i rung C2: tp_proc_exec_pose_lma_prepare_resident treats its
      uploads as three nullable groups - NULL = keep the resident copy, guarded by
      pose_prep_ready bits: reference camera block + centers (per-SEQUENCE), scene
      camera block (per-SCENE). Per-cycle payload shrinks to pose_vectors + 6
      policy floats + the 8-float result D2H. Tile-capacity regrows clear the
      centers ready bit (both entry points). Camera meta now uploads per half.
      Gates: full suite PASS (direct step+prepare bit-exact, NVRTC x3, pose_corr
      @tol 0, sanitizer 0 errors).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      c357cebc
    • Andrey Filippov's avatar
      CLAUDE: rung C1 - resident prepareLMA (assemble + serial normalize on-device) · 7db7cf60
      Andrey Filippov authored
      Design 3-A4i rung C1: the LMA measured inputs never leave the GPU.
      - pose_lma_assemble (grid over resident corr rows): peaks {dx,dy,str,e0x,
        e0y,l0,l1,valid} + packed corr indices -> per-tile y offsets, raw strength
        weights, eigen 2x2 transform (setEigenTransform math, float; identity when
        use_eigen==0) and the fx selection mask. Parameterized contract (counts,
        slot, shift, components, policy scalars) - CUAS specifics stay host policy.
      - pose_lma_prepare_norm + pose_lma_prepare_finish: SERIAL one-thread tails
        (sample normalize + pull rows; y+=fx, H diagonal in Java getWJtJlambda
        order, regularization weights, full-weight normalize + pure_weight) -
        serial by design so the Java/C++ float clones gate BIT-EXACT.
      - tp_proc_exec_pose_lma_prepare_resident: camera/pose/centers/policy H2D,
        assemble -> norm -> pose_fx_jacobian(current, NO readback) -> finish;
        D2H = 8-float compact result (+optional capture of y/weights/eigen for
        the one-shot oracle). Same scratch bookkeeping as the step so a following
        no-H2D step never regrows.
      - tp_proc_exec_pose_lma_resident_step: all-NULL weights/y/eigen = use the
        resident prepared buffers (skip H2D); mixed NULLs rejected.
      Gates: direct CUDA prepare 5120/159 BIT-EXACT vs serial float oracle
      (y/weights/eigen/selection/scalars all 0 mismatches); resident + 19-float +
      fx_jacobian NVRTC PASS; pose_corr bit-exact @tol 0; compute-sanitizer 0
      errors on both binaries.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      7db7cf60
    • Andrey Filippov's avatar
      CLAUDE: rung B - device-visible pose current/candidate set index (no host swap) · 5f473261
      Andrey Filippov authored
      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>
      5f473261
    • Andrey Filippov's avatar
      CODEX: Keep pose LMA acceptance state resident · d9b7afdb
      Andrey Filippov authored
      Co-authored-by: 's avatarCodex <codex@elphel.com>
      d9b7afdb
    • Andrey Filippov's avatar
      CODEX: Evaluate pose LMA candidate RMS on GPU · a9688cbc
      Andrey Filippov authored
      Co-authored-by: 's avatarCodex <codex@elphel.com>
      a9688cbc
    • Andrey Filippov's avatar
      CODEX: Add resident CUDA pose LMA preparation · 702c2f76
      Andrey Filippov authored
      Co-authored-by: 's avatarCodex <codex@elphel.com>
      702c2f76
    • Andrey Filippov's avatar
      CODEX: Add float CUDA pose LMA candidate · 31f70553
      Andrey Filippov authored
      Co-authored-by: 's avatarCodex <codex@elphel.com>
      31f70553
  4. 15 Jul, 2026 6 commits
  5. 14 Jul, 2026 6 commits
    • Andrey Filippov's avatar
      CLAUDE: peak kernel precision two-step - templated body, float instantiation... · 4bcc5195
      Andrey Filippov authored
      CLAUDE: peak kernel precision two-step - templated body, float instantiation corr2D_peak_eig_f (Andrey's methodology)
      
      Step 1 (double vs double Java oracle) was the validated state; the body is
      now a template on the accumulator type with two extern-C instantiations:
      corr2D_peak_eig (double, the oracle-matched reference) and corr2D_peak_eig_f
      (float, ~64x cheaper FLOPs + half the shared footprint - kept adequate for
      full-frame, Andrey's ruling). tp_proc_exec_corr2d_peak grows a use_float arg;
      NVRTC module = 25 kernels. All three tests run BOTH and report float-vs-double
      grouped stats (dx/dy px, strength rel, eigvec abs, lambda rel).
      
      Step 2 measured:
      - synthetic: dx/dy <= 4.8e-7 px, lambda <= 9.4e-7 rel; eigvec 0.031 ONLY on
        the (near-)isotropic tiles where the direction is ill-defined (float can't
        fire the oracle's e=1e-12 branch) AND unused (setEigenTransform degenerates
        to isotropic weighting when lambda0~lambda1) - documented in tp_peak.cu.
      - REAL case (4 iterations x 150 tiles): dx/dy <= 7.2e-7 px, strength
        IDENTICAL, eigvec <= 8.9e-5, lambda <= 1.2e-6 rel - 4+ orders below the
        ~0.01 px measurement noise. Float is adequate for production; double stays
        as the validation/oracle tier. Double regression unchanged (synthetic 0 /
        9.6e-17; real case ALL PASS).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      4bcc5195
    • Andrey Filippov's avatar
      CLAUDE: peaks compare - dual criterion (abs floor OR 4 float ULP at operand scale) · 02508a82
      Andrey Filippov authored
      First rung-2 real case (Andrey's 07/14 export) measured the predicted tier
      precisely: tasks + corr_td + corr_pd ALL BIT-EXACT @tol 0 (the in-place
      FZ-norm is production-identical); peaks ~14% of elements flip by 1-2 float
      ULP at their own magnitude (double-math FMA contraction vs Java, absorbed
      except at float cast boundaries) - a flat absolute tol cannot cover 1 ULP
      of lambda~40 (3.8e-6) while staying meaningful for dx~0.01. Criterion now:
      pass if within --peak-tol ABSOLUTE (near-zero floor, default 1e-6) OR
      within 4 float ULP of the operand (measured max 2 ULP; near-zero relative
      outliers ~21 ULP are 3e-9 absolute = caught by the floor). Verdict on the
      fresh case: ALL PASS, viol=0.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      02508a82
    • Andrey Filippov's avatar
      CLAUDE: scene list points at the test manifest - SET casesFile support · edc6c4ab
      Andrey Filippov authored
      The scene-sequence .list is the single source of truth: it now carries
      SET casesFile lists/cases.list (relative to rootDirectory, the
      EyesisCorrectionParameters rule). run_cases.sh discovery order: -c arg ->
      the scene list's SET casesFile (when -x/-l provides the list; explicit
      pointer, missing target = hard error) -> convention lookup under
      rootDirectory -> repo-local gitignored link. Verified: -l, -x and bare
      modes all resolve to the same manifest/model.
      
      Java companion (imagej-elphel): casesFile added to KEY_DIRS (index 12,
      file-exempt from the auto-mkdirs) so the SET parses cleanly.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      edc6c4ab
    • Andrey Filippov's avatar
      CLAUDE: cases.list -> data root (repo keeps template + code only) · 5b8f2f7a
      Andrey Filippov authored
      Andrey's rulings 07/13/2026: data directories are not git-controlled; the
      repo is shared across computers with different data sets, so it carries
      code, generators and a heavily-commented TEMPLATE (linux-config style) -
      everything data-specific lives under the data root:
      
      - cases.list -> cases.list.tmpl (tracked; install by copying to
        <dataRoot>/lists/cases.list next to the scene lists; SET listFile may
        then be a bare filename - resolved relative to the manifest's directory).
      - /cases.list gitignored: optional repo-local symlink into the data root
        so a bare ./run_cases.sh works.
      - run_cases.sh: manifest lookup order -c arg -> ./cases.list link ->
        via -x/-l through the scene list's rootDirectory (<root>/lists/,
        <root>/, next to the scene list). -x corr-xml alone now finds
        everything (list, version, manifest) from the entries the Java run uses.
      
      Verified live: installed at /home/elphel/lwir16-proc/LV/lists/cases.list;
      bare run ALL PASS via the symlink; -x corr-xml discovery ALL resolved with
      the symlink removed.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      5b8f2f7a
    • Andrey Filippov's avatar
      CLAUDE: manifest-like tests top - cases.list + run_cases.sh (Andrey's design),... · 72e2caf1
      Andrey Filippov authored
      CLAUDE: manifest-like tests top - cases.list + run_cases.sh (Andrey's design), de-hardwire test defaults
      
      The scene-sequence .list is the human single source of truth (SET header +
      body lines selected by uncommenting; commented lines document the setup).
      The tests now follow the SAME convention one level up:
      
      - cases.list: SET header (listFile, version - the version deliberately kept
        out of the scene list, mirroring CORRECTION_PARAMETERS.x3dModelVersion vs
        .sourceSequencesList) + case lines selected by uncommenting; commented
        cases stay as documentation. gen lines map synthetic cases to generators.
      - run_cases.sh: resolves ${MODEL} through the scene list's SET
        rootDirectory/x3dDirectory + its UNCOMMENTED sequence lines + the version
        (the *-CENTER dir carries the DERIVED center timestamp -> matched as the
        smallest center ts >= the sequence's first-scene ts containing <version>/);
        -x <corr-xml> reads sourceSequencesList/x3dModelVersion directly = the
        same two sources that drive the Java run. No args = all uncommented cases;
        named cases run even when commented; missing synthetic data triggers the
        generator.
      - test_proc_consolidate: hardwired absolute case/repo paths -> standard
        --data/--src/--devrt interface (legacy positional kept).
      - test_pose_corr_jna: srcdir default de-hardwired (repo-relative 'src').
      
      Verified live: ./run_cases.sh ALL PASS (pose_corr real-scene tol-0 resolved
      through the list+version, 4 synthetic cases); named-commented case
      avg_td_oob_jna PASS bit-exact via the new interface; gen-on-missing works.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      72e2caf1
    • Andrey Filippov's avatar
      CLAUDE: 3-C rung 2 - corr2D_peak_eig (frozen 15-arg getMaxXYCmEig contract) +... · 7ecab008
      Andrey Filippov authored
      CLAUDE: 3-C rung 2 - corr2D_peak_eig (frozen 15-arg getMaxXYCmEig contract) + checkpoint-2 replay + synthetic numpy gate
      
      Andrey's ruling 07/13/2026: the GPU peak contract = the 15-arg superset -
      closed-form 2x2 eigen, recentering as a runtime param, envelope de-bias as
      an optional array pointer (NULL = off).
      
      - src/tp_peak.{h,cu}: corr2D_peak_eig, one block/tile - parallel load/NaN/
        argmax(first-occurrence)/8-connected grow, thread-0 serial DOUBLE centroid/
        covariance/eigen/recentering in the Java oracle's exact summation order.
      - jna/tp_jna.cpp: kernel in the NVRTC module (24 kernels) +
        tp_proc_exec_corr2d_peak / tp_proc_get_peaks / tp_proc_set_peak_debias.
      - test_pose_corr + test_pose_corr_jna: checkpoint-2 replay (in-place
        corr2D_normalize -> corr_pd tol tier, peaks vs the double Java oracle at
        --peak-tol) when the case carries it; pre-rung-2 cases skip with a note.
      - make_peak_case.py + test_peak: synthetic gate vs an INDEPENDENT numpy
        float64 port (8 adversarial tiles + refine/debias case) - PASS at
        max|diff| 0 / 9.6e-17.
      - Regressions: test_pose_corr_jna bit-exact @tol 0 on the existing v013 case,
        avg_td / avg_td_oob / convert_direct PASS.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      7ecab008
  6. 13 Jul, 2026 2 commits
    • Andrey Filippov's avatar
      CLAUDE: test_pose_corr_jna - the tol-0 verdict binary (NVRTC production... · fc6f5245
      Andrey Filippov authored
      CLAUDE: test_pose_corr_jna - the tol-0 verdict binary (NVRTC production module); direct test = stepping companion
      
      RUNG 1 VALIDATED on the first real v013 case (scene 1773135467_917220,
      4 LMA iterations, 150 tiles/set, 300 corr tiles/iter): test_pose_corr_jna
      PASS BIT-EXACT @tol 0 - tasks (calculate_tiles_offsets) and raw TD
      correlation (correlate2D_inter) both max|diff|=0, every iteration.
      
      The offline-nvcc direct-launch binary (src/tests/test_pose_corr) cannot be
      bit-exact vs the NVRTC JIT (FMA/codegen divergence), measured: -G -O0 ->
      tasks off by 2^-13 px; RELEASE=1 -> tasks BIT-EXACT, corr within ~1 ULP at
      operand scale (max|diff| 128..256 vs amplitudes ~2e9, float spacing 256).
      Role split documented in both headers (same pairing as test_avg_td_oob /
      test_proc_consolidate): direct binary for cuda-gdb stepping, _jna binary
      for the production-equivalence verdict. Build line in the _jna header.
      Co-authored-by: 's avatarClaude Fable 5 <noreply@anthropic.com>
      fc6f5245
    • Andrey Filippov's avatar
      CLAUDE: test_pose_corr - lean pose checkpoint-1 replay (roadmap 3-C rung 1) · e09e873d
      Andrey Filippov authored
      Standalone per-iteration replay of the CuasPoseRT.leanMeasure GPU chain
      against the PoseCorrExport case (imagej-elphel curt.kernel_test=pose_corr):
      calcReverseDistortionTable + calc_rot_deriv + calculate_tiles_offsets (NEW
      under test; GPU-filled tasks compared bit-exact vs the oracle post-offsets
      streams, header+xy fields - the disp_dist tail is not round-tripped by the
      Java flatten), erase_clt_tiles(NaN) + convert_direct for both MB sets,
      the v1 consolidation chain into the cam-0 slot (inputs = the oracle
      post-offsets streams, the exact bytes production flattens), then
      correlate2D_inter vs the resident center TD from gpu_clt_ref cam 0 (NEW
      under test). Raw-TD compare is ORDER-INDEPENDENT (corr slot placement is
      atomicAdd-nondeterministic): tiles matched by packed index, tol 0 goal;
      results/corr_td_it<k> saved in oracle order for the Java round trip. All
      four LPF/HPF __constant__ tables overwritten from the case via extern
      __constant__ + cudaMemcpyToSymbol (correlate2D_inter reads LoG_corr and
      lpf_rb_corr). Built by build_tests.sh (auto-discovered), cuda-gdb steppable.
      Co-authored-by: 's avatarClaude Fable 5 <noreply@anthropic.com>
      e09e873d
  7. 12 Jul, 2026 8 commits
    • Andrey Filippov's avatar
      CLAUDE: JNA export tp_proc_exec_consolidate - on-device TD consolidation chain · d8ac8a6b
      Andrey Filippov authored
      Wire the frozen v1 chain (index_consolidate -> consolidate_oob ->
      clt_average_sensors_list) into the production JNA surface (roadmap 2c ->
      step 4 JNA hookup, Andrey's ruling: JNA-only, no JCuda launch code):
      - tp_jna.cpp: tp_consolidate.h/.cu added to the NVRTC module (23 kernels);
        new export tp_proc_exec_consolidate = host orchestration of the chain on
        the RESIDENT per-cam CLT (contiguous DtoD gather, no D2H/H2D of TD data;
        only the flattened task streams cross the boundary); average lands in the
        cam-0 slot (what the single conj-multiply correlates); lazy scratch,
        freed in tp_proc_destroy; stats {pairs, surviving tiles, misaligned}.
      - tp_consolidate.h/.cu: JCUDA include guards (NVRTC concatenation has no
        include paths) + NAN/INFINITY fallbacks (NVRTC has no math.h macros).
      - jna/test_proc_consolidate.cu: standalone validation of the export vs the
        real-scene avg_td_oob oracle case - PASS bit-exact (max|diff|=0,
        5120 pairs -> 5056 tiles == oracle, 0 misaligned).
      Regressions: tests_bin/test_avg_td, test_avg_td_oob PASS at tol 0 after
      the guard changes; module smoke = 23/23 kernels resolved.
      Co-authored-by: 's avatarClaude Fable 5 <noreply@anthropic.com>
      d8ac8a6b
    • Andrey Filippov's avatar
    • Andrey Filippov's avatar
      CLAUDE: clt_average_sensors v1 chain - MB-aware indexing + OOB priority + masked average · 18976ef3
      Andrey Filippov authored
      Three kernels (tp_consolidate.cu, oracle = imagej-elphel CuasTD @eab1660e):
      - index_consolidate: index_direct successor aware of the motion-blur task
        pair (gpu_ftasks1 may be NULL = no-MB, mirrors Java TpTask[2][] with [1]
        null); keeps tiles active in BOTH sets, txy-alignment verified
        (misaligned counted, skipped); output = compacted even/odd PAIRS (no-MB:
        odd = copy) so pass 2 is uniform. Activity tested on the task word as
        int (v0 index_direct float-compare -0.0 quirk noted).
      - consolidate_oob: frozen 2c spec - per sensor depth = min over the MB
        pair of tile-center distance to nearest frame edge; <hard(8) always
        skipped, any >=soft(12) only those, else hard survivors last resort,
        nobody -> tile dropped; NaN xy excluded (explicit isnan - fminf would
        silently ignore NaN); mask folded into task bits TASK_AVG_SENS_SHIFT=11
        (bits 11+ virgin per the TpTask bit-field survey).
      - clt_average_sensors_list: v0 core driven by the compacted list, gated
        by the mask; host prefills NaN/0 = oracle poison semantics.
      v0 clt_average_sensors refactored onto the shared consolidate_chunk core
      (all-ones mask), verified bit-exact.
      
      test_avg_td_oob: loads AvgTdExport.exportOob cases (raw ftasks0/1
      streams); runs the chain; compares masks exactly + td_avg/counts at tol 0.
      make_avg_td_oob_case.py: synthetic 4-sensor case = the SAME scenario the
      Java oracle self-test passes (every OOB branch); independent float32
      oracle-op-order expectations.
      VERIFIED: synth avg_td (v0 refactor) max|diff|=0; synth avg_td_oob chain
      5 pairs -> 4 tiles, masks exact, avg/counts max|diff|=0 at tol 0;
      test_convert_direct regression PASS both tiers.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      18976ef3
    • Andrey Filippov's avatar
      CLAUDE: tp_consolidate: explicit CUDA includes for the CDT indexer · 93394ad2
      Andrey Filippov authored
      cuda_runtime.h only pulls device_launch_parameters.h under __CUDACC__,
      which the indexer stopped defining when CDT 2025-09 dropped the Nsight
      scanner-discovery provider -> 14 false markers (blockIdx/threadIdx/
      __syncthreads/NAN/isnan unresolved; F3 still jumped via other TUs).
      Fix: include cuda_runtime.h + device_launch_parameters.h + math.h
      explicitly, plus a __CDT_PARSER__-only __syncthreads() decl (its real
      declaration is __CUDACC__-gated). No-op for nvcc: standalone -dc compile
      clean, build_tests OK, test_convert_direct PASS both tiers (strict 0).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      93394ad2
    • Andrey Filippov's avatar
      CLAUDE: eclipse_setup: template debug configs (launches/) + rewrite Eclipse debug recipe · dcb83115
      Andrey Filippov authored
      - launches/test_convert_direct.launch.tmpl: harvested working shared config
        (C/C++ Application + cuda-gdb 12.8; .tmpl suffix so Eclipse does not
        discover the template copy as a duplicate; setup.sh strips it on install)
      - setup.sh: install launches/
      - nsight_per_kernel_tests.md: modern Eclipse does not load the Nsight local
        'CUDA GDB Application' type - use C/C++ Application with cuda-gdb as GDB;
        shared-config save recipe; DP child-launch stepping caveat
      - README: document launches/ templating
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      dcb83115
    • Andrey Filippov's avatar
      CLAUDE: gitignore live /launches (shared Eclipse debug configs; template copy... · 49388c61
      Andrey Filippov authored
      CLAUDE: gitignore live /launches (shared Eclipse debug configs; template copy will live in eclipse_setup/)
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      49388c61
    • Andrey Filippov's avatar
    • Andrey Filippov's avatar
      removed commented-out lines · b9d2e060
      Andrey Filippov authored
      b9d2e060