Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/nornir

crates/mimir-graph/src/runtime.rs

//! Process-wide GraphBLAS state: init once, thread count, version.

use std::sync::OnceLock;

use crate::error::{Error, Result, grb};

/// Major version of the C library the checked-in bindings were generated from.
pub const EXPECTED_MAJOR: i32 = 7;

static INIT: OnceLock<std::result::Result<(i32, i32, i32), Error>> = OnceLock::new();

/// Initialise GraphBLAS (`GrB_init(GrB_NONBLOCKING)`) once per process and
/// check the linked library's major version. Every constructor in this crate
/// calls it, so calling it yourself is only needed to surface the error early.
pub fn init() -> Result<()> {
    INIT.get_or_init(|| {
        grb!(GrB_init(graphblas_sys::GrB_NONBLOCKING))?;
        let v = library_version_raw()?;
        if v.0 != EXPECTED_MAJOR {
            return Err(Error::Version {
                found: v,
                expected_major: EXPECTED_MAJOR,
            });
        }
        Ok(v)
    })
    .clone()
    .map(|_| ())
}

fn library_version_raw() -> Result<(i32, i32, i32)> {
    let mut v = [0i32; 3];
    // Variadic in C; GxB_LIBRARY_VERSION writes three ints.
    grb!(GxB_Global_Option_get(
        graphblas_sys::GxB_LIBRARY_VERSION,
        v.as_mut_ptr()
    ))?;
    Ok((v[0], v[1], v[2]))
}

/// `(major, minor, sub)` of the linked libgraphblas.
pub fn library_version() -> Result<(i32, i32, i32)> {
    init()?;
    INIT.get()
        .cloned()
        .unwrap_or(Err(Error::invalid("GraphBLAS not initialised")))
}

/// Maximum OpenMP threads GraphBLAS uses per call (global setting).
pub fn set_threads(n: i32) -> Result<()> {
    init()?;
    if n < 1 {
        return Err(Error::invalid(format!("thread count {n} < 1")));
    }
    grb!(GxB_Global_Option_set_INT32(
        graphblas_sys::GxB_GLOBAL_NTHREADS,
        n
    ))
}

/// Current global thread limit.
pub fn threads() -> Result<i32> {
    init()?;
    let mut n = 0i32;
    grb!(GxB_Global_Option_get_INT32(
        graphblas_sys::GxB_GLOBAL_NTHREADS,
        &mut n
    ))?;
    Ok(n)
}

/// `GrB_finalize`. GraphBLAS cannot be initialised again afterwards in the
/// same process, and every live [`Matrix`](crate::Matrix)/[`Vector`](crate::Vector)
/// would dangle.
///
/// # Safety
/// No GraphBLAS handle may be alive or created after this call.
pub unsafe fn finalize() -> Result<()> {
    grb!(GrB_finalize())
}