diff --git a/.github/assets/randlapack-banner.png b/.github/assets/randlapack-banner.png new file mode 100644 index 00000000..1c52541d Binary files /dev/null and b/.github/assets/randlapack-banner.png differ diff --git a/.github/assets/randlapack-logo.png b/.github/assets/randlapack-logo.png new file mode 100644 index 00000000..132840f2 Binary files /dev/null and b/.github/assets/randlapack-logo.png differ diff --git a/CMakeLists.txt b/CMakeLists.txt index a05204a8..d33b7391 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,7 @@ set(RandLAPACK_lapackpp_DIR "${lapackpp_DIR}" CACHE INTERNAL "Location of lapack # copy is the only RandBLAS configuration RandLAPACK is developed and tested # against. Do not point RandLAPACK at a RandBLAS working copy, and do not # develop RandBLAS inside the submodule checkout; clone RandBLAS separately -# for that (see INSTALL.md, section "RandBLAS is a pinned submodule"). +# for that (see docs/INSTALL.md, section "RandBLAS is a pinned submodule"). # # RandLAPACK_EXTERNAL_RandBLAS exists for package maintainers only (Spack, # conda-forge, ...), whose recipes build RandBLAS as its own package. The @@ -113,7 +113,7 @@ if (RandLAPACK_EXTERNAL_RandBLAS) "pin). Version skew between the two is not supported. Build the " "external RandBLAS from exactly the pinned commit, or drop " "RandLAPACK_EXTERNAL_RandBLAS to use the submodule. This option " - "is intended for package maintainers; see INSTALL.md, section " + "is intended for package maintainers; see docs/INSTALL.md, section " "\"RandBLAS is a pinned submodule\".") endif() message(STATUS "RandBLAS: external install at ${RandBLAS_DIR} (commit ${RandBLAS_COMMIT_HASH}, matches the submodule pin)") diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..ebb9d8a1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,80 @@ +# Contributing to RandLAPACK + +Questions, ideas, and half-formed plans are all welcome on +[our Discord server](https://discord.gg/R4qj8Er9YW). This page covers the +mechanics of contributing code. + +## Getting a working setup + +Run `bash install.sh` from your clone (see [docs/INSTALL.md](docs/INSTALL.md) for +manual installation). The installer builds the test suite; verify your +baseline before changing anything: + +```shell +ctest --test-dir ../RandNLA-project/build/RandLAPACK-build +``` + +After editing headers, rebuild and re-run the tests from that same build +directory. Because RandLAPACK is header-only, downstream projects (extras, +benchmarks, your own code) pick up changes only after `make install` in the +RandLAPACK build directory. + +## How the library fits together + +Read [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) first, and `devnotes/idioms.md` for +the C++ idioms we use deliberately (duck-typed callables, caller-provided +workspaces, and so on). + +Conventions enforced in review: + +- Column-major layout, `int64_t` dimensions and indices, element type as a + template parameter. +- Raw caller-provided buffers for matrix/vector outputs and workspaces; no + `std::vector` for anything sized by the problem. +- New code throws (`randlapack_require`, `RandLAPACK::Error`) rather than + asserts, with messages that state what was violated and the offending + values. +- Randomness only through `RandBLAS::RNGState` (counter-based Philox), never + through `std::rand` or `std::mt19937`, so results stay reproducible. +- The RandBLAS submodule is read-only from this repository's point of view: + develop RandBLAS in its own clone (see docs/INSTALL.md, "RandBLAS is a pinned + submodule"). + +## Tests + +Every behavioral change needs a test in `test/` (GoogleTest; the tree +mirrors the source layout). Run the suite locally before opening a PR; CI +runs it on Linux and macOS, both through the hand-written recipes and +through `install.sh` itself, and a PR cannot merge with failing required +checks. GPU tests (`test/**/*.cu`) only run on machines with CUDA; if your +change touches GPU code, say in the PR whether you ran them. + +A quirk worth knowing: translation units that use the GPU headers define +`USE_CUDA` themselves (see `test/drivers/test_bqrrp_gpu.cu`), while the GPU +*benchmark* does not; anything added to `gpu_functions/rl_cuda_kernels.cuh` +must compile in both settings (host-callable helpers go outside the +`#ifdef USE_CUDA` region, kernels inside). + +## Experiment branches + +We conduct proof-of-concept and benchmarking experiments under version +control. Create a branch like + +``` +git checkout -b experiments/riley-svdidea-220311 +``` + +The branch name always has the prefix `experiments/` and ideally +keywords plus a YYMMDD date. Push it to BallisticLA/RandLAPACK if you want +to share it. If you reach a clean example you may want to cite later, mark +the commit with a [git tag](https://en.wikibooks.org/wiki/Git/Advanced#Tags). + +## Pull requests + +- Keep PRs reviewable: one logical change per commit, present-tense commit + messages that explain *why*, not just what. +- Reference the issues a PR fixes (`fixes #NNN`) in the commit message or PR + body rather than in code comments. +- Benchmarks are compile-checked in CI but not executed; if your change is + performance-motivated, include measurements in the PR body (machine, BLAS + provider, sizes, medians over repeated runs). diff --git a/INSTALL_SCRIPT.md b/INSTALL_SCRIPT.md deleted file mode 100644 index 7a77afd2..00000000 --- a/INSTALL_SCRIPT.md +++ /dev/null @@ -1,345 +0,0 @@ -# Using RandLAPACK's Automated Install Script - -This guide explains how to use the `install.sh` script to automatically install -RandLAPACK and all of its dependencies (BLAS++, LAPACK++, Random123) with a -single command. - -**When to use this guide:** Use this automated installation method if you want -a quick, streamlined setup process. If you need fine-grained control over -dependency configurations, refer to RandLAPACK's `INSTALL.md` instead. - -## 0. Software Requirements - -Before running the install script, ensure you have the following software -available on your system: - -### Essential Requirements -* **C++ Compiler:** GNU GCC 13.3.0 or higher (required for C++20 features) -* **CMake:** Version 3.27 or higher -* **BLAS/LAPACK Library:** Intel MKL 2022 or higher recommended -* **GoogleTest:** (Optional but recommended) For running RandLAPACK tests - -### GPU Support Requirements (Optional) -* **CUDA Toolkit:** Version 12.4.1 or higher - - **Recommended:** CUDA 12.9.0 + GCC 13.3.0 (verified working as of 2025-11-26) - - **IMPORTANT:** CUDA versions have strict GCC compatibility requirements: - - CUDA 12.9.0: Compatible with GCC 13.x ✓ - - CUDA 12.4.1: Compatible with GCC 13.x ✓ - - CUDA 12.2.1: Requires GCC ≤ 12.x (GCC 13.x will fail with "unsupported GNU version") - - See `INSTALL.md` Section 0 for full compatibility matrix - - Ensure compatible NVIDIA driver (v580+ recommended for CUDA 12.9) -* **CUDA Libraries:** cuBLAS and cuSOLVER (included with CUDA Toolkit) - -### Installing Requirements with Spack - -We strongly recommend using [Spack](https://github.com/spack/spack) to manage -these dependencies. A typical Spack installation would look like: - -```shell -# Step 1: Install the compiler FIRST -spack install gcc@13.3.0 - -# Step 2: Register the new compiler with Spack -spack compiler find - -# Step 3: Load the compiler -spack load gcc@13.3.0 - -# Step 4: Install all other dependencies using the new compiler -spack install cmake@3.27 -spack install intel-oneapi-mkl -spack install googletest - -# For GPU support -spack install cuda@12.9.0 -``` - -**IMPORTANT:** The compiler must be installed, registered with `spack compiler find`, -and loaded *before* installing other dependencies. This ensures all packages are -built with the correct compiler version. Spack will automatically use the loaded -compiler for subsequent package installations. - -After installation, load the environment: -```shell -spack load gcc@13.3.0 -spack load cmake -spack load intel-oneapi-mkl -spack load googletest -spack load cuda@12.9.0 # If GPU support needed -``` - -**Pro tip:** Add the spack load commands to your `~/.bashrc` to automatically -load the environment in every shell session. Make sure to load the compiler first -in your `.bashrc`. - -## 1. Preparing for Installation - -### Directory Structure - -The install script expects a specific directory structure: - -``` -~/RandNLA/ -├── RandLAPACK/ # Clone RandLAPACK here (script will move it) -└── RandNLA-project/ # Created automatically by script - ├── lib/ - │ ├── blaspp/ # Built by script - │ ├── lapackpp/ # Built by script - │ ├── random123/ # Built by script - │ └── RandLAPACK/ # Moved here by script - └── build/ # Build artifacts -``` - -### Initial Setup - -1. Create the base directory: - ```shell - mkdir -p ~/RandNLA - cd ~/RandNLA - ``` - -2. Clone RandLAPACK repository: - ```shell - git clone --recursive https://github.com/BallisticLA/RandLAPACK.git - cd RandLAPACK - ``` - -3. **(Important)** Switch to the correct development branch if needed: - ```shell - git checkout - ``` - - **Note:** Always verify with the development team which branch to use for - the latest GPU support and stability improvements. - -## 2. Running the Install Script - -### Basic Usage - -From inside the `RandLAPACK` directory: - -```shell -bash install.sh -``` - -The script will: -1. Detect if GPU hardware is available on your system and, on a terminal, - ask whether to build with CUDA support -2. Automatically clone and build all dependencies (or reuse preinstalled - ones, see the discovery variables below) -3. Build RandLAPACK with appropriate configuration -4. Build test and benchmark executables - -Run `bash install.sh --help` for the full option list. The main flags, each -with an environment-variable equivalent: - -``` --y, --yes assume "yes" for every prompt - --gpu / --no-gpu decide GPU support without asking --j, --jobs parallel build jobs (default: number of cores) - --fresh clear build directories first (default: reuse them, - so re-running is an incremental rebuild) - --modify-rc append RANDNLA_PROJECT_DIR/RANDNLA_PROJECT_GPU_AVAIL - exports to your shell config (default: never touch it; - the summary prints the lines to add yourself) - --project-dir place/locate RandNLA-project at D -``` - -### Automated Installation (Non-Interactive) - -Prompts appear only when stdin is a terminal. Piped and CI runs are already -non-interactive with safe defaults (NVIDIA detected: GPU build; AMD or no -GPU: CPU build), so no `yes |` piping is needed: - -```shell -bash install.sh < /dev/null # or simply: bash install.sh --yes -``` - -### Installation Logging - -All compiler output goes to `/install.log` automatically; the -console shows one line per step, and any failure prints the log path plus -the last lines of the log. There is no need to tee the output yourself. - -## 3. What the Script Does - -The `install.sh` script performs the following steps automatically: - -1. **Creates Project Structure** - - Creates `~/RandNLA/RandNLA-project/` directory tree - - Sets up subdirectories for libraries and build artifacts - -2. **Builds BLAS++** - - Clones BLAS++ from official repository - - Configures with appropriate BLAS backend (MKL if available) - - Builds with GPU support if requested - - Installs to `~/RandNLA/RandNLA-project/lib/blaspp/` - -3. **Builds LAPACK++** - - Clones LAPACK++ from official repository - - Configures to use previously built BLAS++ - - Builds with GPU support if requested - - Installs to `~/RandNLA/RandNLA-project/lib/lapackpp/` - -4. **Installs Random123** - - Clones Random123 header-only library - - Installs headers to `~/RandNLA/RandNLA-project/lib/random123/` - -5. **Moves and Builds RandLAPACK** - - Moves `RandLAPACK` directory to `~/RandNLA/RandNLA-project/lib/` - - Configures CMake with all dependency paths - - Builds RandLAPACK library - - Builds test suite and benchmarks - - Creates executables in `~/RandNLA/RandNLA-project/build/RandLAPACK-build/bin/` - -## 4. Verifying the Installation - -### Running Tests - -After installation completes, verify everything works correctly: - -```shell -cd ~/RandNLA/RandNLA-project/build/RandLAPACK-build -ctest -``` - -This runs the complete test suite (456 tests). Expected output: -``` -99% tests passed, 1 tests failed out of 456 -Total Test time (real) = 124.62 sec -``` - -**Note:** Some test failures are known and acceptable in development branches. -Consult the development team if you see unexpected failures. - -### Running GPU Tests Only - -If you enabled GPU support, test GPU functionality specifically: - -```shell -./bin/RandLAPACK_tests_gpu -``` - -Expected output: 13-14 GPU tests should pass within 15-20 seconds. - -## 5. Working with the Installed Project - -### Key File Locations - -After installation: - -* **RandLAPACK library:** `~/RandNLA/RandNLA-project/build/RandLAPACK-build/libRandLAPACK.a` -* **Headers:** `~/RandNLA/RandNLA-project/lib/RandLAPACK/RandLAPACK/` -* **Tests:** `~/RandNLA/RandNLA-project/build/RandLAPACK-build/bin/RandLAPACK_tests*` -* **Benchmarks:** `~/RandNLA/RandNLA-project/build/RandLAPACK-build/bin/RandLAPACK_bench*` -* **CMake config:** `~/RandNLA/RandNLA-project/build/RandLAPACK-build/RandLAPACKConfig.cmake` - -### Recompiling After Code Changes - -If you modify RandLAPACK source code: - -```shell -cd ~/RandNLA/RandNLA-project/build/RandLAPACK-build -source ~/.bashrc # Ensures environment is loaded -make -j -``` - -**Important:** Always source your `.bashrc` (or equivalent environment setup) -before running `make` to ensure CUDA libraries and other dependencies are in -your `LD_LIBRARY_PATH`. - -### Using RandLAPACK in Your Own Projects - -See Section 4 of `INSTALL.md` for details on linking RandLAPACK to external -CMake projects. You'll need to specify: - -```cmake --Dblaspp_DIR=~/RandNLA/RandNLA-project/lib/blaspp/lib/cmake/blaspp --Dlapackpp_DIR=~/RandNLA/RandNLA-project/lib/lapackpp/lib/cmake/lapackpp --DRandBLAS_DIR=~/RandNLA/RandNLA-project/build/RandLAPACK-build/RandBLAS --DRandLAPACK_DIR=~/RandNLA/RandNLA-project/build/RandLAPACK-build -``` - ---- - -## Building and Running GPU Benchmarks - -GPU benchmarks are in the `benchmark/` directory and must be built separately from the main RandLAPACK project. - -### Prerequisites - -- RandLAPACK must already be built and installed with CUDA support (`-DRequireCUDA=ON`) -- CUDA Toolkit must be available on your system -- GPU hardware must be available - -### Building GPU Benchmarks - -Navigate to the benchmark directory and build as a standalone project: - -```shell -cd ~/RandNLA/RandNLA-project/lib/RandLAPACK/benchmark -mkdir -p build -cd build -cmake \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_CXX_COMPILER=g++ \ - -DRandLAPACK_DIR=~/RandNLA/RandNLA-project/install/RandLAPACK-install/lib/cmake/RandLAPACK \ - .. -make -j -``` - -**Note:** Adjust the `RandLAPACK_DIR` path to match your installation location. - -### Running GPU Benchmarks - -#### BQRRP GPU Benchmark - -The BQRRP GPU benchmark supports two modes: - -**Block size sweep** (default): -```shell -./BQRRP_GPU_benchmark block_size [matrix_size] [profile_runtime] [run_qrf] -``` - -Examples: -```shell -# Run with default settings (16384x16384 matrix) -./BQRRP_GPU_benchmark block_size - -# Run with 32768x32768 matrix -./BQRRP_GPU_benchmark block_size 32768 - -# Run with profiling enabled and QRF comparison -./BQRRP_GPU_benchmark block_size 16384 1 1 -``` - -**Matrix size sweep**: -```shell -./BQRRP_GPU_benchmark mat_size [profile_runtime] [run_qrf] -``` - -Examples: -```shell -# Run with default settings -./BQRRP_GPU_benchmark mat_size - -# Run with profiling disabled but QRF comparison enabled -./BQRRP_GPU_benchmark mat_size 0 1 -``` - -### Output Files - -The benchmarks generate text files with timing results in the current directory: - -- `_BQRRP_GPU_speed_comparisons_block_size_*.txt` - Speed comparison results for block size sweep -- `BQRRP_GPU_speed_comparisons_mat_size_*.txt` - Speed comparison results for matrix size sweep -- `_BQRRP_GPU_runtime_breakdown_qrf_*.txt` - Detailed profiling with QRF (if profiling enabled) -- `_BQRRP_GPU_runtime_breakdown_cholqr_*.txt` - Detailed profiling with CholQR (if profiling enabled) - -**Last Updated:** 2025-11-26 -**Tested With:** -- GCC 13.3.0 -- CMake 3.31.9 -- CUDA 12.9.0 -- Intel MKL 2025.0.3 -- Ubuntu 22.04 / WSL2 diff --git a/README.md b/README.md index 0f3aedbe..f48932c5 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,85 @@ +

