use std::ffi::{c_char, c_int, c_void};
use std::sync::Once;
use super::_runtime::configure_native_threading;
static LOADED: Once = Once::new();
pub(crate) fn load() {
LOADED.call_once(|| {
if let Some(threads) = configure_native_threading() {
set_blas_threads(threads);
}
});
}
#[cfg(unix)]
fn find_openblas_set_num_threads() -> *mut c_void {
unsafe extern "C" {
fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void;
}
#[cfg(target_os = "macos")]
const RTLD_DEFAULT: *mut c_void = std::ptr::without_provenance_mut(-2isize as usize);
#[cfg(not(target_os = "macos"))]
const RTLD_DEFAULT: *mut c_void = std::ptr::null_mut();
unsafe { dlsym(RTLD_DEFAULT, c"openblas_set_num_threads".as_ptr()) }
}
#[cfg(windows)]
fn find_openblas_set_num_threads() -> *mut c_void {
unsafe extern "system" {
fn GetModuleHandleA(module_name: *const c_char) -> *mut c_void;
fn GetProcAddress(module: *mut c_void, proc_name: *const c_char) -> *mut c_void;
}
unsafe {
let module = GetModuleHandleA(c"libopenblas.dll".as_ptr());
if module.is_null() {
return std::ptr::null_mut();
}
GetProcAddress(module, c"openblas_set_num_threads".as_ptr())
}
}
fn set_blas_threads(threads: c_int) {
unsafe {
let symbol = find_openblas_set_num_threads();
if !symbol.is_null() {
let set_num_threads: extern "C" fn(c_int) = std::mem::transmute(symbol);
set_num_threads(threads);
}
}
}
unsafe extern "C" {
pub(crate) fn viz_filter_mask_(
pct_diff: *const f64,
local_prob: *const f64,
local_z: *const f64,
filter_level: *const c_int,
keep_mask: *mut i8,
status: *mut c_int,
n: *const c_int,
);
pub(crate) fn viz_zstats_radius_gridagg_(
x: *const f64,
y: *const f64,
z: *const f64,
radius: *const f64,
cell_factor: *const c_int,
max_neighbors: *const c_int,
candidate_fraction: *const f64,
dedup_radius: *const f64,
dedup_z_tol: *const f64,
thread_count: *const c_int,
pct_diff: *mut f64,
local_z: *mut f64,
local_prob: *mut f64,
status: *mut c_int,
n: *const c_int,
);
pub(crate) fn fit_variogram_models_(
x: *const f64,
y: *const f64,
z: *const f64,
n_lags: *const c_int,
max_pairs: *const c_int,
max_distance: *const f64,
thread_count: *const c_int,
model_info: *mut f64,
n: *const c_int,
);
pub(crate) fn select_variogram_(model_info: *const f64, params: *mut f64, status: *mut c_int);
pub(crate) fn evaluate_variogram_(
model_info: *const f64,
distance: *const f64,
thread_count: *const c_int,
gamma: *mut f64,
status: *mut c_int,
n: *const c_int,
);
pub(crate) fn idw_local_(
x: *const f64,
y: *const f64,
z: *const f64,
target_x: *const f64,
target_y: *const f64,
radius: *const f64,
power: *const f64,
max_neighbors: *const c_int,
min_neighbors: *const c_int,
thread_count: *const c_int,
estimates: *mut f64,
status: *mut c_int,
n: *const c_int,
ntargets: *const c_int,
);
pub(crate) fn ordinary_kriging_local_(
x: *const f64,
y: *const f64,
z: *const f64,
target_x: *const f64,
target_y: *const f64,
model_info: *const f64,
radius: *const f64,
max_neighbors: *const c_int,
min_neighbors: *const c_int,
thread_count: *const c_int,
estimates: *mut f64,
status: *mut c_int,
n: *const c_int,
ntargets: *const c_int,
);
pub(crate) fn cross_validate_local_(
x: *const f64,
y: *const f64,
z: *const f64,
sample_idx: *const c_int,
radius: *const f64,
power: *const f64,
model_info: *const f64,
max_neighbors: *const c_int,
min_neighbors: *const c_int,
thread_count: *const c_int,
idw_pred: *mut f64,
krig_pred: *mut f64,
idw_mae: *mut f64,
idw_rmse: *mut f64,
idw_r2: *mut f64,
idw_n_valid: *mut c_int,
krig_mae: *mut f64,
krig_rmse: *mut f64,
krig_r2: *mut f64,
krig_n_valid: *mut c_int,
status: *mut c_int,
n: *const c_int,
nsamples: *const c_int,
);
pub(crate) fn cokriging_cross_validate_local_(
x0: *const f64,
y0: *const f64,
z0: *const f64,
sample_idx: *const c_int,
secondary_x: *const f64,
secondary_y: *const f64,
secondary_z: *const f64,
secondary_offset: *const c_int,
run_collocated: *const c_int,
collocated_model: *const f64,
run_icm: *const c_int,
icm_model_id: *const f64,
icm_range: *const f64,
icm_nugget: *const f64,
icm_sill: *const f64,
run_lmc: *const c_int,
lmc_model_id: *const f64,
lmc_ranges: *const f64,
lmc_coefficients: *const f64,
radius: *const f64,
max_neighbors: *const c_int,
max_secondary_neighbors: *const c_int,
min_neighbors: *const c_int,
thread_count: *const c_int,
collocated_pred: *mut f64,
icm_pred: *mut f64,
lmc_pred: *mut f64,
collocated_mae: *mut f64,
collocated_rmse: *mut f64,
collocated_r2: *mut f64,
collocated_n_valid: *mut c_int,
icm_mae: *mut f64,
icm_rmse: *mut f64,
icm_r2: *mut f64,
icm_n_valid: *mut c_int,
lmc_mae: *mut f64,
lmc_rmse: *mut f64,
lmc_r2: *mut f64,
lmc_n_valid: *mut c_int,
status: *mut c_int,
n: *const c_int,
nsamples: *const c_int,
n_secondary_total: *const c_int,
nv: *const c_int,
collocated_model_size: *const c_int,
n_lmc_structures: *const c_int,
n_lmc_continuous: *const c_int,
);
pub(crate) fn fit_cross_variogram_(
xa: *const f64,
ya: *const f64,
za: *const f64,
xb: *const f64,
yb: *const f64,
zb: *const f64,
max_colocation_dist: *const f64,
n_lags: *const c_int,
max_pairs: *const c_int,
max_distance: *const f64,
thread_count: *const c_int,
model_info: *mut f64,
rho: *mut f64,
n_pairs: *mut c_int,
na: *const c_int,
nb: *const c_int,
);
pub(crate) fn screen_covariate_(
model_00: *const f64,
model_uu: *const f64,
model_0u: *const f64,
rho: *const f64,
n_pairs: *const c_int,
alpha: *const f64,
min_abs_rho: *const f64,
max_violation_fraction: *const f64,
decision: *mut c_int,
p_value: *mut f64,
admissible_fraction: *mut f64,
status: *mut c_int,
);
pub(crate) fn collocated_cokriging_local_(
x0: *const f64,
y0: *const f64,
z0: *const f64,
target_x: *const f64,
target_y: *const f64,
coreg_model: *const f64,
secondary_x: *const f64,
secondary_y: *const f64,
secondary_z: *const f64,
secondary_offset: *const c_int,
radius: *const f64,
max_neighbors: *const c_int,
min_neighbors: *const c_int,
thread_count: *const c_int,
estimates: *mut f64,
status: *mut c_int,
n: *const c_int,
ntargets: *const c_int,
coreg_model_size: *const c_int,
n_secondary_total: *const c_int,
n_offsets: *const c_int,
);
pub(crate) fn fit_icm_model_(
x0: *const f64,
y0: *const f64,
z0: *const f64,
secondary_x: *const f64,
secondary_y: *const f64,
secondary_z: *const f64,
secondary_offset: *const c_int,
n_lags: *const c_int,
max_pairs: *const c_int,
max_distance: *const f64,
max_colocation_dist: *const f64,
thread_count: *const c_int,
model_id: *mut f64,
model_range: *mut f64,
nugget_matrix: *mut f64,
sill_matrix: *mut f64,
status: *mut c_int,
n: *const c_int,
n_secondary_total: *const c_int,
nv: *const c_int,
);
pub(crate) fn co_kriging_icm_local_(
x0: *const f64,
y0: *const f64,
z0: *const f64,
target_x: *const f64,
target_y: *const f64,
model_id: *const f64,
model_range: *const f64,
nugget_matrix: *const f64,
sill_matrix: *const f64,
secondary_x: *const f64,
secondary_y: *const f64,
secondary_z: *const f64,
secondary_offset: *const c_int,
radius: *const f64,
max_neighbors: *const c_int,
max_secondary_neighbors: *const c_int,
min_neighbors: *const c_int,
thread_count: *const c_int,
estimates: *mut f64,
status: *mut c_int,
n: *const c_int,
ntargets: *const c_int,
nv: *const c_int,
n_secondary_total: *const c_int,
);
pub(crate) fn fit_lmc_model_(
x0: *const f64,
y0: *const f64,
z0: *const f64,
secondary_x: *const f64,
secondary_y: *const f64,
secondary_z: *const f64,
secondary_offset: *const c_int,
n_structures: *const c_int,
n_lags: *const c_int,
max_pairs: *const c_int,
max_distance: *const f64,
max_colocation_dist: *const f64,
thread_count: *const c_int,
model_id: *mut f64,
structure_ranges: *mut f64,
coefficient_matrices: *mut f64,
status: *mut c_int,
n: *const c_int,
n_secondary_total: *const c_int,
nv: *const c_int,
n_continuous: *const c_int,
);
pub(crate) fn co_kriging_lmc_local_(
x0: *const f64,
y0: *const f64,
z0: *const f64,
target_x: *const f64,
target_y: *const f64,
model_id: *const f64,
structure_ranges: *const f64,
coefficient_matrices: *const f64,
secondary_x: *const f64,
secondary_y: *const f64,
secondary_z: *const f64,
secondary_offset: *const c_int,
radius: *const f64,
max_neighbors: *const c_int,
max_secondary_neighbors: *const c_int,
min_neighbors: *const c_int,
thread_count: *const c_int,
estimates: *mut f64,
status: *mut c_int,
n: *const c_int,
ntargets: *const c_int,
nv: *const c_int,
n_secondary_total: *const c_int,
n_structures: *const c_int,
n_continuous: *const c_int,
);
}
#[cfg(test)]
unsafe extern "C" {
pub(crate) fn erf(x: f64) -> f64;
}