use crate::internal::{to_i32, CcBool, C_TRUE};
extern "C" {
fn c_using_intel_mkl() -> CcBool;
fn c_set_num_threads(n: i32);
fn c_get_num_threads() -> i32;
fn cblas_idamax(n: i32, x: *const f64, incx: i32) -> i32;
}
pub fn using_intel_mkl() -> bool {
unsafe { c_using_intel_mkl() == C_TRUE }
}
pub fn set_num_threads(n: usize) {
let n_i32 = to_i32(n);
unsafe {
c_set_num_threads(n_i32);
}
}
pub fn get_num_threads() -> usize {
unsafe { c_get_num_threads() as usize }
}
pub fn find_index_abs_max(x: &[f64]) -> usize {
let n = to_i32(x.len());
unsafe {
let i = cblas_idamax(n, x.as_ptr(), 1);
assert!(i >= 0);
i as usize
}
}
#[cfg(test)]
mod tests {
use super::{find_index_abs_max, get_num_threads, set_num_threads, using_intel_mkl};
#[test]
fn using_intel_mkl_works() {
if cfg!(feature = "intel_mkl") {
assert!(using_intel_mkl());
} else {
assert!(!using_intel_mkl());
}
}
#[test]
fn set_num_threads_and_get_num_threads_work() {
assert!(get_num_threads() > 0);
set_num_threads(1);
assert_eq!(get_num_threads(), 1);
}
#[test]
fn find_index_abs_max_works() {
let x = &[1.0, -2.0, -8.0, 3.0];
assert_eq!(find_index_abs_max(x), 2);
}
}