cubecl_core/frontend/operation/
branch.rs1use cubecl_macros::intrinsic;
2
3use crate as cubecl;
4use crate::prelude::{CubePrimitive, Vector};
5use crate::{
6 ir::{Operator, Scope, SelectOperands},
7 prelude::*,
8};
9
10pub fn select<C: CubePrimitive>(condition: bool, then: C, or_else: C) -> C {
18 if condition { then } else { or_else }
19}
20
21#[cube]
23pub fn select_many<C: Scalar, N: Size>(
24 condition: Vector<bool, N>,
25 then: Vector<C, N>,
26 or_else: Vector<C, N>,
27) -> Vector<C, N> {
28 intrinsic!(|scope| select::expand(scope, condition.expand.into(), then, or_else))
29}
30
31pub mod select {
32 use cubecl_ir::ValueKind;
33
34 use crate::ir::Instruction;
35
36 use super::*;
37
38 pub fn expand<C: CubePrimitive>(
39 scope: &Scope,
40 condition: NativeExpand<bool>,
41 then: NativeExpand<C>,
42 or_else: NativeExpand<C>,
43 ) -> NativeExpand<C> {
44 let cond = condition.expand;
45
46 if let ValueKind::Constant(value) = cond.kind {
47 if value.as_bool() {
48 return then;
49 } else {
50 return or_else;
51 }
52 }
53
54 let then = then.expand;
55 let or_else = or_else.expand;
56
57 let vf = cond.vector_size();
58 let vf = Ord::max(vf, then.vector_size());
59 let vf = Ord::max(vf, or_else.vector_size());
60
61 let output = scope.create_value(then.value_type().with_vector_size(vf));
62
63 let select = Operator::Select(SelectOperands {
64 cond,
65 then,
66 or_else,
67 });
68 scope.register(Instruction::new(select, output));
69
70 output.into()
71 }
72}