use std::num::NonZero;
use crate::{
ir::{ConstantScalarValue, Item},
prelude::{assign, CubeContext, ExpandElement},
unexpanded,
};
use crate::frontend::{
CubePrimitive, CubeType, ExpandElementBaseInit, ExpandElementTyped, IntoRuntime,
};
#[derive(Clone, Copy, Eq)]
pub struct Line<P: CubePrimitive> {
pub(crate) val: P,
}
mod new {
use super::*;
impl<P: CubePrimitive> Line<P> {
pub fn new(val: P) -> Self {
Self { val }
}
pub fn __expand_new(
_context: &mut CubeContext,
val: P::ExpandType,
) -> ExpandElementTyped<Self> {
let elem: ExpandElementTyped<P> = val;
elem.expand.into()
}
}
}
mod fill {
use super::*;
impl<P: CubePrimitive + Into<ExpandElementTyped<P>>> Line<P> {
#[allow(unused_variables)]
pub fn fill(mut self, value: P) -> Self {
self.val = value;
self
}
pub fn __expand_fill(
context: &mut CubeContext,
line: ExpandElementTyped<Self>,
value: ExpandElementTyped<P>,
) -> ExpandElementTyped<Self> {
line.__expand_fill_method(context, value)
}
}
impl<P: CubePrimitive> ExpandElementTyped<Line<P>> {
pub fn __expand_fill_method(
self,
context: &mut CubeContext,
value: ExpandElementTyped<P>,
) -> Self {
let length = self.expand.item().vectorization;
let output = context.create_local_binding(Item::vectorized(P::as_elem(), length));
assign::expand::<P>(context, value, output.clone().into());
output.into()
}
}
}
mod empty {
use super::*;
impl<P: CubePrimitive + Into<ExpandElementTyped<P>>> Line<P> {
#[allow(unused_variables)]
pub fn empty(size: u32) -> Self {
unexpanded!()
}
pub fn __expand_empty(
context: &mut CubeContext,
length: ExpandElementTyped<u32>,
) -> ExpandElementTyped<Self> {
let length = match length.expand.as_const() {
Some(val) => match val {
ConstantScalarValue::Int(val, _) => NonZero::new(val)
.map(|val| val.get() as u8)
.map(|val| NonZero::new(val).unwrap()),
ConstantScalarValue::Float(val, _) => NonZero::new(val as i64)
.map(|val| val.get() as u8)
.map(|val| NonZero::new(val).unwrap()),
ConstantScalarValue::UInt(val) => NonZero::new(val as u8),
ConstantScalarValue::Bool(_) => None,
},
None => None,
};
context
.create_local_variable(Item::vectorized(Self::as_elem(), length))
.into()
}
}
}
mod size {
use super::*;
impl<P: CubePrimitive> Line<P> {
pub fn size(&self) -> u32 {
unexpanded!()
}
pub fn __expand_size(context: &mut CubeContext, element: ExpandElementTyped<P>) -> u32 {
element.__expand_vectorization_factor_method(context)
}
}
impl<P: CubePrimitive> ExpandElementTyped<Line<P>> {
pub fn size(&self) -> u32 {
self.expand
.item()
.vectorization
.unwrap_or(NonZero::new(1).unwrap())
.get() as u32
}
pub fn __expand_size_method(&self, _context: &mut CubeContext) -> u32 {
self.size()
}
}
}
impl<P: CubePrimitive> CubeType for Line<P> {
type ExpandType = ExpandElementTyped<Self>;
}
impl<P: CubePrimitive> ExpandElementBaseInit for Line<P> {
fn init_elem(context: &mut crate::prelude::CubeContext, elem: ExpandElement) -> ExpandElement {
P::init_elem(context, elem)
}
}
impl<P: CubePrimitive> IntoRuntime for Line<P> {
fn __expand_runtime_method(
self,
context: &mut crate::prelude::CubeContext,
) -> Self::ExpandType {
self.val.__expand_runtime_method(context).expand.into()
}
}
impl<P: CubePrimitive> CubePrimitive for Line<P> {
fn as_elem() -> crate::ir::Elem {
P::as_elem()
}
}