1use core::marker::Sized;
2
3use num_traits::AsPrimitive;
4
5#[rustc_diagnostic_item = "gpu::printf"]
6#[gpu_codegen::device]
7#[inline(never)]
8pub fn printf(_fmt: &'static str) {
9 unimplemented!()
10}
11
12trait SupportedPrintfArg: AsPrimitive<Self::Output> {
13 const HOLDER: &'static str;
14 type Output: Copy + SupportedPrintfArg;
15}
16
17#[allow(private_bounds)]
18pub trait PushPrintfArg: SupportedPrintfArg + Sized {
19 fn _push_printf_arg(self, _holder: &'static str);
21
22 #[gpu_codegen::device]
23 #[inline(always)]
24 fn push_printf_arg(self) {
25 self.as_()._push_printf_arg(Self::HOLDER);
26 }
27}
28
29impl<T: SupportedPrintfArg + Sized> PushPrintfArg for T {
30 #[rustc_diagnostic_item = "gpu::print_args"]
31 #[gpu_codegen::device]
32 #[inline(never)]
33 fn _push_printf_arg(self, _holder: &'static str) {
34 unimplemented!()
36 }
37}
38
39macro_rules! def_push_printf_arg {
40 ($t:ty, $ot: ty, $holder: literal) => {
41 impl SupportedPrintfArg for $t {
42 const HOLDER: &'static str = $holder;
43 type Output = $ot;
44 }
45 };
46 () => {};
47}
48
49def_push_printf_arg!(u8, u32, "%u");
50def_push_printf_arg!(u16, u32, "%u");
51def_push_printf_arg!(u32, u32, "%u");
52def_push_printf_arg!(u64, u64, "%lu");
53def_push_printf_arg!(u128, u128, "%llu");
54def_push_printf_arg!(i8, i32, "%d");
55def_push_printf_arg!(i16, i32, "%d");
56def_push_printf_arg!(i32, i32, "%d");
57def_push_printf_arg!(i64, i64, "%ld");
58def_push_printf_arg!(i128, i128, "%lld");
59def_push_printf_arg!(usize, usize, "%ld");
60def_push_printf_arg!(isize, isize, "%ld");
61def_push_printf_arg!(f32, f32, "%f");
62def_push_printf_arg!(f64, f64, "%f");
63def_push_printf_arg!(bool, u32, "%d");
64
65#[macro_export]
66macro_rules! println {
67 ($fmt:literal) => {{
68 $crate::printf($fmt);
69 }};
70 ($fmt:literal, $($arg:expr),+ $(,)?) => {{
71 use $crate::PushPrintfArg;
72 $(
73 ($arg).push_printf_arg();
74 )+
75 $crate::printf($fmt);
76 }};
77}
78
79#[macro_export]
80macro_rules! println_once {
81 ($($any:tt)*) => {{
82 if $crate::thread_id::<$crate::DimX>() == 0 && $crate::thread_id::<$crate::DimY>() == 0 && $crate::thread_id::<$crate::DimZ>() == 0 && $crate::block_id::<$crate::DimX>() == 0 && $crate::block_id::<$crate::DimY>() == 0 && $crate::block_id::<$crate::DimZ>() == 0 {
83 $crate::println!($($any)*);
84 }
85 }}
86}
87
88#[cfg(debug_assertions)]
89#[macro_export]
90macro_rules! debug_once {
91 ($($any:tt)*) => {{
92 println_once!($($any)*);
93 }}
94}
95
96#[cfg(not(debug_assertions))]
97#[macro_export]
98macro_rules! debug_once {
99 ($($any:tt)*) => {{}};
100}