1
- using Alea ;
1
+ using System ;
2
+ using Alea ;
2
3
using Alea . cuDNN ;
3
4
using NeuralNetworkNET . Extensions ;
4
5
using NeuralNetworkNET . Cuda . Extensions ;
@@ -17,7 +18,7 @@ namespace NeuralNetworkNET.Cuda.Layers
17
18
/// A pooling layer running on cuDNN, with a custom pooling mode
18
19
/// </summary>
19
20
[ JsonObject ( MemberSerialization . OptIn ) ]
20
- internal sealed class CuDnnPoolingLayer : PoolingLayer
21
+ internal sealed class CuDnnPoolingLayer : PoolingLayer , IDisposable
21
22
{
22
23
#region cuDNN fields
23
24
@@ -41,6 +42,16 @@ internal sealed class CuDnnPoolingLayer : PoolingLayer
41
42
42
43
#endregion
43
44
45
+ #region Fields
46
+
47
+ // A copy of the layer inputs
48
+ private Tensor _X ;
49
+
50
+ // A copy of the layer output activity
51
+ private Tensor _Z ;
52
+
53
+ #endregion
54
+
44
55
public CuDnnPoolingLayer ( in TensorInfo input , in PoolingInfo operation , ActivationFunctionType activation ) : base ( input , operation , activation )
45
56
{
46
57
PoolingDescription . Set2D ( ( PoolingMode ) operation . Mode , NanPropagation . PROPAGATE_NAN , operation . WindowHeight , operation . WindowWidth , operation . VerticalPadding , operation . HorizontalPadding , operation . VerticalStride , operation . HorizontalStride ) ;
@@ -49,6 +60,8 @@ public CuDnnPoolingLayer(in TensorInfo input, in PoolingInfo operation, Activati
49
60
/// <inheritdoc/>
50
61
public override void Forward ( in Tensor x , out Tensor z , out Tensor a )
51
62
{
63
+ _X . TryFree ( ) ;
64
+ x . Duplicate ( out _X ) ;
52
65
using ( DeviceMemory < float >
53
66
x_gpu = DnnInstance . Gpu . AllocateDevice ( x ) ,
54
67
z_gpu = DnnInstance . Gpu . AllocateDevice < float > ( x . Entities * OutputInfo . Size ) )
@@ -58,6 +71,8 @@ public override void Forward(in Tensor x, out Tensor z, out Tensor a)
58
71
OutputDescription . Set4D ( DataType . FLOAT , TensorFormat . CUDNN_TENSOR_NCHW , x . Entities , OutputInfo . Channels , OutputInfo . Height , OutputInfo . Width ) ;
59
72
DnnInstance . PoolingForward ( PoolingDescription , 1 , InputDescription , x_gpu . Ptr , 0 , OutputDescription , z_gpu . Ptr ) ;
60
73
z_gpu . CopyToHost ( x . Entities , OutputInfo . Size , out z ) ;
74
+ _Z . TryFree ( ) ;
75
+ z . Duplicate ( out _Z ) ;
61
76
62
77
// Activation
63
78
DnnInstance . ActivationForward ( z . Entities , z . Length , z_gpu . Ptr , z_gpu . Ptr , ActivationFunctions . Activation ) ;
@@ -66,7 +81,24 @@ public override void Forward(in Tensor x, out Tensor z, out Tensor a)
66
81
}
67
82
68
83
/// <inheritdoc/>
69
- public override void Backpropagate ( in Tensor delta_1 , in Tensor z , ActivationFunction activationPrime ) => z . UpscalePool2x2 ( delta_1 , InputInfo . Channels ) ;
84
+ public override void Backpropagate ( in Tensor delta_1 , in Tensor z , ActivationFunction activationPrime )
85
+ {
86
+ using ( DeviceMemory < float > dx_gpu = DnnInstance . Gpu . AllocateDevice < float > ( z . Size ) )
87
+ {
88
+ using ( DeviceMemory < float >
89
+ x_gpu = DnnInstance . Gpu . AllocateDevice ( _X ) ,
90
+ y_gpu = DnnInstance . Gpu . AllocateDevice ( _Z ) ,
91
+ dy_gpu = DnnInstance . Gpu . AllocateDevice ( delta_1 ) )
92
+ {
93
+ DnnInstance . PoolingBackward ( PoolingDescription , 1 , OutputDescription , y_gpu . Ptr , OutputDescription , dy_gpu . Ptr , InputDescription , x_gpu . Ptr , 0 , InputDescription , dx_gpu . Ptr ) ;
94
+ }
95
+ using ( DeviceMemory < float > z_gpu = DnnInstance . Gpu . AllocateDevice ( z ) )
96
+ {
97
+ DnnInstance . ActivationBackward ( z . Entities , z . Length , z_gpu . Ptr , dx_gpu . Ptr , activationPrime ) ;
98
+ z_gpu . CopyTo ( z ) ;
99
+ }
100
+ }
101
+ }
70
102
71
103
/// <inheritdoc/>
72
104
public override INetworkLayer Clone ( ) => new CuDnnPoolingLayer ( InputInfo , OperationInfo , ActivationFunctionType ) ;
@@ -84,5 +116,25 @@ public override void Forward(in Tensor x, out Tensor z, out Tensor a)
84
116
if ( ! stream . TryRead ( out PoolingInfo operation ) ) return null ;
85
117
return new CuDnnPoolingLayer ( input , operation , activation ) ;
86
118
}
119
+
120
+ #region IDisposable
121
+
122
+ ~ CuDnnPoolingLayer ( ) => Dispose ( ) ;
123
+
124
+ /// <inheritdoc/>
125
+ void IDisposable . Dispose ( )
126
+ {
127
+ GC . SuppressFinalize ( this ) ;
128
+ Dispose ( ) ;
129
+ }
130
+
131
+ // Private Dispose method
132
+ private void Dispose ( )
133
+ {
134
+ _X . TryFree ( ) ;
135
+ _Z . TryFree ( ) ;
136
+ }
137
+
138
+ #endregion
87
139
}
88
140
}
0 commit comments