using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; namespace Tensorflow { // from ops.py public partial class Operation { public TF_Output Input(int index) => c_api.TF_OperationInput(new TF_Input(_handle, index)); public TF_DataType InputType(int index) => c_api.TF_OperationInputType(new TF_Input(_handle, index)); public int InputListLength(string name) => c_api.TF_OperationInputListLength(_handle, name, status); public int NumInputs => c_api.TF_OperationNumInputs(_handle); private TF_DataType[] _input_types => _inputs._inputs.Select(x => x.dtype).ToArray(); private InputList _inputs; public InputList inputs { get { if (_inputs == null) { var retval = new Tensor[NumInputs]; for (int i = 0; i < NumInputs; i++) { var tf_outputs = Input(i); var op = new Operation(tf_outputs.oper); retval[i] = op.outputs[tf_outputs.index]; } _inputs = new InputList(retval); } return _inputs; } } public int NumControlInputs => c_api.TF_OperationNumControlInputs(_handle); /// /// The `Operation` objects on which this op has a control dependency. /// /// Before this op is executed, TensorFlow will ensure that the /// operations in `self.control_inputs` have finished executing.This /// mechanism can be used to run ops sequentially for performance /// reasons, or to ensure that the side effects of an op are observed /// in the correct order. /// public Operation[] control_inputs { get { return GetControlInputs(); } } public unsafe Operation[] GetControlInputs() { var control_inputs = new Operation[NumControlInputs]; if (NumControlInputs > 0) { IntPtr control_input_handle = Marshal.AllocHGlobal(Marshal.SizeOf() * NumControlInputs); c_api.TF_OperationGetControlInputs(_handle, control_input_handle, NumControlInputs); for (int i = 0; i < NumControlInputs; i++) { var handle = control_input_handle + Marshal.SizeOf() * i; control_inputs[i] = new Operation(*(IntPtr*)handle); } } return control_inputs; } } }