Skip to content

Commit 5c2818e

Browse files
committed
added KeyError exception.
added VariableDef tf_buffer, tf_operations
1 parent fdf8231 commit 5c2818e

16 files changed

Lines changed: 806 additions & 21 deletions

File tree

src/TensorFlowNET.Core/Buffers/Buffer.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ public Buffer(IntPtr handle)
3434
_handle = handle;
3535
}
3636

37+
public Buffer(byte[] data)
38+
{
39+
var dst = Marshal.AllocHGlobal(data.Length);
40+
Marshal.Copy(data, 0, dst, data.Length);
41+
42+
_handle = c_api.TF_NewBufferFromString(dst, (ulong)data.Length);
43+
}
44+
3745
public static implicit operator IntPtr(Buffer buffer)
3846
{
3947
return buffer._handle;

src/TensorFlowNET.Core/Buffers/c_api.buffer.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,15 @@ public partial class c_api
1919

2020
[DllImport(TensorFlowLibName)]
2121
public static extern IntPtr TF_GetBuffer(TF_Buffer buffer);
22+
23+
/// <summary>
24+
/// Makes a copy of the input and sets an appropriate deallocator. Useful for
25+
/// passing in read-only, input protobufs.
26+
/// </summary>
27+
/// <param name="proto">const void*</param>
28+
/// <param name="proto_len">size_t</param>
29+
/// <returns></returns>
30+
[DllImport(TensorFlowLibName)]
31+
public static extern IntPtr TF_NewBufferFromString(IntPtr proto, ulong proto_len);
2232
}
2333
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Tensorflow
6+
{
7+
public class KeyError : Exception
8+
{
9+
public KeyError() : base()
10+
{
11+
12+
}
13+
14+
public KeyError(string message) : base(message)
15+
{
16+
17+
}
18+
}
19+
}

src/TensorFlowNET.Core/Framework/c_api_util.py.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,25 @@ public class c_api_util
1010

1111
public static ImportGraphDefOptions ScopedTFImportGraphDefOptions() => new ImportGraphDefOptions();
1212

13-
public static IntPtr tf_buffer(byte[] data)
13+
public static Buffer tf_buffer(byte[] data) => new Buffer(data);
14+
15+
public static IEnumerable<Operation> new_tf_operations(Graph graph)
16+
{
17+
foreach (var c_op in tf_operations(graph))
18+
{
19+
if (graph._get_operation_by_tf_operation(c_op) == null)
20+
yield return c_op;
21+
}
22+
}
23+
24+
public static IEnumerable<Operation> tf_operations(Graph graph)
1425
{
15-
if (data != null)
16-
throw new NotImplementedException("");
17-
// var buf = c_api.TF_NewBufferFromString(data);
18-
else
19-
throw new NotImplementedException("");
26+
uint pos = 0;
27+
IntPtr c_op;
28+
while ((c_op = c_api.TF_GraphNextOperation(graph, ref pos)) != IntPtr.Zero)
29+
{
30+
yield return c_op;
31+
}
2032
}
2133
}
2234
}

src/TensorFlowNET.Core/Framework/importer.py.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,27 @@ public static ITensorOrOperation[] import_graph_def(GraphDef graph_def,
4242
_PopulateTFImportGraphDefOptions(scoped_options, prefix, input_map, return_elements);
4343

4444
var bytes = graph_def.ToByteString().ToArray();
45+
IntPtr buffer = c_api_util.tf_buffer(bytes);
4546

4647
var status = new Status();
47-
c_api.TF_GraphImportGraphDefWithResults(graph, IntPtr.Zero, scoped_options, status);
48+
// need to create a class ImportGraphDefWithResults with IDisposal
49+
var results = c_api.TF_GraphImportGraphDefWithResults(graph, buffer, scoped_options, status);
50+
status.Check(true);
4851

49-
throw new NotImplementedException("importer.import_graph_def");
52+
_ProcessNewOps(graph);
53+
54+
if (return_elements == null)
55+
return null;
56+
else
57+
throw new NotImplementedException("import_graph_def return_elements");
58+
}
59+
60+
private static void _ProcessNewOps(Graph graph)
61+
{
62+
foreach(var new_op in graph._add_new_tf_operations())
63+
{
64+
var original_device = new_op.Device;
65+
}
5066
}
5167

