ruda_kernel/dsl/frontend/operation/
branch.rs1use ruda_kernel_macros::intrinsic;
2
3use crate::dsl::prelude::{RudaPrimitive, Vector};
4use crate::dsl::{
5 ir::{Operator, Scope, Select},
6 prelude::*,
7};
8
9pub fn select<C: RudaPrimitive>(condition: bool, then: C, or_else: C) -> C {
17 if condition { then } else { or_else }
18}
19
20#[ruda]
22#[allow(unused_variables)]
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 ruda_core::ir::VariableKind;
33
34 use crate::dsl::ir::Instruction;
35
36 use super::*;
37
38 pub fn expand<C: RudaPrimitive>(
39 scope: &mut Scope,
40 condition: NativeExpand<bool>,
41 then: NativeExpand<C>,
42 or_else: NativeExpand<C>,
43 ) -> NativeExpand<C> {
44 let cond = condition.expand.consume();
45
46 if let VariableKind::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.consume();
55 let or_else = or_else.expand.consume();
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_local(then.ty.with_vector_size(vf));
62 let out = *output;
63
64 let select = Operator::Select(Select {
65 cond,
66 then,
67 or_else,
68 });
69 scope.register(Instruction::new(select, out));
70
71 output.into()
72 }
73}