Running ‘testthat.R’ [46s/49s]
Running the tests in ‘tests/testthat.R’ failed.
Complete output:
  > library(testthat)
  > library(ggmlR)
  > 
  > if (requireNamespace("mlr3", quietly = TRUE)) library(mlr3)
  > if (requireNamespace("parsnip", quietly = TRUE)) library(parsnip)
  > 
  > heavy <- c(
  +   "normalization",
  +   "sequence-ops",
  +   "binary-operations",
  +   "glu",
  +   "nn-sequential",
  +   "matrix-ops",
  +   "callbacks",
  +   "onnx-quant",
  +   "cpu-backend",
  +   "onnx-elementwise",
  +   "onnx-norm",
  +   "onnx-misc",
  +   "onnx-logic",
  +   "onnx-gemm",
  +   "onnx-resize",
  +   "onnx-nn",
  +   "nn-functional",
  +   "activations-extended",
  +   "onnx-ops",
  +   "transformer-ops",
  +   "onnx-shape",
  +   "math-operations",
  +   "activations",
  +   "backend-extended",
  +   "helpers",
  +   "onnx-reduce",
  +   "chain-sequential-batchnorm",
  +   "chain-patterns",
  +   "onnx-chain-quant",
  +   "onnx-chain-qlinearconv",
  +   "onnx-chain-uncovered-ops",
  +   "onnx-chain-transformer",
  +   "onnx-chain-broadcast-strict",
  +   "onnx-chain-maskrcnn-broadcast",
  +   "onnx-chain-erf-gelu",
  +   "onnx-chain-resize-broadcast",
  +   "onnx-chain-constantofshape-int64",
  +   "onnx-chain-roberta-attn",
  +   "onnx-chain-batched-matmul",
  +   "onnx-chain-classify",
  +   "onnx-chain-xcit-dynamic",
  +   "onnx-chain-fpn",
  +   "onnx-chain-pooling",
  +   "onnx-chain-unet",
  +   "onnx-chain-audio",
  +   "onnx-chain-superres",
  +   "onnx-chain-convtranspose",
  +   "onnx-chain-eyelike",
  +   "onnx-chain-decoder",
  +   "onnx-chain-detect",
  +   "onnx-chain-powernorm",
  +   "onnx-chain-bert-mlp",
  +   "onnx-chain-position",
  +   "onnx-chain-attn-mask",
  +   "onnx-chain-postprocess",
  +   "onnx-chain-cast",
  +   "onnx-chain-preprocess",
  +   "model-ops",
  +   "onnx-boundary",
  +   "onnx-edge",
  +   "parsnip",
  +   "parsnip-tidymodels",
  +   "parsnip-broom",
  +   "seed",
  +   "upscale",
  +   "rope-multi",
  +   "mlr3-learner",
  +   "keras-api",
  +   "quants-iq-degenerate",
  +   "getrows-offload-vulkan",
  +   "gpu-linalg"
  + )
  > 
  > # Under the valgrind memtest, running the full light suite (~67 files) blows
  > # the memory limit: valgrind's shadow memory accumulates across every
  > # ggml_init / backend buffer and never returns to the OS, so the process grows
  > # to several GiB and gets SIGKILLed regardless of any single test's size.
  > # valgrind's purpose here is to catch C-level memory bugs (use-after-free,
  > # invalid reads/writes) in the ggml bindings — a small core suite that
  > # exercises context/tensor lifecycle, basic ops and the backend is enough for
  > # that. So under valgrind we run an explicit whitelist instead of the full set.
  > valgrind_core <- c(
  +   "tensors",       # tensor create/free lifecycle
  +   "context",       # ggml_init / ggml_free
  +   "ggml",          # core library smoke
  +   "types",         # type helpers
  +   "operations-extended",
  +   "tensor-utils",
  +   "backend",       # backend init/free + buffers
  +   "memory",
  +   "quants"         # quant/dequant round-trips
  + )
  > 
  > # Detect valgrind via several independent signals (any one is enough):
  > #  1. vgpreload_*.so injected into the process (visible in /proc/self/maps)
  > #  2. the RUNNING_ON_VALGRIND env var some setups export
  > #  3. R's own valgrind marker in the session (R_CHECK_*/loaded vg libs)
  > detect_valgrind <- function() {
  +   if (nzchar(Sys.getenv("RUNNING_ON_VALGRIND"))) return(TRUE)
  +   # /proc/self/maps holds vgpreload_core / vgpreload_memcheck under valgrind
  +   m <- tryCatch(readLines("/proc/self/maps", warn = FALSE),
  +                 error = function(e) character(0))
  +   if (any(grepl("valgrind|vgpreload", m, ignore.case = TRUE))) return(TRUE)
  +   # /proc/self/cmdline of the wrapping process: valgrind launches R
  +   s <- tryCatch(readLines("/proc/self/status", warn = FALSE),
  +                 error = function(e) character(0))
  +   ppid <- sub("^PPid:\\s*", "", grep("^PPid:", s, value = TRUE))
  +   if (length(ppid) == 1L) {
  +     pcmd <- tryCatch(
  +       readChar(file.path("/proc", ppid, "cmdline"), 1e4, useBytes = TRUE),
  +       error = function(e) "")
  +     if (grepl("valgrind", pcmd, ignore.case = TRUE)) return(TRUE)
  +   }
  +   FALSE
  + }
  > under_valgrind <- isTRUE(detect_valgrind())
  Warning message:
  In readChar(file.path("/proc", ppid, "cmdline"), 10000, useBytes = TRUE) :
    truncating string with embedded nuls
  > message("valgrind detected: ", under_valgrind)
  valgrind detected: FALSE
  > 
  > # Disable OpenMP thread pool under valgrind: GOMP_parallel → pthread_create
  > # allocates 352b TLS per worker thread which valgrind flags as "possibly lost".
  > # Under valgrind we test correctness, not throughput — 1 thread is sufficient.
  > if (under_valgrind) {
  +   Sys.setenv(OMP_NUM_THREADS = "1")
  + }
  > 
  > on_cran <- !identical(Sys.getenv("NOT_CRAN"), "true")
  > 
  > test_dir <- if (dir.exists("testthat")) "testthat" else "tests/testthat"
  > 
  > if (on_cran) {
  +   message("--- RUNNING LIGHT TESTS ONLY ---")
  + 
  +   all_tests <- list.files(test_dir, pattern = "^test-.*\\.R$")
  +   all_names <- sub("^test-(.*)\\.R$", "\\1", all_tests)
  + 
  +   if (under_valgrind) {
  +     message("--- VALGRIND DETECTED: running small core suite only ---")
  +     # Whitelist intersected with what actually exists in the package.
  +     light_tests <- intersect(valgrind_core, all_names)
  +   } else {
  +     light_tests <- setdiff(all_names, heavy)
  +   }
  +   message("Tests to run: ", paste(light_tests, collapse = ", "))
  + 
  +   if (length(light_tests) == 0) {
  +     # fallback
  +     test_check("ggmlR")
  +   } else {
  +     # testthat applies `filter` as grepl(filter, <test name>) with no anchors,
  +     # so anchor each name with ^...$ to avoid e.g. "backend" also matching
  +     # "backend-buffers"/"backend-extended" (which would re-bloat the set).
  +     filter_regex <- paste0("^(", paste(light_tests, collapse = "|"), ")$")
  +     test_check("ggmlR", filter = filter_regex)
  +   }
  + } else {
  +   test_check("ggmlR")
  + }
  --- RUNNING LIGHT TESTS ONLY ---
  Tests to run: 5d-ops, ag-device, ag-layers, ag-mha, ag-save, ag-training, autograd-missing, autograd-ops, autograd, backend-buffers, backend, chain-ag-early-stopping, context, conv-transpose-numeric, conv2d-cpu-gpu, conv2d-dw-numeric, conv2d-numeric, convolution-pooling, cpu-features, diagnostics, flash-attn-q4k, flash-attn-quants, functional-shared-layers, ggml, gguf, graph-extended, graph-utils, headers-sync, inplace-ops, logging, memory-extended, memory, meta-backend, misc-ops, mlr3-autograd, new-functions, new-ops-numeric, nn-functional-missing, onnx-activations, onnx-chain-roialign-nms, onnx-chain-scatter-gnn, onnx-helpers, onnx-math, onnx-meta, operations-extended, optimizer, print-methods, q4k-matmul-vulkan, quantization, quantize-fns, quants-missing, quants, reduction-ops, reset, reshape, sc-chunked, sc-knn-gpu, sc-largest-gene, sc-neighbors, sc-normalize-sparse, sc-sce, sc-seurat, sc-umap, scheduler, set-operations, softmax, static-lib, tensor-info, tensor-utils, tensors-extended, tensors, threading, types, version, vulkan-caps, vulkan-push-constants, vulkan-tensor-parallel, vulkan
  Using CPU backend
  GGML library loaded successfully!
  GGML version: 0.11.0
  Tensor overhead: 448 bytes
  Saving _problems/test-sc-umap-339.R
  GGML library loaded successfully!
  GGML version: 0.11.0
  Tensor overhead: 448 bytes
  Vulkan: NOT AVAILABLE
    To enable: install libvulkan-dev and glslc, then reinstall ggmlR
    Ubuntu/Debian: sudo apt install libvulkan-dev glslc
  [ FAIL 1 | WARN 0 | SKIP 72 | PASS 1537 ]
  
  ══ Skipped tests (72) ══════════════════════════════════════════════════════════
  • No Vulkan GPU (7): 'test-sc-seurat.R:145:3', 'test-sc-seurat.R:281:3',
    'test-sc-seurat.R:309:3', 'test-sc-seurat.R:321:3', 'test-sc-seurat.R:338:3',
    'test-sc-seurat.R:359:3', 'test-sc-seurat.R:445:3'
  • No Vulkan GPU available (7): 'test-conv2d-cpu-gpu.R:55:3',
    'test-conv2d-cpu-gpu.R:61:3', 'test-conv2d-cpu-gpu.R:71:3',
    'test-conv2d-cpu-gpu.R:78:3', 'test-conv2d-cpu-gpu.R:88:3',
    'test-conv2d-cpu-gpu.R:98:3', 'test-conv2d-cpu-gpu.R:108:3'
  • Overlapping pooling requires specific tensor layout - tested in 2D pooling
    (1): 'test-convolution-pooling.R:156:3'
  • Platform-dependent behavior (1): 'test-ggml.R:18:3'
  • Slow test (6): 'test-quants-missing.R:4:3', 'test-quants-missing.R:17:3',
    'test-quants-missing.R:30:3', 'test-quants-missing.R:43:3',
    'test-quants-missing.R:56:3', 'test-quants-missing.R:69:3'
  • Slow test - set GGMLR_SLOW_TESTS=1 to run (6): 'test-quants.R:142:3',
    'test-quants.R:168:3', 'test-quants.R:218:3', 'test-quants.R:234:3',
    'test-quants.R:250:3', 'test-quants.R:266:3'
  • Vulkan GPU not available (18): 'test-conv2d-numeric.R:68:3',
    'test-flash-attn-q4k.R:42:3', 'test-flash-attn-quants.R:44:7',
    'test-flash-attn-quants.R:44:7', 'test-flash-attn-quants.R:44:7',
    'test-flash-attn-quants.R:44:7', 'test-flash-attn-quants.R:44:7',
    'test-flash-attn-quants.R:44:7', 'test-q4k-matmul-vulkan.R:49:3',
    'test-q4k-matmul-vulkan.R:55:3', 'test-q4k-matmul-vulkan.R:62:3',
    'test-sc-normalize-sparse.R:77:3', 'test-sc-normalize-sparse.R:95:3',
    'test-sc-umap.R:87:3', 'test-sc-umap.R:106:3', 'test-sc-umap.R:179:3',
    'test-sc-umap.R:230:3', 'test-sc-umap.R:251:3'
  • Vulkan not available (15): 'test-scheduler.R:2:3', 'test-scheduler.R:28:3',
    'test-scheduler.R:55:3', 'test-scheduler.R:109:3', 'test-scheduler.R:172:3',
    'test-scheduler.R:188:3', 'test-scheduler.R:223:3', 'test-vulkan-caps.R:4:3',
    'test-vulkan-caps.R:39:3', 'test-vulkan-push-constants.R:11:3',
    'test-vulkan-push-constants.R:20:3', 'test-vulkan-push-constants.R:26:3',
    'test-vulkan-push-constants.R:36:3', 'test-vulkan-push-constants.R:88:3',
    'test-vulkan-push-constants.R:131:3'
  • Vulkan not available or no devices found (1): 'test-vulkan.R:321:5'
  • Vulkan not compiled in (1): 'test-vulkan-tensor-parallel.R:10:1'
  • ggml_flash_attn_back not implemented (TODO in ggml.c) (1):
    'test-misc-ops.R:81:3'
  • ggml_graph_reset requires a backward graph with gradients allocated (1):
    'test-graph-utils.R:44:3'
  • multi-input shared-layer predict not implemented (backend buffer not set)
    (1): 'test-functional-shared-layers.R:81:3'
  • no Vulkan GPU (4): 'test-sc-knn-gpu.R:50:3', 'test-sc-knn-gpu.R:76:3',
    'test-sc-knn-gpu.R:89:3', 'test-sc-knn-gpu.R:95:3'
  • src/ directory not found (1): 'test-headers-sync.R:17:3'
  • src/ggml.h not found (1): 'test-headers-sync.R:42:3'
  
  ══ Failed tests ════════════════════════════════════════════════════════════════
  ── Failure ('test-sc-umap.R:339:3'): op = 'umap' keeps known clusters separated (quality, not just shape) ──
  Expected `ss` < `4 * ss_uwot`.
  Actual comparison: 0.0197 >= 0.0184
  Difference: 0.0013 >= 0
  
  [ FAIL 1 | WARN 0 | SKIP 72 | PASS 1537 ]
  Error:
  ! Test failures.
  Execution halted