pub struct Executor {
pub gpu_threshold: usize,
/* private fields */
}Expand description
Runtime dispatcher between the CPU and (optional) GPU backends.
Fields§
§gpu_threshold: usizeBatches smaller than this use the CPU even when a GPU is present, because the GPU’s upload/dispatch/download round-trip (~100µs) dominates for small inputs. Public so callers can tune it for their hardware.
Implementations§
Source§impl Executor
impl Executor
Sourcepub fn cpu(&self) -> &CpuBackend
pub fn cpu(&self) -> &CpuBackend
Borrow the CPU backend directly (used by benchmarks).
Examples found in repository?
examples/benchmark_backends.rs (line 45)
22fn main() {
23 let exec = executor();
24 let ch = Channels::standard(32);
25 let has_gpu = exec.gpu().is_some();
26
27 println!("== adele-ring :: backend benchmark (32 channels) ==");
28 println!(
29 "GPU available: {}\n",
30 if has_gpu {
31 exec.gpu().map(|g| g.adapter_name().to_string()).unwrap_or_default()
32 } else {
33 "no (CPU-only)".to_string()
34 }
35 );
36
37 println!("{:>10} | {:>14} | {:>12} | winner", "batch_size", "cpu_rayon_us", "gpu_us");
38 println!("{}", "-".repeat(56));
39
40 for &size in &[1usize, 16, 128, 1024, 16_384, 65_536] {
41 let a = RnsBatch::from_rns_ints(&vec![RnsInt::from_i64(123, ch.clone()); size]);
42 let b = RnsBatch::from_rns_ints(&vec![RnsInt::from_i64(456, ch.clone()); size]);
43
44 let iters = if size <= 128 { 2000 } else { 100 };
45 let cpu_us = time_backend(|| exec.cpu().batch_rns_add(&a, &b), iters);
46
47 let (gpu_str, winner) = if let Some(gpu) = exec.gpu() {
48 let gpu_us = time_backend(|| gpu.batch_rns_add(&a, &b), iters);
49 let w = if cpu_us <= gpu_us { "CPU" } else { "GPU" };
50 (format!("{gpu_us:>12.2}"), w)
51 } else {
52 (" n/a".to_string(), "CPU")
53 };
54
55 println!("{size:>10} | {cpu_us:>14.2} | {gpu_str} | {winner}");
56 }
57
58 println!(
59 "\nNote: CPU wins for small batches (GPU upload/dispatch overhead ~100us);\n\
60 GPU pulls ahead once the batch is large enough to amortize that fixed cost."
61 );
62}Sourcepub fn gpu(&self) -> Option<&GpuBackend>
pub fn gpu(&self) -> Option<&GpuBackend>
Borrow the GPU backend if present (used by benchmarks).
Examples found in repository?
examples/benchmark_backends.rs (line 25)
22fn main() {
23 let exec = executor();
24 let ch = Channels::standard(32);
25 let has_gpu = exec.gpu().is_some();
26
27 println!("== adele-ring :: backend benchmark (32 channels) ==");
28 println!(
29 "GPU available: {}\n",
30 if has_gpu {
31 exec.gpu().map(|g| g.adapter_name().to_string()).unwrap_or_default()
32 } else {
33 "no (CPU-only)".to_string()
34 }
35 );
36
37 println!("{:>10} | {:>14} | {:>12} | winner", "batch_size", "cpu_rayon_us", "gpu_us");
38 println!("{}", "-".repeat(56));
39
40 for &size in &[1usize, 16, 128, 1024, 16_384, 65_536] {
41 let a = RnsBatch::from_rns_ints(&vec![RnsInt::from_i64(123, ch.clone()); size]);
42 let b = RnsBatch::from_rns_ints(&vec![RnsInt::from_i64(456, ch.clone()); size]);
43
44 let iters = if size <= 128 { 2000 } else { 100 };
45 let cpu_us = time_backend(|| exec.cpu().batch_rns_add(&a, &b), iters);
46
47 let (gpu_str, winner) = if let Some(gpu) = exec.gpu() {
48 let gpu_us = time_backend(|| gpu.batch_rns_add(&a, &b), iters);
49 let w = if cpu_us <= gpu_us { "CPU" } else { "GPU" };
50 (format!("{gpu_us:>12.2}"), w)
51 } else {
52 (" n/a".to_string(), "CPU")
53 };
54
55 println!("{size:>10} | {cpu_us:>14.2} | {gpu_str} | {winner}");
56 }
57
58 println!(
59 "\nNote: CPU wins for small batches (GPU upload/dispatch overhead ~100us);\n\
60 GPU pulls ahead once the batch is large enough to amortize that fixed cost."
61 );
62}Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Executor
impl !UnwindSafe for Executor
impl Freeze for Executor
impl Send for Executor
impl Sync for Executor
impl Unpin for Executor
impl UnsafeUnpin for Executor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more