Commit dcc556dd authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: Step 1 — JNA bindings for persistent TpProc API + StageProc validation driver

TpJna: tp_proc_create/setup/set_*/exec_*/get_clt/destroy + tp_proc_convert_selftest.
StageProc: validates the persistent convert path == Stage-2 CLT golden + no_kernels smoke test.
PASS on 5060 Ti. This is the production-facing surface GpuQuadJna (integration step 2) delegates to.
Co-Authored-By: 's avatarClaude Opus 4.8 (1M context) <noreply@anthropic.com>
parent cef5277a
package com.elphel.imagej.gpu.jna;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
/**
* Step-1 validation: the PERSISTENT granular native API (TpProc) — the production-facing surface that
* GpuQuadJna (integration step 2) will delegate to. Drives the convert_direct path through the persistent
* instance (buffers allocated once, reused) and confirms CLT == clt/aux_chnN.clt golden (== Stage 2), plus
* a no_kernels smoke test (the fragile skip-deconvolution path used by rectilinear / FPN back-prop).
*
* Run:
* java -Djna.library.path=&lt;dir with libtileproc.so&gt; -cp target/classes:&lt;jna.jar&gt; \
* com.elphel.imagej.gpu.jna.StageProc [data_root] [lwir]
* By Claude on 2026-06-25.
*/
public class StageProc {
public static void main(String[] args) {
String root = (args.length > 0) ? args[0] : "/home/elphel/git/tile_processor_gpu";
int lwir = (args.length > 1) ? Integer.parseInt(args[1]) : 1;
String srcdir = "/home/elphel/git/tile_processor_gpu/src";
String devrt = "/usr/local/cuda/targets/x86_64-linux/lib/libcudadevrt.a";
System.out.printf("StageProc (persistent TpProc convert via JNA): root=%s lwir=%d%n", root, lwir);
TpJna lib = Native.load("tileproc", TpJna.class);
Pointer m = lib.tp_create_module(srcdir, devrt);
if (m == null) { System.out.println("FAIL: tp_create_module:\n" + lib.tp_last_error()); System.exit(1); }
double[] cltErr = new double[1], nokern = new double[1];
int[] nActive = new int[1];
int rc = lib.tp_proc_convert_selftest(m, lwir, root, cltErr, nokern, nActive);
if (rc != 0) { System.out.printf("FAIL: selftest rc=%d: %s%n", rc, lib.tp_last_error()); System.exit(2); }
boolean cltOk = (cltErr[0] >= 0) && !Double.isNaN(cltErr[0]) && (cltErr[0] < 1.0) && (nActive[0] > 0);
boolean nokernOk = (nokern[0] >= 0); // >=0 means it ran and output was finite (-1 non-finite, -2 launch err)
System.out.printf(" persistent convert_direct: num_active=%d max|CLT-golden|=%.6g %s%n",
nActive[0], cltErr[0], cltOk ? "PASS" : "FAIL");
System.out.printf(" no_kernels smoke: %s (max|CLT|=%.4g)%n",
nokernOk ? "ran, finite" : (nokern[0] == -1 ? "NON-FINITE" : "launch error"), nokern[0]);
lib.tp_destroy_module(m);
boolean ok = cltOk && nokernOk;
System.out.println(ok ? "RESULT: PASS (persistent TpProc convert matches golden; no_kernels path runs)"
: "RESULT: FAIL");
System.exit(ok ? 0 : 3);
}
}
...@@ -62,4 +62,24 @@ public interface TpJna extends Library { ...@@ -62,4 +62,24 @@ public interface TpJna extends Library {
* and the de-interleaved diff_rgb_combo to clt/aux_diff_rgb_combo_dp.drbg (outTexErr[0]). */ * and the de-interleaved diff_rgb_combo to clt/aux_diff_rgb_combo_dp.drbg (outTexErr[0]). */
int tp_tex_selftest(Pointer module, int lwir, String data_root, int tp_tex_selftest(Pointer module, int lwir, String data_root,
double[] outCltErr, double[] outTexErr, int[] outNumActive); double[] outCltErr, double[] outTexErr, int[] outNumActive);
// ---- Step 1: persistent granular API (TpProc) — production-facing surface ----
Pointer tp_proc_create(Pointer module);
int tp_proc_setup(Pointer proc, int num_cams, int num_colors, int img_w, int img_h, int kernels_hor, int kern_tiles);
int tp_proc_set_geometry(Pointer proc, float[] fgc, int n);
int tp_proc_set_correction_vector(Pointer proc, float[] fcv, int n);
int tp_proc_set_kernels(Pointer proc, int cam, float[] d, int n);
int tp_proc_set_kernel_offsets(Pointer proc, int cam, float[] d, int n);
int tp_proc_set_image(Pointer proc, int cam, float[] d);
/** use_center_image: broadcast one center image to all sensors (FPN back-prop mode). */
int tp_proc_set_center_image(Pointer proc, float[] d);
int tp_proc_set_tasks(Pointer proc, float[] ftasks, int ntiles, int totalFloats);
int tp_proc_exec_geometry(Pointer proc, int uniformGrid);
/** convert_direct: ref_scene (0/1 -> clt vs clt_ref), erase_clt (-1/0/1), no_kernels (0/1). */
int tp_proc_exec_convert_direct(Pointer proc, int refScene, int eraseClt, int noKernels);
int tp_proc_get_clt(Pointer proc, int cam, int refScene, float[] out);
void tp_proc_destroy(Pointer proc);
/** Validate the persistent path: standard convert CLT vs golden (outCltErr) + no_kernels smoke (outNokernMax). */
int tp_proc_convert_selftest(Pointer module, int lwir, String data_root,
double[] outCltErr, double[] outNokernMax, int[] outNumActive);
} }
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