Skip to content

Commit 263fbcf

Browse files
sharwellOceania2018
authored andcommitted
Implement SafeTensorHandleHandle as a wrapper for TFE_TensorHandle
1 parent 6244d08 commit 263fbcf

19 files changed

Lines changed: 369 additions & 174 deletions

src/TensorFlowNET.Core/Device/c_api.device.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public partial class c_api
6767
/// <param name="status">TF_Status*</param>
6868
/// <returns>TFE_TensorHandle*</returns>
6969
[DllImport(TensorFlowLibName)]
70-
public static extern IntPtr TFE_TensorHandleCopyToDevice(IntPtr h, SafeContextHandle ctx, string device_name, SafeStatusHandle status);
70+
public static extern SafeTensorHandleHandle TFE_TensorHandleCopyToDevice(SafeTensorHandleHandle h, SafeContextHandle ctx, string device_name, SafeStatusHandle status);
7171

7272
/// <summary>
7373
/// Retrieves the full name of the device (e.g. /job:worker/replica:0/...)

src/TensorFlowNET.Core/Eager/EagerRunner.TFE_Execute.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public Tensor[] TFE_ExecuteCancelable(Context ctx,
3333
{
3434
for (int i = 0; i < inputs.Length; ++i)
3535
{
36-
IntPtr tensor_handle;
36+
SafeTensorHandleHandle tensor_handle;
3737
switch (inputs[i])
3838
{
3939
case EagerTensor et:
@@ -50,10 +50,10 @@ public Tensor[] TFE_ExecuteCancelable(Context ctx,
5050
if (status.ok() && attrs != null)
5151
SetOpAttrs(op, attrs);
5252

53-
var outputs = new IntPtr[num_outputs];
53+
var outputs = new SafeTensorHandleHandle[num_outputs];
5454
if (status.ok())
5555
{
56-
c_api.TFE_Execute(op, outputs, ref num_outputs, status.Handle);
56+
c_api.TFE_Execute(op, outputs, out num_outputs, status.Handle);
5757
status.Check(true);
5858
}
5959
return outputs.Select(x => new EagerTensor(x)).ToArray();

src/TensorFlowNET.Core/Eager/EagerRunner.TFE_FastPathExecute.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ public Tensor[] TFE_FastPathExecute(Context ctx,
154154
num_retvals += (int)delta;
155155
}
156156

157-
var retVals = new IntPtr[num_retvals];
158-
c_api.TFE_Execute(op, retVals, ref num_retvals, status.Handle);
157+
var retVals = new SafeTensorHandleHandle[num_retvals];
158+
c_api.TFE_Execute(op, retVals, out num_retvals, status.Handle);
159159
status.Check(true);
160160

161161
var flat_result = retVals.Select(x => new EagerTensor(x)).ToArray();
@@ -220,7 +220,7 @@ bool AddInputToOp(object inputs,
220220
SafeOpHandle op,
221221
Status status)
222222
{
223-
IntPtr input_handle;
223+
SafeTensorHandleHandle input_handle;
224224

225225
// ConvertToTensor();
226226
switch (inputs)

src/TensorFlowNET.Core/Eager/EagerTensor.Creation.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public EagerTensor() : base(IntPtr.Zero)
1414

1515
}
1616

17-
public EagerTensor(IntPtr handle) : base(IntPtr.Zero)
17+
public EagerTensor(SafeTensorHandleHandle handle) : base(IntPtr.Zero)
1818
{
1919
EagerTensorHandle = handle;
2020
Resolve();
@@ -58,14 +58,20 @@ public EagerTensor Resolve()
5858
}
5959

6060
public override IntPtr ToPointer()
61-
=> EagerTensorHandle;
61+
=> EagerTensorHandle?.DangerousGetHandle() ?? IntPtr.Zero;
62+
63+
protected override void DisposeManagedResources()
64+
{
65+
base.DisposeManagedResources();
66+
67+
//print($"deleting DeleteTensorHandle {Id} {EagerTensorHandle.ToString("x16")}");
68+
EagerTensorHandle.Dispose();
69+
}
6270

6371
protected override void DisposeUnmanagedResources(IntPtr handle)
6472
{
6573
//print($"deleting DeleteTensorHandle {Id} {_handle.ToString("x16")}");
6674
c_api.TF_DeleteTensor(_handle);
67-
//print($"deleting DeleteTensorHandle {Id} {EagerTensorHandle.ToString("x16")}");
68-
c_api.TFE_DeleteTensorHandle(EagerTensorHandle);
6975
}
7076
}
7177
}

src/TensorFlowNET.Core/Eager/EagerTensor.Implicit.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ namespace Tensorflow.Eager
88
{
99
public partial class EagerTensor
1010
{
11+
[Obsolete("Implicit conversion of EagerTensor to IntPtr is not supported.", error: true)]
1112
public static implicit operator IntPtr(EagerTensor tensor)
12-
=> tensor.EagerTensorHandle;
13+
=> throw new NotSupportedException();
1314
}
1415
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*****************************************************************************
2+
Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
******************************************************************************/
16+
17+
using System;
18+
using Tensorflow.Util;
19+
20+
namespace Tensorflow.Eager
21+
{
22+
public sealed class SafeTensorHandleHandle : SafeTensorflowHandle
23+
{
24+
private SafeTensorHandleHandle()
25+
{
26+
}
27+
28+
public SafeTensorHandleHandle(IntPtr handle)
29+
: base(handle)
30+
{
31+
}
32+
33+
protected override bool ReleaseHandle()
34+
{
35+
c_api.TFE_DeleteTensorHandle(handle);
36+
SetHandle(IntPtr.Zero);
37+
return true;
38+
}
39+
}
40+
}

src/TensorFlowNET.Core/Eager/TFE_TensorHandle.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/TensorFlowNET.Core/Eager/c_api.eager.cs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Runtime.InteropServices;
44
using Tensorflow.Device;
55
using Tensorflow.Eager;
6+
using Tensorflow.Util;
67

78
namespace Tensorflow
89
{
@@ -66,7 +67,7 @@ public partial class c_api
6667
/// <param name="status">TF_Status*</param>
6768
/// <returns></returns>
6869
[DllImport(TensorFlowLibName)]
69-
public static extern int TFE_OpAddInputList(SafeOpHandle op, IntPtr[] inputs, int num_inputs, SafeStatusHandle status);
70+
public static extern int TFE_OpAddInputList(SafeOpHandle op, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeHandleArrayMarshaler))] SafeTensorHandleHandle[] inputs, int num_inputs, SafeStatusHandle status);
7071

7172
/// <summary>
7273
///
@@ -90,6 +91,20 @@ public partial class c_api
9091
[DllImport(TensorFlowLibName)]
9192
public static extern void TFE_DeleteContext(IntPtr ctx);
9293

94+
public static void TFE_Execute(SafeOpHandle op, SafeTensorHandleHandle[] retvals, out int num_retvals, SafeStatusHandle status)
95+
{
96+
unsafe
97+
{
98+
num_retvals = retvals?.Length ?? 0;
99+
var rawReturns = stackalloc IntPtr[num_retvals];
100+
TFE_Execute(op, rawReturns, ref num_retvals, status);
101+
for (var i = 0; i < num_retvals; i++)
102+
{
103+
retvals[i] = new SafeTensorHandleHandle(rawReturns[i]);
104+
}
105+
}
106+
}
107+
93108
/// <summary>
94109
/// Execute the operation defined by 'op' and return handles to computed
95110
/// tensors in `retvals`.
@@ -99,7 +114,7 @@ public partial class c_api
99114
/// <param name="num_retvals">int*</param>
100115
/// <param name="status">TF_Status*</param>
101116
[DllImport(TensorFlowLibName)]
102-
public static extern void TFE_Execute(SafeOpHandle op, IntPtr[] retvals, ref int num_retvals, SafeStatusHandle status);
117+
private static unsafe extern void TFE_Execute(SafeOpHandle op, IntPtr* retvals, ref int num_retvals, SafeStatusHandle status);
103118

104119
/// <summary>
105120
///
@@ -198,18 +213,18 @@ public partial class c_api
198213
/// <param name="h">TFE_TensorHandle*</param>
199214
/// <param name="status">TF_Status*</param>
200215
[DllImport(TensorFlowLibName)]
201-
public static extern void TFE_OpAddInput(SafeOpHandle op, IntPtr h, SafeStatusHandle status);
216+
public static extern void TFE_OpAddInput(SafeOpHandle op, SafeTensorHandleHandle h, SafeStatusHandle status);
202217

203218
/// <summary>
204219
///
205220
/// </summary>
206221
/// <param name="t">const tensorflow::Tensor&amp;</param>
207222
/// <returns>TFE_TensorHandle*</returns>
208223
[DllImport(TensorFlowLibName)]
209-
public static extern TFE_TensorHandle TFE_NewTensorHandle(IntPtr t, SafeStatusHandle status);
224+
public static extern SafeTensorHandleHandle TFE_NewTensorHandle(IntPtr t, SafeStatusHandle status);
210225

211226
[DllImport(TensorFlowLibName)]
212-
public static extern IntPtr TFE_EagerTensorHandle(IntPtr t);
227+
public static extern SafeTensorHandleHandle TFE_EagerTensorHandle(IntPtr t);
213228

214229
/// <summary>
215230
/// Sets the default execution mode (sync/async). Note that this can be
@@ -226,7 +241,7 @@ public partial class c_api
226241
/// <param name="h">TFE_TensorHandle*</param>
227242
/// <returns></returns>
228243
[DllImport(TensorFlowLibName)]
229-
public static extern TF_DataType TFE_TensorHandleDataType(IntPtr h);
244+
public static extern TF_DataType TFE_TensorHandleDataType(SafeTensorHandleHandle h);
230245

231246
/// <summary>
232247
/// This function will block till the operation that produces `h` has
@@ -237,7 +252,7 @@ public partial class c_api
237252
/// <param name="status">TF_Status*</param>
238253
/// <returns></returns>
239254
[DllImport(TensorFlowLibName)]
240-
public static extern IntPtr TFE_TensorHandleResolve(IntPtr h, SafeStatusHandle status);
255+
public static extern IntPtr TFE_TensorHandleResolve(SafeTensorHandleHandle h, SafeStatusHandle status);
241256

242257

243258
/// <summary>
@@ -247,10 +262,10 @@ public partial class c_api
247262
/// <param name="status">TF_Status*</param>
248263
/// <returns></returns>
249264
[DllImport(TensorFlowLibName)]
250-
public static extern int TFE_TensorHandleNumDims(IntPtr h, SafeStatusHandle status);
265+
public static extern int TFE_TensorHandleNumDims(SafeTensorHandleHandle h, SafeStatusHandle status);
251266

252267
[DllImport(TensorFlowLibName)]
253-
public static extern int TFE_TensorHandleDim(IntPtr h, int dim, SafeStatusHandle status);
268+
public static extern int TFE_TensorHandleDim(SafeTensorHandleHandle h, int dim, SafeStatusHandle status);
254269

255270
/// <summary>
256271
/// Returns the device of the operation that produced `h`. If `h` was produced by
@@ -263,7 +278,7 @@ public partial class c_api
263278
/// <param name="status">TF_Status*</param>
264279
/// <returns></returns>
265280
[DllImport(TensorFlowLibName)]
266-
public static extern IntPtr TFE_TensorHandleDeviceName(IntPtr h, SafeStatusHandle status);
281+
public static extern IntPtr TFE_TensorHandleDeviceName(SafeTensorHandleHandle h, SafeStatusHandle status);
267282

268283
/// <summary>
269284
/// Returns the name of the device in whose memory `h` resides.
@@ -272,7 +287,7 @@ public partial class c_api
272287
/// <param name="status">TF_Status*</param>
273288
/// <returns></returns>
274289
[DllImport(TensorFlowLibName)]
275-
public static extern IntPtr TFE_TensorHandleBackingDeviceName(IntPtr h, SafeStatusHandle status);
290+
public static extern IntPtr TFE_TensorHandleBackingDeviceName(SafeTensorHandleHandle h, SafeStatusHandle status);
276291

277292
/// <summary>
278293
///

src/TensorFlowNET.Core/Tensors/EagerTensorV2.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Tensorflow
1212
{
1313
public class EagerTensorV2 : DisposableObject, ITensor
1414
{
15-
IntPtr EagerTensorHandle;
15+
SafeTensorHandleHandle EagerTensorHandle;
1616
public string Device => c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(EagerTensorHandle, tf.status.Handle));
1717

1818
public EagerTensorV2(IntPtr handle)
@@ -64,10 +64,14 @@ public unsafe EagerTensorV2(NDArray nd, string device_name = "")
6464
}
6565
}*/
6666

67+
protected override void DisposeManagedResources()
68+
{
69+
EagerTensorHandle.Dispose();
70+
}
71+
6772
protected override void DisposeUnmanagedResources(IntPtr handle)
6873
{
6974
c_api.TF_DeleteTensor(_handle);
70-
c_api.TFE_DeleteTensorHandle(EagerTensorHandle);
7175
}
7276
}
7377
}

src/TensorFlowNET.Core/Tensors/Tensor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ limitations under the License.
2323
using System.Runtime.InteropServices;
2424
using System.Text;
2525
using static Tensorflow.Binding;
26+
using Tensorflow.Eager;
2627
using Tensorflow.Framework;
2728

2829
namespace Tensorflow
@@ -94,7 +95,7 @@ public partial class Tensor : DisposableObject,
9495
/// <summary>
9596
/// TFE_TensorHandle
9697
/// </summary>
97-
public IntPtr EagerTensorHandle { get; set; }
98+
public SafeTensorHandleHandle EagerTensorHandle { get; set; }
9899

99100
/// <summary>
100101
/// Returns the shape of a tensor.

0 commit comments

Comments
 (0)