@@ -20,6 +20,166 @@ public static partial class nn
2020 public static class functional
2121 {
2222
23+ public static Tensor avg_pool2d ( Tensor x , Union < int , Tuple < int , int > > kernel_size , Union < int , Tuple < int , int > > stride = null , Union < int , Tuple < int , int > > padding = null , Union < int , Tuple < int , int > > dilation = null )
24+ {
25+ if ( x . dtype == torch . @bool )
26+ {
27+ throw new TorchException ( "TorchException: nn.functional.avg_pool2d is not implemented for bool tensors." ) ;
28+ }
29+ if ( x . __shape . Length != 4 )
30+ {
31+ throw new TorchException ( "TorchException: nn.functional.avg_pool2d requires 4D input, but " + x . __shape . Length . ToString ( ) + "D given." ) ;
32+ }
33+ Tuple < int , int > kernel_size__ ;
34+ if ( kernel_size == null )
35+ {
36+ throw new TorchException ( "TorchException: kernel_size is not an optional parameter." ) ;
37+ }
38+ else
39+ {
40+ if ( ( Tuple < int , int > ) kernel_size != null )
41+ {
42+ kernel_size__ = ( Tuple < int , int > ) kernel_size ;
43+ }
44+ else
45+ {
46+ kernel_size__ = new Tuple < int , int > ( ( int ) kernel_size , ( int ) kernel_size ) ;
47+ }
48+ }
49+ Tuple < int , int > stride__ ;
50+ if ( stride == null )
51+ {
52+ stride__ = kernel_size__ ;
53+ }
54+ else
55+ {
56+ if ( ( Tuple < int , int > ) stride != null )
57+ {
58+ stride__ = ( Tuple < int , int > ) stride ;
59+ }
60+ else
61+ {
62+ stride__ = new Tuple < int , int > ( ( int ) stride , ( int ) stride ) ;
63+ }
64+ }
65+ Tuple < int , int > padding__ ;
66+ if ( padding == null )
67+ {
68+ padding__ = new Tuple < int , int > ( 0 , 0 ) ;
69+ }
70+ else
71+ {
72+ if ( ( Tuple < int , int > ) padding != null )
73+ {
74+ padding__ = ( Tuple < int , int > ) padding ;
75+ }
76+ else
77+ {
78+ padding__ = new Tuple < int , int > ( ( int ) padding , ( int ) padding ) ;
79+ }
80+ }
81+ Tuple < int , int > dilation__ ;
82+ if ( dilation == null )
83+ {
84+ dilation__ = new Tuple < int , int > ( 1 , 1 ) ;
85+ }
86+ else
87+ {
88+ if ( ( Tuple < int , int > ) dilation != null )
89+ {
90+ dilation__ = ( Tuple < int , int > ) dilation ;
91+ }
92+ else
93+ {
94+ dilation__ = new Tuple < int , int > ( ( int ) dilation , ( int ) dilation ) ;
95+ }
96+ }
97+ if ( ( kernel_size__ . Item1 < 1 ) || ( kernel_size__ . Item2 < 1 ) )
98+ {
99+ throw new TorchException ( "TorchException: kernel size should be >= 1." ) ;
100+ }
101+ if ( ( kernel_size__ . Item1 == 1 ) || ( kernel_size__ . Item2 == 1 ) )
102+ {
103+ __Warnings . warn ( "AvgPool2d with kernel size = 1 is useless." ) ;
104+ }
105+ if ( ( stride__ . Item1 < 1 ) || ( stride__ . Item2 < 1 ) )
106+ {
107+ throw new TorchException ( "TorchException: stride should be >= 1." ) ;
108+ }
109+ if ( ( padding__ . Item1 < 0 ) || ( padding__ . Item2 < 0 ) )
110+ {
111+ throw new TorchException ( "TorchException: padding should be >= 0." ) ;
112+ }
113+ if ( ( dilation__ . Item1 < 1 ) || ( dilation__ . Item2 < 1 ) )
114+ {
115+ throw new TorchException ( "TorchException: dilation should be >= 1." ) ;
116+ }
117+ var y = new Tensor ( x . __shape [ 0 ] , x . __shape [ 1 ] ,
118+ ( x . __shape [ 2 ] + 2 * padding__ . Item1 - dilation__ . Item1 * ( kernel_size__ . Item1 - 1 ) - 1 ) / stride__ . Item1 + 1 ,
119+ ( x . __shape [ 3 ] + 2 * padding__ . Item2 - dilation__ . Item2 * ( kernel_size__ . Item2 - 1 ) - 1 ) / stride__ . Item2 + 1 ,
120+ dtype : x . dtype , requires_grad : ( ! torch . autograd . grad_mode . no_grad . prev ) && x . requires_grad ) ;
121+ switch ( x . dtype )
122+ {
123+ case torch . float16 :
124+ {
125+ MKL . AvgPool2d ( x . __half , x . __shape , kernel_size__ , stride__ , padding__ , dilation__ , y . __half , y . __shape ) ;
126+ if ( y . requires_grad )
127+ {
128+ y . __backward_fn = ( ) =>
129+ {
130+ MKL . dAvgPool2d ( x . grad . __half , x . grad . __shape , kernel_size__ , stride__ , padding__ , dilation__ , y . grad . __half , y . __shape ) ;
131+ if ( x . __backward_fn != null )
132+ {
133+ x . __backward_fn ( ) ;
134+ }
135+ } ;
136+ }
137+ break ;
138+ }
139+ case torch . float32 :
140+ {
141+ MKL . AvgPool2d ( x . __float , x . __shape , kernel_size__ , stride__ , padding__ , dilation__ , y . __float , y . __shape ) ;
142+ if ( y . requires_grad )
143+ {
144+ y . __backward_fn = ( ) =>
145+ {
146+ MKL . dAvgPool2d ( x . grad . __float , x . grad . __shape , kernel_size__ , stride__ , padding__ , dilation__ , y . grad . __float , y . __shape ) ;
147+ if ( x . __backward_fn != null )
148+ {
149+ x . __backward_fn ( ) ;
150+ }
151+ } ;
152+ }
153+ break ;
154+ }
155+ case torch . float64 :
156+ {
157+ MKL . AvgPool2d ( x . __double , x . __shape , kernel_size__ , stride__ , padding__ , dilation__ , y . __double , y . __shape ) ;
158+ if ( y . requires_grad )
159+ {
160+ y . __backward_fn = ( ) =>
161+ {
162+ MKL . dAvgPool2d ( x . grad . __double , x . grad . __shape , kernel_size__ , stride__ , padding__ , dilation__ , y . grad . __double , y . __shape ) ;
163+ if ( x . __backward_fn != null )
164+ {
165+ x . __backward_fn ( ) ;
166+ }
167+ } ;
168+ }
169+ break ;
170+ }
171+ case torch . int8 :
172+ case torch . uint8 :
173+ case torch . int16 :
174+ case torch . int32 :
175+ case torch . int64 :
176+ {
177+ throw new TorchException ( "TorchException: nn.functional.avg_pool2d is not implemented for integer tensors." ) ;
178+ }
179+ }
180+ return y ;
181+ }
182+
23183 public static Tuple < Tensor , Tensor > max_pool2d_with_indices ( Tensor x , Union < int , Tuple < int , int > > kernel_size , Union < int , Tuple < int , int > > stride = null , Union < int , Tuple < int , int > > padding = null , Union < int , Tuple < int , int > > dilation = null )
24184 {
25185 if ( x . dtype == torch . @bool )
0 commit comments