1pub mod kernels;
2mod ops;
3mod storage;
4pub use storage::*;
5
6use crate::{DType, Device};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10pub struct Cpu;
11
12impl Device for Cpu {
13 type FloatStorage = CpuFloatStorage;
14 type IntStorage = CpuIntStorage;
15 type BoolStorage = CpuBoolStorage;
16
17 fn name(&self) -> String {
18 "cpu".into()
19 }
20}
21
22#[macro_export]
30macro_rules! dispatch_float {
31 ($storage:expr, |$data:ident| $body:expr) => {
32 match $storage {
33 $crate::CpuFloatStorage::F32($data) => $crate::CpuFloatStorage::F32($body),
34 $crate::CpuFloatStorage::F64($data) => $crate::CpuFloatStorage::F64($body),
35 }
36 };
37}
38
39#[macro_export]
41macro_rules! dispatch_float_raw {
42 ($storage:expr, |$data:ident| $body:expr) => {
43 match $storage {
44 $crate::CpuFloatStorage::F32($data) => $body,
45 $crate::CpuFloatStorage::F64($data) => $body,
46 }
47 };
48}
49
50#[macro_export]
52macro_rules! dispatch_float2 {
53 ($lhs:expr, $rhs:expr, $op:literal, |$a:ident, $b:ident| $body:expr) => {
54 match ($lhs, $rhs) {
55 ($crate::CpuFloatStorage::F32($a), $crate::CpuFloatStorage::F32($b)) => Ok($crate::CpuFloatStorage::F32($body)),
56 ($crate::CpuFloatStorage::F64($a), $crate::CpuFloatStorage::F64($b)) => Ok($crate::CpuFloatStorage::F64($body)),
57 (l, r) => Err($crate::Error::DTypeMismatch { lhs: l.dtype(), rhs: r.dtype(), op: $op }),
58 }
59 };
60}
61
62#[macro_export]
64macro_rules! dispatch_float2_raw {
65 ($lhs:expr, $rhs:expr, $op:literal, |$a:ident, $b:ident| $body:expr) => {
66 match ($lhs, $rhs) {
67 ($crate::CpuFloatStorage::F32($a), $crate::CpuFloatStorage::F32($b)) => Ok($body),
68 ($crate::CpuFloatStorage::F64($a), $crate::CpuFloatStorage::F64($b)) => Ok($body),
69 (l, r) => Err($crate::Error::DTypeMismatch { lhs: l.dtype(), rhs: r.dtype(), op: $op }),
70 }
71 };
72}
73
74#[macro_export]
75macro_rules! dispatch_int {
76 ($storage:expr, |$data:ident| $body:expr) => {
77 match $storage {
78 $crate::CpuIntStorage::I32($data) => $crate::CpuIntStorage::I32($body),
79 $crate::CpuIntStorage::U32($data) => $crate::CpuIntStorage::U32($body),
80 $crate::CpuIntStorage::U8($data) => $crate::CpuIntStorage::U8($body),
81 }
82 };
83}
84
85#[macro_export]
86macro_rules! dispatch_int_raw {
87 ($storage:expr, |$data:ident| $body:expr) => {
88 match $storage {
89 $crate::CpuIntStorage::I32($data) => $body,
90 $crate::CpuIntStorage::U32($data) => $body,
91 $crate::CpuIntStorage::U8($data) => $body,
92 }
93 };
94}
95
96#[macro_export]
97macro_rules! dispatch_int2 {
98 ($lhs:expr, $rhs:expr, $op:literal, |$a:ident, $b:ident| $body:expr) => {
99 match ($lhs, $rhs) {
100 ($crate::CpuIntStorage::I32($a), $crate::CpuIntStorage::I32($b)) => Ok($crate::CpuIntStorage::I32($body)),
101 ($crate::CpuIntStorage::U32($a), $crate::CpuIntStorage::U32($b)) => Ok($crate::CpuIntStorage::U32($body)),
102 ($crate::CpuIntStorage::U8($a), $crate::CpuIntStorage::U8($b)) => Ok($crate::CpuIntStorage::U8($body)),
103 (l, r) => Err($crate::Error::DTypeMismatch { lhs: l.dtype(), rhs: r.dtype(), op: $op }),
104 }
105 };
106}
107
108#[macro_export]
109macro_rules! dispatch_int2_raw {
110 ($lhs:expr, $rhs:expr, $op:literal, |$a:ident, $b:ident| $body:expr) => {
111 match ($lhs, $rhs) {
112 ($crate::CpuIntStorage::I32($a), $crate::CpuIntStorage::I32($b)) => Ok($body),
113 ($crate::CpuIntStorage::U32($a), $crate::CpuIntStorage::U32($b)) => Ok($body),
114 ($crate::CpuIntStorage::U8($a), $crate::CpuIntStorage::U8($b)) => Ok($body),
115 (l, r) => Err($crate::Error::DTypeMismatch { lhs: l.dtype(), rhs: r.dtype(), op: $op }),
116 }
117 };
118}
119
120pub(crate) fn int_ids_as_usize(storage: &CpuIntStorage, layout: &crate::Layout) -> Vec<usize> {
123 use kernels::element::{CpuInt, CpuNum};
124 use kernels::indexing::PAD;
125 macro_rules! collect {
126 ($data:expr) => {
127 layout
128 .storage_indices()
129 .map(|i| {
130 let v = $data[i];
131 if v == CpuInt::MAX { PAD } else { v.to_usize() }
132 })
133 .collect()
134 };
135 }
136 match storage {
137 CpuIntStorage::I32(d) => collect!(d),
138 CpuIntStorage::U32(d) => collect!(d),
139 CpuIntStorage::U8(d) => collect!(d),
140 }
141}
142
143pub(crate) fn usize_to_int_storage(data: &[usize], dtype: DType) -> CpuIntStorage {
145 match dtype {
146 DType::I32 => CpuIntStorage::I32(data.iter().map(|&v| v as i32).collect()),
147 DType::U32 => CpuIntStorage::U32(data.iter().map(|&v| v as u32).collect()),
148 DType::U8 => CpuIntStorage::U8(data.iter().map(|&v| v as u8).collect()),
149 _ => CpuIntStorage::U32(data.iter().map(|&v| v as u32).collect()),
150 }
151}