1
1
using System ;
2
2
using System . Collections . Generic ;
3
- using System . Linq ;
4
3
using System . Runtime . InteropServices ;
5
4
using System . Text ;
6
5
using System . Threading . Tasks ;
@@ -53,33 +52,6 @@ void NormalizationKernel(int i)
53
52
54
53
#region Misc
55
54
56
- /// <summary>
57
- /// Calculates the position and the value of the biggest item in a matrix
58
- /// </summary>
59
- /// <param name="m">The input matrix</param>
60
- internal static ( int x , int y , float value ) Max ( [ NotNull ] this float [ , ] m )
61
- {
62
- // Checks and local variables setup
63
- if ( m . Length == 0 ) throw new ArgumentOutOfRangeException ( "The input matrix can't be empty" ) ;
64
- if ( m . Length == 1 ) return ( 0 , 0 , m [ 0 , 0 ] ) ;
65
- int
66
- h = m . GetLength ( 0 ) ,
67
- w = m . GetLength ( 1 ) ,
68
- x = 0 , y = 0 ;
69
- float max = float . MinValue ;
70
-
71
- // Find the maximum value and its position
72
- for ( int i = 0 ; i < h ; i ++ )
73
- for ( int j = 0 ; j < w ; j ++ )
74
- {
75
- if ( ! ( m [ i , j ] > max ) ) continue ;
76
- max = m [ i , j ] ;
77
- x = i ;
78
- y = j ;
79
- }
80
- return ( x , y , max ) ;
81
- }
82
-
83
55
/// <summary>
84
56
/// Finds the minimum and maximum value in the input memory area
85
57
/// </summary>
@@ -115,33 +87,6 @@ internal static unsafe (float Min, float Max) MinMax(float* p, int length)
115
87
return m ;
116
88
}
117
89
118
- /// <summary>
119
- /// Flattens the input volume in a linear array
120
- /// </summary>
121
- /// <param name="volume">The volume to flatten</param>
122
- [ PublicAPI ]
123
- [ Pure , NotNull ]
124
- [ CollectionAccess ( CollectionAccessType . Read ) ]
125
- public static float [ ] Flatten ( [ NotNull , ItemNotNull ] this IReadOnlyList < float [ , ] > volume )
126
- {
127
- // Preliminary checks and declarations
128
- if ( volume . Count == 0 ) throw new ArgumentOutOfRangeException ( "The input volume can't be empty" ) ;
129
- int
130
- depth = volume . Count ,
131
- length = volume [ 0 ] . Length ,
132
- bytes = sizeof ( float ) * length ;
133
- float [ ] result = new float [ depth * length ] ;
134
-
135
- // Execute the copy in parallel
136
- bool loopResult = Parallel . For ( 0 , depth , i =>
137
- {
138
- // Copy the volume data
139
- Buffer . BlockCopy ( volume [ i ] , 0 , result , bytes * i , bytes ) ;
140
- } ) . IsCompleted ;
141
- if ( ! loopResult ) throw new Exception ( "Error while runnig the parallel loop" ) ;
142
- return result ;
143
- }
144
-
145
90
/// <summary>
146
91
/// Merges the input samples into a matrix dataset
147
92
/// </summary>
@@ -167,42 +112,12 @@ public static (float[,], float[,]) MergeRows([NotNull] this IReadOnlyList<(float
167
112
return ( x , y ) ;
168
113
}
169
114
170
- /// <summary>
171
- /// Merges the rows of the input matrices into a single matrix
172
- /// </summary>
173
- /// <param name="blocks">The matrices to merge</param>
174
- [ PublicAPI ]
175
- [ Pure , NotNull ]
176
- [ CollectionAccess ( CollectionAccessType . Read ) ]
177
- public static float [ , ] MergeRows ( [ NotNull , ItemNotNull ] this IReadOnlyList < float [ , ] > blocks )
178
- {
179
- // Preliminary checks and declarations
180
- if ( blocks . Count == 0 ) throw new ArgumentOutOfRangeException ( "The blocks list can't be empty" ) ;
181
- int
182
- h = blocks . Sum ( b => b . GetLength ( 0 ) ) ,
183
- w = blocks [ 0 ] . GetLength ( 1 ) ,
184
- rowBytes = sizeof ( float ) * w ;
185
- float [ , ] result = new float [ h , w ] ;
186
-
187
- // Execute the copy in parallel
188
- int position = 0 ;
189
- for ( int i = 0 ; i < blocks . Count ; i ++ )
190
- {
191
- float [ , ] next = blocks [ i ] ;
192
- if ( next . GetLength ( 1 ) != w ) throw new ArgumentOutOfRangeException ( "The blocks must all have the same width" ) ;
193
- int rows = next . GetLength ( 0 ) ;
194
- Buffer . BlockCopy ( next , 0 , result , rowBytes * position , rowBytes * rows ) ;
195
- position += rows ;
196
- }
197
- return result ;
198
- }
199
-
200
115
#endregion
201
116
202
117
#region Argmax
203
118
204
119
/// <summary>
205
- /// Returns the index of the maximum value in the input vector
120
+ /// Returns the index of the maximum value in the input memory area
206
121
/// </summary>
207
122
/// <param name="p">A pointer to the buffer to read</param>
208
123
/// <param name="length">The length of the buffer to consider</param>
@@ -223,10 +138,19 @@ internal static unsafe int Argmax(float* p, int length)
223
138
return index ;
224
139
}
225
140
141
+ /// <summary>
142
+ /// Returns the index of the maximum value in the input tensor
143
+ /// </summary>
144
+ /// <param name="tensor">The input <see cref="Tensor"/> to read from</param>
145
+ [ PublicAPI ]
146
+ [ CollectionAccess ( CollectionAccessType . Read ) ]
147
+ public static unsafe int Argmax ( in this Tensor tensor ) => Argmax ( tensor , tensor . Size ) ;
148
+
226
149
/// <summary>
227
150
/// Returns the index of the maximum value in the input vector
228
151
/// </summary>
229
152
/// <param name="v">The input vector to read from</param>
153
+ [ PublicAPI ]
230
154
[ CollectionAccess ( CollectionAccessType . Read ) ]
231
155
public static unsafe int Argmax ( [ NotNull ] this float [ ] v )
232
156
{
@@ -237,6 +161,7 @@ public static unsafe int Argmax([NotNull] this float[] v)
237
161
/// Returns the index of the maximum value in the input matrix
238
162
/// </summary>
239
163
/// <param name="m">The input matrix to read from</param>
164
+ [ PublicAPI ]
240
165
[ CollectionAccess ( CollectionAccessType . Read ) ]
241
166
public static unsafe int Argmax ( [ NotNull ] this float [ , ] m )
242
167
{
@@ -295,7 +220,7 @@ internal static unsafe void Fill([NotNull] this Array array, [NotNull] Func<floa
295
220
/// Returns a deep copy of the input vector
296
221
/// </summary>
297
222
/// <param name="v">The vector to clone</param>
298
- /// <remarks>This method avoids the boxing of the <see cref="Array.Clone"/> method, and it is faster thanks to <see cref="Buffer.MemoryCopy "/></remarks>
223
+ /// <remarks>This method avoids the boxing of the <see cref="Array.Clone"/> method, and it is faster thanks to the use of the methods in the <see cref="Buffer"/> class </remarks>
299
224
[ Pure , NotNull ]
300
225
[ CollectionAccess ( CollectionAccessType . Read ) ]
301
226
public static unsafe float [ ] BlockCopy ( [ NotNull ] this float [ ] v )
@@ -309,7 +234,7 @@ public static unsafe float[] BlockCopy([NotNull] this float[] v)
309
234
310
235
#endregion
311
236
312
- #region Content check
237
+ #region Content equals
313
238
314
239
/// <summary>
315
240
/// Checks if two matrices have the same size and content
@@ -318,7 +243,7 @@ public static unsafe float[] BlockCopy([NotNull] this float[] v)
318
243
/// <param name="o">The second <see cref="Tensor"/> to test</param>
319
244
/// <param name="absolute">The relative comparison threshold</param>
320
245
/// <param name="relative">The relative comparison threshold</param>
321
- public static unsafe bool ContentEquals ( in this Tensor m , in Tensor o , float absolute = 1e-6f , float relative = 1e-6f )
246
+ public static unsafe bool ContentEquals ( in this Tensor m , in Tensor o , float absolute = 1e-6f , float relative = 1e-6f )
322
247
{
323
248
if ( m . Ptr == IntPtr . Zero && o . Ptr == IntPtr . Zero ) return true ;
324
249
if ( m . Ptr == IntPtr . Zero || o . Ptr == IntPtr . Zero ) return false ;
@@ -374,53 +299,6 @@ public static bool ContentEquals([CanBeNull] this float[] v, [CanBeNull] float[]
374
299
return true ;
375
300
}
376
301
377
- // GetUid helper method
378
- private static unsafe int GetUid ( float * p , int n )
379
- {
380
- int hash = 17 ;
381
- unchecked
382
- {
383
- for ( int i = 0 ; i < n ; i ++ )
384
- hash = hash * 23 + p [ i ] . GetHashCode ( ) ;
385
- return hash ;
386
- }
387
- }
388
-
389
- /// <summary>
390
- /// Calculates a unique hash code for the target row of the input matrix
391
- /// </summary>
392
- [ Pure ]
393
- public static unsafe int GetUid ( [ NotNull ] this float [ , ] m , int row )
394
- {
395
- int
396
- w = m . GetLength ( 1 ) ,
397
- offset = row * w ;
398
- fixed ( float * pm = m )
399
- return GetUid ( pm + offset , w ) ;
400
- }
401
-
402
- /// <summary>
403
- /// Calculates a unique hash code for the input matrix
404
- /// </summary>
405
- /// <param name="m">The matrix to analyze</param>
406
- [ Pure ]
407
- public static unsafe int GetUid ( [ NotNull ] this float [ , ] m )
408
- {
409
- fixed ( float * pm = m )
410
- return GetUid ( pm , m . Length ) ;
411
- }
412
-
413
- /// <summary>
414
- /// Calculates a unique hash code for the input vector
415
- /// </summary>
416
- /// <param name="v">The vector to analyze</param>
417
- [ Pure ]
418
- public static unsafe int GetUid ( [ NotNull ] this float [ ] v )
419
- {
420
- fixed ( float * pv = v )
421
- return GetUid ( pv , v . Length ) ;
422
- }
423
-
424
302
#endregion
425
303
426
304
#region String display
0 commit comments