cubecl_cpp/cuda/ptx/
mod.rs1use cubecl_core::{
2 self as cubecl,
3 frontend::barrier::Barrier,
4 intrinsic,
5 ir::{
6 AddressSpace,
7 interfaces::{TypeExt, aliasing::AliasingOp},
8 prelude::*,
9 types::{
10 PointerType,
11 barrier::{BarrierLevel, BarrierType},
12 cuda::TensorMapType,
13 },
14 },
15 prelude::*,
16};
17
18mod asm;
19mod mma;
20
21pub use asm::*;
22pub use mma::*;
23use pliron::{
24 builtin::types::{IntegerType, Signedness},
25 printable::Printable,
26 verify_err,
27};
28
29pub mod copy_async;
30pub mod tma_load_im2col;
31
32use crate::{cuda::cuda_op_with_out, shared::ty::TypeExtCPP};
33
34#[cube_op(name = "cuda.generic_to_shared", format = "$0 ` : ` type($0)")]
39#[result_ty(fixed = IntegerType::get(ctx, 32, Signedness::Unsigned).to_handle())]
40pub struct GenericToSharedOp {
41 ptr: Value,
42}
43
44#[op_interface_impl]
45impl AliasingOp for GenericToSharedOp {
46 fn source_ptr(&self, ctx: &Context) -> Option<Value> {
47 Some(self.ptr(ctx))
48 }
49}
50
51cuda_op_with_out!(GenericToSharedOp, |op, ctx| {
52 let ptr = op.ptr(ctx).name(ctx);
53 format!("__cvta_generic_to_shared({ptr})")
54});
55
56#[cube]
57pub fn generic_to_shared<T: CubePrimitive>(ptr: *const T) -> u32 {
58 intrinsic!(|scope| {
59 let cvt = GenericToSharedOp::new(scope.ctx_mut(), unsafe { *ptr }.value(scope));
60 scope.register_with_result(&cvt).into()
61 })
62}
63
64#[cube_op(
67 name = "cuda.barrier_native_handle",
68 format = "$0 ` : ` type($0)",
69 verifier = "custom"
70)]
71#[result_ty(fixed = IntegerType::get(ctx, 32, Signedness::Unsigned).to_handle())]
72#[op_interfaces(OperandNOfType<0, PointerType>)]
73pub struct BarrierNativeHandleOp {
74 bar_ptr: Value,
75}
76
77#[op_interface_impl]
78impl AliasingOp for BarrierNativeHandleOp {
79 fn source_ptr(&self, ctx: &Context) -> Option<Value> {
80 Some(self.bar_ptr(ctx))
81 }
82}
83
84impl Verify for BarrierNativeHandleOp {
85 fn verify(&self, ctx: &Context) -> Result<()> {
86 let loc = self.loc(ctx);
87 let barrier_ty = self.bar_ptr(ctx).get_type(ctx).as_ptr(ctx);
88
89 if !barrier_ty.inner.deref(ctx).is::<BarrierType>() {
90 let expected = PointerType::get(
91 ctx,
92 BarrierType::get(ctx, BarrierLevel::Cube).into(),
93 AddressSpace::Shared,
94 )
95 .to_handle();
96 verify_err!(
97 loc,
98 OperandNOfTypeError::AllOperandsOfTypeVerifyErr(
99 expected.disp(ctx).to_string(),
100 self.bar_ptr(ctx).get_type(ctx).disp(ctx).to_string()
101 )
102 )?;
103 }
104 Ok(())
105 }
106}
107
108cuda_op_with_out!(BarrierNativeHandleOp, |op, ctx| {
109 let ptr = op.bar_ptr(ctx).name(ctx);
110 format!("__cvta_generic_to_shared(cuda::device::barrier_native_handle(*{ptr}))")
111});
112
113#[cube]
114pub fn barrier_native_handle(bar: &Barrier) -> u32 {
115 intrinsic!(|scope| {
116 let handle = BarrierNativeHandleOp::new(scope.ctx_mut(), bar.value(scope));
117 scope.register_with_result(&handle).into()
118 })
119}
120
121#[cube_op(name = "cuda.tensor_map_addr", format = "$0 ` : ` type($0)")]
126#[result_ty(fixed = IntegerType::get(ctx, 64, Signedness::Unsigned).to_handle())]
127#[op_interfaces(OperandNOfType<0, TensorMapType>)]
128pub struct TensorMapAddrOp {
129 tensor_map: Value,
130}
131
132cuda_op_with_out!(TensorMapAddrOp, |op, ctx| {
133 let tensor_map = op.tensor_map(ctx).name(ctx);
134 let out_ty = op.get_result(ctx).get_type(ctx).to_cpp(ctx);
135 format!("reinterpret_cast<{out_ty}>(&{tensor_map})")
136});
137
138#[cube]
139pub fn tensor_map_address<T: CubePrimitive, K: TensorMapKind>(tensor_map: &TensorMap<T, K>) -> u64 {
140 intrinsic!(|scope| {
141 let addr = TensorMapAddrOp::new(scope.ctx_mut(), tensor_map.value(scope));
142 scope.register_with_result(&addr).into()
143 })
144}