--- title: "Your first CUDA workflow with cudaverse" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Your first CUDA workflow with cudaverse} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", eval = FALSE) ``` This guide takes you from an ordinary R matrix to PCA and nearest-neighbour results computed with CUDA. You stay in R, use familiar data structures, and do not need a deep-learning framework. ## Before you start Before opening R, make sure you have: 1. Windows or Linux; 2. a CUDA-capable NVIDIA GPU and working NVIDIA driver; 3. a CUDA 12.x installation from NVIDIA; and 4. the current cudaverse release. Follow the [GPU setup guide](gpu-setup.html) first if `nvidia-smi` does not show a GPU or the diagnostic call below reports missing libraries. ```{r install} # install.packages("pak") pak::pak("cudaverse/cudaverse@v0.4.1") library(cudaverse) check <- cuda_diagnostics() check$summary check$next_steps # Stop here with a useful explanation if CUDA is not ready. cuda_select_device("cuda") ``` If the last command succeeds, cudaverse is ready to use the GPU. If it fails, follow the printed next step; the requested CUDA task is never silently run somewhere else. ## PCA and exact nearest neighbours on CUDA This is the most useful first workflow. A numeric R matrix enters the package, PCA reduces it to 20 components, and exact kNN finds 15 neighbours per row. ```{r dense-pca-knn} set.seed(1) x <- matrix(rnorm(10000 * 100), nrow = 10000, ncol = 100) pca <- cuda_pca( x, n_components = 20, center = TRUE, scale. = FALSE, device = "cuda" ) neighbors <- cuda_knn( pca$x, k = 15, metric = "euclidean", device = "cuda" ) dim(pca$x) dim(neighbors$index) head(neighbors$index) head(neighbors$distance) ``` The PCA scores can stay on the GPU while kNN uses them. You can confirm where the work ran: ```{r dense-provenance} cuda_provenance(pca) cuda_provenance(neighbors) cuda_memory_info("cuda") ``` ## GPU-resident matrix operations Use a `cudatensor` when you want several matrix operations to reuse the same data on the GPU. `to_cpu()` brings the final result back as an ordinary R object. ```{r tensors} x_gpu <- cuda_tensor(x, device = "cuda", dtype = "float32") centered_gpu <- x_gpu - tensor_mean(x_gpu, dim = 1) gram_gpu <- tensor_matmul(t(centered_gpu), centered_gpu) column_totals_gpu <- tensor_sum(x_gpu, dim = 1) tensor_device(gram_gpu) gram <- to_cpu(gram_gpu) column_totals <- to_cpu(column_totals_gpu) ``` Subsetting, transpose, arithmetic, matrix multiplication, and summaries follow familiar R conventions while supported results remain on the GPU. ## Sparse normalization, PCA, and kNN Sparse inputs begin as `Matrix` objects. The same workflow can normalize the matrix, run PCA, and find neighbours without making the user learn another API. ```{r sparse-pipeline} 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_neighbors <- cuda_knn( sparse_pca$x, k = 15, device = "cuda" ) sparse_info(normalized_gpu) cuda_provenance(sparse_neighbors) ``` ## Other CUDA tasks The same strict device argument applies to decompositions, distances, and k-means: ```{r more-tasks} svd_fit <- cuda_svd(x, nu = 20, nv = 20, device = "cuda") distances <- cuda_distance( x[1:1000, ], x[1001:2000, ], batch_size = 256, device = "cuda" ) clusters <- cuda_kmeans( pca$x, centers = 20, seed = 1, device = "cuda" ) ``` `cuda_distance()` returns a complete dense matrix, so its host output grows as `nrow(x) * nrow(y)`. Prefer `cuda_knn()` when only the nearest neighbours are needed. ## Where to go next - [GPU setup and troubleshooting](gpu-setup.html) provides exact Windows and Linux dependency checks. - [GPU residency and provenance](backend-provenance.html) shows how to avoid unnecessary transfers. - [CUDA operation coverage](backend-support.html) shows which tasks run fully on the GPU and which currently include an R stage. - [Performance](performance.html) explains the retained comparisons with base R and the optional R `torch` backend.