use alloc::string::String;
use core::hash::Hash;
use pliron::derive::format;
use cubecl_ir::{ElemType, Scope, metadata::Info, pliron::value::Value, settings::KernelSettings};
use serde::{Deserialize, Serialize};
use crate::compiler::CompilationError;
use crate::id::KernelId;
use cubecl_environment::backtrace::BackTrace;
pub trait KernelMetadata: core::any::Any + Send + Sync + 'static {
fn name(&self) -> &'static str {
core::any::type_name::<Self>()
}
fn id(&self) -> KernelId;
fn address_type(&self) -> ElemType;
}
#[allow(missing_docs)]
pub struct KernelDefinition {
pub body: Scope,
pub info: Info,
pub settings: KernelSettings,
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct KernelArg {
pub id: usize,
pub value: Value,
pub has_extended_meta: bool,
}
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
#[allow(missing_docs)]
pub struct ScalarKernelArg {
pub ty: ElemType,
pub count: usize,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Hash)]
#[allow(missing_docs)]
#[format]
pub enum Visibility {
Uniform,
Read,
ReadWrite,
}
pub use cubecl_ir::attributes::BufferIOAttr;
pub struct PrecompiledSource {
pub source: String,
pub entrypoint_name: String,
pub lang: &'static str,
}
pub trait CubeKernel: KernelMetadata {
fn define(&self) -> KernelDefinition;
fn source(&self) -> Option<PrecompiledSource> {
None
}
}
pub fn define_kernel<K: CubeKernel + ?Sized>(
kernel: &K,
) -> Result<KernelDefinition, CompilationError> {
#[cfg(feature = "std")]
{
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| kernel.define())).map_err(
|payload| {
let message = payload
.downcast_ref::<&str>()
.map(|message| String::from(*message))
.or_else(|| payload.downcast_ref::<String>().cloned())
.unwrap_or_else(|| String::from("a panic with no message"));
CompilationError::ExpansionPanicked {
kernel: kernel.name().into(),
message,
backtrace: BackTrace::capture(),
}
},
)
}
#[cfg(not(feature = "std"))]
{
Ok(kernel.define())
}
}