use crate::ir::{self, Elem, Instruction, Item, Scope, Variable, VariableKind};
use crate::{frontend::ExpandElement, ir::Id};
use alloc::rc::Rc;
use core::cell::RefCell;
use cubecl_runtime::debug::DebugLogger;
use std::any::TypeId;
use std::collections::HashMap;
pub struct CubeContext {
pub root: Rc<RefCell<Scope>>,
pub scope: Rc<RefCell<Scope>>,
pub debug_enabled: bool,
pub typemap: Rc<RefCell<HashMap<TypeId, Elem>>>,
}
impl Default for CubeContext {
fn default() -> Self {
Self::root()
}
}
impl CubeContext {
pub fn root() -> CubeContext {
let root = Rc::new(RefCell::new(Scope::root()));
let typemap = Rc::new(RefCell::new(HashMap::new()));
let scope = root.clone();
Self {
scope,
root,
debug_enabled: DebugLogger::default().is_activated(),
typemap,
}
}
pub fn register<O: Into<Instruction>>(&mut self, op: O) {
self.scope.borrow_mut().register(op)
}
pub fn resolve_elem<T: 'static>(&self) -> Option<Elem> {
let map = self.typemap.borrow();
let result = map.get(&TypeId::of::<T>());
result.cloned()
}
pub fn register_elem<T: 'static>(&mut self, elem: Elem) {
let mut map = self.typemap.borrow_mut();
map.insert(TypeId::of::<T>(), elem);
}
pub fn child(&mut self) -> CubeContext {
let scope = self.scope.borrow_mut().child();
Self {
scope: Rc::new(RefCell::new(scope)),
root: self.root.clone(),
debug_enabled: self.debug_enabled,
typemap: self.typemap.clone(),
}
}
pub fn into_scope(self) -> Scope {
core::mem::drop(self.root);
Rc::into_inner(self.scope)
.expect("Only one reference")
.into_inner()
}
pub fn create_local_mut(&mut self, item: Item) -> ExpandElement {
let local = self.scope.borrow().allocator.create_local_mut(item);
self.scope.borrow_mut().add_local_mut(*local);
local
}
pub fn create_local(&mut self, item: Item) -> ExpandElement {
self.scope.borrow().allocator.create_local(item)
}
pub fn create_local_restricted(&mut self, item: Item) -> ExpandElement {
self.scope.borrow().allocator.create_local_restricted(item)
}
pub fn create_matrix(&mut self, matrix: ir::Matrix) -> ExpandElement {
let matrix = self.scope.borrow().allocator.create_matrix(matrix);
self.scope.borrow_mut().add_matrix(*matrix);
matrix
}
pub fn create_slice(&mut self, item: Item) -> ExpandElement {
let slice = self.scope.borrow().allocator.create_slice(item);
self.scope.borrow_mut().add_slice(*slice);
slice
}
pub fn create_shared(&mut self, item: Item, size: u32) -> ExpandElement {
ExpandElement::Plain(self.root.borrow_mut().create_shared(item, size))
}
pub fn create_local_array(&mut self, item: Item, size: u32) -> ExpandElement {
let local_array: ExpandElement =
self.root.borrow().allocator.create_local_array(item, size);
self.root.borrow_mut().add_local_array(*local_array);
local_array
}
pub fn create_const_array(&mut self, item: Item, data: Vec<Variable>) -> ExpandElement {
ExpandElement::Plain(self.root.borrow_mut().create_const_array(item, data))
}
pub fn input(&mut self, id: Id, item: Item) -> ExpandElement {
ExpandElement::Plain(crate::ir::Variable::new(
VariableKind::GlobalInputArray(id),
item,
))
}
pub fn output(&mut self, id: Id, item: Item) -> ExpandElement {
let var = crate::ir::Variable::new(VariableKind::GlobalOutputArray(id), item);
self.scope.borrow_mut().write_global_custom(var);
ExpandElement::Plain(var)
}
pub fn scalar(&self, id: Id, elem: Elem) -> ExpandElement {
ExpandElement::Plain(crate::ir::Variable::new(
VariableKind::GlobalScalar(id),
Item::new(elem),
))
}
}