33using System . ComponentModel ;
44using System . Dynamic ;
55using System . IO ;
6+ using System . Linq ;
67using System . Runtime . InteropServices ;
78using System . Text ;
89using static Tensorflow . OpDef . Types ;
@@ -41,6 +42,7 @@ public Operation _apply_op_helper(string op_type_name, string name = "", dynamic
4142 var attrs = new Dictionary < string , object > ( ) ;
4243 var inputs = new List < Tensor > ( ) ;
4344 var input_types = new List < TF_DataType > ( ) ;
45+ var base_types = new List < TF_DataType > ( ) ;
4446
4547 Operation op = null ;
4648 Python . with < ops . name_scope > ( new ops . name_scope ( name ) , scope =>
@@ -49,34 +51,67 @@ public Operation _apply_op_helper(string op_type_name, string name = "", dynamic
4951 foreach ( var input_arg in op_def . InputArg )
5052 {
5153 var input_name = input_arg . Name ;
52- if ( keywords [ input_name ] is double int_value )
54+ var values = keywords [ input_name ] ;
55+ // Goals:
56+ // * Convert values to Tensors if it contains constants.
57+ // * Verify that values is a list if that matches the input_arg's
58+ // type.
59+ // * If the input_arg's type is determined by attrs, either set
60+ // those attrs and validate those attr values are legal (if
61+ // they have not yet been set) or validate the input matches
62+ // the type indicated by the attrs (if they have already been
63+ // inferred via an earlier input).
64+ // * If the input_arg has an explicit type, make sure the input
65+ // conforms.
66+
67+ if ( _IsListParameter ( input_arg ) )
5368 {
54- keywords [ input_name ] = constant_op . constant ( int_value , input_name ) ;
55- }
69+ DataType dtype = DataType . DtInvalid ;
70+ DataType default_dtype = DataType . DtInvalid ;
5671
57- if ( keywords [ input_name ] is Tensor value )
58- {
59- if ( keywords . ContainsKey ( input_name ) )
72+ if ( ! _IsListValue ( values ) )
73+ throw new TypeError ( $ "Expected list for ' { input_name } ' argument to ' { op_type_name } ' Op, not { values } ." ) ;
74+ if ( input_arg . Type != DataType . DtInvalid )
6075 {
61- inputs . Add ( value ) ;
76+ dtype = input_arg . Type ;
6277 }
63-
64- if ( ! String . IsNullOrEmpty ( input_arg . TypeAttr ) )
78+ else if ( ! String . IsNullOrEmpty ( input_arg . NumberAttr ) )
6579 {
66- attrs [ input_arg . TypeAttr ] = value . dtype ;
80+
6781 }
6882
69- if ( input_arg . IsRef )
70- {
83+ if ( input_arg . IsRef && dtype != DataType . DtInvalid )
84+ dtype = dtype . as_base_dtype ( ) ;
7185
86+ values = ops . internal_convert_n_to_tensor ( values , name : input_arg . Name , dtype : dtype , preferred_dtype : default_dtype , as_ref : input_arg . IsRef ) ;
87+
88+ inputs . AddRange ( values as Tensor [ ] ) ;
89+ }
90+ else
91+ {
92+ if ( ! ( values is Tensor ) )
93+ {
94+ keywords [ input_name ] = constant_op . constant ( values , input_name ) ;
7295 }
73- else
96+
97+ if ( keywords [ input_name ] is Tensor value )
7498 {
75- var base_type = value . dtype . as_base_dtype ( ) ;
99+ if ( keywords . ContainsKey ( input_name ) )
100+ {
101+ inputs . Add ( value ) ;
102+ }
103+
104+ if ( ! String . IsNullOrEmpty ( input_arg . TypeAttr ) )
105+ {
106+ attrs [ input_arg . TypeAttr ] = value . dtype ;
107+ }
76108
77- input_types . Add ( base_type ) ;
109+ values = new Tensor [ ] { value } ;
78110 }
79111 }
112+
113+ base_types . AddRange ( ( values as Tensor [ ] ) . Select ( x => x . dtype . as_base_dtype ( ) ) ) ;
114+ input_types . AddRange ( base_types ) ;
80115 }
81116
82117 // Process remaining attrs
@@ -152,6 +187,27 @@ public DataType _MakeType(TF_DataType v, AttrDef attr_def)
152187 return v . as_base_dtype ( ) . as_datatype_enum ( ) ;
153188 }
154189
190+ private bool _IsListParameter ( ArgDef arg )
191+ {
192+ if ( ! String . IsNullOrEmpty ( arg . NumberAttr ) )
193+ return true ;
194+ else if ( ! String . IsNullOrEmpty ( arg . TypeListAttr ) )
195+ return true ;
196+ else
197+ return false ;
198+ }
199+
200+ private bool _IsListValue ( object v )
201+ {
202+ switch ( v )
203+ {
204+ case Tensor [ ] val :
205+ return true ;
206+ default :
207+ return false ;
208+ }
209+ }
210+
155211 private Dictionary < string , object > ConvertToDict ( dynamic dyn )
156212 {
157213 var dictionary = new Dictionary < string , object > ( ) ;
0 commit comments