@@ -31,7 +31,21 @@ public partial class Tensor
3131 /// <summary>
3232 /// true if unmanaged buffer has been freed.
3333 /// </summary>
34- private bool deallocator_called => _deallocatorArgs . deallocator_called ;
34+ private bool _deallocator_called => _deallocatorArgs . deallocator_called ;
35+
36+ /// <summary>
37+ /// true if the Tensor was created from a managed array
38+ /// </summary>
39+ private bool _isPinnedArray => _deallocatorArgs . gc_handle != IntPtr . Zero ;
40+
41+ /// <summary>
42+ /// This holds values that are used by the unmanaged deallocator callback
43+ /// </summary>
44+ private DeallocatorArgs _deallocatorArgs = new DeallocatorArgs ( ) { gc_handle = IntPtr . Zero } ;
45+
46+ // note: they must be assigned to a static variable in order to work as unmanaged callbacks
47+ static Deallocator _hGlobalDeallocator = FreeHGlobalMemory ;
48+ static Deallocator _gcHandleDeallocator = FreeGCHandle ;
3549
3650 public Tensor ( IntPtr handle )
3751 {
@@ -94,7 +108,7 @@ public unsafe Tensor(sbyte value, TF_DataType? dType = null)
94108 {
95109 var v = ( sbyte * ) Marshal . AllocHGlobal ( sizeof ( sbyte ) ) ;
96110 * v = value ;
97- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( sbyte ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( sbyte ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
111+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( sbyte ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( sbyte ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
98112 }
99113
100114 /// <summary>
@@ -120,7 +134,7 @@ public unsafe Tensor(byte value, TF_DataType? dType = null)
120134 {
121135 var v = ( byte * ) Marshal . AllocHGlobal ( sizeof ( byte ) ) ;
122136 * v = value ;
123- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( byte ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( byte ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
137+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( byte ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( byte ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
124138 }
125139
126140 /// <summary>
@@ -146,7 +160,7 @@ public unsafe Tensor(short value, TF_DataType? dType = null)
146160 {
147161 var v = ( short * ) Marshal . AllocHGlobal ( sizeof ( short ) ) ;
148162 * v = value ;
149- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( short ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( short ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
163+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( short ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( short ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
150164 }
151165
152166 /// <summary>
@@ -172,7 +186,7 @@ public unsafe Tensor(ushort value, TF_DataType? dType = null)
172186 {
173187 var v = ( ushort * ) Marshal . AllocHGlobal ( sizeof ( ushort ) ) ;
174188 * v = value ;
175- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( ushort ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( ushort ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
189+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( ushort ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( ushort ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
176190 }
177191
178192 /// <summary>
@@ -198,7 +212,7 @@ public unsafe Tensor(int value, TF_DataType? dType = null)
198212 {
199213 var v = ( int * ) Marshal . AllocHGlobal ( sizeof ( int ) ) ;
200214 * v = value ;
201- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( int ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( int ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
215+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( int ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( int ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
202216 }
203217
204218 /// <summary>
@@ -224,7 +238,7 @@ public unsafe Tensor(uint value, TF_DataType? dType = null)
224238 {
225239 var v = ( uint * ) Marshal . AllocHGlobal ( sizeof ( uint ) ) ;
226240 * v = value ;
227- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( uint ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( uint ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
241+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( uint ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( uint ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
228242 }
229243
230244 /// <summary>
@@ -250,7 +264,7 @@ public unsafe Tensor(long value, TF_DataType? dType = null)
250264 {
251265 var v = ( long * ) Marshal . AllocHGlobal ( sizeof ( long ) ) ;
252266 * v = value ;
253- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( long ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( long ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
267+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( long ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( long ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
254268 }
255269
256270 /// <summary>
@@ -276,7 +290,7 @@ public unsafe Tensor(ulong value, TF_DataType? dType = null)
276290 {
277291 var v = ( ulong * ) Marshal . AllocHGlobal ( sizeof ( ulong ) ) ;
278292 * v = value ;
279- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( ulong ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( ulong ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
293+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( ulong ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( ulong ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
280294 }
281295
282296 /// <summary>
@@ -302,7 +316,7 @@ public unsafe Tensor(float value, TF_DataType? dType = null)
302316 {
303317 var v = ( float * ) Marshal . AllocHGlobal ( sizeof ( float ) ) ;
304318 * v = value ;
305- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( float ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( float ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
319+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( float ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( float ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
306320 }
307321
308322 /// <summary>
@@ -328,7 +342,7 @@ public unsafe Tensor(double value, TF_DataType? dType = null)
328342 {
329343 var v = ( double * ) Marshal . AllocHGlobal ( sizeof ( double ) ) ;
330344 * v = value ;
331- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( double ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( double ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
345+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( double ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( double ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
332346 }
333347
334348 /// <summary>
@@ -354,7 +368,7 @@ public unsafe Tensor(Complex value, TF_DataType? dType = null)
354368 {
355369 var v = ( Complex * ) Marshal . AllocHGlobal ( sizeof ( Complex ) ) ;
356370 * v = value ;
357- _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( Complex ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( Complex ) , deallocator : hGlobalDeallocator , ref _deallocatorArgs ) ;
371+ _handle = TF_NewTensor ( dType ?? dtypes . as_dtype ( typeof ( Complex ) ) , dims : new long [ 0 ] , num_dims : 0 , data : ( IntPtr ) v , len : ( UIntPtr ) sizeof ( Complex ) , deallocator : _hGlobalDeallocator , ref _deallocatorArgs ) ;
358372 }
359373#endif
360374
@@ -444,7 +458,7 @@ private unsafe IntPtr Allocate(NDArray nd, TF_DataType? tensorDType = null)
444458 dims . Length ,
445459 dotHandle ,
446460 ( UIntPtr ) buffersize ,
447- hGlobalDeallocator ,
461+ _hGlobalDeallocator ,
448462 ref _deallocatorArgs ) ;
449463
450464 return tfHandle ;
@@ -458,8 +472,7 @@ public Tensor(Operation op, int value_index, TF_DataType dtype)
458472 _id = ops . uid ( ) ;
459473 }
460474
461- private bool _isPinnedArray => _deallocatorArgs . gc_handle != IntPtr . Zero ;
462-
475+
463476 /// <summary>
464477 /// Creates a new tensor from the given array without copying memory. The array is pinned down and the pointer passed on.
465478 /// </summary>
@@ -516,17 +529,11 @@ protected unsafe IntPtr CreateTensorWithoutCopying(TF_DataType dt, long[] shape,
516529 var gcHandle = GCHandle . Alloc ( data , GCHandleType . Pinned ) ;
517530 _deallocatorArgs = new DeallocatorArgs ( ) { gc_handle = GCHandle . ToIntPtr ( gcHandle ) } ;
518531 if ( shape == null || shape . Length == 0 )
519- return TF_NewTensor ( dt , new long [ 0 ] , 0 , gcHandle . AddrOfPinnedObject ( ) + start * element_size , ( UIntPtr ) ( count * element_size ) , gcHandleDeallocator , ref _deallocatorArgs ) ;
532+ return TF_NewTensor ( dt , new long [ 0 ] , 0 , gcHandle . AddrOfPinnedObject ( ) + start * element_size , ( UIntPtr ) ( count * element_size ) , _gcHandleDeallocator , ref _deallocatorArgs ) ;
520533 else
521- return TF_NewTensor ( dt , shape , shape . Length , gcHandle . AddrOfPinnedObject ( ) + start * element_size , ( UIntPtr ) ( count * element_size ) , gcHandleDeallocator , ref _deallocatorArgs ) ;
534+ return TF_NewTensor ( dt , shape , shape . Length , gcHandle . AddrOfPinnedObject ( ) + start * element_size , ( UIntPtr ) ( count * element_size ) , _gcHandleDeallocator , ref _deallocatorArgs ) ;
522535 }
523536
524- private DeallocatorArgs _deallocatorArgs = new DeallocatorArgs ( ) { gc_handle = IntPtr . Zero } ;
525-
526- // note: they must be assigned to a static variable in order to work as unmanaged callbacks
527- static Deallocator hGlobalDeallocator = FreeHGlobalMemory ;
528- static Deallocator gcHandleDeallocator = FreeGCHandle ;
529-
530537 [ MonoPInvokeCallback ( typeof ( Deallocator ) ) ]
531538 internal static void FreeHGlobalMemory ( IntPtr dataPtr , IntPtr len , ref DeallocatorArgs args )
532539 {
0 commit comments