5268
public static void _PopulateTFImportGraphDefOptions(ImportGraphDefOptions options,

src/TensorFlowNET.Core/Framework/meta_graph.py.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using System.Text;
6+
using static Tensorflow.CollectionDef;
67
using static Tensorflow.MetaGraphDef.Types;
78

89
namespace Tensorflow
@@ -16,7 +17,7 @@ public static MetaGraphDef read_meta_graph_file(string filename)
1617
return meta_graph_def;
1718
}
1819

19-
public static void import_scoped_meta_graph_with_return_elements(MetaGraphDef meta_graph_or_file,
20+
public static (RefVariable[], string[]) import_scoped_meta_graph_with_return_elements(MetaGraphDef meta_graph_or_file,
2021
bool clear_devices = false,
2122
string import_scope = "",
2223
Dictionary<string, Tensor> input_map = null,
@@ -51,15 +52,49 @@ public static void import_scoped_meta_graph_with_return_elements(MetaGraphDef me
5152
node.Device = "";
5253

5354
var scope_to_prepend_to_names = graph.unique_name("", mark_as_used: false);
54-
importer.import_graph_def(input_graph_def,
55+
var imported_return_elements = importer.import_graph_def(input_graph_def,
5556
name: scope_to_prepend_to_names,
5657
input_map: input_map,
5758
producer_op_list: producer_op_list,
5859
return_elements: return_elements);
5960

6061
// Restores all the other collections.
6162
var variable_objects = new Dictionary<string, RefVariable>();
63+
foreach(var col in meta_graph_def.CollectionDef.OrderBy(x => x.Key))
64+
{
65+
// Don't add unbound_inputs to the new graph.
66+
if (col.Key == unbound_inputs_col_name)
67+
continue;
68+
69+
switch (col.Value.KindCase)
70+
{
71+
case KindOneofCase.NodeList:
72+
foreach(var value in col.Value.NodeList.Value)
73+
{
74+
var col_op = graph.as_graph_element(ops.prepend_name_scope(value, scope_to_prepend_to_names));
75+
graph.add_to_collection(col.Key, col_op);
76+
}
77+
break;
78+
case KindOneofCase.BytesList:
79+
//var proto_type = ops.get_collection_proto_type(key)
80+
if (ops.GraphKeys._VARIABLE_COLLECTIONS.Contains(col.Key))
81+
{
82+
foreach (var value in col.Value.BytesList.Value)
83+
{
84+
var proto = VariableDef.Parser.ParseFrom(value);
85+
throw new NotImplementedException("import_scoped_meta_graph_with_return_elements");
86+
}
87+
}
88+
else
89+
{
90+
throw new NotImplementedException("import_scoped_meta_graph_with_return_elements");
91+
}
92+
93+
break;
94+
}
95+
}
6296

97+
return (null, null);
6398
}
6499

65100
/// <summary>

src/TensorFlowNET.Core/Graphs/Graph.Operation.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using NumSharp.Core;
22
using System;
33
using System.Collections.Generic;
4+
using System.Linq;
45
using System.Runtime.InteropServices;
56
using System.Text;
67

@@ -22,5 +23,57 @@ public OperationDescription NewOperation(string opType, string opName)
2223
{
2324
return c_api.TF_NewOperation(_handle, opType, opName);
2425
}
26+
27+
public ITensorOrOperation _get_operation_by_name_unsafe(string name)
28+
{
29+
return _nodes_by_name.ContainsKey(name) ? _nodes_by_name[name] : null;
30+
}
31+
32+
public ITensorOrOperation _get_operation_by_tf_operation(IntPtr tf_oper)
33+
{
34+
var op_name = Marshal.PtrToStringAnsi(c_api.TF_OperationName(tf_oper));
35+
return _get_operation_by_name_unsafe(op_name);
36+
}
37+
38+
public Operation _create_op_from_tf_operation(IntPtr c_op, bool compute_device = true)
39+
{
40+
var ret = new Operation(c_op);
41+
42+
var name_key = ret.name.ToLower();
43+
if (!_names_in_use.ContainsKey(name_key))
44+
_names_in_use[name_key] = 1;
45+
46+
_create_op_helper(ret, compute_device: compute_device);
47+
48+
return ret;
49+
}
50+
51+
/// <summary>
52+
/// Creates `Operations` in this graph for any new TF_Operations.
53+
///
54+
/// This is useful for when TF_Operations are indirectly created by the C API
55+
/// outside of the Operation constructor (e.g. by TF_ImportGraphDef,
56+
/// TF_FinishWhile). This ensures there are corresponding Operations for all
57+
/// TF_Operations in the underlying TF_Graph.
58+
/// </summary>
59+
/// <param name="compute_devices"></param>
60+
/// <returns></returns>
61+
public IEnumerable<Operation> _add_new_tf_operations(bool compute_devices = true)
62+
{
63+
var new_ops = c_api_util.new_tf_operations(this)
64+
.Select(c_op => _create_op_from_tf_operation(c_op, compute_device: compute_devices))
65+
.ToArray();
66+
67+
foreach(var op in new_ops)
68+
{
69+
var new_control_inputs = _control_dependencies_for_inputs(op.inputs)
70+
.Select(x => x as Operation)
71+
.ToArray();
72+
op._add_control_inputs(new_control_inputs);
73+
op._control_flow_post_processing();
74+
}
75+
76+
return new_ops;
77+
}
2578
}
2679
}

src/TensorFlowNET.Core/Graphs/Graph.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ private ITensorOrOperation _as_graph_element_locked(object obj, bool allow_tenso
8686
if (_nodes_by_name.ContainsKey(op_name))
8787
return _nodes_by_name[op_name].outputs[out_n];
8888
}
89+
else if(!name.Contains(":") & allow_operation)
90+
{
91+
if (!_nodes_by_name.ContainsKey(name))
92+
throw new KeyError($"The name {name} refers to an Operation not in the graph.");
93+
return _nodes_by_name[name];
94+
}
95+
else if (!name.Contains(":") & !allow_operation)
96+
{
97+
throw new NotImplementedException("_as_graph_element_locked");
98+
}
8999
}
90100

91101
if (obj is Tensor tensor && allow_tensor)
@@ -101,7 +111,7 @@ private ITensorOrOperation _as_graph_element_locked(object obj, bool allow_tenso
101111
}
102112
else if (obj is Operation op && allow_operation)
103113
{
104-
if (op.Graph.Equals(this))
114+
if (op.graph.Equals(this))
105115
{
106116
return op;
107117
}

src/TensorFlowNET.Core/Operations/InputList.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,10 @@ public static implicit operator List<Tensor>(InputList input)
2626
{
2727
return input._inputs.ToList();
2828
}
29+
30+
public static implicit operator Tensor[](InputList input)
31+
{
32+
return input._inputs;
33+
}
2934
}
3035
}

src/TensorFlowNET.Core/Operations/Operation.Control.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,13 @@ public void _control_flow_post_processing()
1616

1717
}
1818
}
19+
20+
public void _add_control_inputs(Operation[] ops)
21+
{
22+
foreach(var op in ops)
23+
{
24+
c_api.TF_AddControlInput(graph, op);
25+
}
26+
}
1927
}
2028
}

0 commit comments

Comments
 (0)