extern crate libc;
use self::libc::{c_int, c_uint, c_void};
use crate::array::Array;
use crate::defines::{AfError, SparseFormat};
use crate::error::HANDLE_ERROR;
use crate::util::{AfArray, DimT, MutAfArray, MutDimT};
use crate::util::{FloatingPoint, HasAfEnum};
#[allow(dead_code)]
extern "C" {
fn af_create_sparse_array(
out: MutAfArray,
nRows: DimT,
nCols: DimT,
vals: AfArray,
rowIdx: AfArray,
colIdx: AfArray,
stype: c_uint,
) -> c_int;
fn af_create_sparse_array_from_ptr(
out: MutAfArray,
nRows: DimT,
nCols: DimT,
nNZ: DimT,
values: *const c_void,
rowIdx: *const c_int,
colIdx: *const c_int,
aftype: c_uint,
stype: c_uint,
src: c_uint,
) -> c_int;
fn af_create_sparse_array_from_dense(out: MutAfArray, dense: AfArray, stype: c_uint) -> c_int;
fn af_sparse_convert_to(out: MutAfArray, input: AfArray, dstStrge: c_uint) -> c_int;
fn af_sparse_to_dense(out: MutAfArray, sparse: AfArray) -> c_int;
fn af_sparse_get_info(
vals: MutAfArray,
rIdx: MutAfArray,
cIdx: MutAfArray,
stype: *mut c_uint,
input: AfArray,
) -> c_int;
fn af_sparse_get_values(out: MutAfArray, input: AfArray) -> c_int;
fn af_sparse_get_row_idx(out: MutAfArray, input: AfArray) -> c_int;
fn af_sparse_get_col_idx(out: MutAfArray, input: AfArray) -> c_int;
fn af_sparse_get_nnz(out: MutDimT, input: AfArray) -> c_int;
fn af_sparse_get_storage(out: *mut c_uint, input: AfArray) -> c_int;
}
pub fn sparse<T>(
rows: u64,
cols: u64,
values: &Array<T>,
row_indices: &Array<i32>,
col_indices: &Array<i32>,
format: SparseFormat,
) -> Array<T>
where
T: HasAfEnum + FloatingPoint,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_create_sparse_array(
&mut temp as MutAfArray,
rows as DimT,
cols as DimT,
values.get() as AfArray,
row_indices.get() as AfArray,
col_indices.get() as AfArray,
format as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn sparse_from_host<T>(
rows: u64,
cols: u64,
nzz: u64,
values: &[T],
row_indices: &[i32],
col_indices: &[i32],
format: SparseFormat,
) -> Array<T>
where
T: HasAfEnum + FloatingPoint,
{
let aftype = T::get_af_dtype();
let mut temp: i64 = 0;
unsafe {
let err_val = af_create_sparse_array_from_ptr(
&mut temp as MutAfArray,
rows as DimT,
cols as DimT,
nzz as DimT,
values.as_ptr() as *const c_void,
row_indices.as_ptr() as *const c_int,
col_indices.as_ptr() as *const c_int,
aftype as c_uint,
format as c_uint,
1,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn sparse_from_dense<T>(dense: &Array<T>, format: SparseFormat) -> Array<T>
where
T: HasAfEnum + FloatingPoint,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_create_sparse_array_from_dense(
&mut temp as MutAfArray,
dense.get() as AfArray,
format as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn sparse_convert_to<T>(input: &Array<T>, format: SparseFormat) -> Array<T>
where
T: HasAfEnum + FloatingPoint,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_sparse_convert_to(
&mut temp as MutAfArray,
input.get() as AfArray,
format as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn sparse_to_dense<T>(input: &Array<T>) -> Array<T>
where
T: HasAfEnum + FloatingPoint,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_sparse_to_dense(&mut temp as MutAfArray, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn sparse_get_info<T>(input: &Array<T>) -> (Array<T>, Array<i32>, Array<i32>, SparseFormat)
where
T: HasAfEnum + FloatingPoint,
{
let mut val: i64 = 0;
let mut row: i64 = 0;
let mut col: i64 = 0;
let mut stype: u32 = 0;
unsafe {
let err_val = af_sparse_get_info(
&mut val as MutAfArray,
&mut row as MutAfArray,
&mut col as MutAfArray,
&mut stype as *mut c_uint,
input.get() as AfArray,
);
HANDLE_ERROR(AfError::from(err_val));
}
(
val.into(),
row.into(),
col.into(),
SparseFormat::from(stype),
)
}
pub fn sparse_get_values<T>(input: &Array<T>) -> Array<T>
where
T: HasAfEnum + FloatingPoint,
{
let mut val: i64 = 0;
unsafe {
let err_val = af_sparse_get_values(&mut val as MutAfArray, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
val.into()
}
pub fn sparse_get_row_indices<T>(input: &Array<T>) -> Array<i32>
where
T: HasAfEnum + FloatingPoint,
{
let mut val: i64 = 0;
unsafe {
let err_val = af_sparse_get_row_idx(&mut val as MutAfArray, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
val.into()
}
pub fn sparse_get_col_indices<T>(input: &Array<T>) -> Array<i32>
where
T: HasAfEnum + FloatingPoint,
{
let mut val: i64 = 0;
unsafe {
let err_val = af_sparse_get_col_idx(&mut val as MutAfArray, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
val.into()
}
pub fn sparse_get_nnz<T: HasAfEnum>(input: &Array<T>) -> i64 {
let mut count: i64 = 0;
unsafe {
let err_val = af_sparse_get_nnz(&mut count as *mut DimT, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
count
}
pub fn sparse_get_format<T: HasAfEnum>(input: &Array<T>) -> SparseFormat {
let mut stype: u32 = 0;
unsafe {
let err_val = af_sparse_get_storage(&mut stype as *mut c_uint, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
SparseFormat::from(stype)
}