|
|
@@ -3,6 +3,7 @@ using System.Collections.Generic; |
|
|
using System.ComponentModel; |
|
|
using System.ComponentModel; |
|
|
using System.Dynamic; |
|
|
using System.Dynamic; |
|
|
using System.IO; |
|
|
using System.IO; |
|
|
|
|
|
using System.Linq; |
|
|
using System.Runtime.InteropServices; |
|
|
using System.Runtime.InteropServices; |
|
|
using System.Text; |
|
|
using System.Text; |
|
|
using static Tensorflow.OpDef.Types; |
|
|
using static Tensorflow.OpDef.Types; |
|
|
@@ -41,6 +42,7 @@ namespace Tensorflow |
|
|
var attrs = new Dictionary<string, object>(); |
|
|
var attrs = new Dictionary<string, object>(); |
|
|
var inputs = new List<Tensor>(); |
|
|
var inputs = new List<Tensor>(); |
|
|
var input_types = new List<TF_DataType>(); |
|
|
var input_types = new List<TF_DataType>(); |
|
|
|
|
|
var base_types = new List<TF_DataType>(); |
|
|
|
|
|
|
|
|
Operation op = null; |
|
|
Operation op = null; |
|
|
Python.with<ops.name_scope>(new ops.name_scope(name), scope => |
|
|
Python.with<ops.name_scope>(new ops.name_scope(name), scope => |
|
|
@@ -49,34 +51,67 @@ namespace Tensorflow |
|
|
foreach (var input_arg in op_def.InputArg) |
|
|
foreach (var input_arg in op_def.InputArg) |
|
|
{ |
|
|
{ |
|
|
var input_name = input_arg.Name; |
|
|
var input_name = input_arg.Name; |
|
|
if (keywords[input_name] is double int_value) |
|
|
|
|
|
|
|
|
var values = keywords[input_name]; |
|
|
|
|
|
// Goals: |
|
|
|
|
|
// * Convert values to Tensors if it contains constants. |
|
|
|
|
|
// * Verify that values is a list if that matches the input_arg's |
|
|
|
|
|
// type. |
|
|
|
|
|
// * If the input_arg's type is determined by attrs, either set |
|
|
|
|
|
// those attrs and validate those attr values are legal (if |
|
|
|
|
|
// they have not yet been set) or validate the input matches |
|
|
|
|
|
// the type indicated by the attrs (if they have already been |
|
|
|
|
|
// inferred via an earlier input). |
|
|
|
|
|
// * If the input_arg has an explicit type, make sure the input |
|
|
|
|
|
// conforms. |
|
|
|
|
|
|
|
|
|
|
|
if (_IsListParameter(input_arg)) |
|
|
{ |
|
|
{ |
|
|
keywords[input_name] = constant_op.constant(int_value, input_name); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
DataType dtype = DataType.DtInvalid; |
|
|
|
|
|
DataType default_dtype = DataType.DtInvalid; |
|
|
|
|
|
|
|
|
if (keywords[input_name] is Tensor value) |
|
|
|
|
|
{ |
|
|
|
|
|
if (keywords.ContainsKey(input_name)) |
|
|
|
|
|
|
|
|
if (!_IsListValue(values)) |
|
|
|
|
|
throw new TypeError($"Expected list for '{input_name}' argument to '{op_type_name}' Op, not {values}."); |
|
|
|
|
|
if(input_arg.Type != DataType.DtInvalid) |
|
|
{ |
|
|
{ |
|
|
inputs.Add(value); |
|
|
|
|
|
|
|
|
dtype = input_arg.Type; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!String.IsNullOrEmpty(input_arg.TypeAttr)) |
|
|
|
|
|
|
|
|
else if (!String.IsNullOrEmpty(input_arg.NumberAttr)) |
|
|
{ |
|
|
{ |
|
|
attrs[input_arg.TypeAttr] = value.dtype; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (input_arg.IsRef) |
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
if(input_arg.IsRef && dtype != DataType.DtInvalid) |
|
|
|
|
|
dtype = dtype.as_base_dtype(); |
|
|
|
|
|
|
|
|
|
|
|
values = ops.internal_convert_n_to_tensor(values, name: input_arg.Name, dtype: dtype, preferred_dtype: default_dtype, as_ref: input_arg.IsRef); |
|
|
|
|
|
|
|
|
|
|
|
inputs.AddRange(values as Tensor[]); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
if (!(values is Tensor)) |
|
|
|
|
|
{ |
|
|
|
|
|
keywords[input_name] = constant_op.constant(values, input_name); |
|
|
} |
|
|
} |
|
|
else |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (keywords[input_name] is Tensor value) |
|
|
{ |
|
|
{ |
|
|
var base_type = value.dtype.as_base_dtype(); |
|
|
|
|
|
|
|
|
if (keywords.ContainsKey(input_name)) |
|
|
|
|
|
{ |
|
|
|
|
|
inputs.Add(value); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!String.IsNullOrEmpty(input_arg.TypeAttr)) |
|
|
|
|
|
{ |
|
|
|
|
|
attrs[input_arg.TypeAttr] = value.dtype; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
input_types.Add(base_type); |
|
|
|
|
|
|
|
|
values = new Tensor[] { value }; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
base_types.AddRange((values as Tensor[]).Select(x => x.dtype.as_base_dtype())); |
|
|
|
|
|
input_types.AddRange(base_types); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Process remaining attrs |
|
|
// Process remaining attrs |
|
|
@@ -152,6 +187,27 @@ namespace Tensorflow |
|
|
return v.as_base_dtype().as_datatype_enum(); |
|
|
return v.as_base_dtype().as_datatype_enum(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private bool _IsListParameter(ArgDef arg) |
|
|
|
|
|
{ |
|
|
|
|
|
if (!String.IsNullOrEmpty(arg.NumberAttr)) |
|
|
|
|
|
return true; |
|
|
|
|
|
else if (!String.IsNullOrEmpty(arg.TypeListAttr)) |
|
|
|
|
|
return true; |
|
|
|
|
|
else |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private bool _IsListValue(object v) |
|
|
|
|
|
{ |
|
|
|
|
|
switch (v) |
|
|
|
|
|
{ |
|
|
|
|
|
case Tensor[] val: |
|
|
|
|
|
return true; |
|
|
|
|
|
default: |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private Dictionary<string, object> ConvertToDict(dynamic dyn) |
|
|
private Dictionary<string, object> ConvertToDict(dynamic dyn) |
|
|
{ |
|
|
{ |
|
|
var dictionary = new Dictionary<string, object>(); |
|
|
var dictionary = new Dictionary<string, object>(); |
|
|
|