use std::ptr;
use cugraph_sys::{cugraph_error_t, cugraph_hierarchical_clustering_result_t, cugraph_leiden};
use super::LeidenResult;
use crate::{
error::{Result, check_error, require_non_null},
graph::{Forward, Graph},
handle::EnteredContext,
params::{IterationCount, PositiveF64, defaults},
random::RngState,
types::to_bool_t,
};
const LIBCUGRAPH_IGNORED_THETA: f64 = 1.0;
#[derive(Debug, Clone, Copy)]
#[must_use]
pub struct LeidenParams {
pub max_level: IterationCount,
pub resolution: PositiveF64,
pub do_expensive_check: bool,
}
impl Default for LeidenParams {
fn default() -> Self {
Self {
max_level: defaults::LOUVAIN_MAX_LEVEL,
resolution: defaults::LOUVAIN_RESOLUTION,
do_expensive_check: false,
}
}
}
pub(crate) fn leiden(
handle: &EnteredContext<'_>,
rng_state: &mut RngState,
graph: &mut Graph<Forward>,
params: &LeidenParams,
) -> Result<LeidenResult> {
let mut result: *mut cugraph_hierarchical_clustering_result_t = ptr::null_mut();
let mut error: *mut cugraph_error_t = ptr::null_mut();
let graph_ptr = graph.as_ptr(handle, "leiden")?;
unsafe {
let code = cugraph_leiden(
handle.handle_ptr(),
rng_state.as_ptr(),
graph_ptr,
usize::from(params.max_level),
params.resolution.get(),
LIBCUGRAPH_IGNORED_THETA,
to_bool_t(params.do_expensive_check),
&mut result,
&mut error,
);
check_error(code, error, handle.device(), "leiden")?;
}
let result = require_non_null(result, "leiden", "hierarchical_clustering_result")?;
unsafe { LeidenResult::from_raw(result, handle.device(), handle.runtime_bound_lease()) }
}