Lightweight 'CUDA' Numerical Computing

Provides a lightweight interface to graphics processing unit (GPU)-accelerated numerical computing using 'CUDA'. Dense tensors, sparse matrices, decompositions, distances, exact nearest neighbours, clustering, graph workflows, and embeddings share one consistent interface. The native backend discovers the 'NVIDIA CUDA Driver API', 'cuBLAS', and 'cuSOLVER' libraries at runtime without bundling 'LibTorch' or the 'CUDA Runtime'. Stage-level provenance records the backend, device, and data transfers used by each result. A portable implementation supports package validation on systems without 'CUDA'. Background for the included Leiden community detection and uniform manifold approximation and projection methods is given by Traag, Waltman and van Eck (2019) and McInnes et al. (2018) , respectively.


cudaverse

Lightweight CUDA computing for R. cudaverse lets R users run dense and sparse matrix operations, PCA, distances, exact k-nearest neighbours, and clustering on an NVIDIA GPU through one familiar package.

Use cudaverse when your analysis has outgrown ordinary R execution and you want GPU acceleration without adopting a large deep-learning framework. The native backend is included in the package, discovers CUDA libraries already installed on your system, and keeps supported multi-stage workflows on the GPU until you ask for an R result.

Why use cudaverse?

  • One R interface: start with a matrix or a Matrix sparse matrix and use ordinary R functions such as t(), [, and %*% alongside cuda_pca() and cuda_knn().
  • Lightweight: cudaverse does not bundle LibTorch or a CUDA runtime. In the retained 0.4 benchmark, the installed package was about 1.45 MB; the optional R torch installation used for comparison occupied about 7.37 GB.
  • GPU-resident pipelines: native PCA, distance blocks, stable top-k, exact kNN, k-means, and supported sparse continuations reuse device memory instead of repeatedly copying intermediates to R.
  • Strict CUDA execution: the examples use device = "cuda". If CUDA is not ready, cudaverse reports what is missing instead of silently running the requested GPU task elsewhere.
  • Auditable results: cuda_provenance() records the backend, device, and host/device boundary for every computational stage.

Requirements

GPU execution requires a CUDA-capable NVIDIA GPU and compatible NVIDIA runtime libraries. The easiest supported setup is:

  • Windows: install a current NVIDIA driver and a compatible CUDA 12.x distribution that provides cublas64_12.dll and cusolver64_11.dll.
  • Linux: install a current NVIDIA driver plus CUDA 12.x runtime libraries that provide libcuda.so, libcublas.so.12, and libcusolver.so.11.
  • macOS: current NVIDIA CUDA does not support macOS. The R package can be installed and checked there, but CUDA execution requires Windows or Linux.

Use NVIDIA's current Windows installation guide or Linux installation guide. After installing the driver, confirm that nvidia-smi can see the GPU before starting R.

Install

Install the current release from CRAN:

install.packages("cudaverse")

Then verify the complete runtime—not only GPU detection:

library(cudaverse)

diagnostics <- cuda_diagnostics()
diagnostics$summary
diagnostics$next_steps

# Strict: returns a CUDA selection or explains why CUDA is not ready.
cuda_select_device("cuda")

The native backend needs the NVIDIA driver, cuBLAS 12, and cuSOLVER 11. If Windows or Linux cannot find the libraries automatically, set CUDAVERSE_CUBLAS_PATH and CUDAVERSE_CUSOLVER_PATH to their absolute paths before loading cudaverse. On Windows, these paths select the primary DLLs; the runtime bin directory also needs to be on PATH so their dependent DLLs can load. See the CUDA setup guide for platform-specific examples and troubleshooting.

Optional TF32 matrix multiplication

Version 0.4.2 adds optional TF32 computation through tensor_matmul(..., precision = "tf32") on supported NVIDIA GPUs. It keeps float32 storage and output while allowing reduced input precision. Standard float32 arithmetic remains the default. Check that your installed version is 0.4.2 or newer before using this option:

packageVersion("cudaverse")

A five-minute CUDA workflow

The following workflow computes PCA and exact kNN with CUDA. PCA returns an R model containing scores and loadings, while retaining a device-side score cache so kNN can reuse those scores without uploading them again. Neighbour indices and distances are returned as ordinary R matrices:

library(cudaverse)

set.seed(1)
x <- matrix(rnorm(10000 * 100), nrow = 10000, ncol = 100)

pca <- cuda_pca(
  x,
  n_components = 20,
  device = "cuda"
)

neighbors <- cuda_knn(
  pca$x,
  k = 15,
  device = "cuda"
)

head(neighbors$index)
head(neighbors$distance)
cuda_provenance(neighbors)

Use tensors when you want direct control over GPU-resident matrix operations:

x_gpu <- cuda_tensor(x, device = "cuda", dtype = "float32")
crossprod_gpu <- tensor_matmul(t(x_gpu), x_gpu)

tensor_device(crossprod_gpu)
crossprod <- to_cpu(crossprod_gpu)  # transfer only when the R matrix is needed

Sparse matrices use the same CUDA-facing API:

counts <- Matrix::rsparsematrix(10000, 100, density = 0.03)
counts@x <- abs(counts@x)

counts_gpu <- cuda_sparse(counts, device = "cuda")
normalized_gpu <- sparse_normalize(
  counts_gpu,
  margin = "rows",
  scale_factor = 10000,
  log1p = TRUE
)
sparse_pca <- cuda_pca(normalized_gpu, n_components = 20, device = "cuda")
sparse_knn <- cuda_knn(sparse_pca$x, k = 15, device = "cuda")

How fast is it?

The retained full benchmark uses five warmups and ten timed runs and validates numerical parity before accepting a timing. Selected host-boundary medians are shown below; times include the public R call boundary.

Workload Base R Native CUDA R torch Native vs base Native vs torch
1024 x 1024 float32 matrix multiplication 0.332 s 0.024 s 0.039 s 13.7x 1.6x
Dense PCA + exact kNN, 10,000 x 100 11.915 s 0.275 s 6.094 s 43.4x 22.2x
Sparse PCA + exact kNN, 10,000 x 100 10.265 s 0.203 s 5.198 s 50.6x 25.6x
Dense PCA + exact kNN, 50,000 x 128 668.418 s 2.807 s 126.552 s 238.1x 45.1x

These are workload-specific measurements from one fixed NVIDIA GPU environment, not guarantees for every machine. Small jobs can be dominated by launch and transfer overhead: in the retained sparse 1,000 x 50 case, base R was faster than native CUDA. See the complete benchmark evidence and the performance articles before choosing a workload size.

The versioned benchmark contract defines the workload sizes, warmups, timed runs, transfer boundaries, validation tolerances, and evidence fields used by the retained report.

Learn by task

Graph and embedding helpers are also available. Some currently delegate stages to established CPU packages; cuda_provenance() makes those boundaries visible. The task guides identify which operations are fully native CUDA and which are hybrid.

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.

install.packages("cudaverse")

0.4.2 by Yaoxiang Li, 8 days ago


https://cudaverse.github.io/cudaverse/, https://github.com/cudaverse/cudaverse


Report a bug at https://github.com/cudaverse/cudaverse/issues


Browse source code at https://github.com/cran/cudaverse


Authors: Yaoxiang Li [aut, cre]


Documentation:   PDF Manual  


MIT + file LICENSE license


Imports Matrix, methods, stats

Suggests igraph, knitr, rmarkdown, RSpectra, Rtsne, S4Vectors, SingleCellExperiment, testthat, torch, uwot

System requirements: For GPU execution on Windows or Linux: NVIDIA CUDA-capable GPU, NVIDIA driver with CUDA Driver API, NVIDIA cuBLAS 12, and NVIDIA cuSOLVER 11


See at CRAN