| Title: | Out-of-Core Arrays with Pluggable Codecs and Compute Backends |
|---|---|
| Description: | Computes on arrays that do not fit in memory. Vectors, matrices and tensors are allocated inside a memory-mapped file through R's ALTREP interface, backed by a patched copy of the 'fmalloc' allocator, so available RAM becomes a speed gradient rather than a hard limit. Two plugin registries sit on that substrate: a codec registry deciding how bytes are stored, from lossless floating-point and sparse encodings to compressed and quantized blocks, and a matrix-multiply backend registry deciding how products are computed, defaulting to whatever 'BLAS' the R build links against. Matrix products stream in bounded panels and release the pages they have consumed, so operands larger than memory still multiply. A registered backend may decline any product, in which case the default path answers it, so results never depend on which backend is selected. Also provides persistent and scratch runtimes, durable reference-based serialization, explicit vector lifecycle management, multiple runtime handles per session, and out-of-core reductions and principal components for genomics-scale matrices. |
| Authors: | Sounkou Mahamane Toure [aut, cre], Kenichi Yasukata [cph] (fmalloc), Wolfram Gloger [cph] (ptmalloc3), Free Software Foundation, Inc. [cph] (selected GNU C Library support files) |
| Maintainer: | Sounkou Mahamane Toure <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 0.1.0 |
| Built: | 2026-07-18 22:33:51 UTC |
| Source: | https://github.com/sounkou-bioinfo/Rfmalloc |
Rfmalloc provides experimental memory-mapped file allocation capabilities for R using a patched copy of the fmalloc library. The current package exposes ALTREP file-backed vector allocation for logical, integer, numeric, raw, complex, character, and list vectors with fmalloc payload storage.
open_fmallocOpen an explicit fmalloc runtime handle.
init_fmallocOpen and install a default fmalloc runtime.
create_fmalloc_vectorCreate vectors using fmalloc.
create_fmalloc_matrixCreate matrix-shaped fmalloc vectors.
create_fmalloc_arrayCreate array-shaped fmalloc vectors.
create_fmalloc_data_frameCreate data.frames from fmalloc-backed columns.
as_fmalloc_matrixConvert fmalloc vectors to matrix-shaped objects.
as_fmalloc_arrayConvert fmalloc vectors to array-shaped objects.
as_fmalloc_data_frameConvert fmalloc-backed objects to a data.frame.
fmalloc_linalgMatrix products for fmalloc-backed vectors and matrices.
fmalloc_tensorTyped and ALP-compressed tensors with panel-streamed products.
fmalloc_matmul_oocOut-of-core matrix products for matrices larger than RAM.
fmalloc_insituIn-place, by-reference mutation that bypasses copy-on-modify.
fmalloc_backendSelect a pluggable matrix-multiply backend (default R's BLAS).
fmalloc_pcaOut-of-core PCA and variance reductions for genomics (single-cell) workflows.
list_fmalloc_allocationsList persistent allocation catalog records.
diagnose_fmalloc_runtimeSummarize persistent allocation catalog state and runtime diagnostics.
fmalloc_apiInspect runtimes and vectors through the public R/native API.
cleanup_fmallocRequest cleanup of an fmalloc runtime.
ALTREP file-backed allocation for logical, integer, numeric, raw,
complex, character, and list vectors. List elements are restricted to
NULL or Rfmalloc-backed vectors from the same runtime.
Large allocations spanning multiple fmalloc chunks.
Multiple runtime handles in one R process.
Persistent and scratch runtime modes.
Reference serialization for persistent fixed-width atomic and character ALTREP vectors.
Fmalloc-backed ALTREP subset copies for vector indexing operations.
Elementwise arithmetic/comparison/logical Ops and fmalloc-backed
matrixOps products for %*%, crossprod(), and tcrossprod().
An in-file allocation catalog for persistent vectors.
A C-callable API and installed header for other packages.
Native lifetime tracking so runtime mappings outlive reachable vectors allocated from them.
Runtime and catalog diagnostics for planning recovery and operational cleanup.
R-facing API helpers for runtime/vector predicates, metadata, payload pointers, and version checks.
ALTREP-backed dispatch now covers core Ops, Summary, Math,
Math2, matrix rowSums/colSums/rowMeans/colMeans, and initial
matrixOps workflows through S3 methods for common vector/matrix
usage.
Explicit base-fallback boundaries are:
rowSums(), colSums(), rowMeans(), and colMeans() when
the input is not an exact 2D matrix or dims != 1L; these
cases now emit a warning and call the corresponding
base:: reducer.
Scalar or zero-length results from Summary, Math, and
Math2 generics (for example sum(x) returning a single
value) are returned as ordinary R scalars by design.
Matrix products use BLAS dgemm for finite numeric
operands; operands containing NA/NaN/Inf and
logical/integer/complex operands are computed by managed
native loops with base-consistent semantics.
Full operator- and method-family coverage is still incomplete for all R generics. Some advanced families may still materialize ordinary R objects in a few edge cases.
Future work includes complex zgemm and further LAPACK-backed kernels,
view-based subset representations, catalog compaction and reset tooling,
metadata storage for attributes on persisted elements, robust nested-list
reference validation, and compaction of recovery metadata.
Maintainer: Sounkou Mahamane Toure [email protected]
Other contributors:
Kenichi Yasukata (fmalloc) [copyright holder]
Wolfram Gloger (ptmalloc3) [copyright holder]
Free Software Foundation, Inc. (selected GNU C Library support files) [copyright holder]
Useful links:
Report bugs at https://github.com/sounkou-bioinfo/Rfmalloc/issues
Returns an existing vector re-typed as an array by installing array dimensions (and optional dimnames) as metadata.
as_fmalloc_array(x, dim = NULL, dimnames = NULL, copy = TRUE)as_fmalloc_array(x, dim = NULL, dimnames = NULL, copy = TRUE)
x |
A vector. |
dim |
Target dimension vector. |
dimnames |
Optional |
copy |
If TRUE (default), allocate a new fmalloc-backed array object.
If FALSE, install metadata in place on the same fmalloc ALTREP payload
without allocation (this also updates any aliases of |
An array object, backed by the same payload when copy = FALSE.
Thin convenience wrapper around data.frame().
as_fmalloc_data_frame( ..., row.names = NULL, check.names = TRUE, stringsAsFactors = FALSE )as_fmalloc_data_frame( ..., row.names = NULL, check.names = TRUE, stringsAsFactors = FALSE )
... |
Columns or objects to include in the frame. |
row.names |
Optional row names for the frame. |
check.names |
Whether to enforce syntactic column names. |
stringsAsFactors |
Deprecated: retained for compatibility. |
A data.frame containing the supplied columns.
Returns an existing vector re-typed as a matrix by installing matrix dimensions (and optional dimnames) as metadata.
as_fmalloc_matrix(x, nrow = NULL, ncol = NULL, dimnames = NULL, copy = TRUE)as_fmalloc_matrix(x, nrow = NULL, ncol = NULL, dimnames = NULL, copy = TRUE)
x |
A vector. |
nrow |
Optional target row count. |
ncol |
Optional target column count. |
dimnames |
Optional |
copy |
If TRUE (default), allocate a new fmalloc-backed matrix object.
If FALSE, install metadata in place on the same fmalloc ALTREP payload
without allocation (this also updates any aliases of |
A matrix object, backed by the same payload when copy = FALSE.
Requests cleanup of an fmalloc runtime. If vectors allocated from the runtime are still reachable, the native mapping is kept alive until those vectors are garbage-collected.
cleanup_fmalloc(runtime = NULL)cleanup_fmalloc(runtime = NULL)
runtime |
Optional runtime handle returned by |
NULL (invisibly)
## Not run: init_fmalloc("data.bin") v <- create_fmalloc_vector("integer", 100) rm(v) gc() cleanup_fmalloc() ## End(Not run)## Not run: init_fmalloc("data.bin") v <- create_fmalloc_vector("integer", 100) rm(v) gc() cleanup_fmalloc() ## End(Not run)
Creates an fmalloc-backed ALTREP array in a single step by allocating vector storage and installing array dimensions (and optional dimnames).
create_fmalloc_array( type = "integer", dim, dimnames = NULL, runtime = NULL, zero_initialize = TRUE )create_fmalloc_array( type = "integer", dim, dimnames = NULL, runtime = NULL, zero_initialize = TRUE )
type |
Character string specifying the vector type. Supported values are
the same as for |
dim |
Integer dimension vector. |
dimnames |
Optional |
runtime |
Optional runtime handle returned by |
zero_initialize |
Logical scalar passed through to payload allocation. See
|
An fmalloc-backed ALTREP array.
## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) a <- create_fmalloc_array("numeric", dim = c(2L, 3L), runtime = rt) cleanup_fmalloc(rt) ## End(Not run)## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) a <- create_fmalloc_array("numeric", dim = c(2L, 3L), runtime = rt) cleanup_fmalloc(rt) ## End(Not run)
Thin constructor wrapper around data.frame() that keeps fmalloc vectors as
column payloads.
create_fmalloc_data_frame( ..., row.names = NULL, check.names = TRUE, stringsAsFactors = FALSE )create_fmalloc_data_frame( ..., row.names = NULL, check.names = TRUE, stringsAsFactors = FALSE )
... |
Columns to include in the frame. |
row.names |
Optional row names for the frame. |
check.names |
Whether to enforce syntactic column names. |
stringsAsFactors |
Deprecated: retained for compatibility. |
A data.frame with the provided columns.
## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) x <- create_fmalloc_vector("integer", 3, runtime = rt) y <- create_fmalloc_vector("character", 3, runtime = rt) x[] <- 1:3 y[] <- c("a", "b", "c") df <- create_fmalloc_data_frame(x = x, y = y) cleanup_fmalloc(rt) ## End(Not run)## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) x <- create_fmalloc_vector("integer", 3, runtime = rt) y <- create_fmalloc_vector("character", 3, runtime = rt) x[] <- 1:3 y[] <- c("a", "b", "c") df <- create_fmalloc_data_frame(x = x, y = y) cleanup_fmalloc(rt) ## End(Not run)
Creates an fmalloc-backed ALTREP matrix in a single step by allocating vector storage and installing matrix dimensions (and optional dimnames).
create_fmalloc_matrix( type = "integer", nrow, ncol, dimnames = NULL, runtime = NULL, zero_initialize = TRUE )create_fmalloc_matrix( type = "integer", nrow, ncol, dimnames = NULL, runtime = NULL, zero_initialize = TRUE )
type |
Character string specifying the vector type. Supported values are
the same as for |
nrow |
Integer number of rows. |
ncol |
Integer number of columns. |
dimnames |
Optional |
runtime |
Optional runtime handle returned by |
zero_initialize |
Logical scalar passed through to payload allocation. See
|
An fmalloc-backed ALTREP matrix object.
## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) m <- create_fmalloc_matrix("integer", nrow = 2, ncol = 3, runtime = rt) cleanup_fmalloc(rt) ## End(Not run)## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) m <- create_fmalloc_matrix("integer", nrow = 2, ncol = 3, runtime = rt) cleanup_fmalloc(rt) ## End(Not run)
Creates an ALTREP vector using a file-backed fmalloc runtime. The returned
object is ALTREP from creation time. Fixed-width atomic payload bytes are
allocated directly with fmalloc, and ALTREP duplication and vector subsetting
keep copy-on-write copies fmalloc-backed without using R's non-API
Rf_allocVector3() path.
create_fmalloc_vector( type = "integer", length, runtime = NULL, zero_initialize = TRUE )create_fmalloc_vector( type = "integer", length, runtime = NULL, zero_initialize = TRUE )
type |
Character string specifying the vector type. Supported values are
|
length |
Non-negative integer-valued length of the vector to
create. Supports exact values up to |
runtime |
Optional runtime handle returned by |
zero_initialize |
Logical scalar. If TRUE (default), newly allocated payload bytes are zero-initialized. Set FALSE to skip initialization for faster large allocations when you will fully initialize values yourself. |
A vector of the specified type and length, allocated using fmalloc.
## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) v <- create_fmalloc_vector("integer", 1000, runtime = rt) cleanup_fmalloc(rt) ## End(Not run)## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) v <- create_fmalloc_vector("integer", 1000, runtime = rt) cleanup_fmalloc(rt) ## End(Not run)
Releases runtime bookkeeping for a single fmalloc ALTREP vector immediately. In
scratch mode, payload memory is immediately reclaimed. In persistent mode, the
vector payload is retained by default so existing on-disk state remains
durable; optional unsafe = TRUE reclaims payload memory and marks metadata
as non-recoverable.
destroy_fmalloc_vector(x, unsafe = FALSE)destroy_fmalloc_vector(x, unsafe = FALSE)
x |
Fmalloc ALTREP vector to destroy. |
unsafe |
Whether to physically free persistent payload bytes. Unsafe destroy is intended for short-lived scratch-like cleanup and will mark the catalog entry as non-recoverable. |
Explicit destroy fails when a vector is still referenced by another fmalloc list vector as a child.
Logical value indicating whether a live vector was destroyed.
## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin"), mode = "persistent") v <- create_fmalloc_vector("integer", 10, runtime = rt) destroy_fmalloc_vector(v) ## End(Not run)## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin"), mode = "persistent") v <- create_fmalloc_vector("integer", 10, runtime = rt) destroy_fmalloc_vector(v) ## End(Not run)
Returns diagnostic metadata for an open runtime handle, including lightweight runtime attributes, the current allocation catalog, and a catalog-level summary useful for estimating reclaimable/fragmented payload regions.
diagnose_fmalloc_runtime(runtime = NULL)diagnose_fmalloc_runtime(runtime = NULL)
runtime |
Optional runtime handle returned by |
A named list with three components:
runtime: runtime metadata such as file path, UUID, mode, catalog
counters, live vectors, and reference state;
catalog: the full allocation catalog returned by
list_fmalloc_allocations();
summary: a compact set of computed diagnostics and an explicit compaction
status note.
## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin"), mode = "persistent") x <- create_fmalloc_vector("integer", 4, runtime = rt) y <- create_fmalloc_vector("logical", 2, runtime = rt) diagnose_fmalloc_runtime(rt) cleanup_fmalloc(rt) ## End(Not run)## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin"), mode = "persistent") x <- create_fmalloc_vector("integer", 4, runtime = rt) y <- create_fmalloc_vector("logical", 2, runtime = rt) diagnose_fmalloc_runtime(rt) cleanup_fmalloc(rt) ## End(Not run)
Introspection and lifecycle helpers for fmalloc runtime handles and fmalloc ALTREP vectors. These functions are thin R wrappers around the package's native registered routines and mirror the installed C-callable API.
fmalloc_default_runtime() is_fmalloc_runtime(x) is_fmalloc_vector(x) fmalloc_runtime(x) fmalloc_runtime_info(runtime = NULL) fmalloc_vector_info(x) fmalloc_vector_type(x, label = TRUE) fmalloc_vector_length(x) fmalloc_vector_payload_ptr(x)fmalloc_default_runtime() is_fmalloc_runtime(x) is_fmalloc_vector(x) fmalloc_runtime(x) fmalloc_runtime_info(runtime = NULL) fmalloc_vector_info(x) fmalloc_vector_type(x, label = TRUE) fmalloc_vector_length(x) fmalloc_vector_payload_ptr(x)
x |
An object to test or inspect. For vector helpers, |
runtime |
Optional runtime handle returned by |
label |
Logical scalar. If TRUE, return an R type label such as
|
Depends on the helper: logical predicates, runtime external pointers, metadata lists, or payload external pointers.
Rfmalloc's matrix-product kernels (%*%, crossprod(), tcrossprod(),
the out-of-core and typed-tensor products) dispatch their dgemm calls
through a selectable backend. By default this is R's BLAS; downstream
packages can register an alternative (for example a GPU cuBLAS kernel or an
out-of-core-aware GEMM) through the Rfmalloc_register_matmul_backend
C-callable and select it here. Selection is Rfmalloc-scoped: base R's %*%
is unaffected.
fmalloc_matmul_backend(name = NULL) fmalloc_matmul_backends()fmalloc_matmul_backend(name = NULL) fmalloc_matmul_backends()
name |
Backend name to select. |
A registered backend may decline a given call (returning non-zero), in which case Rfmalloc falls back to R's BLAS for that product.
fmalloc_matmul_backend() returns the active backend name;
fmalloc_matmul_backends() returns the registered backend names (BLAS is
always available and not listed).
fmalloc_matmul_backend() # "blas" by default fmalloc_matmul_backends() # names registered by other packagesfmalloc_matmul_backend() # "blas" by default fmalloc_matmul_backends() # names registered by other packages
Encodes an integer dosage matrix (0, 1, 2, NA) into PLINK 1 .bed
bit packing and stores it in fmalloc-backed, memory-mapped storage as an
fmalloc_tensor of codec "bed". Samples are rows, variants are columns,
matching .bed's SNP-major layout: a variant is a contiguous column.
fmalloc_bed(x, runtime = NULL)fmalloc_bed(x, runtime = NULL)
x |
An integer matrix of dosages of the first allele: |
runtime |
Runtime handle from |
Two bits per genotype. That is four times tighter than a one-byte-per-genotype file-backed matrix, and thirty-two times tighter than the doubles it decodes to. Products against the tensor decode bounded column panels on the fly and contract them with BLAS, so the genotypes are never materialized as doubles.
Missing genotypes decode to NA_real_, which the matrix-product path does not
impute; standardize or impute before multiplying.
An fmalloc_tensor of dtype "bed" with dim(x).
create_fmalloc_tensor(), fmalloc_tensor_materialize()
rt <- open_fmalloc(tempfile(), size_gb = 0.1) g <- matrix(c(0L, 1L, 2L, NA_integer_, 2L, 0L), nrow = 3, ncol = 2) tn <- fmalloc_bed(g, runtime = rt) fmalloc_tensor_materialize(tn) cleanup_fmalloc(rt)rt <- open_fmalloc(tempfile(), size_gb = 0.1) g <- matrix(c(0L, 1L, 2L, NA_integer_, 2L, 0L), nrow = 3, ncol = 2) tn <- fmalloc_bed(g, runtime = rt) fmalloc_tensor_materialize(tn) cleanup_fmalloc(rt)
Computes each variant's mean and standard deviation in one streaming pass and
stores them in the tensor, so that every subsequent decode returns
standardized, mean-imputed values: missing genotypes decode to the variant
mean, hence to 0 after centering. Products against the standardized tensor
are therefore centered-and-scaled with no genotype ever materialized as a
double and no second pass, which is what a genotype PCA or GRM needs.
fmalloc_bed_standardize(x, scale = c("sd", "binomial"), runtime = NULL)fmalloc_bed_standardize(x, scale = c("sd", "binomial"), runtime = NULL)
x |
A |
scale |
One of |
runtime |
Runtime handle from |
A "bed" fmalloc_tensor whose decode is standardized. Monomorphic
variants (zero variance) decode to 0.
rt <- open_fmalloc(tempfile(), size_gb = 0.1) g <- matrix(c(0L, 1L, 2L, 1L, 2L, 0L), nrow = 3, ncol = 2) tn <- fmalloc_bed_standardize(fmalloc_bed(g, runtime = rt), runtime = rt) round(fmalloc_tensor_materialize(tn), 3) cleanup_fmalloc(rt)rt <- open_fmalloc(tempfile(), size_gb = 0.1) g <- matrix(c(0L, 1L, 2L, 1L, 2L, 0L), nrow = 3, ncol = 2) tn <- fmalloc_bed_standardize(fmalloc_bed(g, runtime = rt), runtime = rt) round(fmalloc_tensor_materialize(tn), 3) cleanup_fmalloc(rt)
Per-column (fmalloc_colVars) or per-row (fmalloc_rowVars) sample
variances, for highly-variable-feature selection and QC. Computed from the
fmalloc reduction kernels (colMeans/rowMeans of X and X^2), so the
result stays out-of-core-friendly and never materializes an ordinary R copy
of X.
fmalloc_colVars(X) fmalloc_rowVars(X)fmalloc_colVars(X) fmalloc_rowVars(X)
X |
An fmalloc-backed numeric matrix. |
A numeric vector of length ncol(X) (fmalloc_colVars) or
nrow(X) (fmalloc_rowVars).
Encodes a numeric matrix of dosages (values in [0, 2], NA allowed) into
fixed-point single-byte storage as an fmalloc_tensor of codec "dosage",
the continuous sibling of fmalloc_bed(). Samples are rows, variants are
columns. A dosage d is stored as round(d * 127) (0..254), with 255
reserved for missing, so the resolution is 2 / 254. This is lossy by
design: it is a storage codec, eight times tighter than the doubles it decodes
to, and it is the target a PLINK 2 .pgen dosage import re-encodes into.
fmalloc_dosage(x, runtime = NULL)fmalloc_dosage(x, runtime = NULL)
x |
A numeric matrix of dosages in |
runtime |
Runtime handle from |
Products against the tensor decode bounded column panels and contract them with BLAS, so dosages are never materialized as doubles.
An fmalloc_tensor of dtype "dosage" with dim(x).
fmalloc_bed(), fmalloc_dosage_standardize()
rt <- open_fmalloc(tempfile(), size_gb = 0.1) d <- matrix(c(0, 0.3, 1.7, NA, 2, 0.9), nrow = 3, ncol = 2) tn <- fmalloc_dosage(d, runtime = rt) round(fmalloc_tensor_materialize(tn), 2) cleanup_fmalloc(rt)rt <- open_fmalloc(tempfile(), size_gb = 0.1) d <- matrix(c(0, 0.3, 1.7, NA, 2, 0.9), nrow = 3, ncol = 2) tn <- fmalloc_dosage(d, runtime = rt) round(fmalloc_tensor_materialize(tn), 2) cleanup_fmalloc(rt)
Computes each variant's mean and standard deviation in one streaming pass and
stores them in the tensor, so that every subsequent decode returns
standardized, mean-imputed values: missing dosages decode to the variant mean,
hence to 0 after centering. Products against the standardized tensor are
therefore centered-and-scaled with no dosage ever materialized as a double and
no second pass, which is what a dosage-based PCA or GRM needs. The mirror of
fmalloc_bed_standardize() for continuous dosages.
fmalloc_dosage_standardize(x, scale = c("sd", "binomial"), runtime = NULL)fmalloc_dosage_standardize(x, scale = c("sd", "binomial"), runtime = NULL)
x |
A |
scale |
One of |
runtime |
Runtime handle from |
A "dosage" fmalloc_tensor whose decode is standardized.
Monomorphic variants (zero variance) decode to 0.
fmalloc_dosage(), fmalloc_bed_standardize()
rt <- open_fmalloc(tempfile(), size_gb = 0.1) d <- matrix(c(0, 0.3, 1.7, 2, 1.1, 0.9), nrow = 3, ncol = 2) tn <- fmalloc_dosage_standardize(fmalloc_dosage(d, runtime = rt), runtime = rt) round(fmalloc_tensor_materialize(tn), 3) cleanup_fmalloc(rt)rt <- open_fmalloc(tempfile(), size_gb = 0.1) d <- matrix(c(0, 0.3, 1.7, 2, 1.1, 0.9), nrow = 3, ncol = 2) tn <- fmalloc_dosage_standardize(fmalloc_dosage(d, runtime = rt), runtime = rt) round(fmalloc_tensor_materialize(tn), 3) cleanup_fmalloc(rt)
Decodes an fmalloc_haplotypes() store back into an L x N matrix of
0L/1L integer calls, variants in rows and haplotypes in columns. The
result is itself fmalloc-backed (file-mapped storage, not an R-heap copy):
this is the same "decode into typed storage, not into a plain R object"
discipline fmalloc_tensor_materialize() uses for the matmul codecs.
fmalloc_hap_materialize(x, runtime = NULL)fmalloc_hap_materialize(x, runtime = NULL)
x |
An |
runtime |
Runtime handle from |
This adapter exists for consumers that require a conventional R matrix.
Native HMM consumers should instead resolve Rfmalloc_haplotypes_data()
from the installed C header and borrow the aligned locus rows directly.
kalis::CacheHaplotypes() can consume the adapted matrix, but a kalis
packed-buffer method can use the direct view without either expansion or
repacking.
An fmalloc-backed integer matrix of 0L/1L calls with dim(x).
rt <- open_fmalloc(tempfile(), size_gb = 0.1) h <- matrix(c(0L, 1L, 1L, 0L, 1L, 0L), nrow = 3, ncol = 2) hap <- fmalloc_haplotypes(h, runtime = rt) identical(fmalloc_hap_materialize(hap, runtime = rt)[], h) cleanup_fmalloc(rt)rt <- open_fmalloc(tempfile(), size_gb = 0.1) h <- matrix(c(0L, 1L, 1L, 0L, 1L, 0L), nrow = 3, ncol = 2) hap <- fmalloc_haplotypes(h, runtime = rt) identical(fmalloc_hap_materialize(hap, runtime = rt)[], h) cleanup_fmalloc(rt)
Encodes an L x N matrix of phased haplotype calls (0/1, variants in
rows, haplotypes in columns - the convention kalis::CacheHaplotypes()
expects for a matrix source) into fmalloc-backed, memory-mapped storage at
one bit per call. The file layout is locus-major: all haplotypes at one
variant form a contiguous bit row, and each row begins on a 64-byte
boundary. This is the layout kalis builds internally and the access pattern
Li and Stephens forward/backward kernels consume.
fmalloc_haplotypes(x, runtime = NULL) create_fmalloc_haplotypes(payload, dim) ## S3 method for class 'fmalloc_haplotypes' dim(x) ## S3 method for class 'fmalloc_haplotypes' print(x, ...)fmalloc_haplotypes(x, runtime = NULL) create_fmalloc_haplotypes(payload, dim) ## S3 method for class 'fmalloc_haplotypes' dim(x) ## S3 method for class 'fmalloc_haplotypes' print(x, ...)
x |
An integer, numeric, or logical matrix of haplotype calls, values
|
runtime |
Runtime handle from |
payload |
An fmalloc raw vector created by the native haplotype buffer writer. |
dim |
Integer dimensions |
... |
Unused. |
This is a SIBLING interface to the matmul fmalloc_tensor codec ABI, not
an instance of it: haplotype hidden-Markov methods (Li and Stephens local-
ancestry inference) are not linear algebra, so fmalloc_haplotypes()
never registers a tensor codec and the resulting object never
participates in %*%. It shares the same fmalloc storage substrate as
fmalloc_bed() and the typed tensors, with its own encode/decode pair.
The packed body is one bit per call, asymptotically thirty-two times tighter
than an integer 0/1 matrix and sixty-four times tighter than doubles.
Each locus is padded to a 64-byte boundary so an HMM kernel can load donor
words without repacking; that padding is visible for very small panels.
An fmalloc_haplotypes object with dim(x).
fmalloc_hap_materialize() to decode back to a 0/1 matrix.
rt <- open_fmalloc(tempfile(), size_gb = 0.1) h <- matrix(c(0L, 1L, 1L, 0L, 1L, 0L), nrow = 3, ncol = 2) hap <- fmalloc_haplotypes(h, runtime = rt) fmalloc_hap_materialize(hap, runtime = rt) cleanup_fmalloc(rt)rt <- open_fmalloc(tempfile(), size_gb = 0.1) h <- matrix(c(0L, 1L, 1L, 0L, 1L, 0L), nrow = 3, ncol = 2) hap <- fmalloc_haplotypes(h, runtime = rt) fmalloc_hap_materialize(hap, runtime = rt) cleanup_fmalloc(rt)
Modify an fmalloc-backed atomic vector in place, writing straight through
the backing store and deliberately bypassing R's copy-on-modify.
fmalloc_set()/fmalloc_fill() are the by-reference analogue of
x[i] <- value / x[] <- value; fmalloc_add()/fmalloc_sub()/
fmalloc_mul()/fmalloc_div() compute x <- x op y in place (the
accumulate-into-x pattern iterative algorithms need), for numeric vectors.
fmalloc_set(x, i, value) fmalloc_fill(x, value) fmalloc_add(x, y) fmalloc_sub(x, y) fmalloc_mul(x, y) fmalloc_div(x, y)fmalloc_set(x, i, value) fmalloc_fill(x, value) fmalloc_add(x, y) fmalloc_sub(x, y) fmalloc_mul(x, y) fmalloc_div(x, y)
x |
An fmalloc-backed atomic vector (or matrix/array). |
i |
Positive integer (1-based) linear indices to assign. |
value |
For |
y |
For the arithmetic ops, a numeric scalar (recycled) or a vector of
|
On an unshared fmalloc vector, an ordinary x[i] <- value already writes
in place through the ALTREP data pointer - no copy - because the file-backed
storage is exposed directly and this package controls duplication. The copy
that hurts happens when the vector is shared (y <- x): R then duplicates
the whole payload to preserve value semantics before modifying, which is
catastrophic for a larger-than-RAM or persistent vector. These functions
mutate by reference regardless of sharing - they never copy, updating the
durable store directly and returning the same object invisibly.
x, invisibly, mutated in place.
Because there is no copy, all bindings to the same fmalloc vector observe the
change. After y <- x; fmalloc_set(x, 1, 5), y[1] is also 5 - x and
y name the same backing store, whereas ordinary x[1] <- 5 would copy x
(leaving y untouched). This breaks R's usual value semantics by design;
for a persistent runtime it is a feature (the durable data is updated). For
this reason mutation is only ever done through these explicitly-named
functions, never a silent [<- method.
Supported for fixed-width atomic vectors (logical, integer, numeric, complex, raw). Indices are 1-based linear positions (column-major for matrices/arrays).
## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) x <- create_fmalloc_vector("numeric", 5, runtime = rt) fmalloc_fill(x, 0) # x[] <- 0, no copy fmalloc_set(x, c(1, 3), 9) # x[c(1,3)] <- 9, no copy cleanup_fmalloc(rt) ## End(Not run)## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) x <- create_fmalloc_vector("numeric", 5, runtime = rt) fmalloc_fill(x, 0) # x[] <- 0, no copy fmalloc_set(x, c(1, 3), 9) # x[c(1,3)] <- 9, no copy cleanup_fmalloc(rt) ## End(Not run)
Stores a banded symmetric linkage-disequilibrium (Pearson correlation)
matrix in fmalloc-backed, memory-mapped storage as quantized integers. This
is a SIBLING interface to the matmul fmalloc_tensor codec ABI, not an
instance of it (like fmalloc_haplotypes()): an LD matrix is read one
column's neighbours at a time by a Gibbs sampler or a ridge solve
(LDpred2), never multiplied as a decoded dense p x p double matrix, so
the store is a typed accessor with its own read API and never participates
in %*%.
fmalloc_ld(i, j, x, n_variants, bits = 8L, window = 0L, runtime = NULL) ## S3 method for class 'fmalloc_ld' dim(x) ## S3 method for class 'fmalloc_ld' print(x, ...)fmalloc_ld(i, j, x, n_variants, bits = 8L, window = 0L, runtime = NULL) ## S3 method for class 'fmalloc_ld' dim(x) ## S3 method for class 'fmalloc_ld' print(x, ...)
i, j
|
Integer vectors of 1-based row/column indices of the stored
correlations (COO triplets). The band of column |
x |
An |
n_variants |
Number of variants (the matrix is |
bits |
Quantization width, |
window |
Optional integer recording the build window (informational,
stored in the header); |
runtime |
Runtime handle from |
... |
Unused. |
The variants are assumed position-sorted, so each column j's in-window
neighbours form a contiguous index range [lo_j, hi_j]. The store keeps the
full symmetric band per column (both r[j, k] and r[k, j]), the diagonal
is 1, and no explicit neighbour indices are stored - the row of a column's
t-th stored value is lo_j + t. A per-column offset table gives O(1)
random access to any column's neighbour run and a cache-friendly banded
matvec.
Correlations are quantized to bits-wide integers: r in [-1, 1] becomes
round(r * S) clamped to [-S, S], decoded back as q / S, with S = 127
for bits = 8 (int8, resolution ~1/127) or S = 32767 for bits = 16
(int16, resolution ~3e-5).
fmalloc_ld() builds a store from (i, j, x) correlation triplets;
RfmallocStatgen's statgen_snp_cor() builds one directly from a genotype
tensor. Read it with ld_ncol(), ld_pair() and ld_col().
An fmalloc_ld object (a compressed, mmap-backed banded LD matrix).
ld_ncol(), ld_pair(), ld_col()
rt <- open_fmalloc(tempfile(), size_gb = 0.1) ## a 4-variant tridiagonal correlation matrix i <- c(1, 2, 1, 2, 3, 2, 3, 4, 3, 4) j <- c(1, 1, 2, 2, 2, 3, 3, 3, 4, 4) x <- c(1, 0.5, 0.5, 1, 0.3, 0.3, 1, -0.2, -0.2, 1) corr <- fmalloc_ld(i, j, x, n_variants = 4, runtime = rt) ld_pair(corr, 1, 2) ld_col(corr, 2) cleanup_fmalloc(rt)rt <- open_fmalloc(tempfile(), size_gb = 0.1) ## a 4-variant tridiagonal correlation matrix i <- c(1, 2, 1, 2, 3, 2, 3, 4, 3, 4) j <- c(1, 1, 2, 2, 2, 3, 3, 3, 4, 4) x <- c(1, 0.5, 0.5, 1, 0.3, 0.3, 1, -0.2, -0.2, 1) corr <- fmalloc_ld(i, j, x, n_variants = 4, runtime = rt) ld_pair(corr, 1, 2) ld_col(corr, 2) cleanup_fmalloc(rt)
Provides fmalloc-aware matrix products for %*%, crossprod(), and
tcrossprod(). Results are allocated in the runtime of the first fmalloc
operand and returned as fmalloc-backed matrices.
## S3 method for class 'fmalloc' x %*% y ## S3 method for class 'fmalloc' crossprod(x, y = NULL, ...) ## S3 method for class 'fmalloc' tcrossprod(x, y = NULL, ...) ## S3 method for class 'fmalloc' matrixOps(x, y)## S3 method for class 'fmalloc' x %*% y ## S3 method for class 'fmalloc' crossprod(x, y = NULL, ...) ## S3 method for class 'fmalloc' tcrossprod(x, y = NULL, ...) ## S3 method for class 'fmalloc' matrixOps(x, y)
x, y
|
Numeric, logical, or complex vectors/matrices. At least one operand must be fmalloc-backed for these methods to dispatch. |
... |
Unused. |
These methods use native C kernels to keep computations in package-managed fmalloc storage while preserving base R behavior for matrix products.
An fmalloc-backed numeric or complex matrix.
Computes A %*% x where A is a large column-major fmalloc-backed double
matrix living in the backing file and x is an ordinary numeric vector or
matrix. A is consumed one contiguous column tile at a time: each tile is
multiplied into the accumulator with BLAS dgemm, then its pages are
released with madvise(MADV_DONTNEED), so the resident set stays bounded by
tile_mb rather than the size of A. This lets A exceed physical RAM.
fmalloc_matmul_ooc(A, x, tile_mb = 256) fmalloc_crossprod_ooc(A, tile_mb = 256) fmalloc_tcrossprod_ooc(A, tile_mb = 256)fmalloc_matmul_ooc(A, x, tile_mb = 256) fmalloc_crossprod_ooc(A, tile_mb = 256) fmalloc_tcrossprod_ooc(A, tile_mb = 256)
A |
An fmalloc-backed double matrix ( |
x |
A numeric vector of length |
tile_mb |
Target resident megabytes per column tile of |
The backing storage is advised MADV_SEQUENTIAL so the kernel reads ahead.
The result is an fmalloc-backed matrix allocated in A's runtime.
%*% on an fmalloc matrix calls this automatically when the left operand's
payload reaches getOption("Rfmalloc.ooc_threshold_gb") (default: half of
physical RAM), using getOption("Rfmalloc.ooc_tile_mb", 256) for the tile
size; smaller products keep the in-core BLAS path. crossprod()/
tcrossprod() are not auto-routed (their output can itself exceed RAM).
An fmalloc-backed double matrix (m x k), equal to A %*% x.
## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin"), size_gb = 8) A <- create_fmalloc_matrix("numeric", nrow = 100000, ncol = 20000, runtime = rt) # ... fill A ... y <- fmalloc_matmul_ooc(A, rnorm(20000), tile_mb = 128) cleanup_fmalloc(rt) ## End(Not run)## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin"), size_gb = 8) A <- create_fmalloc_matrix("numeric", nrow = 100000, ncol = 20000, runtime = rt) # ... fill A ... y <- fmalloc_matmul_ooc(A, rnorm(20000), tile_mb = 128) cleanup_fmalloc(rt) ## End(Not run)
Principal component analysis of a large, file-backed fmalloc matrix,
computed from the Gram matrix: G = X'X via out-of-core crossprod(), a
truncated eigendecomposition of the (small) n x n G, and the scores
X V via out-of-core %*%. Every heavy step - the Gram matrix and the
projection - dispatches through the pluggable matrix-multiply backend (see
fmalloc_backend), so the same call runs on CPU BLAS today and on a
registered GPU backend unchanged. X may exceed RAM: the Gram matrix and
projection stream column tiles with a bounded resident set.
fmalloc_pca(X, k = 10L, center = TRUE)fmalloc_pca(X, k = 10L, center = TRUE)
X |
An fmalloc-backed numeric matrix ( |
k |
Number of principal components to return. |
center |
Logical; center the columns (applied implicitly as a rank-1
correction to the Gram matrix and scores, so |
This is efficient when the number of features n is moderate (e.g. after
highly-variable-feature selection with fmalloc_colVars()); the n x n
Gram matrix and its eigendecomposition are formed in memory.
A list with prcomp-like elements: sdev (component standard
deviations), rotation (n x k loadings), x (m x k scores), and
center (the column means, or FALSE).
fmalloc_colVars(), fmalloc_backend
These S3 methods preserve current fmalloc behavior for matrix summary/reduction operations while returning ordinary R vectors for small results.
rowSums(x, na.rm = FALSE, dims = 1L) colSums(x, na.rm = FALSE, dims = 1L) rowMeans(x, na.rm = FALSE, dims = 1L) colMeans(x, na.rm = FALSE, dims = 1L)rowSums(x, na.rm = FALSE, dims = 1L) colSums(x, na.rm = FALSE, dims = 1L) rowMeans(x, na.rm = FALSE, dims = 1L) colMeans(x, na.rm = FALSE, dims = 1L)
x |
A matrix-like object. |
na.rm |
Logical scalar controlling NA removal. |
dims |
Numeric scalar for dimensions. |
These implementations keep managed execution for 2D fmalloc matrices with
dims = 1L. For unsupported shapes or dims values (for example,
non-2D arrays or dims != 1L), the methods warn and delegate to the base R
implementations (base::rowSums, base::colSums, base::rowMeans, and
base::colMeans).
The reduction result, as either an ordinary R object or a
fmalloc vector when result length exceeds
getOption("Rfmalloc.reduce_result_length", 1e6).
Applies a best-effort access hint to an fmalloc tensor payload or borrowed
storage view. "sequential" asks the pager to read ahead, "willneed"
asks it to prefetch, and "dontneed" releases fully covered pages after a
phase has consumed them. Unsupported platforms treat the hint as a no-op.
The function never changes the tensor bytes.
fmalloc_storage_advise( x, advice = c("sequential", "willneed", "dontneed"), offset = 0, nbytes = NULL )fmalloc_storage_advise( x, advice = c("sequential", "willneed", "dontneed"), offset = 0, nbytes = NULL )
x |
An |
advice |
One of |
offset |
Byte offset into the payload. |
nbytes |
Number of bytes to advise. |
This is deliberately a storage primitive rather than an LLM policy. A graph scheduler, HMM, or out-of-core matrix algorithm can express its own access phases over the same mapped spans.
x, invisibly.
Writes to an fmalloc runtime (including in-place mutations via
fmalloc_set() and friends) land in the OS page cache of the MAP_SHARED
backing file. They survive a normal process exit, but until the kernel
writes dirty pages back - which it does asynchronously - a crash or power
loss can lose unsynced data, with no atomicity. fmalloc_sync() forces the
durability barrier with msync() (and fsync()), so persistent data is on
disk when it returns.
fmalloc_sync(runtime = NULL, wait = TRUE)fmalloc_sync(runtime = NULL, wait = TRUE)
runtime |
Runtime handle from |
wait |
If |
This matters only for persistent runtimes where durability across an
unclean shutdown is required; scratch runtimes are ephemeral by design.
On platforms without msync (e.g. the Windows/Rtools toolchain) this is a
no-op and returns 0, relying on OS writeback.
The number of bytes flushed, invisibly.
A typed fmalloc tensor is an fmalloc raw vector holding a matrix payload in
a foreign element encoding ("f32", "f16", "bf16", or any codec
registered by another package through the Rfmalloc_register_tensor_codec
C-callable), plus dimension and dtype tags. Matrix products against dense
double operands decode the payload in bounded, block-aligned column panels
that are streamed through BLAS dgemm, so the double representation of the
full tensor is never materialized at once.
fmalloc_tensor_codecs() create_fmalloc_tensor(payload, dtype, dim) as_fmalloc_tensor(x, dtype = "alp", runtime = NULL) fmalloc_tensor_dtype(x) fmalloc_tensor_materialize(x) ## S3 method for class 'fmalloc_tensor' dim(x) ## S3 method for class 'fmalloc_tensor' print(x, ...) ## S3 method for class 'fmalloc_tensor' x %*% y ## S3 method for class 'fmalloc_tensor' matrixOps(x, y) ## S3 method for class 'fmalloc_tensor' crossprod(x, y = NULL, ...) ## S3 method for class 'fmalloc_tensor' tcrossprod(x, y = NULL, ...)fmalloc_tensor_codecs() create_fmalloc_tensor(payload, dtype, dim) as_fmalloc_tensor(x, dtype = "alp", runtime = NULL) fmalloc_tensor_dtype(x) fmalloc_tensor_materialize(x) ## S3 method for class 'fmalloc_tensor' dim(x) ## S3 method for class 'fmalloc_tensor' print(x, ...) ## S3 method for class 'fmalloc_tensor' x %*% y ## S3 method for class 'fmalloc_tensor' matrixOps(x, y) ## S3 method for class 'fmalloc_tensor' crossprod(x, y = NULL, ...) ## S3 method for class 'fmalloc_tensor' tcrossprod(x, y = NULL, ...)
payload |
An fmalloc raw vector holding the encoded payload in column-major order (first dimension fastest). |
dtype |
Codec name, e.g. |
dim |
Integer dimensions of the decoded tensor (any rank). Storage and
|
x |
An |
runtime |
Optional runtime handle from |
... |
Unused. |
y |
The other matrix product operand. |
create_fmalloc_tensor() tags an existing fmalloc raw payload.
as_fmalloc_tensor() compresses a double vector/matrix into fmalloc
storage with dtype = "sparse" (stores only the nonzeros of each chunk, for
mostly-zero data such as single-cell counts) or the builtin, lossless
"alp" codec (Afroozeh et al.,
doi:10.1145/3626717; scalar core adapted from the MIT-licensed zap
implementation, see inst/COPYRIGHTS), storing decimal-scaled doubles as
bit-packed integers in independently decodable 1024-value chunks with
exact-value patches and a raw escape hatch for incompressible chunks.
fmalloc_tensor_materialize() decodes the whole tensor into an fmalloc
double matrix. fmalloc_tensor_codecs() lists registered codec names, and
fmalloc_tensor_dtype() returns a tensor's dtype tag.
When a tensor's compressed payload reaches
getOption("Rfmalloc.ooc_threshold_gb"), its matrix products stream
out-of-core: each column panel's source pages are released after decoding
(for fixed-geometry codecs), so a tensor whose decoded f64 form exceeds
RAM multiplies with a bounded resident set.
create_fmalloc_tensor() returns an fmalloc_tensor.
fmalloc_tensor_materialize() and the matrix products return
fmalloc-backed double matrices. fmalloc_tensor_codecs() returns a
character vector.
Compatibility wrapper that opens an fmalloc runtime and installs it as the
package default runtime used by create_fmalloc_vector() when no explicit
runtime is supplied.
init_fmalloc(filepath, size_gb = NULL, mode = c("persistent", "scratch"))init_fmalloc(filepath, size_gb = NULL, mode = c("persistent", "scratch"))
filepath |
Character string specifying the file path for fmalloc data. |
size_gb |
Numeric value specifying the size of the backing file in GB (optional). If not specified, uses the package default size for new files or the existing file size. |
mode |
Runtime mode. |
For new code, prefer open_fmalloc() and pass the returned runtime handle to
create_fmalloc_vector().
Logical indicating whether the file was newly initialized.
## Not run: alloc_file <- tempfile(fileext = ".bin") init_fmalloc(alloc_file) v <- create_fmalloc_vector("integer", 1000) cleanup_fmalloc() unlink(alloc_file) ## End(Not run)## Not run: alloc_file <- tempfile(fileext = ".bin") init_fmalloc(alloc_file) v <- create_fmalloc_vector("integer", 1000) cleanup_fmalloc() unlink(alloc_file) ## End(Not run)
Returns column j's contiguous band of correlations: the decoded values for
rows lo..hi (the window around variant j), where hi - lo + 1 is the
band length. This is the O(1) per-column access the LDpred2 banded matvec
rides.
ld_col(store, j)ld_col(store, j)
store |
An fmalloc_ld object. |
j |
1-based column index. |
A list with lo and hi (1-based inclusive row bounds of the band)
and x (the decoded correlations for rows lo:hi, length hi - lo + 1).
fmalloc_ld(), ld_pair(), ld_ncol()
Number of variants in a banded LD store
ld_ncol(store)ld_ncol(store)
store |
An fmalloc_ld object. |
The number of variants (columns == rows) as an integer.
fmalloc_ld(), ld_pair(), ld_col()
Returns r[i, j] from a banded LD store. Pairs outside the stored band (too
far apart to be in each other's window) return 0.
ld_pair(store, i, j)ld_pair(store, i, j)
store |
An fmalloc_ld object. |
i, j
|
1-based variant indices. |
The (quantized) correlation r[i, j], or 0 if the pair is outside
the band.
fmalloc_ld(), ld_col(), ld_ncol()
Returns the in-file allocation catalog for a persistent fmalloc runtime. The catalog is stored in the backing file and records physical allocation metadata used to validate serialized persistent references.
list_fmalloc_allocations(runtime = NULL)list_fmalloc_allocations(runtime = NULL)
runtime |
Optional runtime handle returned by |
For successful recovery, look at the state column:
"committed": valid serialized payload exists for that record;
"tombstone": the payload has been destroyed and is non-recoverable unless
the runtime remains open and referenced directly by an existing SEXP;
other transient states are internal and are generally not expected.
recoverable indicates whether the record can be reopened via serialized
reference metadata. payload_offset == 0 or payload_nbytes == 0 generally
indicates a non-payload entry.
A data frame with one row per catalog record and columns describing the catalog record offset, generation, state, vector type, length, payload offset, payload byte size, flags, and whether the record is recoverable by reference serialization.
## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) v <- create_fmalloc_vector("integer", 10, runtime = rt) list_fmalloc_allocations(rt) cleanup_fmalloc(rt) ## End(Not run)## Not run: rt <- open_fmalloc(tempfile(fileext = ".bin")) v <- create_fmalloc_vector("integer", 10, runtime = rt) list_fmalloc_allocations(rt) cleanup_fmalloc(rt) ## End(Not run)
Opens a file-backed fmalloc runtime and returns an external-pointer handle. Multiple handles to the same path share the same underlying runtime within a process. Runtime mode mismatches are rejected for an already-open path. Runtime mode controls whether vector payloads are durable persistent allocations or scratch allocations that can be returned to fmalloc when their ALTREP handles are garbage-collected.
open_fmalloc(filepath, size_gb = NULL, mode = c("persistent", "scratch"))open_fmalloc(filepath, size_gb = NULL, mode = c("persistent", "scratch"))
filepath |
Character string specifying the file path for fmalloc data. |
size_gb |
Numeric value specifying the size of the backing file in GB (optional). If not specified, uses the package default size for new files or the existing file size. |
mode |
Runtime mode. |
An external pointer of class fmalloc_runtime.