+ RandLAPACK +

+ # RandLAPACK -RandLAPACK provides high-performance randomized algorithms for linear algebra problems such as least squares, (kernel) ridge regression, low-rank approximation, and matrix factorizations. +RandLAPACK provides high-performance randomized algorithms for linear algebra +problems such as least squares, (kernel) ridge regression, low-rank +approximation, and matrix factorizations. RandLAPACK's API is not yet stable; we're actively working on changing that. -Please swing by [**our Discord server**](https://discord.gg/R4qj8Er9YW) if you have questions about RandLAPACK or would like to get involved in its development. +Please swing by [**our Discord server**](https://discord.gg/R4qj8Er9YW) if you +have questions about RandLAPACK or would like to get involved in its +development. + +## Quickstart + +```shell +git clone https://github.com/BallisticLA/RandLAPACK.git +cd RandLAPACK +bash install.sh +``` + +The installer builds RandLAPACK together with its dependencies (BLAS++, +LAPACK++, Random123; RandBLAS comes along as a pinned git submodule) and the +test and benchmark executables. Run `bash install.sh --help` for the options +(GPU support, parallelism, reusing preinstalled dependencies, and more), and +see [docs/INSTALL.md](docs/INSTALL.md) for manual installation and for consuming +RandLAPACK from your own CMake project. A smoke test after installation: + +```shell +ctest --test-dir ../RandNLA-project/build/RandLAPACK-build +``` + +## What's in the library + +The user-facing algorithms ("drivers"; see +[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for how the library is organized): + +| Driver | Problem it solves | Reference | +|--------|-------------------|-----------| +| `BQRRP` | Blocked QR with randomized column pivoting, any aspect ratio | [arXiv:2507.00976](https://arxiv.org/abs/2507.00976) | +| `CQRRPT` | Sketch-based QR with column pivoting for tall matrices | [arXiv:2311.08316](https://arxiv.org/abs/2311.08316) | +| `CQRRT` | Q-less randomized QR (preconditioner construction) | | +| `RSVD` | Randomized low-rank SVD via the QB decomposition | [arXiv:2009.06392](https://arxiv.org/abs/2009.06392) | +| `REVD2` | Randomized eigendecomposition of symmetric matrices | [arXiv:2009.06392](https://arxiv.org/abs/2009.06392) | +| `ABRIK` | Block-Krylov iterative SVD for many accurate singular triplets | | +| `HQRRP` | Householder QR with randomized pivoting | [arXiv:1512.02671](https://arxiv.org/abs/1512.02671) | +| `KRILL` | Kernel ridge regression solvers | [arXiv:2302.11474](https://arxiv.org/abs/2302.11474) | +| `RPCholesky` | Randomly pivoted Cholesky for kernel matrices | [arXiv:2207.06503](https://arxiv.org/abs/2207.06503) | + +BQRRP and CQRRPT also have CUDA implementations (`*_gpu`). Drivers are +assembled from smaller randomized building blocks (rangefinders, sketching +wrappers, orthogonalization and stabilization routines) that are usable on +their own; the RandNLA monograph +([arXiv:2302.11474](https://arxiv.org/abs/2302.11474)) is the best background +reference for the algorithm families. ## Related libraries -RandLAPACK depends on [RandBLAS](https://github.com/BallisticLA/RandBLAS), which we are also -developing. +RandLAPACK depends on [RandBLAS](https://github.com/BallisticLA/RandBLAS), +which we are also developing. -Before starting on RandLAPACK we implemented several high-level RandNLA algorithms in Matlab ([MARLA](https://github.com/BallisticLA/marla)) and Python ([PARLA](https://github.com/BallisticLA/parla)). +Before starting on RandLAPACK we implemented several high-level RandNLA +algorithms in Matlab ([MARLA](https://github.com/BallisticLA/marla)) and +Python ([PARLA](https://github.com/BallisticLA/parla)). In the latter library we took an approach where *algorithms are objects.* -An algorithm needs to be instantiated with its tuning parameters and subroutines in order to be used. +An algorithm needs to be instantiated with its tuning parameters and +subroutines in order to be used. RandLAPACK currently emphasizes that "algorithms as objects" approach. -## Notes for collaborators +## Where to go from here + +Everything beyond this page lives in two places: `docs/` for reference +documentation, and `CONTRIBUTING.md` at the root for the development +workflow. -Refer to ``INSTALL.md`` for directions on how to install RandLAPACK's dependencies, -install RandLAPACK itself, and use RandLAPACK in other projects. +| You want to... | Read | +|----------------|------| +| Install with one command | [docs/INSTALL_SCRIPT.md](docs/INSTALL_SCRIPT.md) | +| Install by hand, or use RandLAPACK from your CMake project | [docs/INSTALL.md](docs/INSTALL.md) | +| Understand how the library is organized | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | +| Contribute code | [CONTRIBUTING.md](CONTRIBUTING.md) | +| Run or add performance benchmarks | [benchmark/README.md](benchmark/README.md) | +| Use the Eigen/Matrix-Market integrations | [extras/README.md](extras/README.md) | diff --git a/benchmark/README.md b/benchmark/README.md new file mode 100644 index 00000000..51e52a39 --- /dev/null +++ b/benchmark/README.md @@ -0,0 +1,77 @@ +# RandLAPACK benchmarks + +Performance-measurement harnesses for RandLAPACK's drivers and subroutines +(the numbers behind the papers and speed regressions). Not to be confused +with `extras/`, which extends functionality using third-party dependencies. + +This directory is a **standalone CMake project**: it consumes an *installed* +RandLAPACK via `find_package`, exactly like user code does. The autoinstaller +builds it automatically into `RandNLA-project/build/benchmark-build/`; to +build it by hand against an existing install: + +```shell +cmake -S benchmark -B benchmark-build \ + -DCMAKE_BUILD_TYPE=Release \ + -DRandLAPACK_DIR=/path/to/RandLAPACK-install/lib/cmake/RandLAPACK +cmake --build benchmark-build -j +``` + +(If BLAS++/LAPACK++/Random123 are not discoverable from the RandLAPACK +config, pass `-Dblaspp_DIR/-Dlapackpp_DIR/-DRandom123_DIR` too, as printed +by the installer's final summary.) + +The executables are grouped by driver: `bench_BQRRP/`, `bench_CQRRPT/`, +`bench_ABRIK/`, `bench_CQRRT_linops/`, and `bench_general/`. Each writes +timing text files into the current working directory. Benchmarks are +compile-checked in CI but never executed there; run them on quiet, pinned +hardware if you intend to quote numbers. + +Note for macOS: benchmarks that depend on routines absent from Apple's +default LAPACK build as whole-file stubs that print a message and return 1. + +## GPU benchmarks + +Prerequisites: RandLAPACK installed with CUDA support (`--gpu` in the +installer, or `-DRequireCUDA=ON` manually), the CUDA Toolkit, and a GPU. + +### BQRRP GPU benchmark + +Two modes: + +**Block size sweep** (default): +```shell +./BQRRP_GPU_benchmark block_size [matrix_size] [profile_runtime] [run_qrf] +``` + +Examples: +```shell +# Default settings (16384x16384 matrix) +./BQRRP_GPU_benchmark block_size + +# 32768x32768 matrix +./BQRRP_GPU_benchmark block_size 32768 + +# Profiling enabled and QRF comparison +./BQRRP_GPU_benchmark block_size 16384 1 1 +``` + +**Matrix size sweep**: +```shell +./BQRRP_GPU_benchmark mat_size [profile_runtime] [run_qrf] +``` + +Examples: +```shell +# Default settings +./BQRRP_GPU_benchmark mat_size + +# Profiling disabled, QRF comparison enabled +./BQRRP_GPU_benchmark mat_size 0 1 +``` + +### Output files + +- `_BQRRP_GPU_speed_comparisons_block_size_*.txt` - block size sweep results +- `BQRRP_GPU_speed_comparisons_mat_size_*.txt` - matrix size sweep results +- `_BQRRP_GPU_runtime_breakdown_qrf_*.txt` - detailed profiling with QRF (profiling enabled) +- `_BQRRP_GPU_runtime_breakdown_cholqr_*.txt` - detailed profiling with CholQR (profiling enabled) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 00000000..73ec6e45 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,113 @@ +# How RandLAPACK is organized + +This is the map for reading or extending the library. For installation see +[INSTALL.md](INSTALL.md); for the contribution workflow see +[CONTRIBUTING.md](../CONTRIBUTING.md). + +## The one-paragraph version + +RandLAPACK is a header-only C++20 template library. User code includes a +single umbrella header, `RandLAPACK.hh`, and calls **drivers**: complete +randomized algorithms (randomized SVD, QR with column pivoting, kernel ridge +regression solvers, ...). Drivers are assembled from **computational +routines** (rangefinders, orthogonalization, stabilization) and from the +sketching primitives of **RandBLAS**, which ships inside this repository as a +pinned git submodule. Dense linear algebra goes through the **BLAS++** and +**LAPACK++** wrapper libraries, so any BLAS/LAPACK provider (MKL, OpenBLAS, +AOCL, Accelerate) can sit underneath. Matrices are column-major, dimensions +are `int64_t`, and every public entry point is templated on the element type. + +```mermaid +flowchart TD + U[User code
#include <RandLAPACK.hh>] --> D + X[extras/ and benchmark/
standalone projects in this repo,
consume the installed RandLAPACK] --> D + subgraph RandLAPACK + D[drivers/
RSVD, BQRRP, CQRRPT, CQRRT,
REVD2, ABRIK, HQRRP, KRILL, ...] + C[comps/
rangefinders, QB, orthogonalization,
stabilization, preconditioners] + L[linops/
dense, sparse, symmetric,
composite linear operators] + M[misc/ + testing/
utilities, matrix generators] + GPU[gpu_functions/ + drivers/*_gpu
CUDA kernels and GPU drivers,
compiled only in CUDA builds] + D --> C + D --> L + C --> M + D --- GPU + end + C --> RB[RandBLAS submodule
sketching operators, counter-based RNG] + D --> LPP[LAPACK++] + C --> BPP[BLAS++] + RB --> BPP + LPP --> BPP + BPP --> BLAS[(BLAS/LAPACK provider:
MKL, OpenBLAS, AOCL, Accelerate)] + GPU --> CUDALIBS[(cuBLAS, cuSOLVER)] +``` + +## Directory map + +``` +RandLAPACK/ (repository root) +|-- RandLAPACK.hh single umbrella header: the public include +|-- RandLAPACK/ all library code (header-only templates) +| |-- rl_blaspp.hh BLAS++ shim +| |-- rl_lapackpp.hh LAPACK++ shim +| |-- rl_exceptions.hh RandLAPACK::Error + randlapack_require +| |-- drivers/ user-facing algorithms (rl_rsvd.hh, +| | rl_bqrrp.hh + rl_bqrrp_gpu.hh, rl_cqrrpt.hh +| | + rl_cqrrpt_gpu.hh, rl_cqrrt.hh, rl_revd2.hh, +| | rl_abrik.hh, rl_hqrrp.hh, rl_krill.hh, ...) +| |-- comps/ computational building blocks (rl_rf.hh +| | rangefinders, rl_qb.hh, rl_orth.hh, +| | rl_syps.hh/rl_syrf.hh, rl_rpchol.hh, +| | rl_preconditioners.hh, rl_determiter.hh) +| |-- linops/ linear-operator abstractions used by +| | matrix-free drivers +| |-- gpu_functions/ CUDA kernels and cuSOLVER dispatch helpers +| | (compiled only in CUDA translation units) +| |-- misc/ rl_util.hh, rl_pdkernels.hh +| `-- testing/ matrix generators and test utilities that +| ship with the library (rl_gen.hh, ...) +|-- RandBLAS/ git submodule, pinned to an exact commit +|-- test/ GoogleTest suite, mirrors the source layout +|-- benchmark/ standalone CMake project (see its README) +|-- extras/ standalone CMake project (Eigen + +| fast_matrix_market integrations) +|-- CMake/ build options, version, config templates +`-- install.sh the autoinstaller (see INSTALL_SCRIPT.md) +``` + +## The three-tier build + +The repository builds as three CMake projects, not one: + +1. **Core library** (root `CMakeLists.txt`): installs the headers and CMake + config, and builds the test suite when `RandLAPACK_BUILD_TESTS=ON`. + RandBLAS is built from the submodule (or, for package maintainers only, + consumed as an installed package behind the + `RandLAPACK_EXTERNAL_RandBLAS` commit gate; see INSTALL.md). +2. **extras/** and 3. **benchmark/**: separate downstream projects that + consume the *installed* RandLAPACK via `find_package`, exactly like user + code does. This keeps them honest as consumers and keeps their extra + dependencies out of the library build. Their purposes differ: `benchmark/` + measures RandLAPACK's performance (the harnesses behind the papers), + while `extras/` is a holding area for functionality that currently needs + third-party libraries (Eigen, fast_matrix_market) that core RandLAPACK + will not depend on; see `extras/README.md` for the graduation policy. + +`install.sh` drives all three in order, plus the dependency builds. + +## Conventions that hold everywhere + +- Column-major storage; `int64_t` for all dimensions, leading dimensions, + and indices; element type is a template parameter `T` (float/double). +- Algorithms are objects: construct with tuning parameters, then `call(...)`. + Outputs and workspaces are caller-provided raw buffers. +- Errors: `randlapack_require(...)` throws `RandLAPACK::Error` with a + descriptive message; new code throws rather than asserts. +- Randomness comes exclusively from RandBLAS's counter-based generators + (`RandBLAS::RNGState`), which makes every randomized routine reproducible + from a seed, independent of threading. +- GPU code lives in `gpu_functions/` and `drivers/*_gpu.hh`, and is compiled + only in CUDA translation units; the umbrella header does not include it + (a known 1.0 work item tracks improving this). + +See `../devnotes/idioms.md` (repo root) for a catalog of the C++ idioms (duck-typed +callables, workspace patterns) with rationale and examples. diff --git a/INSTALL.md b/docs/INSTALL.md similarity index 88% rename from INSTALL.md rename to docs/INSTALL.md index a8932156..cd25bd98 100644 --- a/INSTALL.md +++ b/docs/INSTALL.md @@ -1,5 +1,10 @@ # Installing and using RandLAPACK +**The fastest route is the autoinstaller**: `bash install.sh` builds +RandLAPACK, its dependencies, and the test and benchmark executables in one +command; see [INSTALL_SCRIPT.md](INSTALL_SCRIPT.md). This file covers manual +installation for fine-grained control. + Sections 1 through 3 of this file describe how to perform a *basic* installation of RandLAPACK and its dependencies. @@ -19,7 +24,7 @@ of the corresponding instructions in Section 1. - **C++ Compiler**: C++20 support required - GCC 11 or higher - Clang 14 or higher (not extensively tested) - - Intel ICPX (has known issues, see GitHub issue #91) + - Intel ICPX (not extensively tested) ### GPU Support (Optional) For GPU/CUDA support (enabled with `-DRequireCUDA=ON`), you need: @@ -29,9 +34,13 @@ For GPU/CUDA support (enabled with `-DRequireCUDA=ON`), you need: #### CUDA/GCC Compatibility Matrix +The table lists configurations we have verified; it is not exhaustive. The +authoritative host-compiler caps are in each CUDA Toolkit's release notes. + | CUDA Version | GCC Support | Status | Notes | |--------------|-------------|---------|-------| -| **12.9.0** | **GCC 13.x ✓** | **✅ Recommended** | **Tested with GCC 13.3.0 + Driver v581.80** | +| 13.3.0 | GCC up to 15.x ✓ | ✅ Supported | Tested with GCC 15.2 | +| **12.9.0** | **GCC 13.x ✓** (up to 14.x) | **✅ Recommended** | **Tested with GCC 13.3.0 + Driver v581.80; nvcc rejects GCC > 14** | | 12.4.1 | GCC 13.x ✓ | ✅ Supported | Minimum supported version | | 12.2.1 | GCC 12.x ✓ | ⚠️ Limited | Use GCC ≤ 12.3.0 only | | 12.2.1 | GCC 13.x ✗ | ❌ Incompatible | NVCC error: "unsupported GNU version" | @@ -46,7 +55,7 @@ For GPU/CUDA support (enabled with `-DRequireCUDA=ON`), you need: ### Note on Directory Names On some systems, library directories are called `lib` while on others they're called `lib64`. Adjust paths accordingly in the CMake configuration commands below. -We recomment installing software (including googletest, if desired) using Spack: +We recommend installing software (including googletest, if desired) using Spack: https://github.com/spack/spack.git ## 1. Optional dependencies @@ -99,14 +108,13 @@ Later on, we'll assume these recipes were executed from a directory that contains (or will contain) the ``RandLAPACK`` project directory as a subdirectory. One can compile and install BLAS++ from -[source](https://bitbucket.org/icl/blaspp/src/master/) using CMake by running +[source](https://github.com/icl-utk-edu/blaspp) using CMake by running ```shell git clone https://github.com/icl-utk-edu/blaspp.git mkdir blaspp-build cd blaspp-build cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=`pwd`/../blaspp-install \ - -DCMAKE_BINARY_DIR=`pwd` \ -Dbuild_tests=OFF \ -Dblas_int=int64 \ ../blaspp @@ -118,7 +126,7 @@ i.e. pointing at the BLAS vendor library's /include/ folder. This will ensure that CBLAS is properly encountered by CMake. One can compile and install LAPACK++ from -[source](https://bitbucket.org/icl/lapackpp/src/master/) using CMake by running +[source](https://github.com/icl-utk-edu/lapackpp) using CMake by running ```shell git clone https://github.com/icl-utk-edu/lapackpp.git mkdir lapackpp-build @@ -126,7 +134,6 @@ cd lapackpp-build cmake -DCMAKE_BUILD_TYPE=Release \ -Dblaspp_DIR=`pwd`/../blaspp-install/lib/cmake/blaspp \ -DCMAKE_INSTALL_PREFIX=`pwd`/../lapackpp-install \ - -DCMAKE_BINARY_DIR=`pwd` \ -Dbuild_tests=OFF \ ../lapackpp make -j2 install @@ -157,7 +164,6 @@ cmake -DCMAKE_BUILD_TYPE=Release \ -Dlapackpp_DIR=`pwd`/../lapackpp-install/lib/cmake/lapackpp/ \ -Dblaspp_DIR=`pwd`/../blaspp-install/lib/cmake/blaspp/ \ -DRandom123_DIR=`pwd`/../random123-install/include/ \ - -DCMAKE_BINARY_DIR=`pwd` \ -DCMAKE_INSTALL_PREFIX=`pwd`/../RandLAPACK-install \ ../RandLAPACK/ make -j install @@ -176,6 +182,10 @@ Here are the conceptual meanings in the recipe's build flags: * `-Dblaspp_DIR=X` means `X` is the directory containing the file `blasppConfig.cmake`. +* `-DRandLAPACK_BUILD_TESTS=ON` builds the GoogleTest regression suite + (requires GTest); `-DBUILD_SHARED_LIBS` and `-DSANITIZE_ADDRESS=ON` + (AddressSanitizer instrumentation, Debug builds) are also available. + * `-DRandom123_DIR=X` means `X` is the directory that contains a folder called ``Random123`` that includes the Random123 header files. For example, ``X/Random123/philox.h`` needs to be a file on your system. @@ -193,7 +203,7 @@ For instance, the following CMakeLists.txt demonstrates how an executable can be linked to the RandLAPACK library: ```cmake -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.21) project(myexec) find_package(blaspp REQUIRED) @@ -232,15 +242,16 @@ you want to make a project that connects RandLAPACK and Intel MKL. Such a situation might arise if you want to use RandLAPACK together with MKL's sparse linear algebra functionality. -One of the RandLAPACK developers (Riley) has run into trouble -getting BLAS++ to link to MKL as intended. -Here's how Riley configured his BLAS++ and LAPACK++ installations: +RandLAPACK developers have run into trouble getting BLAS++ to link to MKL +as intended. Here is a configuration of BLAS++ and LAPACK++ that is known +to work: 0. Install and configure MKL. You can get MKL [here](https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit-download.html?operatingsystem=linux&distributions=webdownload&options=online). - Once you've installed it you need to edit your `.bashrc` file. - Riley's bashrc file was updated to contain the line + Once you've installed it you need to make its libraries findable, for + example by adding lines like the following to your shell startup file + (adjust the path to your MKL installation): ``` - export MAIN_MKL_LIBS="/home/riley/intel/oneapi/mkl/latest/lib/intel64" + export MAIN_MKL_LIBS="/path/to/intel/oneapi/mkl/latest/lib/intel64" export LD_LIBRARY_PATH="${MAIN_MKL_LIBS}:${LD_LIBRARY_PATH}" export LIBRARY_PATH="${MAIN_MKL_LIBS}:${LIBRARY_PATH}" ``` @@ -278,7 +289,6 @@ Here's how Riley configured his BLAS++ and LAPACK++ installations: cmake -DCMAKE_BUILD_TYPE=Release \ -Dblaspp_DIR=/opt/mklpp/lib/blaspp \ -DCMAKE_INSTALL_PREFIX=/opt/mklpp \ - -DCMAKE_BINARY_DIR=`pwd` \ -Dbuild_tests=OFF .. make -j2 install ``` diff --git a/docs/INSTALL_SCRIPT.md b/docs/INSTALL_SCRIPT.md new file mode 100644 index 00000000..ad799e3b --- /dev/null +++ b/docs/INSTALL_SCRIPT.md @@ -0,0 +1,261 @@ +# Using RandLAPACK's Automated Install Script + +This guide explains how to use the `install.sh` script to automatically install +RandLAPACK and all of its dependencies (BLAS++, LAPACK++, Random123) with a +single command. + +**When to use this guide:** Use this automated installation method if you want +a quick, streamlined setup process. If you need fine-grained control over +dependency configurations, refer to RandLAPACK's `docs/INSTALL.md` instead. + +## 0. Software Requirements + +Before running the install script, ensure you have the following software +available on your system: + +### Essential Requirements +* **C++ Compiler:** GNU GCC 13.3.0 is the reference version (any C++20 + compiler can work; the script warns on other versions and continues) +* **CMake:** Version 3.21 or higher (recent releases recommended) +* **BLAS/LAPACK Library:** Intel MKL 2022 or higher recommended on Linux; + on macOS, Homebrew OpenBLAS and libomp are required + (`brew install openblas libomp`) +* **GoogleTest:** (Optional but recommended) For running RandLAPACK tests + +### GPU Support Requirements (Optional) +* **CUDA Toolkit:** Version 12.4.1 or higher + - **Recommended:** CUDA 12.9.0 + GCC 13.3.0 + - **IMPORTANT:** CUDA versions have strict GCC compatibility requirements: + - CUDA 12.9.0: Compatible with GCC 13.x + - CUDA 12.4.1: Compatible with GCC 13.x + - CUDA 12.2.1: Requires GCC 12.x or older ("unsupported GNU version" otherwise) + - See `INSTALL.md` Section 0 for the full compatibility matrix + - Ensure a compatible NVIDIA driver (v580+ recommended for CUDA 12.9) +* **CUDA Libraries:** cuBLAS and cuSOLVER (included with the CUDA Toolkit) + +### Installing Requirements with Spack + +We recommend [Spack](https://github.com/spack/spack) for managing these +dependencies. A typical installation: + +```shell +# Step 1: Install the compiler FIRST +spack install gcc@13.3.0 + +# Step 2: Register the new compiler with Spack +spack compiler find + +# Step 3: Load the compiler +spack load gcc@13.3.0 + +# Step 4: Install all other dependencies using the new compiler +spack install cmake +spack install intel-oneapi-mkl +spack install googletest + +# For GPU support +spack install cuda@12.9.0 +``` + +**IMPORTANT:** The compiler must be installed, registered with +`spack compiler find`, and loaded *before* installing other dependencies, so +every package builds with the intended compiler. + +After installation, load the environment (and consider adding these commands +to your shell startup file, compiler first): + +```shell +spack load gcc@13.3.0 +spack load cmake +spack load intel-oneapi-mkl +spack load googletest +spack load cuda@12.9.0 # If GPU support needed +``` + +## 1. Preparing for Installation + +### Directory Structure + +On its first run the script moves your clone into a project layout that it +creates next to the clone: + +``` +/ +|-- RandLAPACK/ # your clone (moved into the layout on first run) +`-- RandNLA-project/ # created by the script + |-- lib/ + | |-- RandLAPACK/ # the clone, after the move + | |-- blaspp/ # cloned + built by the script + | `-- lapackpp/ # cloned + built by the script + |-- install/ + | |-- RandLAPACK-install/ # installed headers + CMake config + | |-- blaspp-install/ + | |-- lapackpp-install/ + | `-- random123/ # header-only clone + |-- build/ # one build directory per project above + `-- install.log # full build log of the latest run +``` + +Re-running the script from the moved location +(`RandNLA-project/lib/RandLAPACK/install.sh`) detects the layout, reuses the +dependency installs and build directories, and performs an incremental +rebuild. + +### Initial Setup + +```shell +mkdir -p ~/RandNLA +cd ~/RandNLA +git clone --recursive https://github.com/BallisticLA/RandLAPACK.git +cd RandLAPACK +``` + +If you need a development branch, check it out before running the script. + +## 2. Running the Install Script + +### Basic Usage + +From inside the `RandLAPACK` directory: + +```shell +bash install.sh +``` + +The script will: +1. Detect if GPU hardware is available on your system and, on a terminal, + ask whether to build with CUDA support +2. Automatically clone and build all dependencies (or reuse preinstalled + ones, see the discovery variables below) +3. Build RandLAPACK with appropriate configuration +4. Build test and benchmark executables + +Run `bash install.sh --help` for the full option list. The main flags, each +with an environment-variable equivalent: + +``` +-y, --yes assume "yes" for every prompt + --gpu / --no-gpu decide GPU support without asking +-j, --jobs parallel build jobs (default: number of cores) + --fresh clear build directories first (default: reuse them, + so re-running is an incremental rebuild) + --modify-rc append RANDNLA_PROJECT_DIR/RANDNLA_PROJECT_GPU_AVAIL + exports to your shell config (default: never touch it; + the summary prints the lines to add yourself) + --project-dir place/locate RandNLA-project at D +``` + +### Automated Installation (Non-Interactive) + +Prompts appear only when stdin is a terminal. Piped and CI runs are already +non-interactive with safe defaults (NVIDIA detected: GPU build; AMD or no +GPU: CPU build), so no `yes |` piping is needed: + +```shell +bash install.sh < /dev/null # or simply: bash install.sh --yes +``` + +### Installation Logging + +All compiler output goes to `/install.log` automatically; the +console shows one line per step, and any failure prints the log path plus +the last lines of the log. There is no need to tee the output yourself. + +### Reusing Preinstalled Dependencies (Discovery) + +If you already have BLAS++, LAPACK++, or Random123 installed, point the +script at them and it will skip those builds: + +```shell +BLASPP_INSTALL_DIR=/path/to/blaspp-install \ +LAPACKPP_INSTALL_DIR=/path/to/lapackpp-install \ +RANDOM123_INSTALL_DIR=/path/to/random123 \ +bash install.sh +``` + +Each variable must point at an install root (the directory containing +`lib*/cmake//` or, for Random123, `include/Random123/`). Dependencies +the script itself installed on a previous run are reused automatically. +RandBLAS is deliberately not covered: it stays a pinned git submodule (see +`INSTALL.md`, section "RandBLAS is a pinned submodule"). + +## 3. What the Script Does + +In order (steps are numbered on the console and logged to `install.log`): + +1. **Toolchain and GPU decision.** GCC/NVCC versions are checked (warn and + continue by default), GPU hardware is detected, and the CUDA choice is + made from flags, prompts, or non-interactive defaults. +2. **Project layout.** Creates `RandNLA-project/{lib,install,build}` next to + the clone and moves the clone into `lib/RandLAPACK` (first run only). +3. **Dependency discovery.** Reuses externally provided or previously built + BLAS++/LAPACK++/Random123 installs; clones what is missing. +4. **BLAS++** configure, build, install (into `install/blaspp-install/`). +5. **LAPACK++** configure, build, install (into `install/lapackpp-install/`), + against the BLAS++ from the previous step. +6. **RandLAPACK** configure, build, install (headers and CMake config into + `install/RandLAPACK-install/`), with the test suite enabled. +7. **extras** and **benchmarks**: two standalone downstream projects, + configured against the *installed* RandLAPACK and built (executables stay + in their build directories). + +## 4. Verifying the Installation + +Run the test suite from anywhere: + +```shell +ctest --test-dir /RandNLA-project/build/RandLAPACK-build +``` + +The suite should pass (the exact test count grows over time; CI runs this +same suite on every change). If you enabled GPU support, the GPU tests run +as part of the same suite; to run only them: + +```shell +/RandNLA-project/build/RandLAPACK-build/bin/RandLAPACK_tests_gpu +``` + +## 5. Working with the Installed Project + +### Key File Locations + +* **Installed headers + CMake config:** + `RandNLA-project/install/RandLAPACK-install/` (the config file lives under + `lib*/cmake/RandLAPACK/`; RandLAPACK is header-only, so there is no + library archive) +* **Test executables:** `RandNLA-project/build/RandLAPACK-build/bin/` +* **Extras executables:** `RandNLA-project/build/extras-build/` +* **Benchmark executables:** `RandNLA-project/build/benchmark-build/` + (see `benchmark/README.md` for how to run them) + +### Recompiling After Code Changes + +```shell +cd /RandNLA-project/build/RandLAPACK-build +make -j && make install +``` + +The `make install` matters: RandLAPACK is header-only, and the extras, +benchmarks, and your own projects consume the *installed* headers, so +changes only reach them after an install. Alternatively just re-run +`bash install.sh` from `lib/RandLAPACK/`; re-runs are incremental. + +### Using RandLAPACK in Your Own Projects + +See Section 4 of `INSTALL.md`. The paths produced by this script are: + +``` +-Dblaspp_DIR=/RandNLA-project/install/blaspp-install/lib/cmake/blaspp +-Dlapackpp_DIR=/RandNLA-project/install/lapackpp-install/lib/cmake/lapackpp +-DRandLAPACK_DIR=/RandNLA-project/install/RandLAPACK-install/lib/cmake/RandLAPACK +``` + +(depending on the platform, `lib` may be `lib64`; the installer's final +summary prints the exact `RandLAPACK_DIR` for your machine). + +## 6. Benchmarks + +Benchmark executables are built automatically into +`RandNLA-project/build/benchmark-build/`. Usage, including the GPU +benchmarks and their output formats, is documented in +[`benchmark/README.md`](../benchmark/README.md). diff --git a/extras/README.md b/extras/README.md index 102bb9be..57498dcc 100644 --- a/extras/README.md +++ b/extras/README.md @@ -1,6 +1,21 @@ # RandLAPACK Extras -Standalone project for extended functionality and tests that depend on libraries not required by core RandLAPACK (e.g., Eigen, fast_matrix_market). +Standalone project for extended functionality and tests that depend on +libraries not required by core RandLAPACK (e.g., Eigen, fast_matrix_market). + +**Why this folder exists, and why it is a holding area.** Core RandLAPACK +deliberately depends on nothing beyond RandBLAS, BLAS++, LAPACK++, and +Random123. Some useful functionality (solver-backed linear operators, Matrix +Market file I/O) currently needs third-party libraries that we are not +willing to make RandLAPACK dependencies. Such code lives here, quarantined +behind its own build, until one of two things happens: the external +dependency is replaced with an in-house implementation and the functionality +graduates into RandLAPACK proper, or the functionality proves niche enough +to stay an optional integration permanently. Nothing in `extras/` is part of +RandLAPACK's API, and nothing in RandLAPACK may include from it. + +**Not to be confused with `benchmark/`**: that directory measures the +performance of RandLAPACK itself; this one extends its functionality. ## Directory Layout diff --git a/install.sh b/install.sh index 0fe96323..52e4a28e 100755 --- a/install.sh +++ b/install.sh @@ -38,7 +38,7 @@ # All compiler output goes to /install.log; the console shows one # line per step. On failure the log path is printed. # -# Prerequisites are listed in INSTALL.md. +# Prerequisites are listed in docs/INSTALL.md. set -euo pipefail #==============================================================================