use cubecl_macros_internal::{cube_op, op_traits};
use crate::{CanMaterialize, dialect::ptr_value_ty, prelude::*};
macro_rules! atomic_binop {
($name: literal, $ty: ident) => {
#[cube_op(name = $name)]
#[result_ty(same_as = value)]
#[op_traits(CanMaterialize)]
pub struct $ty {
#[operand(ptr_read, ptr_write)]
pub ptr: Value,
pub value: Value,
}
};
}
atomic_binop!("atomic.exchange", AtomicExchangeOp);
atomic_binop!("atomic.i_add", AtomicIAddOp);
atomic_binop!("atomic.f_add", AtomicFAddOp);
atomic_binop!("atomic.i_sub", AtomicISubOp);
atomic_binop!("atomic.f_sub", AtomicFSubOp);
atomic_binop!("atomic.s_min", AtomicSMinOp);
atomic_binop!("atomic.u_min", AtomicUMinOp);
atomic_binop!("atomic.f_min", AtomicFMinOp);
atomic_binop!("atomic.s_max", AtomicSMaxOp);
atomic_binop!("atomic.u_max", AtomicUMaxOp);
atomic_binop!("atomic.f_max", AtomicFMaxOp);
atomic_binop!("atomic.and", AtomicAndOp);
atomic_binop!("atomic.or", AtomicOrOp);
atomic_binop!("atomic.xor", AtomicXorOp);
#[cube_op(name = "atomic.load")]
#[result_ty(from_inputs = ptr_value_ty)]
#[op_traits(CanMaterialize)]
pub struct AtomicLoadOp {
#[operand(ptr_read)]
pub ptr: Value,
}
#[cube_op(name = "atomic.store")]
#[result_ty(none)]
#[op_traits(CanMaterialize)]
pub struct AtomicStoreOp {
#[operand(ptr_write)]
pub ptr: Value,
pub value: Value,
}
#[cube_op(name = "atomic.compare_exchange_weak")]
#[result_ty(same_as = value)]
#[op_traits(CanMaterialize)]
pub struct AtomicCompareExchangeWeakOp {
#[operand(ptr_read, ptr_write)]
pub ptr: Value,
pub cmp: Value,
pub value: Value,
}