diff --git a/src/TensorFlowNET.Core/Attributes/c_api.ops.cs b/src/TensorFlowNET.Core/Attributes/c_api.ops.cs index 77877a43..0bca1bba 100644 --- a/src/TensorFlowNET.Core/Attributes/c_api.ops.cs +++ b/src/TensorFlowNET.Core/Attributes/c_api.ops.cs @@ -32,7 +32,7 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern TF_AttrMetadata TF_OperationGetAttrMetadata(IntPtr oper, string attr_name, IntPtr status); + public static extern TF_AttrMetadata TF_OperationGetAttrMetadata(IntPtr oper, string attr_name, SafeStatusHandle status); /// /// Fills in `value` with the value of the attribute `attr_name`. `value` must @@ -46,7 +46,7 @@ namespace Tensorflow /// size_t /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TF_OperationGetAttrString(IntPtr oper, string attr_name, IntPtr value, uint max_length, IntPtr status); + public static extern void TF_OperationGetAttrString(IntPtr oper, string attr_name, IntPtr value, uint max_length, SafeStatusHandle status); /// /// Sets `output_attr_value` to the binary-serialized AttrValue proto @@ -55,13 +55,13 @@ namespace Tensorflow /// /// [DllImport(TensorFlowLibName)] - public static extern int TF_OperationGetAttrValueProto(IntPtr oper, string attr_name, IntPtr output_attr_value, IntPtr status); + public static extern int TF_OperationGetAttrValueProto(IntPtr oper, string attr_name, IntPtr output_attr_value, SafeStatusHandle status); [DllImport(TensorFlowLibName)] public static extern void TF_SetAttrBool(IntPtr desc, string attr_name, bool value); [DllImport(TensorFlowLibName)] - public static extern void TF_SetAttrValueProto(IntPtr desc, string attr_name, IntPtr proto, uint proto_len, IntPtr status); + public static extern void TF_SetAttrValueProto(IntPtr desc, string attr_name, IntPtr proto, uint proto_len, SafeStatusHandle status); /// /// Set `num_dims` to -1 to represent "unknown rank". @@ -99,7 +99,7 @@ namespace Tensorflow public static extern void TF_SetAttrStringList(IntPtr desc, string attr_name, IntPtr[] values, uint[] lengths, int num_values); [DllImport(TensorFlowLibName)] - public static extern void TF_SetAttrTensor(IntPtr desc, string attr_name, IntPtr value, IntPtr status); + public static extern void TF_SetAttrTensor(IntPtr desc, string attr_name, IntPtr value, SafeStatusHandle status); [DllImport(TensorFlowLibName)] public static extern void TF_SetAttrType(IntPtr desc, string attr_name, TF_DataType value); diff --git a/src/TensorFlowNET.Core/Device/c_api.device.cs b/src/TensorFlowNET.Core/Device/c_api.device.cs index f2289cee..698aa227 100644 --- a/src/TensorFlowNET.Core/Device/c_api.device.cs +++ b/src/TensorFlowNET.Core/Device/c_api.device.cs @@ -45,7 +45,7 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern IntPtr TF_DeviceListType(IntPtr list, int index, IntPtr status); + public static extern IntPtr TF_DeviceListType(IntPtr list, int index, SafeStatusHandle status); /// /// Deallocates the device list. @@ -64,7 +64,7 @@ namespace Tensorflow /// TF_Status* /// TFE_TensorHandle* [DllImport(TensorFlowLibName)] - public static extern IntPtr TFE_TensorHandleCopyToDevice(IntPtr h, IntPtr ctx, string device_name, IntPtr status); + public static extern IntPtr TFE_TensorHandleCopyToDevice(IntPtr h, IntPtr ctx, string device_name, SafeStatusHandle status); /// /// Retrieves the full name of the device (e.g. /job:worker/replica:0/...) @@ -76,6 +76,6 @@ namespace Tensorflow /// /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern IntPtr TF_DeviceListName(IntPtr list, int index, IntPtr status); + public static extern IntPtr TF_DeviceListName(IntPtr list, int index, SafeStatusHandle status); } } diff --git a/src/TensorFlowNET.Core/Eager/Context.cs b/src/TensorFlowNET.Core/Eager/Context.cs index 58d882ad..d697fafa 100644 --- a/src/TensorFlowNET.Core/Eager/Context.cs +++ b/src/TensorFlowNET.Core/Eager/Context.cs @@ -14,7 +14,7 @@ namespace Tensorflow.Eager public Context(ContextOptions opts, Status status) { - _handle = c_api.TFE_NewContext(opts, status); + _handle = c_api.TFE_NewContext(opts, status.Handle); status.Check(true); } diff --git a/src/TensorFlowNET.Core/Eager/EagerOperation.cs b/src/TensorFlowNET.Core/Eager/EagerOperation.cs index fe0054cf..fdcf1cd5 100644 --- a/src/TensorFlowNET.Core/Eager/EagerOperation.cs +++ b/src/TensorFlowNET.Core/Eager/EagerOperation.cs @@ -53,7 +53,7 @@ namespace Tensorflow.Eager { object value = null; byte isList = 0; - var attrType = c_api.TFE_OpNameGetAttrType(tf.context, Name, attr_name, ref isList, tf.status); + var attrType = c_api.TFE_OpNameGetAttrType(tf.context, Name, attr_name, ref isList, tf.status.Handle); switch (attrType) { case TF_AttrType.TF_ATTR_BOOL: diff --git a/src/TensorFlowNET.Core/Eager/EagerTensor.Creation.cs b/src/TensorFlowNET.Core/Eager/EagerTensor.Creation.cs index ce227185..1dea32bf 100644 --- a/src/TensorFlowNET.Core/Eager/EagerTensor.Creation.cs +++ b/src/TensorFlowNET.Core/Eager/EagerTensor.Creation.cs @@ -22,13 +22,13 @@ namespace Tensorflow.Eager public EagerTensor(string value, string device_name) : base(value) { - EagerTensorHandle = c_api.TFE_NewTensorHandle(_handle, tf.status); + EagerTensorHandle = c_api.TFE_NewTensorHandle(_handle, tf.status.Handle); Resolve(); } public EagerTensor(NDArray value, string device_name) : base(value) { - EagerTensorHandle = c_api.TFE_NewTensorHandle(_handle, tf.status); + EagerTensorHandle = c_api.TFE_NewTensorHandle(_handle, tf.status.Handle); Resolve(); } @@ -37,7 +37,7 @@ namespace Tensorflow.Eager _id = get_uid(); if (_handle == IntPtr.Zero) - _handle = c_api.TFE_TensorHandleResolve(EagerTensorHandle, tf.status); + _handle = c_api.TFE_TensorHandleResolve(EagerTensorHandle, tf.status.Handle); //print($"new Tensor {Id} {_handle.ToString("x16")}"); //print($"new TensorHandle {Id} {EagerTensorHandle.ToString("x16")}"); diff --git a/src/TensorFlowNET.Core/Eager/EagerTensor.cs b/src/TensorFlowNET.Core/Eager/EagerTensor.cs index d084ffae..2d247750 100644 --- a/src/TensorFlowNET.Core/Eager/EagerTensor.cs +++ b/src/TensorFlowNET.Core/Eager/EagerTensor.cs @@ -9,22 +9,22 @@ namespace Tensorflow.Eager public partial class EagerTensor : Tensor { public IntPtr EagerTensorHandle; - public override string Device => c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(EagerTensorHandle, tf.status)); + public override string Device => c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(EagerTensorHandle, tf.status.Handle)); - public override int rank => c_api.TFE_TensorHandleNumDims(EagerTensorHandle, tf.status); + public override int rank => c_api.TFE_TensorHandleNumDims(EagerTensorHandle, tf.status.Handle); public static int GetRank(IntPtr handle) { var tfe_tensor_handle = c_api.TFE_EagerTensorHandle(handle); - return c_api.TFE_TensorHandleNumDims(tfe_tensor_handle, tf.status); + return c_api.TFE_TensorHandleNumDims(tfe_tensor_handle, tf.status.Handle); } public static int[] GetDims(IntPtr handle) { var tfe_tensor_handle = c_api.TFE_EagerTensorHandle(handle); - var dims = new int[c_api.TFE_TensorHandleNumDims(tfe_tensor_handle, tf.status)]; + var dims = new int[c_api.TFE_TensorHandleNumDims(tfe_tensor_handle, tf.status.Handle)]; for (int i = 0; i < dims.Length; i++) - dims[i] = c_api.TFE_TensorHandleDim(tfe_tensor_handle, i, tf.status); + dims[i] = c_api.TFE_TensorHandleDim(tfe_tensor_handle, i, tf.status.Handle); return dims; } diff --git a/src/TensorFlowNET.Core/Eager/c_api.eager.cs b/src/TensorFlowNET.Core/Eager/c_api.eager.cs index d12f9678..4e9f59c1 100644 --- a/src/TensorFlowNET.Core/Eager/c_api.eager.cs +++ b/src/TensorFlowNET.Core/Eager/c_api.eager.cs @@ -70,10 +70,10 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern TF_AttrType TFE_OpGetAttrType(IntPtr op, string attr_name, ref byte is_list, IntPtr status); + public static extern TF_AttrType TFE_OpGetAttrType(IntPtr op, string attr_name, ref byte is_list, SafeStatusHandle status); [DllImport(TensorFlowLibName)] - public static extern TF_AttrType TFE_OpNameGetAttrType(IntPtr ct, string op_or_function_name, string attr_name, ref byte is_list, IntPtr status); + public static extern TF_AttrType TFE_OpNameGetAttrType(IntPtr ct, string op_or_function_name, string attr_name, ref byte is_list, SafeStatusHandle status); /// /// Returns the length (number of tensors) of the input argument `input_name` @@ -83,7 +83,7 @@ namespace Tensorflow /// const char* /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern int TFE_OpGetInputLength(IntPtr op, string input_name, IntPtr status); + public static extern int TFE_OpGetInputLength(IntPtr op, string input_name, SafeStatusHandle status); /// /// Returns the length (number of tensors) of the output argument `output_name` @@ -94,7 +94,7 @@ namespace Tensorflow /// /// [DllImport(TensorFlowLibName)] - public static extern int TFE_OpGetOutputLength(IntPtr op, string input_name, IntPtr status); + public static extern int TFE_OpGetOutputLength(IntPtr op, string input_name, SafeStatusHandle status); /// /// @@ -105,7 +105,7 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern int TFE_OpAddInputList(IntPtr op, IntPtr[] inputs, int num_inputs, IntPtr status); + public static extern int TFE_OpAddInputList(IntPtr op, IntPtr[] inputs, int num_inputs, SafeStatusHandle status); /// /// @@ -114,7 +114,7 @@ namespace Tensorflow /// TF_Status* /// TFE_Context* [DllImport(TensorFlowLibName)] - public static extern TFE_Context TFE_NewContext(IntPtr opts, IntPtr status); + public static extern TFE_Context TFE_NewContext(IntPtr opts, SafeStatusHandle status); [DllImport(TensorFlowLibName)] public static extern TFE_Context TFE_ContextStartStep(IntPtr ctx); @@ -138,7 +138,7 @@ namespace Tensorflow /// int* /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TFE_Execute(IntPtr op, IntPtr[] retvals, ref int num_retvals, IntPtr status); + public static extern void TFE_Execute(IntPtr op, IntPtr[] retvals, ref int num_retvals, SafeStatusHandle status); /// /// @@ -148,7 +148,7 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern TFE_Op TFE_NewOp(IntPtr ctx, string op_or_function_name, IntPtr status); + public static extern TFE_Op TFE_NewOp(IntPtr ctx, string op_or_function_name, SafeStatusHandle status); /// /// Resets `op_to_reset` with `op_or_function_name` and `raw_device_name`. This @@ -164,7 +164,7 @@ namespace Tensorflow /// const char* /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TFE_OpReset(IntPtr op_to_reset, string op_or_function_name, string raw_device_name, IntPtr status); + public static extern void TFE_OpReset(IntPtr op_to_reset, string op_or_function_name, string raw_device_name, SafeStatusHandle status); /// /// @@ -194,7 +194,7 @@ namespace Tensorflow /// const int /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TFE_OpSetAttrShape(IntPtr op, string attr_name, long[] dims, int num_dims, IntPtr out_status); + public static extern void TFE_OpSetAttrShape(IntPtr op, string attr_name, long[] dims, int num_dims, SafeStatusHandle out_status); [DllImport(TensorFlowLibName)] public static extern void TFE_OpSetAttrBool(IntPtr op, string attr_name, bool value); @@ -216,7 +216,7 @@ namespace Tensorflow /// /// [DllImport(TensorFlowLibName)] - public static extern void TFE_OpSetDevice(TFE_Op op, string device_name, IntPtr status); + public static extern void TFE_OpSetDevice(TFE_Op op, string device_name, SafeStatusHandle status); /// /// @@ -225,7 +225,7 @@ namespace Tensorflow /// TFE_TensorHandle* /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TFE_OpAddInput(IntPtr op, IntPtr h, IntPtr status); + public static extern void TFE_OpAddInput(IntPtr op, IntPtr h, SafeStatusHandle status); /// /// @@ -233,7 +233,7 @@ namespace Tensorflow /// const tensorflow::Tensor& /// TFE_TensorHandle* [DllImport(TensorFlowLibName)] - public static extern TFE_TensorHandle TFE_NewTensorHandle(IntPtr t, IntPtr status); + public static extern TFE_TensorHandle TFE_NewTensorHandle(IntPtr t, SafeStatusHandle status); [DllImport(TensorFlowLibName)] public static extern IntPtr TFE_EagerTensorHandle(IntPtr t); @@ -273,7 +273,7 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern IntPtr TFE_TensorHandleResolve(IntPtr h, IntPtr status); + public static extern IntPtr TFE_TensorHandleResolve(IntPtr h, SafeStatusHandle status); /// @@ -283,10 +283,10 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern int TFE_TensorHandleNumDims(IntPtr h, IntPtr status); + public static extern int TFE_TensorHandleNumDims(IntPtr h, SafeStatusHandle status); [DllImport(TensorFlowLibName)] - public static extern int TFE_TensorHandleDim(IntPtr h, int dim, IntPtr status); + public static extern int TFE_TensorHandleDim(IntPtr h, int dim, SafeStatusHandle status); /// /// Returns the device of the operation that produced `h`. If `h` was produced by @@ -299,7 +299,7 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern IntPtr TFE_TensorHandleDeviceName(IntPtr h, IntPtr status); + public static extern IntPtr TFE_TensorHandleDeviceName(IntPtr h, SafeStatusHandle status); /// /// Returns the name of the device in whose memory `h` resides. @@ -308,7 +308,7 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern IntPtr TFE_TensorHandleBackingDeviceName(IntPtr h, IntPtr status); + public static extern IntPtr TFE_TensorHandleBackingDeviceName(IntPtr h, SafeStatusHandle status); /// /// @@ -317,7 +317,7 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern IntPtr TFE_ContextListDevices(IntPtr ctx, IntPtr status); + public static extern IntPtr TFE_ContextListDevices(IntPtr ctx, SafeStatusHandle status); /// /// @@ -370,7 +370,7 @@ namespace Tensorflow /// TFE_Executor* /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TFE_ExecutorWaitForAllPendingNodes(TFE_Executor executor, IntPtr status); + public static extern void TFE_ExecutorWaitForAllPendingNodes(TFE_Executor executor, SafeStatusHandle status); /// /// Sets a custom Executor for current thread. All nodes created by this thread @@ -402,7 +402,7 @@ namespace Tensorflow /// /// EagerTensorHandle [DllImport(TensorFlowLibName)] - public static extern IntPtr TFE_FastPathExecute(IntPtr ctx, + public static extern SafeStatusHandle TFE_FastPathExecute(IntPtr ctx, string device_name, string op_name, string name, @@ -416,7 +416,7 @@ namespace Tensorflow public delegate void TFE_FastPathExecute_SetOpAttrs(IntPtr op); [DllImport(TensorFlowLibName)] - public static extern IntPtr TFE_QuickExecute(IntPtr ctx, + public static extern SafeStatusHandle TFE_QuickExecute(IntPtr ctx, string device_name, string op_name, IntPtr[] inputs, @@ -444,7 +444,7 @@ namespace Tensorflow public static extern IntPtr ResourceVariable_Handle(IntPtr variable); [DllImport(TensorFlowLibName)] - public static extern IntPtr TFE_TapeGradient(IntPtr tape, + public static extern SafeStatusHandle TFE_TapeGradient(IntPtr tape, IntPtr[] target, int target_size, IntPtr[] sources, int source_size, IntPtr[] outputs, int output_size); diff --git a/src/TensorFlowNET.Core/Framework/Models/ScopedTFStatus.cs b/src/TensorFlowNET.Core/Framework/Models/ScopedTFStatus.cs deleted file mode 100644 index a427c994..00000000 --- a/src/TensorFlowNET.Core/Framework/Models/ScopedTFStatus.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Tensorflow.Framework.Models -{ - public class ScopedTFStatus : Status - { - public ScopedTFStatus() : base() - { - } - } -} diff --git a/src/TensorFlowNET.Core/Framework/importer.cs b/src/TensorFlowNET.Core/Framework/importer.cs index b4bf1c73..ff1ba4f5 100644 --- a/src/TensorFlowNET.Core/Framework/importer.cs +++ b/src/TensorFlowNET.Core/Framework/importer.cs @@ -62,7 +62,7 @@ namespace Tensorflow { _PopulateTFImportGraphDefOptions(scoped_options, prefix, input_map, return_elements); // need to create a class ImportGraphDefWithResults with IDisposal - results = c_api.TF_GraphImportGraphDefWithResults(graph, buffer, scoped_options, status); + results = c_api.TF_GraphImportGraphDefWithResults(graph, buffer, scoped_options, status.Handle); status.Check(true); } diff --git a/src/TensorFlowNET.Core/Functions/c_api.function.cs b/src/TensorFlowNET.Core/Functions/c_api.function.cs index 9fa12efc..11ed7bdd 100644 --- a/src/TensorFlowNET.Core/Functions/c_api.function.cs +++ b/src/TensorFlowNET.Core/Functions/c_api.function.cs @@ -31,7 +31,7 @@ namespace Tensorflow /// /// [DllImport(TensorFlowLibName)] - public static extern void TF_FunctionToFunctionDef(IntPtr func, IntPtr output_func_def, IntPtr status); + public static extern void TF_FunctionToFunctionDef(IntPtr func, IntPtr output_func_def, SafeStatusHandle status); } diff --git a/src/TensorFlowNET.Core/Gradients/c_api.gradient.cs b/src/TensorFlowNET.Core/Gradients/c_api.gradient.cs index 2459626f..c0f132ee 100644 --- a/src/TensorFlowNET.Core/Gradients/c_api.gradient.cs +++ b/src/TensorFlowNET.Core/Gradients/c_api.gradient.cs @@ -41,6 +41,6 @@ namespace Tensorflow /// TF_Output* [DllImport(TensorFlowLibName)] public static extern void TF_AddGradientsWithPrefix(IntPtr g, string prefix, TF_Output[] y, int ny, - TF_Output[] x, int nx, TF_Output[] dx, IntPtr status, IntPtr[] dy); + TF_Output[] x, int nx, TF_Output[] dx, SafeStatusHandle status, IntPtr[] dy); } } diff --git a/src/TensorFlowNET.Core/GraphTransformation/GraphTransformer.cs b/src/TensorFlowNET.Core/GraphTransformation/GraphTransformer.cs index 381ff744..e1225e63 100644 --- a/src/TensorFlowNET.Core/GraphTransformation/GraphTransformer.cs +++ b/src/TensorFlowNET.Core/GraphTransformation/GraphTransformer.cs @@ -35,7 +35,7 @@ namespace Tensorflow outputs_string, transforms_string, buffer, - status); + status.Handle); status.Check(false); var bytes = buffer.ToArray(); diff --git a/src/TensorFlowNET.Core/GraphTransformation/c_api.transform_graph.cs b/src/TensorFlowNET.Core/GraphTransformation/c_api.transform_graph.cs index 8390d74e..a08db0a8 100644 --- a/src/TensorFlowNET.Core/GraphTransformation/c_api.transform_graph.cs +++ b/src/TensorFlowNET.Core/GraphTransformation/c_api.transform_graph.cs @@ -28,6 +28,6 @@ namespace Tensorflow string outputs_string, string transforms_string, IntPtr output_buffer, - IntPtr status); + SafeStatusHandle status); } } diff --git a/src/TensorFlowNET.Core/Graphs/Graph.Export.cs b/src/TensorFlowNET.Core/Graphs/Graph.Export.cs index 2a0d939e..e85cc7be 100644 --- a/src/TensorFlowNET.Core/Graphs/Graph.Export.cs +++ b/src/TensorFlowNET.Core/Graphs/Graph.Export.cs @@ -25,7 +25,7 @@ namespace Tensorflow public Buffer ToGraphDef(Status s) { var buffer = new Buffer(); - c_api.TF_GraphToGraphDef(_handle, buffer, s); + c_api.TF_GraphToGraphDef(_handle, buffer, s.Handle); s.Check(true); return buffer; diff --git a/src/TensorFlowNET.Core/Graphs/Graph.Import.cs b/src/TensorFlowNET.Core/Graphs/Graph.Import.cs index d759e38d..4df5e1eb 100644 --- a/src/TensorFlowNET.Core/Graphs/Graph.Import.cs +++ b/src/TensorFlowNET.Core/Graphs/Graph.Import.cs @@ -29,7 +29,7 @@ namespace Tensorflow int size = Marshal.SizeOf(); var return_output_handle = Marshal.AllocHGlobal(size * num_return_outputs); - c_api.TF_GraphImportGraphDefWithReturnOutputs(_handle, graph_def, opts, return_output_handle, num_return_outputs, s); + c_api.TF_GraphImportGraphDefWithReturnOutputs(_handle, graph_def, opts, return_output_handle, num_return_outputs, s.Handle); var tf_output_ptr = (TF_Output*) return_output_handle; for (int i = 0; i < num_return_outputs; i++) @@ -54,7 +54,7 @@ namespace Tensorflow { as_default(); c_api.TF_ImportGraphDefOptionsSetPrefix(opts, prefix); - c_api.TF_GraphImportGraphDef(_handle, graph_def, opts, status); + c_api.TF_GraphImportGraphDef(_handle, graph_def, opts, status.Handle); status.Check(true); return status.Code == TF_Code.TF_OK; } diff --git a/src/TensorFlowNET.Core/Graphs/Graph.cs b/src/TensorFlowNET.Core/Graphs/Graph.cs index de47d15a..69192634 100644 --- a/src/TensorFlowNET.Core/Graphs/Graph.cs +++ b/src/TensorFlowNET.Core/Graphs/Graph.cs @@ -513,14 +513,14 @@ namespace Tensorflow public TensorShape GetTensorShape(TF_Output output) { var status = tf.status; - var ndim = c_api.TF_GraphGetTensorNumDims(_handle, output, status); + var ndim = c_api.TF_GraphGetTensorNumDims(_handle, output, status.Handle); status.Check(); if (ndim == -1) return new TensorShape(); var dims = new long[ndim]; - c_api.TF_GraphGetTensorShape(_handle, output, dims, dims.Length, status); + c_api.TF_GraphGetTensorShape(_handle, output, dims, dims.Length, status.Handle); status.Check(); return new TensorShape(dims.Select(x => (int)x).ToArray()); diff --git a/src/TensorFlowNET.Core/Graphs/c_api.graph.cs b/src/TensorFlowNET.Core/Graphs/c_api.graph.cs index 889949ef..888c4fea 100644 --- a/src/TensorFlowNET.Core/Graphs/c_api.graph.cs +++ b/src/TensorFlowNET.Core/Graphs/c_api.graph.cs @@ -47,7 +47,7 @@ namespace Tensorflow public static extern string TF_GraphDebugString(IntPtr graph, out int len); [DllImport(TensorFlowLibName)] - public static extern void TF_GraphGetOpDef(IntPtr graph, string op_name, IntPtr output_op_def, IntPtr status); + public static extern void TF_GraphGetOpDef(IntPtr graph, string op_name, IntPtr output_op_def, SafeStatusHandle status); /// /// Returns the shape of the Tensor referenced by `output` in `graph` @@ -60,7 +60,7 @@ namespace Tensorflow /// /// [DllImport(TensorFlowLibName)] - public static extern void TF_GraphGetTensorShape(IntPtr graph, TF_Output output, long[] dims, int num_dims, IntPtr status); + public static extern void TF_GraphGetTensorShape(IntPtr graph, TF_Output output, long[] dims, int num_dims, SafeStatusHandle status); /// /// Import the graph serialized in `graph_def` into `graph`. @@ -78,7 +78,7 @@ namespace Tensorflow /// int /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern unsafe void TF_GraphImportGraphDefWithReturnOutputs(IntPtr graph, IntPtr graph_def, IntPtr options, IntPtr return_outputs, int num_return_outputs, IntPtr status); + public static extern unsafe void TF_GraphImportGraphDefWithReturnOutputs(IntPtr graph, IntPtr graph_def, IntPtr options, IntPtr return_outputs, int num_return_outputs, SafeStatusHandle status); /// /// Import the graph serialized in `graph_def` into `graph`. Returns nullptr and @@ -92,7 +92,7 @@ namespace Tensorflow /// TF_Status* /// TF_ImportGraphDefResults* [DllImport(TensorFlowLibName)] - public static extern IntPtr TF_GraphImportGraphDefWithResults(IntPtr graph, IntPtr graph_def, IntPtr options, IntPtr status); + public static extern IntPtr TF_GraphImportGraphDefWithResults(IntPtr graph, IntPtr graph_def, IntPtr options, SafeStatusHandle status); /// /// Import the graph serialized in `graph_def` into `graph`. @@ -102,7 +102,7 @@ namespace Tensorflow /// TF_ImportGraphDefOptions* /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TF_GraphImportGraphDef(IntPtr graph, IntPtr graph_def, IntPtr options, IntPtr status); + public static extern void TF_GraphImportGraphDef(IntPtr graph, IntPtr graph_def, IntPtr options, SafeStatusHandle status); /// /// Iterate through the operations of a graph. @@ -128,7 +128,7 @@ namespace Tensorflow /// the shape described by `dims` and `num_dims`. /// [DllImport(TensorFlowLibName)] - public static extern void TF_GraphSetTensorShape(IntPtr graph, TF_Output output, long[] dims, int num_dims, IntPtr status); + public static extern void TF_GraphSetTensorShape(IntPtr graph, TF_Output output, long[] dims, int num_dims, SafeStatusHandle status); /// /// Write out a serialized representation of `graph` (as a GraphDef protocol @@ -138,7 +138,7 @@ namespace Tensorflow /// TF_Buffer* /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TF_GraphToGraphDef(IntPtr graph, IntPtr output_graph_def, IntPtr status); + public static extern void TF_GraphToGraphDef(IntPtr graph, IntPtr output_graph_def, SafeStatusHandle status); /// /// Returns the number of dimensions of the Tensor referenced by `output` @@ -151,7 +151,7 @@ namespace Tensorflow /// /// [DllImport(TensorFlowLibName)] - public static extern int TF_GraphGetTensorNumDims(IntPtr graph, TF_Output output, IntPtr status); + public static extern int TF_GraphGetTensorNumDims(IntPtr graph, TF_Output output, SafeStatusHandle status); /// /// Cause the imported graph to have a control dependency on `oper`. `oper` @@ -289,7 +289,7 @@ namespace Tensorflow [DllImport(TensorFlowLibName)] public static extern IntPtr TF_LoadSessionFromSavedModel(IntPtr session_options, IntPtr run_options, string export_dir, string[] tags, int tags_len, - IntPtr graph, ref TF_Buffer meta_graph_def, IntPtr status); + IntPtr graph, ref TF_Buffer meta_graph_def, SafeStatusHandle status); [DllImport(TensorFlowLibName)] public static extern IntPtr TF_NewGraph(); @@ -306,6 +306,6 @@ namespace Tensorflow /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void UpdateEdge(IntPtr graph, TF_Output new_src, TF_Input dst, IntPtr status); + public static extern void UpdateEdge(IntPtr graph, TF_Output new_src, TF_Input dst, SafeStatusHandle status); } } diff --git a/src/TensorFlowNET.Core/Operations/Operation.Input.cs b/src/TensorFlowNET.Core/Operations/Operation.Input.cs index 3941425d..336d1d5c 100644 --- a/src/TensorFlowNET.Core/Operations/Operation.Input.cs +++ b/src/TensorFlowNET.Core/Operations/Operation.Input.cs @@ -31,7 +31,7 @@ namespace Tensorflow public int InputListLength(string name) { int num = 0; - num = c_api.TF_OperationInputListLength(_handle, name, tf.status); + num = c_api.TF_OperationInputListLength(_handle, name, tf.status.Handle); tf.status.Check(true); return num; } diff --git a/src/TensorFlowNET.Core/Operations/Operation.Output.cs b/src/TensorFlowNET.Core/Operations/Operation.Output.cs index 72bd3db0..779ed185 100644 --- a/src/TensorFlowNET.Core/Operations/Operation.Output.cs +++ b/src/TensorFlowNET.Core/Operations/Operation.Output.cs @@ -28,7 +28,7 @@ namespace Tensorflow public int OutputListLength(string name) { - int num = c_api.TF_OperationOutputListLength(_handle, name, tf.status); + int num = c_api.TF_OperationOutputListLength(_handle, name, tf.status.Handle); tf.status.Check(true); return num; diff --git a/src/TensorFlowNET.Core/Operations/Operation.cs b/src/TensorFlowNET.Core/Operations/Operation.cs index 4d927f76..0d416d32 100644 --- a/src/TensorFlowNET.Core/Operations/Operation.cs +++ b/src/TensorFlowNET.Core/Operations/Operation.cs @@ -236,7 +236,7 @@ namespace Tensorflow lock (Locks.ProcessWide) { using var buf = new Buffer(); - c_api.TF_OperationGetAttrValueProto(_handle, name, buf, tf.status); + c_api.TF_OperationGetAttrValueProto(_handle, name, buf, tf.status.Handle); tf.status.Check(true); x = AttrValue.Parser.ParseFrom(buf.MemoryBlock.Stream()); @@ -260,7 +260,7 @@ namespace Tensorflow public TF_AttrMetadata GetAttributeMetadata(string attr_name, Status s) { - return c_api.TF_OperationGetAttrMetadata(_handle, attr_name, s); + return c_api.TF_OperationGetAttrMetadata(_handle, attr_name, s.Handle); } private NodeDef GetNodeDef() @@ -269,7 +269,7 @@ namespace Tensorflow using (var s = new Status()) using (var buffer = new Buffer()) { - c_api.TF_OperationToNodeDef(_handle, buffer, s); + c_api.TF_OperationToNodeDef(_handle, buffer, s.Handle); s.Check(); return NodeDef.Parser.ParseFrom(buffer.MemoryBlock.Stream()); @@ -295,11 +295,11 @@ namespace Tensorflow // after the c_api call next time _inputs is accessed // the updated inputs are reloaded from the c_api lock (Locks.ProcessWide) - { - c_api.UpdateEdge(_graph, output, input, tf.status); - //var updated_inputs = inputs; - tf.status.Check(); - } + { + c_api.UpdateEdge(_graph, output, input, tf.status.Handle); + //var updated_inputs = inputs; + tf.status.Check(); + } } private void _assert_same_graph(Tensor tensor) diff --git a/src/TensorFlowNET.Core/Operations/OperationDescription.cs b/src/TensorFlowNET.Core/Operations/OperationDescription.cs index 28df548d..384f5386 100644 --- a/src/TensorFlowNET.Core/Operations/OperationDescription.cs +++ b/src/TensorFlowNET.Core/Operations/OperationDescription.cs @@ -50,7 +50,7 @@ namespace Tensorflow public Operation FinishOperation(Status status) { - return c_api.TF_FinishOperation(_handle, status); + return c_api.TF_FinishOperation(_handle, status.Handle); } public static implicit operator OperationDescription(IntPtr handle) diff --git a/src/TensorFlowNET.Core/Operations/c_api.ops.cs b/src/TensorFlowNET.Core/Operations/c_api.ops.cs index a23cd406..988bb287 100644 --- a/src/TensorFlowNET.Core/Operations/c_api.ops.cs +++ b/src/TensorFlowNET.Core/Operations/c_api.ops.cs @@ -83,7 +83,7 @@ namespace Tensorflow public static extern void TF_AddInputList(IntPtr desc, TF_Output[] inputs, int num_inputs); [DllImport(TensorFlowLibName)] - public static extern IntPtr TF_FinishOperation(IntPtr desc, IntPtr status); + public static extern IntPtr TF_FinishOperation(IntPtr desc, SafeStatusHandle status); /// /// Operation will only be added to *graph when TF_FinishOperation() is @@ -141,7 +141,7 @@ namespace Tensorflow public static extern TF_Output TF_OperationInput(TF_Input oper_in); [DllImport(TensorFlowLibName)] - public static extern int TF_OperationInputListLength(IntPtr oper, string arg_name, IntPtr status); + public static extern int TF_OperationInputListLength(IntPtr oper, string arg_name, SafeStatusHandle status); [DllImport(TensorFlowLibName)] public static extern TF_DataType TF_OperationInputType(TF_Input oper_in); @@ -204,9 +204,9 @@ namespace Tensorflow public static extern TF_DataType TF_OperationOutputType(TF_Output oper_out); [DllImport(TensorFlowLibName)] - public static extern void TF_OperationToNodeDef(IntPtr oper, IntPtr buffer, IntPtr status); + public static extern void TF_OperationToNodeDef(IntPtr oper, IntPtr buffer, SafeStatusHandle status); [DllImport(TensorFlowLibName)] - public static extern int TF_OperationOutputListLength(IntPtr oper, string arg_name, IntPtr status); + public static extern int TF_OperationOutputListLength(IntPtr oper, string arg_name, SafeStatusHandle status); } } diff --git a/src/TensorFlowNET.Core/Sessions/BaseSession.cs b/src/TensorFlowNET.Core/Sessions/BaseSession.cs index 7992db2d..8f8e3f9f 100644 --- a/src/TensorFlowNET.Core/Sessions/BaseSession.cs +++ b/src/TensorFlowNET.Core/Sessions/BaseSession.cs @@ -47,7 +47,7 @@ namespace Tensorflow lock (Locks.ProcessWide) { status = status ?? new Status(); - _handle = c_api.TF_NewSession(_graph, opts, status); + _handle = c_api.TF_NewSession(_graph, opts, status.Handle); status.Check(true); } } @@ -251,7 +251,7 @@ namespace Tensorflow target_opers: target_list.Select(f => (IntPtr) f).ToArray(), ntargets: target_list.Count, run_metadata: IntPtr.Zero, - status: status); + status: status.Handle); status.Check(true); @@ -463,7 +463,7 @@ namespace Tensorflow lock (Locks.ProcessWide) using (var status = new Status()) { - c_api.TF_DeleteSession(handle, status); + c_api.TF_DeleteSession(handle, status.Handle); status.Check(true); } } diff --git a/src/TensorFlowNET.Core/Sessions/Session.cs b/src/TensorFlowNET.Core/Sessions/Session.cs index a38764fc..bda3acbd 100644 --- a/src/TensorFlowNET.Core/Sessions/Session.cs +++ b/src/TensorFlowNET.Core/Sessions/Session.cs @@ -62,7 +62,7 @@ namespace Tensorflow tags.Length, graph, ref buffer, - status); + status.Handle); status.Check(true); } catch (TensorflowException ex) when (ex.Message.Contains("Could not find SavedModel")) { @@ -73,7 +73,7 @@ namespace Tensorflow tags.Length, graph, ref buffer, - status); + status.Handle); status.Check(true); } diff --git a/src/TensorFlowNET.Core/Sessions/SessionOptions.cs b/src/TensorFlowNET.Core/Sessions/SessionOptions.cs index 0e64033c..56f13628 100644 --- a/src/TensorFlowNET.Core/Sessions/SessionOptions.cs +++ b/src/TensorFlowNET.Core/Sessions/SessionOptions.cs @@ -46,7 +46,7 @@ namespace Tensorflow using (var status = new Status()) { - c_api.TF_SetConfig(_handle, proto, (ulong)bytes.Length, status); + c_api.TF_SetConfig(_handle, proto, (ulong)bytes.Length, status.Handle); status.Check(false); } diff --git a/src/TensorFlowNET.Core/Sessions/c_api.session.cs b/src/TensorFlowNET.Core/Sessions/c_api.session.cs index 713d0d5f..7082c617 100644 --- a/src/TensorFlowNET.Core/Sessions/c_api.session.cs +++ b/src/TensorFlowNET.Core/Sessions/c_api.session.cs @@ -32,7 +32,7 @@ namespace Tensorflow /// TF_Session* /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TF_DeleteSession(IntPtr session, IntPtr status); + public static extern void TF_DeleteSession(IntPtr session, SafeStatusHandle status); /// /// Destroy an options object. @@ -50,7 +50,7 @@ namespace Tensorflow /// TF_Status* /// TF_Session* [DllImport(TensorFlowLibName)] - public static extern IntPtr TF_NewSession(IntPtr graph, IntPtr opts, IntPtr status); + public static extern IntPtr TF_NewSession(IntPtr graph, IntPtr opts, SafeStatusHandle status); /// /// Return a new options object. @@ -103,7 +103,7 @@ namespace Tensorflow TF_Output[] outputs, IntPtr[] output_values, int noutputs, IntPtr[] target_opers, int ntargets, IntPtr run_metadata, - IntPtr status); + SafeStatusHandle status); /// /// Set the config in TF_SessionOptions.options. @@ -116,7 +116,7 @@ namespace Tensorflow /// size_t /// TF_Status* [DllImport(TensorFlowLibName)] - public static extern void TF_SetConfig(IntPtr options, IntPtr proto, ulong proto_len, IntPtr status); + public static extern void TF_SetConfig(IntPtr options, IntPtr proto, ulong proto_len, SafeStatusHandle status); [DllImport(TensorFlowLibName)] public static extern void TF_SetTarget(IntPtr options, string target); diff --git a/src/TensorFlowNET.Core/Status/SafeStatusHandle.cs b/src/TensorFlowNET.Core/Status/SafeStatusHandle.cs new file mode 100644 index 00000000..81fcd4fb --- /dev/null +++ b/src/TensorFlowNET.Core/Status/SafeStatusHandle.cs @@ -0,0 +1,39 @@ +/***************************************************************************** + Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************/ + +using System; +using Tensorflow.Util; + +namespace Tensorflow +{ + public sealed class SafeStatusHandle : SafeTensorflowHandle + { + public SafeStatusHandle() + { + } + + public SafeStatusHandle(IntPtr handle) + : base(handle) + { + } + + protected override bool ReleaseHandle() + { + c_api.TF_DeleteStatus(handle); + return true; + } + } +} diff --git a/src/TensorFlowNET.Core/Status/Status.cs b/src/TensorFlowNET.Core/Status/Status.cs index 68f86c4e..95ab82d9 100644 --- a/src/TensorFlowNET.Core/Status/Status.cs +++ b/src/TensorFlowNET.Core/Status/Status.cs @@ -17,6 +17,7 @@ using System; using System.Diagnostics; using System.Runtime.CompilerServices; +using Tensorflow.Util; using static Tensorflow.c_api; namespace Tensorflow @@ -25,31 +26,42 @@ namespace Tensorflow /// TF_Status holds error information. It either has an OK code, or /// else an error code with an associated error message. /// - public class Status : DisposableObject + public sealed class Status : IDisposable { /// /// Error message /// - public string Message => c_api.StringPiece(TF_Message(_handle)); + public string Message + { + get + { + using (Handle.Lease()) + { + return StringPiece(TF_Message(Handle)); + } + } + } /// /// Error code /// - public TF_Code Code => TF_GetCode(_handle); + public TF_Code Code => TF_GetCode(Handle); + + public SafeStatusHandle Handle { get; } public Status() { - _handle = TF_NewStatus(); + Handle = TF_NewStatus(); } - public Status(IntPtr handle) + public Status(SafeStatusHandle handle) { - _handle = handle; + Handle = handle ?? throw new ArgumentNullException(nameof(handle)); } public void SetStatus(TF_Code code, string msg) { - TF_SetStatus(_handle, code, msg); + TF_SetStatus(Handle, code, msg); } public bool ok() => Code == TF_Code.TF_OK; @@ -65,22 +77,17 @@ namespace Tensorflow { if (Code != TF_Code.TF_OK) { - Console.WriteLine(Message); + var message = Message; + Console.WriteLine(message); if (throwException) - throw new TensorflowException(Message); + throw new TensorflowException(message); } } - public static implicit operator IntPtr(Status status) - => status._handle; - - public static implicit operator Status(IntPtr handle) - => new Status(handle); - - protected override void DisposeUnmanagedResources(IntPtr handle) - => TF_DeleteStatus(handle); + public void Dispose() + => Handle.Dispose(); public override string ToString() - => $"{Code} 0x{_handle.ToString("x16")}"; + => $"{Code} 0x{Handle.DangerousGetHandle():x16}"; } } \ No newline at end of file diff --git a/src/TensorFlowNET.Core/Status/c_api.status.cs b/src/TensorFlowNET.Core/Status/c_api.status.cs index ee17e447..b5da21bf 100644 --- a/src/TensorFlowNET.Core/Status/c_api.status.cs +++ b/src/TensorFlowNET.Core/Status/c_api.status.cs @@ -34,7 +34,7 @@ namespace Tensorflow /// /// [DllImport(TensorFlowLibName)] - public static extern TF_Code TF_GetCode(IntPtr s); + public static extern TF_Code TF_GetCode(SafeStatusHandle s); /// /// Return a pointer to the (null-terminated) error message in *s. @@ -44,14 +44,14 @@ namespace Tensorflow /// /// [DllImport(TensorFlowLibName)] - public static extern IntPtr TF_Message(IntPtr s); + public static extern IntPtr TF_Message(SafeStatusHandle s); /// /// Return a new status object. /// /// [DllImport(TensorFlowLibName)] - public static extern IntPtr TF_NewStatus(); + public static extern SafeStatusHandle TF_NewStatus(); /// /// Record in *s. Any previous information is lost. @@ -61,6 +61,6 @@ namespace Tensorflow /// /// [DllImport(TensorFlowLibName)] - public static extern void TF_SetStatus(IntPtr s, TF_Code code, string msg); + public static extern void TF_SetStatus(SafeStatusHandle s, TF_Code code, string msg); } } diff --git a/src/TensorFlowNET.Core/Tensors/EagerTensorV2.cs b/src/TensorFlowNET.Core/Tensors/EagerTensorV2.cs index 08e9e964..43e2312d 100644 --- a/src/TensorFlowNET.Core/Tensors/EagerTensorV2.cs +++ b/src/TensorFlowNET.Core/Tensors/EagerTensorV2.cs @@ -13,12 +13,12 @@ namespace Tensorflow public class EagerTensorV2 : DisposableObject, ITensor { IntPtr EagerTensorHandle; - public string Device => c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(EagerTensorHandle, tf.status)); + public string Device => c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(EagerTensorHandle, tf.status.Handle)); public EagerTensorV2(IntPtr handle) { EagerTensorHandle = c_api.TFE_EagerTensorHandle(handle); - _handle = c_api.TFE_TensorHandleResolve(EagerTensorHandle, tf.status); + _handle = c_api.TFE_TensorHandleResolve(EagerTensorHandle, tf.status.Handle); } public unsafe EagerTensorV2(NDArray nd, string device_name = "") @@ -38,7 +38,7 @@ namespace Tensorflow }, IntPtr.Zero); - EagerTensorHandle = c_api.TFE_NewTensorHandle(_handle, tf.status); + EagerTensorHandle = c_api.TFE_NewTensorHandle(_handle, tf.status.Handle); } /*public unsafe EagerTensorV2(float[,] value) diff --git a/src/TensorFlowNET.Core/Tensors/Tensor.Conversions.cs b/src/TensorFlowNET.Core/Tensors/Tensor.Conversions.cs index e83978fc..aa9e7d90 100644 --- a/src/TensorFlowNET.Core/Tensors/Tensor.Conversions.cs +++ b/src/TensorFlowNET.Core/Tensors/Tensor.Conversions.cs @@ -70,7 +70,7 @@ namespace Tensorflow IntPtr stringStartAddress = IntPtr.Zero; UIntPtr dstLen = UIntPtr.Zero; - c_api.TF_StringDecode((byte*) this.buffer + 8, (UIntPtr) (this.bytesize), (byte**) &stringStartAddress, &dstLen, tf.status); + c_api.TF_StringDecode((byte*) this.buffer + 8, (UIntPtr) (this.bytesize), (byte**) &stringStartAddress, &dstLen, tf.status.Handle); tf.status.Check(true); var dstLenInt = checked((int) dstLen); diff --git a/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs b/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs index f87f80bb..3c3f1546 100644 --- a/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs +++ b/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs @@ -459,7 +459,7 @@ namespace Tensorflow IntPtr tensor = c_api.TF_TensorData(handle); Marshal.WriteInt64(tensor, 0); fixed (byte* src = buffer) - c_api.TF_StringEncode(src, (UIntPtr)buffer.Length, (sbyte*)(tensor + sizeof(long)), size, tf.status); + c_api.TF_StringEncode(src, (UIntPtr)buffer.Length, (sbyte*)(tensor + sizeof(long)), size, tf.status.Handle); _handle = handle; tf.status.Check(true); } @@ -482,7 +482,7 @@ namespace Tensorflow IntPtr tensor = c_api.TF_TensorData(handle); Marshal.WriteInt64(tensor, 0); - c_api.TF_StringEncode((byte*) nd.Unsafe.Address, bytesLength, (sbyte*) (tensor + sizeof(Int64)), size, tf.status); + c_api.TF_StringEncode((byte*) nd.Unsafe.Address, bytesLength, (sbyte*) (tensor + sizeof(Int64)), size, tf.status.Handle); tf.status.Check(true); _handle = handle; } else @@ -496,7 +496,7 @@ namespace Tensorflow Marshal.WriteInt64(tensor, 0); fixed (byte* src = buffer) - c_api.TF_StringEncode(src, (UIntPtr) buffer.Length, (sbyte*) (tensor + sizeof(Int64)), size, tf.status); + c_api.TF_StringEncode(src, (UIntPtr) buffer.Length, (sbyte*) (tensor + sizeof(Int64)), size, tf.status.Handle); tf.status.Check(true); _handle = handle; @@ -557,7 +557,7 @@ namespace Tensorflow { fixed (byte* src = &buffer[i][0]) { - var written = TF_StringEncode(src, (UIntPtr) buffer[i].Length, (sbyte*) dst, (UIntPtr) (dstLimit.ToInt64() - dst.ToInt64()), status); + var written = TF_StringEncode(src, (UIntPtr) buffer[i].Length, (sbyte*) dst, (UIntPtr) (dstLimit.ToInt64() - dst.ToInt64()), status.Handle); status.Check(true); pOffset += 8; dst += (int) written; @@ -604,7 +604,7 @@ namespace Tensorflow Marshal.WriteInt64(tensor, 0); fixed (byte* src = buffer) - c_api.TF_StringEncode(src, (UIntPtr) buffer.Length, (sbyte*) (tensor + sizeof(long)), size, tf.status); + c_api.TF_StringEncode(src, (UIntPtr) buffer.Length, (sbyte*) (tensor + sizeof(long)), size, tf.status.Handle); tf.status.Check(true); return handle; diff --git a/src/TensorFlowNET.Core/Tensors/Tensor.Value.cs b/src/TensorFlowNET.Core/Tensors/Tensor.Value.cs index ea9e68ee..04b22a68 100644 --- a/src/TensorFlowNET.Core/Tensors/Tensor.Value.cs +++ b/src/TensorFlowNET.Core/Tensors/Tensor.Value.cs @@ -241,7 +241,7 @@ namespace Tensorflow { IntPtr dst = IntPtr.Zero; UIntPtr dstLen = UIntPtr.Zero; - var read = c_api.TF_StringDecode((byte*)src, (UIntPtr)(srcLen.ToInt64() - src.ToInt64()), (byte**)&dst, &dstLen, tf.status); + var read = c_api.TF_StringDecode((byte*)src, (UIntPtr)(srcLen.ToInt64() - src.ToInt64()), (byte**)&dst, &dstLen, tf.status.Handle); tf.status.Check(true); buffer[i] = new byte[(int)dstLen]; Marshal.Copy(dst, buffer[i], 0, buffer[i].Length); diff --git a/src/TensorFlowNET.Core/Tensors/Tensor.cs b/src/TensorFlowNET.Core/Tensors/Tensor.cs index 506defba..186082f1 100644 --- a/src/TensorFlowNET.Core/Tensors/Tensor.cs +++ b/src/TensorFlowNET.Core/Tensors/Tensor.cs @@ -109,7 +109,7 @@ namespace Tensorflow if (_handle == IntPtr.Zero) { - c_api.TF_GraphGetTensorShape(op.graph, _as_tf_output(), dims, rank, tf.status); + c_api.TF_GraphGetTensorShape(op.graph, _as_tf_output(), dims, rank, tf.status.Handle); } else { @@ -123,9 +123,9 @@ namespace Tensorflow set { if (value == null) - c_api.TF_GraphSetTensorShape(graph, _as_tf_output(), null, -1, tf.status); + c_api.TF_GraphSetTensorShape(graph, _as_tf_output(), null, -1, tf.status.Handle); else - c_api.TF_GraphSetTensorShape(graph, _as_tf_output(), value.Select(Convert.ToInt64).ToArray(), value.Length, tf.status); + c_api.TF_GraphSetTensorShape(graph, _as_tf_output(), value.Select(Convert.ToInt64).ToArray(), value.Length, tf.status.Handle); tf.status.Check(true); } @@ -172,7 +172,7 @@ namespace Tensorflow if (_handle == IntPtr.Zero) { var output = _as_tf_output(); - int ndim = c_api.TF_GraphGetTensorNumDims(op.graph, output, tf.status); + int ndim = c_api.TF_GraphGetTensorNumDims(op.graph, output, tf.status.Handle); return ndim; } diff --git a/src/TensorFlowNET.Core/Tensors/c_api.tensor.cs b/src/TensorFlowNET.Core/Tensors/c_api.tensor.cs index 1a0634d2..ebc2b192 100644 --- a/src/TensorFlowNET.Core/Tensors/c_api.tensor.cs +++ b/src/TensorFlowNET.Core/Tensors/c_api.tensor.cs @@ -189,10 +189,10 @@ namespace Tensorflow /// TF_Status* /// On success returns the size in bytes of the encoded string. [DllImport(TensorFlowLibName)] - public static extern unsafe ulong TF_StringEncode(byte* src, UIntPtr src_len, sbyte* dst, UIntPtr dst_len, IntPtr status); + public static extern unsafe ulong TF_StringEncode(byte* src, UIntPtr src_len, sbyte* dst, UIntPtr dst_len, SafeStatusHandle status); [DllImport(TensorFlowLibName)] - public static extern unsafe ulong TF_StringEncode(IntPtr src, ulong src_len, IntPtr dst, ulong dst_len, IntPtr status); + public static extern unsafe ulong TF_StringEncode(IntPtr src, ulong src_len, IntPtr dst, ulong dst_len, SafeStatusHandle status); /// /// Decode a string encoded using TF_StringEncode. @@ -204,10 +204,10 @@ namespace Tensorflow /// TF_Status* /// [DllImport(TensorFlowLibName)] - public static extern ulong TF_StringDecode(IntPtr src, ulong src_len, IntPtr dst, ref ulong dst_len, IntPtr status); + public static extern ulong TF_StringDecode(IntPtr src, ulong src_len, IntPtr dst, ref ulong dst_len, SafeStatusHandle status); [DllImport(TensorFlowLibName)] - public static extern unsafe UIntPtr TF_StringDecode(byte* src, UIntPtr src_len, byte** dst, UIntPtr* dst_len, IntPtr status); + public static extern unsafe UIntPtr TF_StringDecode(byte* src, UIntPtr src_len, byte** dst, UIntPtr* dst_len, SafeStatusHandle status); public static c_api.Deallocator EmptyDeallocator = FreeNothingDeallocator; diff --git a/src/TensorFlowNET.Core/Util/SafeHandleExtensions.cs b/src/TensorFlowNET.Core/Util/SafeHandleExtensions.cs new file mode 100644 index 00000000..dca0bac3 --- /dev/null +++ b/src/TensorFlowNET.Core/Util/SafeHandleExtensions.cs @@ -0,0 +1,54 @@ +/***************************************************************************** + Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +namespace Tensorflow.Util +{ + internal static class SafeHandleExtensions + { + /// + /// Acquires a lease on a safe handle. This method is intended to be used in the initializer of a using + /// statement. + /// + /// The to lease. + /// A , which must be disposed to release the resource. + /// If the lease could not be acquired. + public static SafeHandleLease Lease(this SafeHandle handle) + { + if (handle is null) + throw new ArgumentNullException(nameof(handle)); + + var success = false; + try + { + handle.DangerousAddRef(ref success); + if (!success) + throw new ObjectDisposedException(handle.GetType().FullName); + + return new SafeHandleLease(handle); + } + catch + { + if (success) + handle.DangerousRelease(); + + throw; + } + } + } +} diff --git a/src/TensorFlowNET.Core/Util/SafeHandleLease.cs b/src/TensorFlowNET.Core/Util/SafeHandleLease.cs new file mode 100644 index 00000000..dcc0e846 --- /dev/null +++ b/src/TensorFlowNET.Core/Util/SafeHandleLease.cs @@ -0,0 +1,36 @@ +/***************************************************************************** + Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +namespace Tensorflow.Util +{ + /// + /// Represents a lease of a . + /// + /// + public readonly struct SafeHandleLease : IDisposable + { + private readonly SafeHandle _handle; + + internal SafeHandleLease(SafeHandle handle) + => _handle = handle; + + public void Dispose() + => _handle?.DangerousRelease(); + } +} \ No newline at end of file diff --git a/src/TensorFlowNET.Core/Util/SafeTensorflowHandle.cs b/src/TensorFlowNET.Core/Util/SafeTensorflowHandle.cs new file mode 100644 index 00000000..abfb3446 --- /dev/null +++ b/src/TensorFlowNET.Core/Util/SafeTensorflowHandle.cs @@ -0,0 +1,43 @@ +/***************************************************************************** + Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************/ + +using System; +using System.Runtime.InteropServices; + +namespace Tensorflow.Util +{ + public abstract class SafeTensorflowHandle : SafeHandle + { + private protected SafeTensorflowHandle() + : base(IntPtr.Zero, ownsHandle: true) + { + } + + private protected SafeTensorflowHandle(IntPtr handle) + : base(IntPtr.Zero, ownsHandle: true) + { + SetHandle(handle); + } + + private protected SafeTensorflowHandle(IntPtr handle, bool ownsHandle) + : base(IntPtr.Zero, ownsHandle) + { + SetHandle(handle); + } + + public override bool IsInvalid => handle == IntPtr.Zero; + } +} diff --git a/src/TensorFlowNET.Core/ops.cs b/src/TensorFlowNET.Core/ops.cs index e06265fd..697d3c04 100644 --- a/src/TensorFlowNET.Core/ops.cs +++ b/src/TensorFlowNET.Core/ops.cs @@ -189,12 +189,12 @@ namespace Tensorflow var protoHandle = Marshal.AllocHGlobal(bytes.Length); Marshal.Copy(bytes, 0, protoHandle, bytes.Length); uint len = (uint)bytes.Length; - c_api.TF_SetAttrValueProto(op_desc, attr.Key, protoHandle, proto_len: len, status: status); + c_api.TF_SetAttrValueProto(op_desc, attr.Key, protoHandle, proto_len: len, status: status.Handle); status.Check(true); Marshal.FreeHGlobal(protoHandle); } - var c_op = c_api.TF_FinishOperation(op_desc, status); + var c_op = c_api.TF_FinishOperation(op_desc, status.Handle); status.Check(true); diff --git a/test/TensorFlowNET.UnitTest/Basics/TensorTest.cs b/test/TensorFlowNET.UnitTest/Basics/TensorTest.cs index 730217eb..86df2039 100644 --- a/test/TensorFlowNET.UnitTest/Basics/TensorTest.cs +++ b/test/TensorFlowNET.UnitTest/Basics/TensorTest.cs @@ -125,45 +125,45 @@ namespace TensorFlowNET.UnitTest.NativeAPI var feed_out_0 = new TF_Output(feed, 0); // Fetch the shape, it should be completely unknown. - int num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s); + int num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); EXPECT_EQ(-1, num_dims); // Set the shape to be unknown, expect no change. - c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s); + c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); - num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s); + num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s.Handle); EXPECT_EQ(-1, num_dims); // Set the shape to be 2 x Unknown long[] dims = {2, -1}; - c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s); + c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); - num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s); + num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s.Handle); EXPECT_EQ(2, num_dims); // Get the dimension vector appropriately. var returned_dims = new long[dims.Length]; - c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s); + c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); Assert.IsTrue(Enumerable.SequenceEqual(dims, returned_dims)); // Set to a new valid shape: [2, 3] dims[1] = 3; - c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s); + c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); // Fetch and see that the new value is returned. - c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s); + c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); Assert.IsTrue(Enumerable.SequenceEqual(dims, returned_dims)); // Try to set 'unknown' with unknown rank on the shape and see that // it doesn't change. - c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s); + c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); - c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s); + c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); EXPECT_EQ(2, num_dims); EXPECT_EQ(2, (int) returned_dims[0]); @@ -173,21 +173,21 @@ namespace TensorFlowNET.UnitTest.NativeAPI // it doesn't change. dims[0] = -1; dims[1] = -1; - c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s); + c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); - c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s); + c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); EXPECT_EQ(2, num_dims); EXPECT_EQ(2, (int) returned_dims[0]); EXPECT_EQ(3, (int) returned_dims[1]); // Try to fetch a shape with the wrong num_dims - c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, 5, s); + c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, 5, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_INVALID_ARGUMENT); // Try to set an invalid shape (cannot change 2x3 to a 2x5). dims[1] = 5; - c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s); + c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_INVALID_ARGUMENT); // Test for a scalar. @@ -195,10 +195,10 @@ namespace TensorFlowNET.UnitTest.NativeAPI Assert.IsTrue(s.Code == TF_Code.TF_OK); var three_out_0 = new TF_Output(three, 0); - num_dims = c_api.TF_GraphGetTensorNumDims(graph, three_out_0, s); + num_dims = c_api.TF_GraphGetTensorNumDims(graph, three_out_0, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); EXPECT_EQ(0, num_dims); - c_api.TF_GraphGetTensorShape(graph, feed_out_0, null, num_dims, s); + c_api.TF_GraphGetTensorShape(graph, feed_out_0, null, num_dims, s.Handle); //Assert.IsTrue(s.Code == TF_Code.TF_OK); // graph.Dispose(); diff --git a/test/TensorFlowNET.UnitTest/ConstantTest.cs b/test/TensorFlowNET.UnitTest/ConstantTest.cs index 45dc64fe..97ec8e61 100644 --- a/test/TensorFlowNET.UnitTest/ConstantTest.cs +++ b/test/TensorFlowNET.UnitTest/ConstantTest.cs @@ -169,7 +169,7 @@ namespace TensorFlowNET.UnitTest.Basics ulong dst_len = (ulong)c_api.TF_StringEncodedSize((UIntPtr)str.Length); Assert.AreEqual(dst_len, (ulong)23); IntPtr dst = Marshal.AllocHGlobal((int)dst_len); - ulong encoded_len = c_api.TF_StringEncode(handle, (ulong)str.Length, dst, dst_len, status); + ulong encoded_len = c_api.TF_StringEncode(handle, (ulong)str.Length, dst, dst_len, status.Handle); Assert.AreEqual((ulong)23, encoded_len); Assert.AreEqual(status.Code, TF_Code.TF_OK); string encoded_str = Marshal.PtrToStringUTF8(dst + sizeof(byte)); diff --git a/test/TensorFlowNET.UnitTest/GraphTest.cs b/test/TensorFlowNET.UnitTest/GraphTest.cs index b611160f..9deb5361 100644 --- a/test/TensorFlowNET.UnitTest/GraphTest.cs +++ b/test/TensorFlowNET.UnitTest/GraphTest.cs @@ -39,7 +39,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI EXPECT_EQ(attr_value.Type, DataType.DtInt32); // Test not found errors in TF_Operation*() query functions. - EXPECT_EQ(-1, c_api.TF_OperationOutputListLength(feed, "bogus", s)); + EXPECT_EQ(-1, c_api.TF_OperationOutputListLength(feed, "bogus", s.Handle)); EXPECT_EQ(TF_Code.TF_INVALID_ARGUMENT, s.Code); Assert.IsFalse(c_test_util.GetAttrValue(feed, "missing", ref attr_value, s)); EXPECT_EQ("Operation 'feed' has no attr named 'missing'.", s.Message); @@ -217,7 +217,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI // Export to a GraphDef. var graph_def = new Buffer(); - c_api.TF_GraphToGraphDef(graph, graph_def, s); + c_api.TF_GraphToGraphDef(graph, graph_def, s.Handle); EXPECT_EQ(TF_Code.TF_OK, s.Code); // Import it, with a prefix, in a fresh graph. @@ -225,7 +225,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI graph = new Graph().as_default(); var opts = c_api.TF_NewImportGraphDefOptions(); c_api.TF_ImportGraphDefOptionsSetPrefix(opts, "imported"); - c_api.TF_GraphImportGraphDef(graph, graph_def, opts, s); + c_api.TF_GraphImportGraphDef(graph, graph_def, opts, s.Handle); EXPECT_EQ(TF_Code.TF_OK, s.Code); Operation scalar = graph.OperationByName("imported/scalar"); @@ -268,7 +268,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI EXPECT_EQ(2, c_api.TF_ImportGraphDefOptionsNumReturnOutputs(opts)); c_api.TF_ImportGraphDefOptionsAddReturnOperation(opts, "scalar"); EXPECT_EQ(1, c_api.TF_ImportGraphDefOptionsNumReturnOperations(opts)); - var results = c_api.TF_GraphImportGraphDefWithResults(graph, graph_def, opts, s); + var results = c_api.TF_GraphImportGraphDefWithResults(graph, graph_def, opts, s.Handle); EXPECT_EQ(TF_Code.TF_OK, s.Code); Operation scalar2 = graph.OperationByName("imported2/scalar"); @@ -300,7 +300,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI c_api.TF_ImportGraphDefOptionsSetPrefix(opts, "imported3"); c_api.TF_ImportGraphDefOptionsAddControlDependency(opts, feed); c_api.TF_ImportGraphDefOptionsAddControlDependency(opts, feed2); - c_api.TF_GraphImportGraphDef(graph, graph_def, opts, s); + c_api.TF_GraphImportGraphDef(graph, graph_def, opts, s.Handle); EXPECT_EQ(TF_Code.TF_OK, s.Code); var scalar3 = graph.OperationByName("imported3/scalar"); @@ -324,7 +324,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI // Export to a graph def so we can import a graph with control dependencies graph_def = new Buffer(); - c_api.TF_GraphToGraphDef(graph, graph_def, s); + c_api.TF_GraphToGraphDef(graph, graph_def, s.Handle); EXPECT_EQ(TF_Code.TF_OK, s.Code); // Import again, with remapped control dependency, into the same graph @@ -332,7 +332,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI opts = c_api.TF_NewImportGraphDefOptions(); c_api.TF_ImportGraphDefOptionsSetPrefix(opts, "imported4"); c_api.TF_ImportGraphDefOptionsRemapControlDependency(opts, "imported/feed", feed); - c_api.TF_GraphImportGraphDef(graph, graph_def, opts, s); + c_api.TF_GraphImportGraphDef(graph, graph_def, opts, s.Handle); ASSERT_EQ(TF_Code.TF_OK, s.Code); var scalar4 = graph.OperationByName("imported4/imported3/scalar"); diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/CApiAttributesTestcs.cs b/test/TensorFlowNET.UnitTest/NativeAPI/CApiAttributesTestcs.cs index 765827c7..d5a816c8 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/CApiAttributesTestcs.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/CApiAttributesTestcs.cs @@ -50,7 +50,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI private void EXPECT_TF_META(Operation oper, string attr_name, int expected_list_size, TF_AttrType expected_type, uint expected_total_size) { - var m = c_api.TF_OperationGetAttrMetadata(oper, attr_name, s_); + var m = c_api.TF_OperationGetAttrMetadata(oper, attr_name, s_.Handle); EXPECT_EQ(TF_Code.TF_OK, s_.Code); char e = expected_list_size >= 0 ? (char)1 : (char)0; /*EXPECT_EQ(e, m.is_list); @@ -65,7 +65,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI var desc = init("string"); c_api.TF_SetAttrString(desc, "v", "bunny", 5); - var oper = c_api.TF_FinishOperation(desc, s_); + var oper = c_api.TF_FinishOperation(desc, s_.Handle); //ASSERT_EQ(TF_Code.TF_OK, s_.Code); //EXPECT_TF_META(oper, "v", -1, TF_AttrType.TF_ATTR_STRING, 5); //var value = new char[5]; diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/CApiColocationTest.cs b/test/TensorFlowNET.UnitTest/NativeAPI/CApiColocationTest.cs index 15725513..64f6b2f2 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/CApiColocationTest.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/CApiColocationTest.cs @@ -61,7 +61,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI private void VerifyCollocation(Operation op, string[] expected) { - var handle = c_api.TF_OperationGetAttrMetadata(op, "_class", s_); + var handle = c_api.TF_OperationGetAttrMetadata(op, "_class", s_.Handle); TF_AttrMetadata m = new TF_AttrMetadata(); if (expected.Length == 0) { diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/CApiGradientsTest.cs b/test/TensorFlowNET.UnitTest/NativeAPI/CApiGradientsTest.cs index 3f6147d4..e9d2012b 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/CApiGradientsTest.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/CApiGradientsTest.cs @@ -50,7 +50,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI { using (var buffer = new Buffer()) { - c_api.TF_GraphToGraphDef(graph, buffer, s); + c_api.TF_GraphToGraphDef(graph, buffer, s.Handle); bool ret = TF_GetCode(s) == TF_OK; EXPECT_EQ(TF_OK, TF_GetCode(s)); if (ret) @@ -113,7 +113,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI IntPtr[] handles = new IntPtr[2] { IntPtr.Zero, IntPtr.Zero }; c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs, - ninputs, grad_inputs, s_, handles); + ninputs, grad_inputs, s_.Handle, handles); var op = new Operation(handles[0]); } diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/CApiTest.cs b/test/TensorFlowNET.UnitTest/NativeAPI/CApiTest.cs index f27b5f9d..17d95945 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/CApiTest.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/CApiTest.cs @@ -42,10 +42,10 @@ namespace TensorFlowNET.UnitTest => c_api.TF_AddInput(desc, input); protected Operation TF_FinishOperation(OperationDescription desc, Status s) - => c_api.TF_FinishOperation(desc, s); + => c_api.TF_FinishOperation(desc, s.Handle); protected void TF_SetAttrTensor(OperationDescription desc, string attrName, Tensor value, Status s) - => c_api.TF_SetAttrTensor(desc, attrName, value, s); + => c_api.TF_SetAttrTensor(desc, attrName, value, s.Handle); protected void TF_SetAttrType(OperationDescription desc, string attrName, TF_DataType dtype) => c_api.TF_SetAttrType(desc, attrName, dtype); @@ -56,24 +56,21 @@ namespace TensorFlowNET.UnitTest protected TF_DataType TFE_TensorHandleDataType(IntPtr h) => c_api.TFE_TensorHandleDataType(h); - protected int TFE_TensorHandleNumDims(IntPtr h, IntPtr status) + protected int TFE_TensorHandleNumDims(IntPtr h, SafeStatusHandle status) => c_api.TFE_TensorHandleNumDims(h, status); protected TF_Code TF_GetCode(Status s) => s.Code; - protected TF_Code TF_GetCode(IntPtr s) + protected TF_Code TF_GetCode(SafeStatusHandle s) => c_api.TF_GetCode(s); - protected string TF_Message(IntPtr s) + protected string TF_Message(SafeStatusHandle s) => c_api.StringPiece(c_api.TF_Message(s)); - protected IntPtr TF_NewStatus() + protected SafeStatusHandle TF_NewStatus() => c_api.TF_NewStatus(); - protected void TF_DeleteStatus(IntPtr s) - => c_api.TF_DeleteStatus(s); - protected void TF_DeleteTensor(IntPtr t) => c_api.TF_DeleteTensor(t); @@ -83,25 +80,25 @@ namespace TensorFlowNET.UnitTest protected ulong TF_TensorByteSize(IntPtr t) => c_api.TF_TensorByteSize(t); - protected void TFE_OpAddInput(IntPtr op, IntPtr h, IntPtr status) + protected void TFE_OpAddInput(IntPtr op, IntPtr h, SafeStatusHandle status) => c_api.TFE_OpAddInput(op, h, status); protected void TFE_OpSetAttrType(IntPtr op, string attr_name, TF_DataType value) => c_api.TFE_OpSetAttrType(op, attr_name, value); - protected void TFE_OpSetAttrShape(IntPtr op, string attr_name, long[] dims, int num_dims, IntPtr out_status) + protected void TFE_OpSetAttrShape(IntPtr op, string attr_name, long[] dims, int num_dims, SafeStatusHandle out_status) => c_api.TFE_OpSetAttrShape(op, attr_name, dims, num_dims, out_status); protected void TFE_OpSetAttrString(IntPtr op, string attr_name, string value, uint length) => c_api.TFE_OpSetAttrString(op, attr_name, value, length); - protected IntPtr TFE_NewOp(IntPtr ctx, string op_or_function_name, IntPtr status) + protected IntPtr TFE_NewOp(IntPtr ctx, string op_or_function_name, SafeStatusHandle status) => c_api.TFE_NewOp(ctx, op_or_function_name, status); - protected IntPtr TFE_NewTensorHandle(IntPtr t, IntPtr status) + protected IntPtr TFE_NewTensorHandle(IntPtr t, SafeStatusHandle status) => c_api.TFE_NewTensorHandle(t, status); - protected void TFE_Execute(IntPtr op, IntPtr[] retvals, ref int num_retvals, IntPtr status) + protected void TFE_Execute(IntPtr op, IntPtr[] retvals, ref int num_retvals, SafeStatusHandle status) => c_api.TFE_Execute(op, retvals, ref num_retvals, status); protected IntPtr TFE_NewContextOptions() @@ -110,19 +107,19 @@ namespace TensorFlowNET.UnitTest protected void TFE_DeleteContext(IntPtr t) => c_api.TFE_DeleteContext(t); - protected IntPtr TFE_NewContext(IntPtr opts, IntPtr status) + protected IntPtr TFE_NewContext(IntPtr opts, SafeStatusHandle status) => c_api.TFE_NewContext(opts, status); protected void TFE_DeleteContextOptions(IntPtr opts) => c_api.TFE_DeleteContextOptions(opts); - protected int TFE_OpGetInputLength(IntPtr op, string input_name, IntPtr status) + protected int TFE_OpGetInputLength(IntPtr op, string input_name, SafeStatusHandle status) => c_api.TFE_OpGetInputLength(op, input_name, status); - protected int TFE_OpAddInputList(IntPtr op, IntPtr[] inputs, int num_inputs, IntPtr status) + protected int TFE_OpAddInputList(IntPtr op, IntPtr[] inputs, int num_inputs, SafeStatusHandle status) => c_api.TFE_OpAddInputList(op, inputs, num_inputs, status); - protected int TFE_OpGetOutputLength(IntPtr op, string input_name, IntPtr status) + protected int TFE_OpGetOutputLength(IntPtr op, string input_name, SafeStatusHandle status) => c_api.TFE_OpGetOutputLength(op, input_name, status); protected void TFE_DeleteTensorHandle(IntPtr h) @@ -137,37 +134,37 @@ namespace TensorFlowNET.UnitTest protected IntPtr TFE_ContextGetExecutorForThread(IntPtr ctx) => c_api.TFE_ContextGetExecutorForThread(ctx); - protected void TFE_ExecutorWaitForAllPendingNodes(IntPtr executor, IntPtr status) + protected void TFE_ExecutorWaitForAllPendingNodes(IntPtr executor, SafeStatusHandle status) => c_api.TFE_ExecutorWaitForAllPendingNodes(executor, status); - protected IntPtr TFE_TensorHandleResolve(IntPtr h, IntPtr status) + protected IntPtr TFE_TensorHandleResolve(IntPtr h, SafeStatusHandle status) => c_api.TFE_TensorHandleResolve(h, status); - protected string TFE_TensorHandleDeviceName(IntPtr h, IntPtr status) + protected string TFE_TensorHandleDeviceName(IntPtr h, SafeStatusHandle status) => c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(h, status)); - protected string TFE_TensorHandleBackingDeviceName(IntPtr h, IntPtr status) + protected string TFE_TensorHandleBackingDeviceName(IntPtr h, SafeStatusHandle status) => c_api.StringPiece(c_api.TFE_TensorHandleBackingDeviceName(h, status)); - protected IntPtr TFE_ContextListDevices(IntPtr ctx, IntPtr status) + protected IntPtr TFE_ContextListDevices(IntPtr ctx, SafeStatusHandle status) => c_api.TFE_ContextListDevices(ctx, status); protected int TF_DeviceListCount(IntPtr list) => c_api.TF_DeviceListCount(list); - protected string TF_DeviceListType(IntPtr list, int index, IntPtr status) + protected string TF_DeviceListType(IntPtr list, int index, SafeStatusHandle status) => c_api.StringPiece(c_api.TF_DeviceListType(list, index, status)); - protected string TF_DeviceListName(IntPtr list, int index, IntPtr status) + protected string TF_DeviceListName(IntPtr list, int index, SafeStatusHandle status) => c_api.StringPiece(c_api.TF_DeviceListName(list, index, status)); protected void TF_DeleteDeviceList(IntPtr list) => c_api.TF_DeleteDeviceList(list); - protected IntPtr TFE_TensorHandleCopyToDevice(IntPtr h, IntPtr ctx, string device_name, IntPtr status) + protected IntPtr TFE_TensorHandleCopyToDevice(IntPtr h, IntPtr ctx, string device_name, SafeStatusHandle status) => c_api.TFE_TensorHandleCopyToDevice(h, ctx, device_name, status); - protected void TFE_OpSetDevice(IntPtr op, string device_name, IntPtr status) + protected void TFE_OpSetDevice(IntPtr op, string device_name, SafeStatusHandle status) => c_api.TFE_OpSetDevice(op, device_name, status); } } diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/CSession.cs b/test/TensorFlowNET.UnitTest/NativeAPI/CSession.cs index e9ed7784..1dc79b20 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/CSession.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/CSession.cs @@ -75,7 +75,7 @@ namespace TensorFlowNET.UnitTest c_api.TF_SessionRun(session_, null, inputs_ptr, input_values_ptr, inputs_ptr.Length, outputs_ptr, output_values_ptr, outputs_.Count, targets_ptr, targets_.Count, - IntPtr.Zero, s); + IntPtr.Zero, s.Handle); s.Check(); diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Context.cs b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Context.cs index df23ddaf..617edb8b 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Context.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Context.cs @@ -13,7 +13,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI [TestMethod] public void Context() { - var status = c_api.TF_NewStatus(); + using var status = c_api.TF_NewStatus(); var opts = c_api.TFE_NewContextOptions(); var ctx = c_api.TFE_NewContext(opts, status); @@ -34,7 +34,6 @@ namespace TensorFlowNET.UnitTest.NativeAPI } c_api.TF_DeleteDeviceList(devices); - c_api.TF_DeleteStatus(status); } } } diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Execute_MatMul_CPU.cs b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Execute_MatMul_CPU.cs index f03f159e..554714bc 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Execute_MatMul_CPU.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Execute_MatMul_CPU.cs @@ -18,7 +18,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI unsafe void Execute_MatMul_CPU(bool async) { - var status = TF_NewStatus(); + using var status = TF_NewStatus(); var opts = TFE_NewContextOptions(); c_api.TFE_ContextOptionsSetAsync(opts, Convert.ToByte(async)); var ctx = TFE_NewContext(opts, status); @@ -49,7 +49,6 @@ namespace TensorFlowNET.UnitTest.NativeAPI EXPECT_EQ(10f, product[1]); EXPECT_EQ(15f, product[2]); EXPECT_EQ(22f, product[3]); - TF_DeleteStatus(status); } } } diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpGetInputAndOutputLengths.cs b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpGetInputAndOutputLengths.cs index 30ab6e8b..5128f114 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpGetInputAndOutputLengths.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpGetInputAndOutputLengths.cs @@ -14,7 +14,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI [TestMethod] public unsafe void OpGetInputAndOutputLengths() { - var status = TF_NewStatus(); + using var status = TF_NewStatus(); var opts = TFE_NewContextOptions(); var ctx = TFE_NewContext(opts, status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); @@ -52,7 +52,6 @@ namespace TensorFlowNET.UnitTest.NativeAPI EXPECT_EQ(2, TFE_OpGetOutputLength(identityOp, "output", status)); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); - TF_DeleteStatus(status); TFE_DeleteOp(identityOp); TFE_DeleteTensorHandle(input1); TFE_DeleteTensorHandle(input2); diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpInferMixedTypeInputListAttrs.cs b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpInferMixedTypeInputListAttrs.cs index 22d2fe2e..7f6f74fc 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpInferMixedTypeInputListAttrs.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.OpInferMixedTypeInputListAttrs.cs @@ -16,7 +16,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI [TestMethod] public unsafe void OpInferMixedTypeInputListAttrs() { - var status = TF_NewStatus(); + using var status = TF_NewStatus(); var opts = TFE_NewContextOptions(); var ctx = TFE_NewContext(opts, status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); @@ -45,7 +45,6 @@ namespace TensorFlowNET.UnitTest.NativeAPI TFE_Execute(assertOp, retvals, ref num_retvals, status); EXPECT_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); - TF_DeleteStatus(status); TFE_DeleteOp(assertOp); TFE_DeleteTensorHandle(condition); TFE_DeleteTensorHandle(t1); diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Variables.cs b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Variables.cs index ff426770..0713ec15 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Variables.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.Variables.cs @@ -13,7 +13,7 @@ namespace TensorFlowNET.UnitTest.NativeAPI [TestMethod] public unsafe void Variables() { - var status = c_api.TF_NewStatus(); + using var status = c_api.TF_NewStatus(); var opts = TFE_NewContextOptions(); var ctx = TFE_NewContext(opts, status); ASSERT_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); @@ -49,7 +49,6 @@ namespace TensorFlowNET.UnitTest.NativeAPI TFE_DeleteTensorHandle(value_handle[0]); TFE_DeleteContext(ctx); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); - TF_DeleteStatus(status); } } } diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.cs b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.cs index ea9d5b14..34184672 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/Eager/CApi.Eager.cs @@ -18,17 +18,16 @@ namespace TensorFlowNET.UnitTest.NativeAPI var t = c_api.TF_AllocateTensor(TF_FLOAT, dims, dims.Length, (ulong)data.Length * sizeof(float)); tf.memcpy(c_api.TF_TensorData(t), data, data.Length * sizeof(float)); - var status = c_api.TF_NewStatus(); + using var status = c_api.TF_NewStatus(); var th = c_api.TFE_NewTensorHandle(t, status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); c_api.TF_DeleteTensor(t); - c_api.TF_DeleteStatus(status); return th; } IntPtr MatMulOp(IntPtr ctx, IntPtr a, IntPtr b) { - var status = TF_NewStatus(); + using var status = TF_NewStatus(); var op = TFE_NewOp(ctx, "MatMul", status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); @@ -36,7 +35,6 @@ namespace TensorFlowNET.UnitTest.NativeAPI CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); TFE_OpAddInput(op, b, status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); - TF_DeleteStatus(status); TFE_OpSetAttrType(op, "T", TFE_TensorHandleDataType(a)); return op; @@ -69,19 +67,18 @@ namespace TensorFlowNET.UnitTest.NativeAPI IntPtr ShapeOp(IntPtr ctx, IntPtr a) { - var status = TF_NewStatus(); + using var status = TF_NewStatus(); var op = TFE_NewOp(ctx, "Shape", status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); TFE_OpAddInput(op, a, status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); - TF_DeleteStatus(status); TFE_OpSetAttrType(op, "T", TFE_TensorHandleDataType(a)); return op; } - unsafe IntPtr CreateVariable(IntPtr ctx, float value, IntPtr status) + unsafe IntPtr CreateVariable(IntPtr ctx, float value, SafeStatusHandle status) { var op = TFE_NewOp(ctx, "VarHandleOp", status); if (TF_GetCode(status) != TF_OK) return IntPtr.Zero; @@ -128,11 +125,10 @@ namespace TensorFlowNET.UnitTest.NativeAPI var data = new int[] { 1 }; var t = c_api.TF_AllocateTensor(TF_DataType.TF_INT32, dims, 1, sizeof(int)); tf.memcpy(TF_TensorData(t), data, TF_TensorByteSize(t)); - var status = TF_NewStatus(); + using var status = TF_NewStatus(); var th = c_api.TFE_NewTensorHandle(t, status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); TF_DeleteTensor(t); - TF_DeleteStatus(status); return th; } @@ -141,11 +137,10 @@ namespace TensorFlowNET.UnitTest.NativeAPI var data = new[] { value }; var t = c_api.TF_AllocateTensor(TF_BOOL, null, 0, sizeof(bool)); tf.memcpy(TF_TensorData(t), data, TF_TensorByteSize(t)); - var status = TF_NewStatus(); + using var status = TF_NewStatus(); var th = TFE_NewTensorHandle(t, status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); TF_DeleteTensor(t); - TF_DeleteStatus(status); return th; } @@ -154,11 +149,10 @@ namespace TensorFlowNET.UnitTest.NativeAPI var data = new [] { value }; var t = c_api.TF_AllocateTensor(TF_FLOAT, null, 0, sizeof(float)); tf.memcpy(TF_TensorData(t), data, TF_TensorByteSize(t)); - var status = TF_NewStatus(); + using var status = TF_NewStatus(); var th = TFE_NewTensorHandle(t, status); CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); TF_DeleteTensor(t); - TF_DeleteStatus(status); return th; } } diff --git a/test/TensorFlowNET.UnitTest/NativeAPI/c_test_util.cs b/test/TensorFlowNET.UnitTest/NativeAPI/c_test_util.cs index 988afa17..48c717c8 100644 --- a/test/TensorFlowNET.UnitTest/NativeAPI/c_test_util.cs +++ b/test/TensorFlowNET.UnitTest/NativeAPI/c_test_util.cs @@ -24,7 +24,7 @@ namespace TensorFlowNET.UnitTest c_api.TF_AddInputList(desc, inputs, inputs.Length); - var op = c_api.TF_FinishOperation(desc, s); + var op = c_api.TF_FinishOperation(desc, s.Handle); s.Check(); return op; @@ -38,7 +38,7 @@ namespace TensorFlowNET.UnitTest { using (var buffer = new Buffer()) { - c_api.TF_OperationGetAttrValueProto(oper, attr_name, buffer, s); + c_api.TF_OperationGetAttrValueProto(oper, attr_name, buffer, s.Handle); attr_value = AttrValue.Parser.ParseFrom(buffer.MemoryBlock.Stream()); } @@ -53,7 +53,7 @@ namespace TensorFlowNET.UnitTest using (var s = new Status()) using (var buffer = new Buffer()) { - c_api.TF_GraphToGraphDef(graph, buffer, s); + c_api.TF_GraphToGraphDef(graph, buffer, s.Handle); s.Check(); return GraphDef.Parser.ParseFrom(buffer.MemoryBlock.Stream()); } @@ -175,7 +175,7 @@ namespace TensorFlowNET.UnitTest OperationDescription desc = c_api.TF_NewOperation(graph, "Neg", name); var neg_input = new TF_Output(n, 0); c_api.TF_AddInput(desc, neg_input); - var op = c_api.TF_FinishOperation(desc, s); + var op = c_api.TF_FinishOperation(desc, s.Handle); s.Check(); return op; @@ -193,7 +193,7 @@ namespace TensorFlowNET.UnitTest c_api.TF_SetAttrShape(desc, "shape", dims, dims.Length); } - var op = c_api.TF_FinishOperation(desc, s); + var op = c_api.TF_FinishOperation(desc, s.Handle); s.Check(); return op; @@ -205,10 +205,10 @@ namespace TensorFlowNET.UnitTest lock (Locks.ProcessWide) { var desc = c_api.TF_NewOperation(graph, "Const", name); - c_api.TF_SetAttrTensor(desc, "value", t, s); + c_api.TF_SetAttrTensor(desc, "value", t, s.Handle); s.Check(); c_api.TF_SetAttrType(desc, "dtype", t.dtype); - var op = c_api.TF_FinishOperation(desc, s); + var op = c_api.TF_FinishOperation(desc, s.Handle); s.Check(); return op;