MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
PermuteLayer.cs
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using MyCaffe.basecode;
6using MyCaffe.common;
7using MyCaffe.fillers;
8using MyCaffe.param;
9using MyCaffe.param.ssd;
10
11namespace MyCaffe.layers.ssd
12{
22 public class PermuteLayer<T> : Layer<T>
23 {
24 Blob<T> m_blobPermuteOrder;
25 Blob<T> m_blobOldSteps;
26 Blob<T> m_blobNewSteps;
27 int m_nNumAxes = 0;
28 bool m_bNeedPermute = false;
29
40 : base(cuda, log, p)
41 {
43
44 m_blobPermuteOrder = new Blob<T>(cuda, log);
45 m_blobPermuteOrder.Name = m_param.name + " order";
46 m_blobNewSteps = new Blob<T>(cuda, log);
47 m_blobNewSteps.Name = m_param.name + " new-steps";
48 m_blobOldSteps = new Blob<T>(cuda, log);
49 m_blobOldSteps.Name = m_param.name + " old-steps";
50 }
51
53 protected override void dispose()
54 {
55 if (m_blobPermuteOrder != null)
56 {
57 m_blobPermuteOrder.Dispose();
58 m_blobPermuteOrder = null;
59 }
60
61 if (m_blobNewSteps != null)
62 {
63 m_blobNewSteps.Dispose();
64 m_blobNewSteps = null;
65 }
66
67 if (m_blobOldSteps != null)
68 {
69 m_blobOldSteps.Dispose();
70 m_blobOldSteps = null;
71 }
72
73 base.dispose();
74 }
75
77 protected override void setup_internal_blobs(BlobCollection<T> col)
78 {
79 if (col.Count > 0)
80 return;
81
82 col.Add(m_blobPermuteOrder);
83 col.Add(m_blobNewSteps);
84 col.Add(m_blobOldSteps);
85 }
86
90 public override int ExactNumBottomBlobs
91 {
92 get { return 1; }
93 }
94
98 public override int ExactNumTopBlobs
99 {
100 get { return 1; }
101 }
102
108 public override void LayerSetUp(BlobCollection<T> colBottom, BlobCollection<T> colTop)
109 {
110 m_log.CHECK_EQ(colBottom.Count, 1, "There should only be one botom blob.");
112
113 m_nNumAxes = colBottom[0].num_axes;
114
115 // Push the specified new orders
116 List<int> rgOrders = new List<int>();
117 foreach (int nOrder in permute_param.order)
118 {
119 m_log.CHECK_LT(nOrder, m_nNumAxes, "The order should be less than the input dimension '" + m_nNumAxes.ToString() + "'!");
120
121 if (rgOrders.Contains(nOrder))
122 m_log.FAIL("The order '" + nOrder.ToString() + "' is a duplicate order!");
123
124 rgOrders.Add(nOrder);
125 }
126
127 // Push the rest of the orders and save the orginal step sizes for each axis.
128 for (int i = 0; i < m_nNumAxes; i++)
129 {
130 if (!rgOrders.Contains(i))
131 rgOrders.Add(i);
132 }
133
134 m_log.CHECK_EQ(rgOrders.Count, m_nNumAxes, "The order count should be the same as the input dimension of '" + m_nNumAxes.ToString() + "'!");
135
136 // Check if we need to reorder the data or keep it.
137 m_bNeedPermute = false;
138
139 for (int i = 0; i < m_nNumAxes; i++)
140 {
141 if (rgOrders[i] != i)
142 {
143 // As long as there is one order which is different from the natural order
144 // of the data, we need to permute. Otherwise, we share the data and diff.
145 m_bNeedPermute = true;
146 break;
147 }
148 }
149
150 List<int> rgTopShape = Utility.Create<int>(m_nNumAxes, 1);
151
152 m_blobPermuteOrder.Reshape(m_nNumAxes, 1, 1, 1);
153 m_blobOldSteps.ReshapeLike(m_blobPermuteOrder);
154 m_blobNewSteps.ReshapeLike(m_blobPermuteOrder);
155
156 T[] rgOrder1 = new T[m_nNumAxes];
157 for (int i = 0; i < m_nNumAxes; i++)
158 {
159 int nOrder = rgOrders[i];
160 rgOrder1[i] = Utility.ConvertVal<T>(nOrder);
161 int nShape = colBottom[0].shape(nOrder);
162 rgTopShape[i] = nShape;
163 }
164
165 m_blobPermuteOrder.mutable_cpu_data = rgOrder1;
166 colTop[0].Reshape(rgTopShape);
167 }
168
174 public override void Reshape(BlobCollection<T> colBottom, BlobCollection<T> colTop)
175 {
176 T[] rgOldSteps = new T[m_nNumAxes];
177 T[] rgNewSteps = new T[m_nNumAxes];
178 T[] rgOrder1 = m_blobPermuteOrder.mutable_cpu_data;
179 List<int> rgOrder = new List<int>();
180
181 for (int i = 0; i < rgOrder1.Length; i++)
182 {
183 if (i < m_nNumAxes)
184 {
185 if (i == m_nNumAxes - 1)
186 rgOldSteps[i] = m_tOne;
187 else
188 rgOldSteps[i] = Utility.ConvertVal<T>(colBottom[0].count(i + 1));
189 }
190
191 rgOrder.Add((int)Utility.ConvertVal<T>(rgOrder1[i]));
192 }
193
194 m_blobOldSteps.mutable_cpu_data = rgOldSteps;
195 List<int> rgTopShape = PermuteParameter.Reshape(rgOrder, colBottom[0].shape(), colBottom[0].num_axes);
196 colTop[0].Reshape(rgTopShape);
197
198 for (int i = 0; i < m_nNumAxes; i++)
199 {
200 if (i == m_nNumAxes - 1)
201 rgNewSteps[i] = m_tOne;
202 else
203 rgNewSteps[i] = Utility.ConvertVal<T>(colTop[0].count(i + 1));
204 }
205
206 m_blobNewSteps.mutable_cpu_data = rgNewSteps;
207 }
208
216 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
217 {
218 if (m_bNeedPermute)
219 {
220 long hBottomData = colBottom[0].mutable_gpu_data;
221 long hTopData = colTop[0].mutable_gpu_data;
222 int nCount = colTop[0].count();
223 long hPermuteOrder = m_blobPermuteOrder.gpu_data;
224 long hNewSteps = m_blobNewSteps.gpu_data;
225 long hOldSteps = m_blobOldSteps.gpu_data;
226 bool bForward = true;
227
228 m_cuda.permute(nCount, hBottomData, bForward, hPermuteOrder, hOldSteps, hNewSteps, m_nNumAxes, hTopData);
229 }
230 else
231 {
232 colTop[0].ShareData(colBottom[0]);
233 }
234 }
235
244 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
245 {
246 if (m_bNeedPermute)
247 {
248 long hTopDiff = colTop[0].mutable_gpu_diff;
249 long hBottomDiff = colBottom[0].mutable_gpu_diff;
250 int nCount = colTop[0].count();
251 long hPermuteOrder = m_blobPermuteOrder.gpu_data;
252 long hNewSteps = m_blobNewSteps.gpu_data;
253 long hOldSteps = m_blobOldSteps.gpu_data;
254 bool bForward = false;
255
256 m_cuda.permute(nCount, hBottomDiff, bForward, hPermuteOrder, hOldSteps, hNewSteps, m_nNumAxes, hTopDiff);
257 }
258 else
259 {
260 colBottom[0].ShareDiff(colTop[0]);
261 }
262 }
263 }
264}
The Log class provides general output in text form.
Definition: Log.cs:13
void FAIL(string str)
Causes a failure which throws an exception with the desciptive text.
Definition: Log.cs:394
void CHECK_EQ(double df1, double df2, string str)
Test whether one number is equal to another.
Definition: Log.cs:239
void CHECK_LT(double df1, double df2, string str)
Test whether one number is less than another.
Definition: Log.cs:275
The Utility class provides general utility funtions.
Definition: Utility.cs:35
static List< int > Create(int nCount, int nStart, int nInc)
Create a new List and fill it with values starting with start and incrementing by inc.
Definition: Utility.cs:721
The BlobCollection contains a list of Blobs.
void Add(Blob< T > b)
Add a new Blob to the collection.
int Count
Returns the number of items in the collection.
void Reshape(int[] rgShape)
Reshapes all blobs in the collection to the given shape.
The Blob is the main holder of data that moves through the Layers of the Net.
Definition: Blob.cs:25
T[] mutable_cpu_data
Get data from the GPU and bring it over to the host, or Set data from the Host and send it over to th...
Definition: Blob.cs:1461
void ReshapeLike(Blob< T > b, bool? bUseHalfSize=null)
Reshape this Blob to have the same shape as another Blob.
Definition: Blob.cs:648
string Name
Get/set the name of the Blob.
Definition: Blob.cs:2184
virtual void Dispose(bool bDisposing)
Releases all resources used by the Blob (including both GPU and Host).
Definition: Blob.cs:402
long gpu_data
Returns the data GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1479
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Definition: CudaDnn.cs:969
An interface for the units of computation which can be composed into a Net.
Definition: Layer.cs:31
Log m_log
Specifies the Log for output.
Definition: Layer.cs:43
LayerParameter m_param
Specifies the LayerParameter describing the Layer.
Definition: Layer.cs:47
T m_tOne
Specifies a generic type equal to 1.0.
Definition: Layer.cs:72
CudaDnn< T > m_cuda
Specifies the CudaDnn connection to Cuda.
Definition: Layer.cs:39
LayerParameter.LayerType m_type
Specifies the Layer type.
Definition: Layer.cs:35
LayerParameter layer_param
Returns the LayerParameter for this Layer.
Definition: Layer.cs:899
The PermuteLayer performs permutation on the input blob by changing the memory order of the data whic...
Definition: PermuteLayer.cs:23
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
override int ExactNumBottomBlobs
Returns the exact number of required bottom (input) Blobs: data
Definition: PermuteLayer.cs:91
override int ExactNumTopBlobs
Returns the exact number of required top (output) Blobs: permute
Definition: PermuteLayer.cs:99
PermuteLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The PermuteLayer constructor.
Definition: PermuteLayer.cs:39
override void dispose()
Releases all GPU and host resources used by the Layer.
Definition: PermuteLayer.cs:53
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the error gradient w.r.t the inputs.
override void setup_internal_blobs(BlobCollection< T > col)
Derivative layers should add all internal blobws to the 'col' provided.
Definition: PermuteLayer.cs:77
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Computes the forward calculation.
Specifies the base parameter for all layers.
string name
Specifies the name of this LayerParameter.
PermuteParameter permute_param
Returns the parameter set when initialized with LayerType.PERMUTE
LayerType
Specifies the layer type.
Specifies the parameters for the PermuteLayer.
static List< int > Reshape(List< int > rgOrder, List< int > rgShape, int nNumAxes)
Calculates the top shape by running the Reshape calculation.
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
Definition: Annotation.cs:12
The MyCaffe.common namespace contains common MyCaffe classes.
Definition: BatchInput.cs:8
The MyCaffe.fillers namespace contains all fillers including the Filler class.
The MyCaffe.layers.ssd namespace contains all Single-Shot MultiBox (SSD) related layers.
Definition: LayerFactory.cs:19
The MyCaffe.param.ssd namespace contains all SSD related parameter objects that correspond to the nat...
The MyCaffe.param namespace contains parameters used to create models.
The MyCaffe namespace contains the main body of MyCaffe code that closesly tracks the C++ Caffe open-...
Definition: Annotation.cs:12