use ruda_kernel::dsl as kernel_dsl;
use ruda_kernel::dsl::prelude::*;
#[ruda]
pub fn sort_histogram<T: Numeric, C: Numeric>(
samples: &Array<T>, histogram: &mut SharedMemory<C>,
source: &mut SharedMemory<T>, destination: &mut SharedMemory<T>, valid: usize,
#[comptime] bins: usize, #[comptime] threads: usize, #[comptime] items: usize,
#[comptime] accumulate: bool,
) {
let mut sorted = Array::<T>::new(items);
#[unroll]
for item in 0..items {
if UNIT_POS as usize * items + item < valid { sorted[item] = samples[item]; }
}
let compare = crate::collective::RudaAscending {};
crate::block::sort::merge_sort_keys::<T, crate::collective::RudaAscending>(
&mut sorted, source, destination, &compare, valid, threads, items);
let mut bin = UNIT_POS as usize;
while bin < bins {
let mut lower = 0usize;
let mut upper = valid;
while lower < upper {
let middle = lower + (upper - lower) / 2;
if usize::cast_from(source[middle]) < bin { lower = middle + 1; } else { upper = middle; }
}
let begin = lower;
upper = valid;
while lower < upper {
let middle = lower + (upper - lower) / 2;
if usize::cast_from(source[middle]) <= bin { lower = middle + 1; } else { upper = middle; }
}
let count = C::cast_from(lower - begin);
if accumulate { histogram[bin] += count; } else { histogram[bin] = count; }
bin += threads;
}
sync_ruda();
}
#[ruda]
pub fn initialise<C: Numeric>(histogram: &mut SharedMemory<Atomic<C>>, #[comptime] bins: usize, #[comptime] threads: usize) {
let mut bin = UNIT_POS as usize;
while bin < bins {
histogram[bin].store(C::from_int(0));
bin += threads;
}
sync_ruda();
}
#[ruda]
pub fn composite<T: Numeric, C: Numeric>(
samples: &Array<T>, histogram: &mut SharedMemory<Atomic<C>>, valid_items: usize,
#[comptime] items_per_thread: usize,
) {
let start = UNIT_POS as usize * items_per_thread;
#[unroll]
for item in 0..items_per_thread {
if start + item < valid_items {
histogram[usize::cast_from(samples[item])].fetch_add(C::from_int(1));
}
}
sync_ruda();
}
#[ruda]
pub fn histogram<T: Numeric, C: Numeric>(
samples: &Array<T>, histogram: &mut SharedMemory<Atomic<C>>, valid_items: usize,
#[comptime] bins: usize, #[comptime] threads: usize, #[comptime] items_per_thread: usize,
) {
initialise(histogram, bins, threads);
composite(samples, histogram, valid_items, items_per_thread);
}