cubecl-cpu 0.11.0-pre.1

CPU runtime for CubeCL
use cubecl_core::ir::{self};
use tracel_llvm::mlir_rs::{
    Context,
    dialect::{arith, ods::vector},
    ir::{
        Type, Value,
        attribute::{FloatAttribute, IntegerAttribute},
        r#type::IntegerType,
    },
};

use super::prelude::*;

impl IntoType for ir::Type {
    fn to_type<'a>(self, context: &'a Context) -> Type<'a> {
        let inner_type = match self {
            ir::Type::Opaque(ir::OpaqueType::Barrier(..)) => IntegerType::new(context, 32).into(),
            other => other.storage_type().to_type(context),
        };
        match self.vector_size() {
            size if size > 1 => Type::vector(&[size as u64], inner_type),
            _ => inner_type,
        }
    }

    fn is_vectorized(&self) -> bool {
        self.vector_size() > 1
    }
}

impl<'a> Visitor<'a> {
    pub fn create_float_constant_from_item(&self, item: ir::Type, constant: f64) -> Value<'a, 'a> {
        let float = item.storage_type().to_type(self.context);
        let constant = FloatAttribute::new(self.context, float, constant);
        let constant = self.append_operation_with_result(arith::constant(
            self.context,
            constant.into(),
            self.location,
        ));
        let result_type = item.to_type(self.context);
        match item.is_vectorized() {
            true => self.append_operation_with_result(vector::broadcast(
                self.context,
                result_type,
                constant,
                self.location,
            )),
            false => constant,
        }
    }

    pub fn create_int_constant_from_item(&self, item: ir::Type, constant: i64) -> Value<'a, 'a> {
        let integer = item.storage_type().to_type(self.context);
        let constant = IntegerAttribute::new(integer, constant);
        let constant = self.append_operation_with_result(arith::constant(
            self.context,
            constant.into(),
            self.location,
        ));
        let result_type = item.to_type(self.context);
        match item.is_vectorized() {
            true => self.append_operation_with_result(vector::broadcast(
                self.context,
                result_type,
                constant,
                self.location,
            )),
            false => constant,
        }
    }

    pub fn create_constant_index(&self, constant: i64) -> Value<'a, 'a> {
        let ty = Type::index(self.context);
        let constant = IntegerAttribute::new(ty, constant);
        self.append_operation_with_result(arith::constant(
            self.context,
            constant.into(),
            self.location,
        ))
    }

    pub fn cast_to_bool(&self, value: Value<'a, 'a>, item: ir::Type) -> Value<'a, 'a> {
        let mut bool = IntegerType::new(self.context, 1).into();
        if item.is_vectorized() {
            bool = Type::vector(&[item.vector_size() as u64], bool);
        }
        self.append_operation_with_result(arith::trunci(value, bool, self.location))
    }

    pub fn cast_to_u8(&self, value: Value<'a, 'a>, item: ir::Type) -> Value<'a, 'a> {
        let mut byte = IntegerType::new(self.context, 8).into();
        if item.is_vectorized() {
            byte = Type::vector(&[item.vector_size() as u64], byte);
        }
        self.append_operation_with_result(arith::extui(value, byte, self.location))
    }
}