| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent fdf8231 commit 5c2818e
16 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -34,6 +34,14 @@ public Buffer(IntPtr handle) | |||
| 34 | 34 | _handle = handle; | |
| 35 | 35 | } | |
| 36 | 36 | ||
| 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 | + | ||
| 37 | 45 | public static implicit operator IntPtr(Buffer buffer) | |
| 38 | 46 | { | |
| 39 | 47 | return buffer._handle; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,5 +19,15 @@ public partial class c_api | |||
| 19 | 19 | ||
| 20 | 20 | [DllImport(TensorFlowLibName)] | |
| 21 | 21 | 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); | ||
| 22 | 32 | } | |
| 23 | 33 | } | |
| Original file line number | Diff line number | Diff 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 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,13 +10,25 @@ public class c_api_util | |||
| 10 | 10 | ||
| 11 | 11 | public static ImportGraphDefOptions ScopedTFImportGraphDefOptions() => new ImportGraphDefOptions(); | |
| 12 | 12 | ||
| 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) | ||
| 14 | 25 | { | |
| 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 | + } | ||
| 20 | 32 | } | |
| 21 | 33 | } | |
| 22 | 34 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -42,11 +42,27 @@ public static ITensorOrOperation[] import_graph_def(GraphDef graph_def, | |||
| 42 | 42 | _PopulateTFImportGraphDefOptions(scoped_options, prefix, input_map, return_elements); | |
| 43 | 43 | ||
| 44 | 44 | var bytes = graph_def.ToByteString().ToArray(); | |
| 45 | + IntPtr buffer = c_api_util.tf_buffer(bytes); | ||
| 45 | 46 | ||
| 46 | 47 | 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); | ||
| 48 | 51 | ||
| 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 | + } | ||
| 50 | 66 | } | |
| 51 | 67 | ||
| 52 | 68 | public static void _PopulateTFImportGraphDefOptions(ImportGraphDefOptions options, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,7 @@ | |||
| 3 | 3 | using System.IO; | |
| 4 | 4 | using System.Linq; | |
| 5 | 5 | using System.Text; | |
| 6 | + using static Tensorflow.CollectionDef; | ||
| 6 | 7 | using static Tensorflow.MetaGraphDef.Types; | |
| 7 | 8 | ||
| 8 | 9 | namespace Tensorflow | |
@@ -16,7 +17,7 @@ public static MetaGraphDef read_meta_graph_file(string filename) | |||
| 16 | 17 | return meta_graph_def; | |
| 17 | 18 | } | |
| 18 | 19 | ||
| 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, | ||
| 20 | 21 | bool clear_devices = false, | |
| 21 | 22 | string import_scope = "", | |
| 22 | 23 | Dictionary<string, Tensor> input_map = null, | |
@@ -51,15 +52,49 @@ public static void import_scoped_meta_graph_with_return_elements(MetaGraphDef me | |||
| 51 | 52 | node.Device = ""; | |
| 52 | 53 | ||
| 53 | 54 | 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, | ||
| 55 | 56 | name: scope_to_prepend_to_names, | |
| 56 | 57 | input_map: input_map, | |
| 57 | 58 | producer_op_list: producer_op_list, | |
| 58 | 59 | return_elements: return_elements); | |
| 59 | 60 | ||
| 60 | 61 | // Restores all the other collections. | |
| 61 | 62 | 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 | + } | ||
| 62 | 96 | ||
| 97 | + return (null, null); | ||
| 63 | 98 | } | |
| 64 | 99 | ||
| 65 | 100 | /// <summary> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,7 @@ | |||
| 1 | 1 | using NumSharp.Core; | |
| 2 | 2 | using System; | |
| 3 | 3 | using System.Collections.Generic; | |
| 4 | + using System.Linq; | ||
| 4 | 5 | using System.Runtime.InteropServices; | |
| 5 | 6 | using System.Text; | |
| 6 | 7 | ||
@@ -22,5 +23,57 @@ public OperationDescription NewOperation(string opType, string opName) | |||
| 22 | 23 | { | |
| 23 | 24 | return c_api.TF_NewOperation(_handle, opType, opName); | |
| 24 | 25 | } | |
| 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 | + } | ||
| 25 | 78 | } | |
| 26 | 79 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -86,6 +86,16 @@ private ITensorOrOperation _as_graph_element_locked(object obj, bool allow_tenso | |||
| 86 | 86 | if (_nodes_by_name.ContainsKey(op_name)) | |
| 87 | 87 | return _nodes_by_name[op_name].outputs[out_n]; | |
| 88 | 88 | } | |
| 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 | + } | ||
| 89 | 99 | } | |
| 90 | 100 | ||
| 91 | 101 | if (obj is Tensor tensor && allow_tensor) | |
@@ -101,7 +111,7 @@ private ITensorOrOperation _as_graph_element_locked(object obj, bool allow_tenso | |||
| 101 | 111 | } | |
| 102 | 112 | else if (obj is Operation op && allow_operation) | |
| 103 | 113 | { | |
| 104 | - if (op.Graph.Equals(this)) | ||
| 114 | + if (op.graph.Equals(this)) | ||
| 105 | 115 | { | |
| 106 | 116 | return op; | |
| 107 | 117 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,5 +26,10 @@ public static implicit operator List<Tensor>(InputList input) | |||
| 26 | 26 | { | |
| 27 | 27 | return input._inputs.ToList(); | |
| 28 | 28 | } | |
| 29 | + | ||
| 30 | + public static implicit operator Tensor[](InputList input) | ||
| 31 | + { | ||
| 32 | + return input._inputs; | ||
| 33 | + } | ||
| 29 | 34 | } | |
| 30 | 35 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,5 +16,13 @@ public void _control_flow_post_processing() | |||
| 16 | 16 | ||
| 17 | 17 | } | |
| 18 | 18 | } | |
| 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 | + } | ||
| 19 | 27 | } | |
| 20 | 28 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments