From f85ef20784ca06de5f08e9d8d4c7f096001b43b6 Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Sun, 14 Jun 2026 19:54:59 -0400 Subject: [PATCH] =?UTF-8?q?bend:=20cuda-secp256k1-bench=20=E2=80=94=20drop?= =?UTF-8?q?=20sample-x=20read=20(binary=20read-char=20hung=20child)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sample-x convenience was reading the BSCR output file via read-char in a loop. C tier's read-char does buffered UTF-8 decode which hangs on the high-bit bytes that fill a real point's X coordinate — the child handler stalls right after the daemon reports back, log shows the kernel timing then nothing, HTTP client times out. The timing fields (gpu-ms, gpu-mkeys-per-sec, cpu-est-sec, speedup-est) are the whole story for this demo. Killing the sample-x output drops the read-binary-file-prefix / read-string-bytes / sample-x-hex / hex-digit helpers and unblocks the response. Worker now returns inside ~1s of the daemon finishing. --- examples/cuda-fanout/gpu-worker.lsp | 52 ++--------------------------- 1 file changed, 2 insertions(+), 50 deletions(-) diff --git a/examples/cuda-fanout/gpu-worker.lsp b/examples/cuda-fanout/gpu-worker.lsp index 541f23a..1236a00 100644 --- a/examples/cuda-fanout/gpu-worker.lsp +++ b/examples/cuda-fanout/gpu-worker.lsp @@ -419,9 +419,7 @@ (if (file-exists? out-path) (delete-file out-path)) (list 'error (list 'daemon-failed (cdr status)))) (else - (let* ((sample (read-binary-file-prefix out-path 76)) ; 4+4+4 hdr + 64 first pt - (sample-hex (sample-x-hex sample)) - (gpu-sec (/ gpu-ms 1000.0)) + (let* ((gpu-sec (/ gpu-ms 1000.0)) (gpu-rate (cond ((> gpu-sec 0) (/ count gpu-sec 1000000.0)) (else 0))) (cpu-rate *cpu-secp256k1-rate-mkeys-per-sec*) @@ -443,53 +441,7 @@ (list 'gpu-mkeys-per-sec gpu-rate) (list 'cpu-rate-mkeys-per-sec cpu-rate) (list 'cpu-est-sec cpu-est-sec) - (list 'speedup-est speedup) - (list 'sample-x sample-hex))))))))))))) - -;; read first N bytes of file as a binary string. Used to peek at the -;; BSCR header + first output point without slurping the whole result -;; file (which is 64 * count bytes for large counts). -(define (read-binary-file-prefix path n) - (let* ((port (open-input-file path)) - (acc (read-string-bytes port n))) - (close-port port) - acc)) - -;; read up to n bytes from input port — falls back through read-char -;; on tiers where bulk read isn't a primitive. Returns a string of -;; whatever was available (may be shorter than n at EOF). -(define (read-string-bytes port n) - (let loop ((i 0) (acc '())) - (cond - ((>= i n) (apply string-append (reverse acc))) - (else - (let ((c (read-char port))) - (cond - ((eof-object? c) (apply string-append (reverse acc))) - (else (loop (+ i 1) (cons (string c) acc))))))))) - -;; Extract the X coordinate of the first output point from a BSCR -;; prefix as a 64-char hex string. BSCR layout: "BSCR"(4) status(4) -;; n(4) point0_x(32) point0_y(32) ... — so x bytes are at offset 12. -;; Returns "(unavailable)" if the prefix is too short. -(define (sample-x-hex bytes) - (cond - ((< (string-length bytes) 44) "(unavailable)") - (else - (let loop ((i 12) (end 44) (acc '())) - (cond - ((>= i end) (apply string-append (reverse acc))) - (else - (let* ((b (char->integer (string-ref bytes i))) - (hi (quotient b 16)) - (lo (remainder b 16))) - (loop (+ i 1) end - (cons (string (hex-digit hi) (hex-digit lo)) acc))))))))) - -(define (hex-digit n) - (cond - ((< n 10) (integer->char (+ n (char->integer #\0)))) - (else (integer->char (+ (- n 10) (char->integer #\a)))))) + (list 'speedup-est speedup))))))))))))) ;;; -- op handler -- health -------------------------------------- ;;;