cubecl_std/throughput/runners/
compute_direct.rs1use cubecl::prelude::*;
2use cubecl_core::{self as cubecl, frontend::fma, ir::ElemType};
3use cubecl_runtime::throughput::KernelConfig;
4
5use crate::throughput::LaunchConfig;
6
7pub fn build_kernel(client: &Client, dtype: ElemType, config: LaunchConfig) -> KernelConfig {
8 let client = client.clone();
9
10 let use_fma = matches!(dtype, ElemType::Float(_));
11
12 let sample = Box::new(move |iterations: usize| {
13 let start = cubecl_common::profile::Instant::now();
14 unsafe {
15 let out = client.empty(config.vector_size * dtype.size());
16
17 compute_direct_throughput::launch_unchecked(
18 &client,
19 CubeCount::Static(config.cube_count as u32, 1, 1),
20 config.cube_dim,
21 config.vector_size,
22 BufferArg::from_raw_parts(out, 1),
23 iterations,
24 use_fma,
25 dtype,
26 )
27 };
28 let _ = cubecl_core::future::block_on(client.sync());
29 start.elapsed()
30 });
31
32 let ops_per_chain = if use_fma { 2 } else { 1 };
34 let ops_count = ops_per_chain
35 * CHAINS
36 * config.cube_count
37 * config.cube_dim.num_elems() as usize
38 * config.vector_size;
39
40 KernelConfig {
41 sample,
42 ops_count,
43 min_iterations: 1,
44 }
45}
46
47const CHAINS: usize = 4;
49
50#[cube(launch_unchecked)]
51pub fn compute_direct_throughput<I: Numeric, N: Size>(
52 output: &mut [Vector<I, N>],
53 n_iter: usize,
54 #[comptime] use_fma: bool,
55 #[define(I)] _dtype: ElemType,
56) {
57 let tid = I::cast_from(ABSOLUTE_POS);
58
59 let mut b = Vector::<I, N>::empty();
60 let mut c = Vector::<I, N>::empty();
61
62 let mut s0 = Vector::<I, N>::empty();
63 let mut s1 = Vector::<I, N>::empty();
64 let mut s2 = Vector::<I, N>::empty();
65 let mut s3 = Vector::<I, N>::empty();
66
67 let lanes = b.vector_size();
69 #[unroll]
70 for lane in 0..lanes {
71 let offset = I::cast_from(lane);
72 b.insert(lane, tid + offset + I::cast_from(1));
73 c.insert(lane, tid + offset);
74
75 s0.insert(lane, offset + I::cast_from(1));
76 s1.insert(lane, offset + I::cast_from(2));
77 s2.insert(lane, offset + I::cast_from(3));
78 s3.insert(lane, offset + I::cast_from(4));
79 }
80
81 for _ in 0..n_iter {
82 s0 = step(s0, b, c, use_fma);
83 s1 = step(s1, b, c, use_fma);
84 s2 = step(s2, b, c, use_fma);
85 s3 = step(s3, b, c, use_fma);
86 }
87
88 let sum = s0 + s1 + s2 + s3;
89
90 if ABSOLUTE_POS == 0 {
91 output[0] = sum;
92 }
93}
94
95#[cube]
98fn step<I: Numeric, N: Size>(
99 s: Vector<I, N>,
100 b: Vector<I, N>,
101 c: Vector<I, N>,
102 #[comptime] use_fma: bool,
103) -> Vector<I, N> {
104 if use_fma { fma(s, b, c) } else { s * b }
105}