1use core::marker::PhantomData;
18
19use crate::{
20 dtype::{Dtype, EagerTensor, Tensor},
21 nn::Layer,
22};
23
24macro_rules! pool_layer_1d {
29 (#[doc = $doc:expr] $name:ident) => {
30 #[doc = $doc]
31 pub struct $name<D: Dtype, IT, OT, const RANK: usize> {
32 pub kernel_l: usize,
34 pub stride: usize,
36 _pd: PhantomData<(D, IT, OT)>,
37 }
38
39 impl<D: Dtype, IT, OT, const RANK: usize> $name<D, IT, OT, RANK> {
40 pub fn new(kernel_size: usize, stride: usize) -> Self {
42 Self {
43 kernel_l: kernel_size,
44 stride,
45 _pd: PhantomData,
46 }
47 }
48 }
49
50 impl<D: Dtype, IT: Tensor<D, RANK> + EagerTensor, OT: Tensor<D, RANK>, const RANK: usize>
51 Layer<IT> for $name<D, IT, OT, RANK>
52 {
53 type Output = OT;
54 fn call(&self, _input: IT) -> Self::Output {
55 todo!()
56 }
57 }
58 };
59}
60
61macro_rules! pool_layer_2d {
62 (#[doc = $doc:expr] $name:ident) => {
63 #[doc = $doc]
64 pub struct $name<D: Dtype, IT, OT, const RANK: usize> {
65 pub kernel_h: usize,
67 pub kernel_w: usize,
69 pub stride_h: usize,
71 pub stride_w: usize,
73 pub padding_h: usize,
75 pub padding_w: usize,
77 _pd: PhantomData<(D, IT, OT)>,
78 }
79
80 impl<D: Dtype, IT, OT, const RANK: usize> $name<D, IT, OT, RANK> {
81 pub fn new(kernel_size: (usize, usize), stride: (usize, usize)) -> Self {
83 Self {
84 kernel_h: kernel_size.0,
85 kernel_w: kernel_size.1,
86 stride_h: stride.0,
87 stride_w: stride.1,
88 padding_h: 0,
89 padding_w: 0,
90 _pd: PhantomData,
91 }
92 }
93
94 pub fn with_padding(
96 kernel_size: (usize, usize),
97 stride: (usize, usize),
98 padding: (usize, usize),
99 ) -> Self {
100 Self {
101 kernel_h: kernel_size.0,
102 kernel_w: kernel_size.1,
103 stride_h: stride.0,
104 stride_w: stride.1,
105 padding_h: padding.0,
106 padding_w: padding.1,
107 _pd: PhantomData,
108 }
109 }
110 }
111
112 impl<D: Dtype, IT: Tensor<D, RANK> + EagerTensor, OT: Tensor<D, RANK>, const RANK: usize>
113 Layer<IT> for $name<D, IT, OT, RANK>
114 {
115 type Output = OT;
116 fn call(&self, _input: IT) -> Self::Output {
117 todo!()
118 }
119 }
120 };
121}
122
123macro_rules! pool_layer_3d {
124 (#[doc = $doc:expr] $name:ident) => {
125 #[doc = $doc]
126 pub struct $name<D: Dtype, IT, OT, const RANK: usize> {
127 pub kernel_d: usize,
129 pub kernel_h: usize,
131 pub kernel_w: usize,
133 pub stride_d: usize,
135 pub stride_h: usize,
137 pub stride_w: usize,
139 _pd: PhantomData<(D, IT, OT)>,
140 }
141
142 impl<D: Dtype, IT, OT, const RANK: usize> $name<D, IT, OT, RANK> {
143 pub fn new(kernel_size: (usize, usize, usize), stride: (usize, usize, usize)) -> Self {
145 Self {
146 kernel_d: kernel_size.0,
147 kernel_h: kernel_size.1,
148 kernel_w: kernel_size.2,
149 stride_d: stride.0,
150 stride_h: stride.1,
151 stride_w: stride.2,
152 _pd: PhantomData,
153 }
154 }
155 }
156
157 impl<D: Dtype, IT: Tensor<D, RANK> + EagerTensor, OT: Tensor<D, RANK>, const RANK: usize>
158 Layer<IT> for $name<D, IT, OT, RANK>
159 {
160 type Output = OT;
161 fn call(&self, _input: IT) -> Self::Output {
162 todo!()
163 }
164 }
165 };
166}
167
168pool_layer_1d!(
173 #[doc = "1-D average pooling."]
174 AvgPool1d
175);
176pool_layer_2d!(
177 #[doc = "2-D average pooling."]
178 AvgPool2d
179);
180pool_layer_3d!(
181 #[doc = "3-D average pooling."]
182 AvgPool3d
183);
184
185pool_layer_1d!(
190 #[doc = "1-D max pooling."]
191 MaxPool1d
192);
193pool_layer_2d!(
194 #[doc = "2-D max pooling."]
195 MaxPool2d
196);
197pool_layer_3d!(
198 #[doc = "3-D max pooling."]
199 MaxPool3d
200);
201
202pub struct LpPool1d<D: Dtype, IT, OT, const RANK: usize> {
208 pub kernel_l: usize,
210 pub stride: usize,
212 pub p: f64,
214 _pd: PhantomData<(D, IT, OT)>,
215}
216
217impl<D: Dtype, IT, OT, const RANK: usize> LpPool1d<D, IT, OT, RANK> {
218 pub fn new(kernel_size: usize, stride: usize, p: f64) -> Self {
220 Self {
221 kernel_l: kernel_size,
222 stride,
223 p,
224 _pd: PhantomData,
225 }
226 }
227}
228
229impl<D: Dtype, IT: Tensor<D, RANK> + EagerTensor, OT: Tensor<D, RANK>, const RANK: usize> Layer<IT>
230 for LpPool1d<D, IT, OT, RANK>
231{
232 type Output = OT;
233 fn call(&self, _input: IT) -> Self::Output {
234 todo!()
235 }
236}
237
238pub struct LpPool2d<D: Dtype, IT, OT, const RANK: usize> {
240 pub kernel_h: usize,
242 pub kernel_w: usize,
244 pub stride_h: usize,
246 pub stride_w: usize,
248 pub p: f64,
250 _pd: PhantomData<(D, IT, OT)>,
251}
252
253impl<D: Dtype, IT, OT, const RANK: usize> LpPool2d<D, IT, OT, RANK> {
254 pub fn new(kernel_size: (usize, usize), stride: (usize, usize), p: f64) -> Self {
256 Self {
257 kernel_h: kernel_size.0,
258 kernel_w: kernel_size.1,
259 stride_h: stride.0,
260 stride_w: stride.1,
261 p,
262 _pd: PhantomData,
263 }
264 }
265}
266
267impl<D: Dtype, IT: Tensor<D, RANK> + EagerTensor, OT: Tensor<D, RANK>, const RANK: usize> Layer<IT>
268 for LpPool2d<D, IT, OT, RANK>
269{
270 type Output = OT;
271 fn call(&self, _input: IT) -> Self::Output {
272 todo!()
273 }
274}
275
276pub struct LpPool3d<D: Dtype, IT, OT, const RANK: usize> {
278 pub kernel_d: usize,
280 pub kernel_h: usize,
282 pub kernel_w: usize,
284 pub stride_d: usize,
286 pub stride_h: usize,
288 pub stride_w: usize,
290 pub p: f64,
292 _pd: PhantomData<(D, IT, OT)>,
293}
294
295impl<D: Dtype, IT, OT, const RANK: usize> LpPool3d<D, IT, OT, RANK> {
296 pub fn new(kernel_size: (usize, usize, usize), stride: (usize, usize, usize), p: f64) -> Self {
298 Self {
299 kernel_d: kernel_size.0,
300 kernel_h: kernel_size.1,
301 kernel_w: kernel_size.2,
302 stride_d: stride.0,
303 stride_h: stride.1,
304 stride_w: stride.2,
305 p,
306 _pd: PhantomData,
307 }
308 }
309}
310
311impl<D: Dtype, IT: Tensor<D, RANK> + EagerTensor, OT: Tensor<D, RANK>, const RANK: usize> Layer<IT>
312 for LpPool3d<D, IT, OT, RANK>
313{
314 type Output = OT;
315 fn call(&self, _input: IT) -> Self::Output {
316 todo!()
317 }
318}