use std::sync::Arc;
use morok_dtype::DType;
use smallvec::SmallVec;
use crate::op::Op;
use crate::types::{AxisId, AxisType, ConstValue};
use crate::uop::UOp;
impl UOp {
pub fn range_axis(end: Arc<Self>, axis_id: AxisId, axis_type: AxisType) -> Arc<Self> {
Self::new(Op::Range { end, axis_id, axis_type, deps: SmallVec::new() }, DType::Index)
}
pub fn range(end: Arc<Self>, axis_id: usize) -> Arc<Self> {
Self::range_axis(end, AxisId::Renumbered(axis_id), AxisType::Loop)
}
pub fn range_const(end_value: i64, axis_id: usize) -> Arc<Self> {
let end = Self::const_(DType::Index, ConstValue::Int(end_value));
Self::range_axis(end, AxisId::Renumbered(axis_id), AxisType::Loop)
}
pub fn range_outer_const(end_value: i64, axis_id: usize) -> Arc<Self> {
let end = Self::const_(DType::Index, ConstValue::Int(end_value));
Self::range_axis(end, AxisId::Renumbered(axis_id), AxisType::Outer)
}
pub fn if_(condition: Arc<Self>, body: SmallVec<[Arc<Self>; 4]>) -> Arc<Self> {
Self::new(Op::If { condition, body }, DType::Void)
}
pub fn endif(if_op: Arc<Self>) -> Arc<Self> {
Self::new(Op::EndIf { if_op }, DType::Void)
}
pub fn end(self: &Arc<Self>, ranges: SmallVec<[Arc<Self>; 4]>) -> Arc<Self> {
if ranges.is_empty() {
return self.clone();
}
Self::new(Op::End { computation: self.clone(), ranges }, DType::Void)
}
pub fn barrier(self: &Arc<Self>, deps: SmallVec<[Arc<Self>; 4]>) -> Arc<Self> {
let dtype = self.dtype();
Self::new(Op::Barrier { src: self.clone(), deps }, dtype)
}
pub fn var(name: impl Into<String>, dtype: DType, min_val: i64, max_val: i64) -> Arc<Self> {
Self::new(Op::DefineVar { name: name.into(), min_val, max_val }, dtype)
}
pub fn define_var(name: String, min_val: i64, max_val: i64) -> Arc<Self> {
Self::new(Op::DefineVar { name, min_val, max_val }, DType::Index)
}
pub fn bind(self: &Arc<Self>, value: Arc<Self>) -> Arc<Self> {
let dtype = self.dtype();
Self::new(Op::Bind { var: self.clone(), value }, dtype)
}
pub fn special(end: Arc<Self>, name: String) -> Arc<Self> {
Self::new(Op::Special { end, name }, DType::Index)
}
}