Files
obikmer/DevDoc/installation/index.html
T
Eric Coissac 5c1584967f feat: enable index resumption and enforce directory creation
The command now supports reopening existing indexes instead of failing when the output file exists. Control flow branches between opening an existing index and constructing a new one, moving configuration setup exclusively to the creation path. Directory existence is enforced upfront with proper I/O error propagation. The --force flag retains its original semantics by removing the target directory before proceeding with a fresh build.
2026-08-21 05:06:38 +02:00

1681 lines
30 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="prev" href="..">
<link rel="next" href="../kmers/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<title>Installation - obikmer</title>
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#installation" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="obikmer" class="md-header__button md-logo" aria-label="obikmer" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
obikmer
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Installation
</span>
</div>
</div>
</div>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="obikmer" class="md-nav__button md-logo" aria-label="obikmer" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
obikmer
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Installation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Installation
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#prerequisites" class="md-nav__link">
<span class="md-ellipsis">
Prerequisites
</span>
</a>
<nav class="md-nav" aria-label="Prerequisites">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#rust-toolchain" class="md-nav__link">
<span class="md-ellipsis">
Rust toolchain
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#c-build-environment-required-for-hwloc" class="md-nav__link">
<span class="md-ellipsis">
C build environment (required for hwloc)
</span>
</a>
<nav class="md-nav" aria-label="C build environment (required for hwloc)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#linux-debianubuntu" class="md-nav__link">
<span class="md-ellipsis">
Linux (Debian/Ubuntu)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#linux-rhelrockyalmalinux" class="md-nav__link">
<span class="md-ellipsis">
Linux (RHEL/Rocky/AlmaLinux)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#hpc-clusters" class="md-nav__link">
<span class="md-ellipsis">
HPC clusters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#macos" class="md-nav__link">
<span class="md-ellipsis">
macOS
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#building" class="md-nav__link">
<span class="md-ellipsis">
Building
</span>
</a>
<nav class="md-nav" aria-label="Building">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#building-on-hpc-clusters-network-filesystems" class="md-nav__link">
<span class="md-ellipsis">
Building on HPC clusters (network filesystems)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#numa-support" class="md-nav__link">
<span class="md-ellipsis">
NUMA support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#verifying-the-installation" class="md-nav__link">
<span class="md-ellipsis">
Verifying the installation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
Theory
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Theory
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../kmers/" class="md-nav__link">
<span class="md-ellipsis">
Kmers and super-kmers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../theory/encoding/" class="md-nav__link">
<span class="md-ellipsis">
DNA encoding
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../theory/entropy/" class="md-nav__link">
<span class="md-ellipsis">
Entropy filter
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../theory/minimizer/" class="md-nav__link">
<span class="md-ellipsis">
Minimizer selection
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../theory/indexing/" class="md-nav__link">
<span class="md-ellipsis">
Partitioning architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../theory/evolutionary_distances/" class="md-nav__link">
<span class="md-ellipsis">
Central-position SNP distance (discussion)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
Implementation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Implementation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../implementation/superkmer/" class="md-nav__link">
<span class="md-ellipsis">
SuperKmer
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/kmer/" class="md-nav__link">
<span class="md-ellipsis">
Kmer
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/chunkreader/" class="md-nav__link">
<span class="md-ellipsis">
Chunk reader
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/pipeline/" class="md-nav__link">
<span class="md-ellipsis">
Construction pipeline
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/obipipeline/" class="md-nav__link">
<span class="md-ellipsis">
obipipeline library
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/storage/" class="md-nav__link">
<span class="md-ellipsis">
On-disk storage
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/mphf/" class="md-nav__link">
<span class="md-ellipsis">
MPHF selection
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/unitig_evidence/" class="md-nav__link">
<span class="md-ellipsis">
Unitig evidence encoding
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/evidence_elimination/" class="md-nav__link">
<span class="md-ellipsis">
Evidence elimination (discussion)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/layer_tier/" class="md-nav__link">
<span class="md-ellipsis">
obikindex layer tier
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/persistent_compact_int_vec/" class="md-nav__link">
<span class="md-ellipsis">
PersistentCompactIntVec
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/persistent_bit_vec/" class="md-nav__link">
<span class="md-ellipsis">
PersistentBitVec
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/merge/" class="md-nav__link">
<span class="md-ellipsis">
Merge command
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/merge_parallelism/" class="md-nav__link">
<span class="md-ellipsis">
Merge parallelism & memory
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/filtering/" class="md-nav__link">
<span class="md-ellipsis">
Kmer filtering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/select/" class="md-nav__link">
<span class="md-ellipsis">
Select command
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/obitaxonomy/" class="md-nav__link">
<span class="md-ellipsis">
obitaxonomy crate
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/benchmark_query_testing/" class="md-nav__link">
<span class="md-ellipsis">
Benchmark: query-path testing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../implementation/partition_layer_cache/" class="md-nav__link">
<span class="md-ellipsis">
Partition and layer caching (discussion)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Architecture
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Architecture
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../architecture/sequences/invariant/" class="md-nav__link">
<span class="md-ellipsis">
Sequences
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../architecture/index_architecture/" class="md-nav__link">
<span class="md-ellipsis">
Kmer index
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../architecture/siblings/" class="md-nav__link">
<span class="md-ellipsis">
Sibling annex (discussion)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../architecture/numa_worker_pools/" class="md-nav__link">
<span class="md-ellipsis">
NUMA-aware worker pools
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../architecture/numa_partition_runner/" class="md-nav__link">
<span class="md-ellipsis">
NUMA-aware partition runner
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#prerequisites" class="md-nav__link">
<span class="md-ellipsis">
Prerequisites
</span>
</a>
<nav class="md-nav" aria-label="Prerequisites">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#rust-toolchain" class="md-nav__link">
<span class="md-ellipsis">
Rust toolchain
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#c-build-environment-required-for-hwloc" class="md-nav__link">
<span class="md-ellipsis">
C build environment (required for hwloc)
</span>
</a>
<nav class="md-nav" aria-label="C build environment (required for hwloc)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#linux-debianubuntu" class="md-nav__link">
<span class="md-ellipsis">
Linux (Debian/Ubuntu)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#linux-rhelrockyalmalinux" class="md-nav__link">
<span class="md-ellipsis">
Linux (RHEL/Rocky/AlmaLinux)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#hpc-clusters" class="md-nav__link">
<span class="md-ellipsis">
HPC clusters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#macos" class="md-nav__link">
<span class="md-ellipsis">
macOS
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#building" class="md-nav__link">
<span class="md-ellipsis">
Building
</span>
</a>
<nav class="md-nav" aria-label="Building">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#building-on-hpc-clusters-network-filesystems" class="md-nav__link">
<span class="md-ellipsis">
Building on HPC clusters (network filesystems)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#numa-support" class="md-nav__link">
<span class="md-ellipsis">
NUMA support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#verifying-the-installation" class="md-nav__link">
<span class="md-ellipsis">
Verifying the installation
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="installation">Installation</h1>
<h2 id="prerequisites">Prerequisites</h2>
<h3 id="rust-toolchain">Rust toolchain</h3>
<p><code>obikmer</code> requires <strong>Rust 1.85 or later</strong> (edition 2024). Install or update via <a href="https://rustup.rs">rustup</a>:</p>
<div class="highlight"><pre><span></span><code>curl<span class="w"> </span>--proto<span class="w"> </span><span class="s1">&#39;=https&#39;</span><span class="w"> </span>--tlsv1.2<span class="w"> </span>-sSf<span class="w"> </span>https://sh.rustup.rs<span class="w"> </span><span class="p">|</span><span class="w"> </span>sh
rustup<span class="w"> </span>update<span class="w"> </span>stable
</code></pre></div>
<h3 id="c-build-environment-required-for-hwloc">C build environment (required for hwloc)</h3>
<p><code>obikmer</code> embeds <a href="https://www.open-mpi.org/projects/hwloc/">hwloc</a> (Hardware Locality) for NUMA-aware thread placement on multi-socket machines. hwloc is built from source at compile time via the <code>vendored</code> feature of the <code>hwlocality</code> crate. This requires a standard C build environment.</p>
<h4 id="linux-debianubuntu">Linux (Debian/Ubuntu)</h4>
<div class="highlight"><pre><span></span><code>apt<span class="w"> </span>install<span class="w"> </span>build-essential<span class="w"> </span>automake<span class="w"> </span>libtool<span class="w"> </span>autoconf<span class="w"> </span>pkg-config
</code></pre></div>
<h4 id="linux-rhelrockyalmalinux">Linux (RHEL/Rocky/AlmaLinux)</h4>
<div class="highlight"><pre><span></span><code>dnf<span class="w"> </span>install<span class="w"> </span>gcc<span class="w"> </span>make<span class="w"> </span>automake<span class="w"> </span>libtool<span class="w"> </span>autoconf<span class="w"> </span>pkgconfig
</code></pre></div>
<h4 id="hpc-clusters">HPC clusters</h4>
<p>Most HPC clusters provide these tools via the module system:</p>
<div class="highlight"><pre><span></span><code>module<span class="w"> </span>load<span class="w"> </span>gcc<span class="w"> </span>automake<span class="w"> </span>libtool<span class="w"> </span>autoconf
</code></pre></div>
<p>If in doubt, check whether <code>autoreconf --version</code> and <code>libtool --version</code> return successfully.</p>
<h4 id="macos">macOS</h4>
<div class="highlight"><pre><span></span><code>brew<span class="w"> </span>install<span class="w"> </span>automake<span class="w"> </span>libtool<span class="w"> </span>autoconf<span class="w"> </span>pkg-config
</code></pre></div>
<h2 id="building">Building</h2>
<div class="highlight"><pre><span></span><code>git<span class="w"> </span>clone<span class="w"> </span>&lt;repository-url&gt;
<span class="nb">cd</span><span class="w"> </span>obikmer/src
cargo<span class="w"> </span>build<span class="w"> </span>--release
</code></pre></div>
<p>The compiled binary is at <code>target/release/obikmer</code>.</p>
<h3 id="building-on-hpc-clusters-network-filesystems">Building on HPC clusters (network filesystems)</h3>
<p>HPC home directories are typically on a network filesystem (Lustre, NFS) optimised for large sequential reads — not for the thousands of small file operations that Cargo generates during compilation. Building directly on such a filesystem can be extremely slow (0.1% CPU utilisation, tens of minutes for what should take seconds).</p>
<p><strong>Always redirect the build directory to a local scratch disk:</strong></p>
<div class="highlight"><pre><span></span><code><span class="nv">CARGO_TARGET_DIR</span><span class="o">=</span>/scratch/<span class="nv">$USER</span>/cargo-target<span class="w"> </span>cargo<span class="w"> </span>build<span class="w"> </span>--release
</code></pre></div>
<p>Adapt the path to the local scratch available on your cluster (<code>/var/tmp</code>, <code>/tmp</code>, <code>/scratch/local</code>, etc.). Once built, copy the binary to a permanent location:</p>
<div class="highlight"><pre><span></span><code>cp<span class="w"> </span>/scratch/<span class="nv">$USER</span>/cargo-target/release/obikmer<span class="w"> </span>~/bin/
</code></pre></div>
<h2 id="numa-support">NUMA support</h2>
<p>NUMA-aware thread placement is active automatically on multi-socket Linux machines (detected at runtime via hwloc). No special build flag is required — the detection is built in and falls back gracefully to the single-pool adaptive strategy on:</p>
<ul>
<li>macOS (Apple Silicon, unified memory)</li>
<li>single-socket Linux machines</li>
<li>any system where hwloc reports only one NUMA node</li>
</ul>
<h2 id="verifying-the-installation">Verifying the installation</h2>
<div class="highlight"><pre><span></span><code>obikmer<span class="w"> </span>--help
</code></pre></div>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": [], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js"></script>
</body>
</html>