diff --git a/lib/tensorflow.rb b/lib/tensorflow.rb index 01dc00c..15a250a 100644 --- a/lib/tensorflow.rb +++ b/lib/tensorflow.rb @@ -1,4 +1,4 @@ -require 'sciruby/Tensorflow' +require 'tensorflow/tensorflow_wrap' require 'tensorflow/opspec' require 'tensorflow/tensor' require 'tensorflow/graph' diff --git a/lib/tensorflow/graph.rb b/lib/tensorflow/graph.rb index d7a3505..6deab25 100644 --- a/lib/tensorflow/graph.rb +++ b/lib/tensorflow/graph.rb @@ -7,12 +7,12 @@ class Tensorflow::Graph # @!attribute c # contains the graph representation. def initialize - self.c = Tensorflow::TF_NewGraph() + self.c = TensorflowAPI::new_graph() @number_of_defaults_created = Hash.new(0) end def delete_graph - Tensorflow::TF_DeleteGraph(c) + Tensorflow::delete_graph(c) end # write_to writes out a serialized representation of graph in binary wire format. @@ -94,11 +94,11 @@ def AddOperation(opspec) opspec.name = opspec.type if opspec.name == '' cname = CString(opspec.name) ctype = CString(opspec.type) - cdesc = Tensorflow::TF_NewOperation(c, ctype, cname) + cdesc = TensorflowAPI::new_operation(c, ctype, cname) unless opspec.input.empty? opspec.input.each do |name| - Tensorflow::TF_AddInput(cdesc, name.c) + Tensorflow::add_input(cdesc, name.c) end end @@ -110,7 +110,7 @@ def AddOperation(opspec) cdesc = Tensorflow.input_list_helper(cdesc, c_array, length) end - status = Tensorflow::Status.new + status = TensorflowAPI::Status.new opspec.attr.each do |name, value| cdesc, status = set_attributes(cdesc, status, name, value) # Memory leak here as the TF_OperationDescription @@ -122,7 +122,7 @@ def AddOperation(opspec) # consider adding a TF_DeleteOperationDescription # function to the C API. end - Tensorflow::Operation.new(Tensorflow::TF_FinishOperation(cdesc, status.c), self) + Tensorflow::Operation.new(Tensorflow::finish_operation(cdesc, status.c), self) end private @@ -192,9 +192,9 @@ def set_attributes(cdesc, status, name, value) end Tensorflow::TF_SetAttrFloatList(cdesc, cAttrName, list, size) when 'DataType' - Tensorflow::TF_SetAttrType(cdesc, cAttrName, value) + TensorflowAPI::set_attr_type(cdesc, cAttrName, value) when 'Tensor' - Tensorflow::TF_SetAttrTensor(cdesc, cAttrName, value.tensor, status.c) + TensorflowAPI::set_attr_tensor(cdesc, cAttrName, value.tensor, status) # TODO: Insert Tensor_list, DataType_list, Bool else raise 'Attribute type not supported or attribute type not specififed properly. Please look into the documentation for set_attributes in the graph class for more information.' diff --git a/lib/tensorflow/op.rb b/lib/tensorflow/op.rb index 85549bf..e08f81c 100644 --- a/lib/tensorflow/op.rb +++ b/lib/tensorflow/op.rb @@ -33,7 +33,5 @@ def Placeholder(scope, dtype) # A simple makeshift function to convert a ruby string to C++ string def CString(string) - vector = Tensorflow::String_Vector.new - vector[0] = string - vector[0] + string end diff --git a/lib/tensorflow/status.rb b/lib/tensorflow/status.rb index 41b2fd8..0cfe924 100644 --- a/lib/tensorflow/status.rb +++ b/lib/tensorflow/status.rb @@ -3,11 +3,11 @@ class Tensorflow::Status attr_accessor :c def initialize - self.c = Tensorflow::TF_NewStatus() + self.c = Tensorflow::new_status() end def newstatus - self.c = Tensorflow::TF_NewStatus() + self.c = Tensorflow::new_status() end def code diff --git a/lib/tensorflow/tensor.rb b/lib/tensorflow/tensor.rb index e5ce68c..da52e2e 100644 --- a/lib/tensorflow/tensor.rb +++ b/lib/tensorflow/tensor.rb @@ -53,11 +53,11 @@ def initialize(value, type = nil) rank.zero? ? [1] : shape, Tensorflow::TF_INT64 ) if type_num == Tensorflow::TF_STRING - self.tensor = Tensorflow::String_encoder(CString(value), CString([0].pack("Q")) ) + self.tensor = Tensorflow::String_encoder(value, [0].pack("Q")) return self end - self.tensor = Tensorflow::TF_NewTensor_wrapper(type_num, - dimension_data, rank, tensor_data, data_size * flatten.length) + self.tensor = TensorflowAPI.new_tensor(type_num, + dimension_data, rank, tensor_data, data_size * flatten.length, nil, nil) end # @@ -148,12 +148,11 @@ def ruby_array_to_c(array, type) c_array = Tensorflow::Int.new(array.length) array.each_with_index { |value, i| c_array[i] = value } when Tensorflow::TF_INT64 - c_array = Tensorflow::Long_long.new(array.length) - array.each_with_index { |value, i| c_array[i] = value } + c_array = FFI::MemoryPointer.new(:long_long, array.size) + array.each_with_index { |value, i| c_array.put_long_long i, value } when Tensorflow::TF_STRING - c_array = Tensorflow::String_Vector.new - array.each_with_index { |value, i| c_array[i] = value } - c_array = Tensorflow.string_array_from_string_vector(c_array) + c_array = FFI::MemoryPointer.new(:pointer, array.size) + array.each_with_index { |value, i| c_array.put_pointer i, FFI::MemoryPointer.from_string(value) } else c_array = Tensorflow::Complex_Vector.new array.each_with_index { |value, i| c_array[i] = value } diff --git a/lib/tensorflow/tensorflow_api.rb b/lib/tensorflow/tensorflow_api.rb new file mode 100644 index 0000000..4e87443 --- /dev/null +++ b/lib/tensorflow/tensorflow_api.rb @@ -0,0 +1,1942 @@ +# Generated by ffi_gen. Please do not change this file by hand. + +require 'ffi' + +module TensorflowAPI + extend FFI::Library + ffi_lib "tensorflow" + + def self.attach_function(name, *_) + begin; super; rescue FFI::NotFoundError => e + (class << self; self; end).class_eval { define_method(name) { |*_| raise e } } + end + end + + # TensorFlow library. TensorFlow using semantic versioning. + # + # @method version() + # @return [String] + # @scope class + attach_function :version, :TF_Version, [], :string + + # The enum values here are identical to corresponding values in types.proto. + # + # This entry is only for documentation and no real method. The FFI::Enum can be accessed via #enum_type(:data_type). + # + # === Options: + # :float :: + # + # :double :: + # + # :int32 :: + # + # :uint8 :: + # Int32 tensors are always in 'host' memory. + # :int16 :: + # + # :int8 :: + # + # :string :: + # + # :complex64 :: + # + # :complex :: + # Single-precision complex + # :int64 :: + # Old identifier kept for API backwards compatibility + # :bool :: + # + # :qint8 :: + # + # :quint8 :: + # Quantized int8 + # :qint32 :: + # Quantized uint8 + # :bfloat16 :: + # Quantized int32 + # :qint16 :: + # Float32 truncated to 16 bits. Only for cast ops. + # :quint16 :: + # Quantized int16 + # :uint16 :: + # Quantized uint16 + # :complex128 :: + # + # :half :: + # Double-precision complex + # :resource :: + # + # + # @method _enum_data_type_ + # @return [Symbol] + # @scope class + enum :data_type, [ + :float, 1, + :double, 2, + :int32, 3, + :uint8, 4, + :int16, 5, + :int8, 6, + :string, 7, + :complex64, 8, + :complex, 8, + :int64, 9, + :bool, 10, + :qint8, 11, + :quint8, 12, + :qint32, 13, + :bfloat16, 14, + :qint16, 15, + :quint16, 16, + :uint16, 17, + :complex128, 18, + :half, 19, + :resource, 20 + ] + + # (eg. TF_STRING) or on failure. + # + # @method data_type_size(dt) + # @param [Symbol from _enum_data_type_] dt + # @return [Integer] + # @scope class + attach_function :data_type_size, :TF_DataTypeSize, [:data_type], :ulong + + # corresponding values in error_codes.proto. + # + # This entry is only for documentation and no real method. The FFI::Enum can be accessed via #enum_type(:code). + # + # === Options: + # :ok :: + # + # :cancelled :: + # + # :unknown :: + # + # :invalid_argument :: + # + # :deadline_exceeded :: + # + # :not_found :: + # + # :already_exists :: + # + # :permission_denied :: + # + # :unauthenticated :: + # + # :resource_exhausted :: + # + # :failed_precondition :: + # + # :aborted :: + # + # :out_of_range :: + # + # :unimplemented :: + # + # :internal :: + # + # :unavailable :: + # + # :data_loss :: + # + # + # @method _enum_code_ + # @return [Symbol] + # @scope class + enum :code, [ + :ok, 0, + :cancelled, 1, + :unknown, 2, + :invalid_argument, 3, + :deadline_exceeded, 4, + :not_found, 5, + :already_exists, 6, + :permission_denied, 7, + :unauthenticated, 16, + :resource_exhausted, 8, + :failed_precondition, 9, + :aborted, 10, + :out_of_range, 11, + :unimplemented, 12, + :internal, 13, + :unavailable, 14, + :data_loss, 15 + ] + + # else an error code with an associated error message. + class Status < FFI::Struct + layout :dummy, :char + end + + # Return a new status object. + # + # @method new_status() + # @return [Status] + # @scope class + attach_function :new_status, :TF_NewStatus, [], Status + + # Delete a previously created status object. + # + # @method delete_status(status) + # @param [Status] status + # @return [nil] + # @scope class + attach_function :delete_status, :TF_DeleteStatus, [Status], :void + + # A common use is to clear a status: TF_SetStatus(s, TF_OK, ""); + # + # @method set_status(s, code, msg) + # @param [Status] s + # @param [Symbol from _enum_code_] code + # @param [String] msg + # @return [nil] + # @scope class + attach_function :set_status, :TF_SetStatus, [Status, :code, :string], :void + + # Return the code record in *s. + # + # @method get_code(s) + # @param [Status] s + # @return [Symbol from _enum_code_] + # @scope class + attach_function :get_code, :TF_GetCode, [Status], :code + + # TF_OK. + # + # @method message(s) + # @param [Status] s + # @return [String] + # @scope class + attach_function :message, :TF_Message, [Status], :string + + # deallocate the block by setting the `data_deallocator` function pointer. + # + # = Fields: + # :data :: + # (FFI::Pointer(*Void)) + # :length :: + # (Integer) + # :data_deallocator :: + # (FFI::Pointer(*)) + class Buffer < FFI::Struct + layout :data, :pointer, + :length, :ulong, + :data_deallocator, :pointer + end + + # passing in read-only, input protobufs. + # + # @method new_buffer_from_string(proto, proto_len) + # @param [FFI::Pointer(*Void)] proto + # @param [Integer] proto_len + # @return [Buffer] + # @scope class + attach_function :new_buffer_from_string, :TF_NewBufferFromString, [:pointer, :ulong], Buffer + + # Useful for passing *out* a protobuf. + # + # @method new_buffer() + # @return [Buffer] + # @scope class + attach_function :new_buffer, :TF_NewBuffer, [], Buffer + + # (Not documented) + # + # @method delete_buffer(buffer) + # @param [Buffer] buffer + # @return [nil] + # @scope class + attach_function :delete_buffer, :TF_DeleteBuffer, [Buffer], :void + + # (Not documented) + # + # @method get_buffer(buffer) + # @param [Buffer] buffer + # @return [Buffer] + # @scope class + attach_function :get_buffer, :TF_GetBuffer, [Buffer], Buffer.by_value + + # facilitate this encoding. + module TensorWrappers + # @return [Symbol from _enum_data_type_] + def type() + TensorflowAPI.tensor_type(self) + end + + # @return [Integer] + def byte_size() + TensorflowAPI.tensor_byte_size(self) + end + + # @return [FFI::Pointer(*Void)] + def data() + TensorflowAPI.tensor_data(self) + end + end + + class Tensor < FFI::Struct + include TensorWrappers + layout :dummy, :char + end + + # memory managed by something like numpy. + # + # @method new_tensor(data_type, dims, num_dims, data, len, deallocator, deallocator_arg) + # @param [Symbol from _enum_data_type_] data_type + # @param [FFI::Pointer(*LongLong)] dims + # @param [Integer] num_dims + # @param [FFI::Pointer(*Void)] data + # @param [Integer] len + # @param [FFI::Pointer(*)] deallocator + # @param [FFI::Pointer(*Void)] deallocator_arg + # @return [Tensor] + # @scope class + attach_function :new_tensor, :TF_NewTensor, [:data_type, :pointer, :int, :pointer, :ulong, :pointer, :pointer], Tensor + + # by TF_TensorData with length TF_TensorByteSize. + # + # @method allocate_tensor(data_type, dims, num_dims, len) + # @param [Symbol from _enum_data_type_] data_type + # @param [FFI::Pointer(*LongLong)] dims + # @param [Integer] num_dims + # @param [Integer] len + # @return [Tensor] + # @scope class + attach_function :allocate_tensor, :TF_AllocateTensor, [:data_type, :pointer, :int, :ulong], Tensor + + # Destroy a tensor. + # + # @method delete_tensor(tensor) + # @param [Tensor] tensor + # @return [nil] + # @scope class + attach_function :delete_tensor, :TF_DeleteTensor, [Tensor], :void + + # Return the type of a tensor element. + # + # @method tensor_type(tensor) + # @param [Tensor] tensor + # @return [Symbol from _enum_data_type_] + # @scope class + attach_function :tensor_type, :TF_TensorType, [Tensor], :data_type + + # Return the number of dimensions that the tensor has. + # + # @method num_dims(tensor) + # @param [Tensor] tensor + # @return [Integer] + # @scope class + attach_function :num_dims, :TF_NumDims, [Tensor], :int + + # REQUIRES: 0 <= dim_index < TF_NumDims(tensor) + # + # @method dim(tensor, dim_index) + # @param [Tensor] tensor + # @param [Integer] dim_index + # @return [Integer] + # @scope class + attach_function :dim, :TF_Dim, [Tensor, :int], :long_long + + # Return the size of the underlying data in bytes. + # + # @method tensor_byte_size(tensor) + # @param [Tensor] tensor + # @return [Integer] + # @scope class + attach_function :tensor_byte_size, :TF_TensorByteSize, [Tensor], :ulong + + # Return a pointer to the underlying data buffer. + # + # @method tensor_data(tensor) + # @param [Tensor] tensor + # @return [FFI::Pointer(*Void)] + # @scope class + attach_function :tensor_data, :TF_TensorData, [Tensor], :pointer + + # Returns an error into `status` otherwise. + # + # @method string_encode(src, src_len, dst, dst_len, status) + # @param [String] src + # @param [Integer] src_len + # @param [String] dst + # @param [Integer] dst_len + # @param [Status] status + # @return [Integer] + # @scope class + attach_function :string_encode, :TF_StringEncode, [:string, :ulong, :pointer, :ulong, Status], :ulong + + # Does not read memory more than `src_len` bytes beyond `src`. + # + # @method string_decode(src, src_len, dst, dst_len, status) + # @param [String] src + # @param [Integer] src_len + # @param [FFI::Pointer(**CharS)] dst + # @param [FFI::Pointer(*SizeT)] dst_len + # @param [Status] status + # @return [Integer] + # @scope class + attach_function :string_decode, :TF_StringDecode, [:string, :ulong, :pointer, :pointer, Status], :ulong + + # TF_STRING tensor. + # + # @method string_encoded_size(len) + # @param [Integer] len + # @return [Integer] + # @scope class + attach_function :string_encoded_size, :TF_StringEncodedSize, [:ulong], :ulong + + # TF_SessionOptions holds options that can be passed during session creation. + class SessionOptions < FFI::Struct + layout :dummy, :char + end + + # Return a new options object. + # + # @method new_session_options() + # @return [SessionOptions] + # @scope class + attach_function :new_session_options, :TF_NewSessionOptions, [], SessionOptions + + # host:port + # + # @method set_target(options, target) + # @param [SessionOptions] options + # @param [String] target + # @return [nil] + # @scope class + attach_function :set_target, :TF_SetTarget, [SessionOptions, :string], :void + + # error information in *status. + # + # @method set_config(options, proto, proto_len, status) + # @param [SessionOptions] options + # @param [FFI::Pointer(*Void)] proto + # @param [Integer] proto_len + # @param [Status] status + # @return [nil] + # @scope class + attach_function :set_config, :TF_SetConfig, [SessionOptions, :pointer, :ulong, Status], :void + + # Destroy an options object. + # + # @method delete_session_options(session_options) + # @param [SessionOptions] session_options + # @return [nil] + # @scope class + attach_function :delete_session_options, :TF_DeleteSessionOptions, [SessionOptions], :void + + # Graphs are thread-safe when used as directed below. + module GraphWrappers + # @param [Output] output + # @param [FFI::Pointer(*LongLong)] dims + # @param [Integer] num_dims + # @param [Status] status + # @return [nil] + def set_tensor_shape(output, dims, num_dims, status) + TensorflowAPI.graph_set_tensor_shape(self, output, dims, num_dims, status) + end + + # @param [Output] output + # @param [Status] status + # @return [Integer] + def get_tensor_num_dims(output, status) + TensorflowAPI.graph_get_tensor_num_dims(self, output, status) + end + + # @param [Output] output + # @param [FFI::Pointer(*LongLong)] dims + # @param [Integer] num_dims + # @param [Status] status + # @return [nil] + def get_tensor_shape(output, dims, num_dims, status) + TensorflowAPI.graph_get_tensor_shape(self, output, dims, num_dims, status) + end + + # @param [String] oper_name + # @return [Operation] + def operation_by_name(oper_name) + Operation.new TensorflowAPI.graph_operation_by_name(self, oper_name) + end + + # @param [FFI::Pointer(*SizeT)] pos + # @return [Operation] + def next_operation(pos) + Operation.new TensorflowAPI.graph_next_operation(self, pos) + end + + # @param [Buffer] output_graph_def + # @param [Status] status + # @return [nil] + def to_graph_def(output_graph_def, status) + TensorflowAPI.graph_to_graph_def(self, output_graph_def, status) + end + + # @param [Buffer] graph_def + # @param [FFI::Pointer(*ImportGraphDefOptions)] options + # @param [FFI::Pointer(*Output)] return_outputs + # @param [Integer] num_return_outputs + # @param [Status] status + # @return [nil] + def import_graph_def_with_return_outputs(graph_def, options, return_outputs, num_return_outputs, status) + TensorflowAPI.graph_import_graph_def_with_return_outputs(self, graph_def, options, return_outputs, num_return_outputs, status) + end + + # @param [Buffer] graph_def + # @param [FFI::Pointer(*ImportGraphDefOptions)] options + # @param [Status] status + # @return [nil] + def import_graph_def(graph_def, options, status) + TensorflowAPI.graph_import_graph_def(self, graph_def, options, status) + end + end + + class Graph < FFI::Struct + include GraphWrappers + layout :dummy, :char + end + + # Return a new graph object. + # + # @method new_graph() + # @return [Graph] + # @scope class + attach_function :new_graph, :TF_NewGraph, [], Graph + + # TFSession's are referencing it. + # + # @method delete_graph(graph) + # @param [Graph] graph + # @return [nil] + # @scope class + attach_function :delete_graph, :TF_DeleteGraph, [Graph], :void + + # Operation being built. The underlying graph must outlive this. + class OperationDescription < FFI::Struct + layout :dummy, :char + end + + # invalidate old TF_Operation* pointers. + module OperationWrappers + # @return [String] + def name() + TensorflowAPI.operation_name(self) + end + + # @return [String] + def op_type() + TensorflowAPI.operation_op_type(self) + end + + # @return [String] + def device() + TensorflowAPI.operation_device(self) + end + + # @return [Integer] + def num_outputs() + TensorflowAPI.operation_num_outputs(self) + end + + # @param [String] arg_name + # @param [Status] status + # @return [Integer] + def output_list_length(arg_name, status) + TensorflowAPI.operation_output_list_length(self, arg_name, status) + end + + # @return [Integer] + def num_inputs() + TensorflowAPI.operation_num_inputs(self) + end + + # @param [String] arg_name + # @param [Status] status + # @return [Integer] + def input_list_length(arg_name, status) + TensorflowAPI.operation_input_list_length(self, arg_name, status) + end + + # @return [Integer] + def num_control_inputs() + TensorflowAPI.operation_num_control_inputs(self) + end + + # @param [FFI::Pointer(**Operation)] control_inputs + # @param [Integer] max_control_inputs + # @return [Integer] + def get_control_inputs(control_inputs, max_control_inputs) + TensorflowAPI.operation_get_control_inputs(self, control_inputs, max_control_inputs) + end + + # @return [Integer] + def num_control_outputs() + TensorflowAPI.operation_num_control_outputs(self) + end + + # @param [FFI::Pointer(**Operation)] control_outputs + # @param [Integer] max_control_outputs + # @return [Integer] + def get_control_outputs(control_outputs, max_control_outputs) + TensorflowAPI.operation_get_control_outputs(self, control_outputs, max_control_outputs) + end + + # @param [String] attr_name + # @param [Status] status + # @return [AttrMetadata] + def get_attr_metadata(attr_name, status) + TensorflowAPI.operation_get_attr_metadata(self, attr_name, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*Void)] value + # @param [Integer] max_length + # @param [Status] status + # @return [nil] + def get_attr_string(attr_name, value, max_length, status) + TensorflowAPI.operation_get_attr_string(self, attr_name, value, max_length, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(**Void)] values + # @param [FFI::Pointer(*SizeT)] lengths + # @param [Integer] max_values + # @param [FFI::Pointer(*Void)] storage + # @param [Integer] storage_size + # @param [Status] status + # @return [nil] + def get_attr_string_list(attr_name, values, lengths, max_values, storage, storage_size, status) + TensorflowAPI.operation_get_attr_string_list(self, attr_name, values, lengths, max_values, storage, storage_size, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*LongLong)] value + # @param [Status] status + # @return [nil] + def get_attr_int(attr_name, value, status) + TensorflowAPI.operation_get_attr_int(self, attr_name, value, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*LongLong)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + def get_attr_int_list(attr_name, values, max_values, status) + TensorflowAPI.operation_get_attr_int_list(self, attr_name, values, max_values, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*Float)] value + # @param [Status] status + # @return [nil] + def get_attr_float(attr_name, value, status) + TensorflowAPI.operation_get_attr_float(self, attr_name, value, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*Float)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + def get_attr_float_list(attr_name, values, max_values, status) + TensorflowAPI.operation_get_attr_float_list(self, attr_name, values, max_values, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*UChar)] value + # @param [Status] status + # @return [nil] + def get_attr_bool(attr_name, value, status) + TensorflowAPI.operation_get_attr_bool(self, attr_name, value, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*UChar)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + def get_attr_bool_list(attr_name, values, max_values, status) + TensorflowAPI.operation_get_attr_bool_list(self, attr_name, values, max_values, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*DataType)] value + # @param [Status] status + # @return [nil] + def get_attr_type(attr_name, value, status) + TensorflowAPI.operation_get_attr_type(self, attr_name, value, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*DataType)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + def get_attr_type_list(attr_name, values, max_values, status) + TensorflowAPI.operation_get_attr_type_list(self, attr_name, values, max_values, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(*LongLong)] value + # @param [Integer] num_dims + # @param [Status] status + # @return [nil] + def get_attr_shape(attr_name, value, num_dims, status) + TensorflowAPI.operation_get_attr_shape(self, attr_name, value, num_dims, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(**LongLong)] dims + # @param [FFI::Pointer(*Int)] num_dims + # @param [Integer] num_shapes + # @param [FFI::Pointer(*LongLong)] storage + # @param [Integer] storage_size + # @param [Status] status + # @return [nil] + def get_attr_shape_list(attr_name, dims, num_dims, num_shapes, storage, storage_size, status) + TensorflowAPI.operation_get_attr_shape_list(self, attr_name, dims, num_dims, num_shapes, storage, storage_size, status) + end + + # @param [String] attr_name + # @param [Buffer] value + # @param [Status] status + # @return [nil] + def get_attr_tensor_shape_proto(attr_name, value, status) + TensorflowAPI.operation_get_attr_tensor_shape_proto(self, attr_name, value, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(**Buffer)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + def get_attr_tensor_shape_proto_list(attr_name, values, max_values, status) + TensorflowAPI.operation_get_attr_tensor_shape_proto_list(self, attr_name, values, max_values, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(**Tensor)] value + # @param [Status] status + # @return [nil] + def get_attr_tensor(attr_name, value, status) + TensorflowAPI.operation_get_attr_tensor(self, attr_name, value, status) + end + + # @param [String] attr_name + # @param [FFI::Pointer(**Tensor)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + def get_attr_tensor_list(attr_name, values, max_values, status) + TensorflowAPI.operation_get_attr_tensor_list(self, attr_name, values, max_values, status) + end + + # @param [String] attr_name + # @param [Buffer] output_attr_value + # @param [Status] status + # @return [nil] + def get_attr_value_proto(attr_name, output_attr_value, status) + TensorflowAPI.operation_get_attr_value_proto(self, attr_name, output_attr_value, status) + end + + # @param [Buffer] output_node_def + # @param [Status] status + # @return [nil] + def to_node_def(output_node_def, status) + TensorflowAPI.operation_to_node_def(self, output_node_def, status) + end + end + + class Operation < FFI::Struct + include OperationWrappers + layout :dummy, :char + end + + # Represents a specific input of an operation. + # + # = Fields: + # :oper :: + # (Operation) + # :index :: + # (Integer) The index of the input within oper. + class Input < FFI::Struct + layout :oper, Operation, + :index, :int + end + + # Represents a specific output of an operation. + # + # = Fields: + # :oper :: + # (Operation) + # :index :: + # (Integer) The index of the output within oper. + class Output < FFI::Struct + layout :oper, Operation, + :index, :int + end + + # is incompatible with the existing shape). + # + # @method graph_set_tensor_shape(graph, output, dims, num_dims, status) + # @param [Graph] graph + # @param [Output] output + # @param [FFI::Pointer(*LongLong)] dims + # @param [Integer] num_dims + # @param [Status] status + # @return [nil] + # @scope class + attach_function :graph_set_tensor_shape, :TF_GraphSetTensorShape, [Graph, Output.by_value, :pointer, :int, Status], :void + + # * `output` is not in `graph`. + # + # @method graph_get_tensor_num_dims(graph, output, status) + # @param [Graph] graph + # @param [Output] output + # @param [Status] status + # @return [Integer] + # @scope class + attach_function :graph_get_tensor_num_dims, :TF_GraphGetTensorNumDims, [Graph, Output.by_value, Status], :int + + # * `num_dims` does not match the actual number of dimensions. + # + # @method graph_get_tensor_shape(graph, output, dims, num_dims, status) + # @param [Graph] graph + # @param [Output] output + # @param [FFI::Pointer(*LongLong)] dims + # @param [Integer] num_dims + # @param [Status] status + # @return [nil] + # @scope class + attach_function :graph_get_tensor_shape, :TF_GraphGetTensorShape, [Graph, Output.by_value, :pointer, :int, Status], :void + + # called. + # + # @method new_operation(graph, op_type, oper_name) + # @param [Graph] graph + # @param [String] op_type + # @param [String] oper_name + # @return [OperationDescription] + # @scope class + attach_function :new_operation, :TF_NewOperation, [Graph, :string, :string], OperationDescription + + # Specify the device for `desc`. Defaults to empty, meaning unconstrained. + # + # @method set_device(desc, device) + # @param [OperationDescription] desc + # @param [String] device + # @return [nil] + # @scope class + attach_function :set_device, :TF_SetDevice, [OperationDescription, :string], :void + + # For inputs that take a single tensor. + # + # @method add_input(desc, input) + # @param [OperationDescription] desc + # @param [Output] input + # @return [nil] + # @scope class + attach_function :add_input, :TF_AddInput, [OperationDescription, Output.by_value], :void + + # inputs must point to TF_Output(num_inputs). + # + # @method add_input_list(desc, inputs, num_inputs) + # @param [OperationDescription] desc + # @param [Output] inputs + # @param [Integer] num_inputs + # @return [nil] + # @scope class + attach_function :add_input_list, :TF_AddInputList, [OperationDescription, Output, :int], :void + + # Call once per control input to `desc`. + # + # @method add_control_input(desc, input) + # @param [OperationDescription] desc + # @param [Operation] input + # @return [nil] + # @scope class + attach_function :add_control_input, :TF_AddControlInput, [OperationDescription, Operation], :void + + # subject to change. Primarily intended for internal libraries + # + # @method colocate_with(desc, op) + # @param [OperationDescription] desc + # @param [Operation] op + # @return [nil] + # @scope class + attach_function :colocate_with, :TF_ColocateWith, [OperationDescription, Operation], :void + + # `value` must point to a string of length `length` bytes. + # + # @method set_attr_string(desc, attr_name, value, length) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(*Void)] value + # @param [Integer] length + # @return [nil] + # @scope class + attach_function :set_attr_string, :TF_SetAttrString, [OperationDescription, :string, :pointer, :ulong], :void + + # `values(i)` must point to a string of length `lengths(i)` bytes. + # + # @method set_attr_string_list(desc, attr_name, values, lengths, num_values) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(**Void)] values + # @param [FFI::Pointer(*SizeT)] lengths + # @param [Integer] num_values + # @return [nil] + # @scope class + attach_function :set_attr_string_list, :TF_SetAttrStringList, [OperationDescription, :string, :pointer, :pointer, :int], :void + + # (Not documented) + # + # @method set_attr_int(desc, attr_name, value) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [Integer] value + # @return [nil] + # @scope class + attach_function :set_attr_int, :TF_SetAttrInt, [OperationDescription, :string, :long_long], :void + + # (Not documented) + # + # @method set_attr_int_list(desc, attr_name, values, num_values) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(*LongLong)] values + # @param [Integer] num_values + # @return [nil] + # @scope class + attach_function :set_attr_int_list, :TF_SetAttrIntList, [OperationDescription, :string, :pointer, :int], :void + + # (Not documented) + # + # @method set_attr_float(desc, attr_name, value) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [Float] value + # @return [nil] + # @scope class + attach_function :set_attr_float, :TF_SetAttrFloat, [OperationDescription, :string, :float], :void + + # (Not documented) + # + # @method set_attr_float_list(desc, attr_name, values, num_values) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(*Float)] values + # @param [Integer] num_values + # @return [nil] + # @scope class + attach_function :set_attr_float_list, :TF_SetAttrFloatList, [OperationDescription, :string, :pointer, :int], :void + + # (Not documented) + # + # @method set_attr_bool(desc, attr_name, value) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [Integer] value + # @return [nil] + # @scope class + attach_function :set_attr_bool, :TF_SetAttrBool, [OperationDescription, :string, :uchar], :void + + # (Not documented) + # + # @method set_attr_bool_list(desc, attr_name, values, num_values) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(*UChar)] values + # @param [Integer] num_values + # @return [nil] + # @scope class + attach_function :set_attr_bool_list, :TF_SetAttrBoolList, [OperationDescription, :string, :pointer, :int], :void + + # (Not documented) + # + # @method set_attr_type(desc, attr_name, value) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [Symbol from _enum_data_type_] value + # @return [nil] + # @scope class + attach_function :set_attr_type, :TF_SetAttrType, [OperationDescription, :string, :data_type], :void + + # (Not documented) + # + # @method set_attr_type_list(desc, attr_name, values, num_values) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(*DataType)] values + # @param [Integer] num_values + # @return [nil] + # @scope class + attach_function :set_attr_type_list, :TF_SetAttrTypeList, [OperationDescription, :string, :pointer, :int], :void + + # >= -1, with -1 meaning "unknown dimension". + # + # @method set_attr_shape(desc, attr_name, dims, num_dims) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(*LongLong)] dims + # @param [Integer] num_dims + # @return [nil] + # @scope class + attach_function :set_attr_shape, :TF_SetAttrShape, [OperationDescription, :string, :pointer, :int], :void + + # must be >= -1, with -1 meaning "unknown dimension". + # + # @method set_attr_shape_list(desc, attr_name, dims, num_dims, num_shapes) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(**LongLong)] dims + # @param [FFI::Pointer(*Int)] num_dims + # @param [Integer] num_shapes + # @return [nil] + # @scope class + attach_function :set_attr_shape_list, :TF_SetAttrShapeList, [OperationDescription, :string, :pointer, :pointer, :int], :void + + # binary-serialized TensorShapeProto. + # + # @method set_attr_tensor_shape_proto(desc, attr_name, proto, proto_len, status) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(*Void)] proto + # @param [Integer] proto_len + # @param [Status] status + # @return [nil] + # @scope class + attach_function :set_attr_tensor_shape_proto, :TF_SetAttrTensorShapeProto, [OperationDescription, :string, :pointer, :ulong, Status], :void + + # representing a binary-serialized TensorShapeProto. + # + # @method set_attr_tensor_shape_proto_list(desc, attr_name, protos, proto_lens, num_shapes, status) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(**Void)] protos + # @param [FFI::Pointer(*SizeT)] proto_lens + # @param [Integer] num_shapes + # @param [Status] status + # @return [nil] + # @scope class + attach_function :set_attr_tensor_shape_proto_list, :TF_SetAttrTensorShapeProtoList, [OperationDescription, :string, :pointer, :pointer, :int, Status], :void + + # (Not documented) + # + # @method set_attr_tensor(desc, attr_name, value, status) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [Tensor] value + # @param [Status] status + # @return [nil] + # @scope class + attach_function :set_attr_tensor, :TF_SetAttrTensor, [OperationDescription, :string, Tensor, Status], :void + + # (Not documented) + # + # @method set_attr_tensor_list(desc, attr_name, values, num_values, status) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(**Tensor)] values + # @param [Integer] num_values + # @param [Status] status + # @return [nil] + # @scope class + attach_function :set_attr_tensor_list, :TF_SetAttrTensorList, [OperationDescription, :string, :pointer, :int, Status], :void + + # buffer. + # + # @method set_attr_value_proto(desc, attr_name, proto, proto_len, status) + # @param [OperationDescription] desc + # @param [String] attr_name + # @param [FFI::Pointer(*Void)] proto + # @param [Integer] proto_len + # @param [Status] status + # @return [nil] + # @scope class + attach_function :set_attr_value_proto, :TF_SetAttrValueProto, [OperationDescription, :string, :pointer, :ulong, Status], :void + + # In either case, it deletes `desc`. + # + # @method finish_operation(desc, status) + # @param [OperationDescription] desc + # @param [Status] status + # @return [Operation] + # @scope class + attach_function :finish_operation, :TF_FinishOperation, [OperationDescription, Status], Operation + + # these are all query functions. + # + # @method operation_name(oper) + # @param [Operation] oper + # @return [String] + # @scope class + attach_function :operation_name, :TF_OperationName, [Operation], :string + + # (Not documented) + # + # @method operation_op_type(oper) + # @param [Operation] oper + # @return [String] + # @scope class + attach_function :operation_op_type, :TF_OperationOpType, [Operation], :string + + # (Not documented) + # + # @method operation_device(oper) + # @param [Operation] oper + # @return [String] + # @scope class + attach_function :operation_device, :TF_OperationDevice, [Operation], :string + + # (Not documented) + # + # @method operation_num_outputs(oper) + # @param [Operation] oper + # @return [Integer] + # @scope class + attach_function :operation_num_outputs, :TF_OperationNumOutputs, [Operation], :int + + # (Not documented) + # + # @method operation_output_type(oper_out) + # @param [Output] oper_out + # @return [Symbol from _enum_data_type_] + # @scope class + attach_function :operation_output_type, :TF_OperationOutputType, [Output.by_value], :data_type + + # (Not documented) + # + # @method operation_output_list_length(oper, arg_name, status) + # @param [Operation] oper + # @param [String] arg_name + # @param [Status] status + # @return [Integer] + # @scope class + attach_function :operation_output_list_length, :TF_OperationOutputListLength, [Operation, :string, Status], :int + + # (Not documented) + # + # @method operation_num_inputs(oper) + # @param [Operation] oper + # @return [Integer] + # @scope class + attach_function :operation_num_inputs, :TF_OperationNumInputs, [Operation], :int + + # (Not documented) + # + # @method operation_input_type(oper_in) + # @param [Input] oper_in + # @return [Symbol from _enum_data_type_] + # @scope class + attach_function :operation_input_type, :TF_OperationInputType, [Input.by_value], :data_type + + # (Not documented) + # + # @method operation_input_list_length(oper, arg_name, status) + # @param [Operation] oper + # @param [String] arg_name + # @param [Status] status + # @return [Integer] + # @scope class + attach_function :operation_input_list_length, :TF_OperationInputListLength, [Operation, :string, Status], :int + + # producer.index) to consumer.oper's input (given by consumer.index). + # + # @method operation_input(oper_in) + # @param [Input] oper_in + # @return [Output] + # @scope class + attach_function :operation_input, :TF_OperationInput, [Input.by_value], Output.by_value + + # are added to the graph. + # + # @method operation_output_num_consumers(oper_out) + # @param [Output] oper_out + # @return [Integer] + # @scope class + attach_function :operation_output_num_consumers, :TF_OperationOutputNumConsumers, [Output.by_value], :int + + # TF_OperationOutputNumConsumers(oper_out)). + # + # @method operation_output_consumers(oper_out, consumers, max_consumers) + # @param [Output] oper_out + # @param [Input] consumers + # @param [Integer] max_consumers + # @return [Integer] + # @scope class + attach_function :operation_output_consumers, :TF_OperationOutputConsumers, [Output.by_value, Input, :int], :int + + # Get the number of control inputs to an operation. + # + # @method operation_num_control_inputs(oper) + # @param [Operation] oper + # @return [Integer] + # @scope class + attach_function :operation_num_control_inputs, :TF_OperationNumControlInputs, [Operation], :int + + # inputs (should match TF_OperationNumControlInputs(oper)). + # + # @method operation_get_control_inputs(oper, control_inputs, max_control_inputs) + # @param [Operation] oper + # @param [FFI::Pointer(**Operation)] control_inputs + # @param [Integer] max_control_inputs + # @return [Integer] + # @scope class + attach_function :operation_get_control_inputs, :TF_OperationGetControlInputs, [Operation, :pointer, :int], :int + + # the graph. + # + # @method operation_num_control_outputs(oper) + # @param [Operation] oper + # @return [Integer] + # @scope class + attach_function :operation_num_control_outputs, :TF_OperationNumControlOutputs, [Operation], :int + + # TF_OperationNumControlOutputs(oper)). + # + # @method operation_get_control_outputs(oper, control_outputs, max_control_outputs) + # @param [Operation] oper + # @param [FFI::Pointer(**Operation)] control_outputs + # @param [Integer] max_control_outputs + # @return [Integer] + # @scope class + attach_function :operation_get_control_outputs, :TF_OperationGetControlOutputs, [Operation, :pointer, :int], :int + + # TF_AttrType describes the type of the value of an attribute on an operation. + # + # This entry is only for documentation and no real method. The FFI::Enum can be accessed via #enum_type(:attr_type). + # + # === Options: + # :string :: + # + # :int :: + # + # :float :: + # + # :bool :: + # + # :type :: + # + # :shape :: + # + # :tensor :: + # + # :placeholder :: + # + # :func :: + # + # + # @method _enum_attr_type_ + # @return [Symbol] + # @scope class + enum :attr_type, [ + :string, 0, + :int, 1, + :float, 2, + :bool, 3, + :type, 4, + :shape, 5, + :tensor, 6, + :placeholder, 7, + :func, 8 + ] + + # TF_AttrMetadata describes the value of an attribute on an operation. + # + # = Fields: + # :is_list :: + # (Integer) A boolean: 1 if the attribute value is a list, 0 otherwise. + # :list_size :: + # (Integer) Length of the list if is_list is true. Undefined otherwise. + # :type :: + # (Symbol from _enum_attr_type_) Type of the single value stored in the attribute if is_list == 0. + # :total_size :: + # (Integer) (5) Otherwise, total_size is undefined. + class AttrMetadata < FFI::Struct + layout :is_list, :uchar, + :list_size, :long_long, + :type, :attr_type, + :total_size, :long_long + end + + # Returns metadata about the value of the attribute `attr_name` of `oper`. + # + # @method operation_get_attr_metadata(oper, attr_name, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [Status] status + # @return [AttrMetadata] + # @scope class + attach_function :operation_get_attr_metadata, :TF_OperationGetAttrMetadata, [Operation, :string, Status], AttrMetadata.by_value + + # attr_name)). + # + # @method operation_get_attr_string(oper, attr_name, value, max_length, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*Void)] value + # @param [Integer] max_length + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_string, :TF_OperationGetAttrString, [Operation, :string, :pointer, :ulong, Status], :void + + # Fails if storage_size is too small to hold the requested number of strings. + # + # @method operation_get_attr_string_list(oper, attr_name, values, lengths, max_values, storage, storage_size, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(**Void)] values + # @param [FFI::Pointer(*SizeT)] lengths + # @param [Integer] max_values + # @param [FFI::Pointer(*Void)] storage + # @param [Integer] storage_size + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_string_list, :TF_OperationGetAttrStringList, [Operation, :string, :pointer, :pointer, :int, :pointer, :ulong, Status], :void + + # (Not documented) + # + # @method operation_get_attr_int(oper, attr_name, value, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*LongLong)] value + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_int, :TF_OperationGetAttrInt, [Operation, :string, :pointer, Status], :void + + # attr_name)). + # + # @method operation_get_attr_int_list(oper, attr_name, values, max_values, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*LongLong)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_int_list, :TF_OperationGetAttrIntList, [Operation, :string, :pointer, :int, Status], :void + + # (Not documented) + # + # @method operation_get_attr_float(oper, attr_name, value, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*Float)] value + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_float, :TF_OperationGetAttrFloat, [Operation, :string, :pointer, Status], :void + + # attr_name)). + # + # @method operation_get_attr_float_list(oper, attr_name, values, max_values, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*Float)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_float_list, :TF_OperationGetAttrFloatList, [Operation, :string, :pointer, :int, Status], :void + + # (Not documented) + # + # @method operation_get_attr_bool(oper, attr_name, value, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*UChar)] value + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_bool, :TF_OperationGetAttrBool, [Operation, :string, :pointer, Status], :void + + # attr_name)). + # + # @method operation_get_attr_bool_list(oper, attr_name, values, max_values, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*UChar)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_bool_list, :TF_OperationGetAttrBoolList, [Operation, :string, :pointer, :int, Status], :void + + # (Not documented) + # + # @method operation_get_attr_type(oper, attr_name, value, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*DataType)] value + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_type, :TF_OperationGetAttrType, [Operation, :string, :pointer, Status], :void + + # attr_name)). + # + # @method operation_get_attr_type_list(oper, attr_name, values, max_values, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*DataType)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_type_list, :TF_OperationGetAttrTypeList, [Operation, :string, :pointer, :int, Status], :void + + # TF_Attr_Meta.size from TF_OperationGetAttrMetadata(oper, attr_name)). + # + # @method operation_get_attr_shape(oper, attr_name, value, num_dims, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(*LongLong)] value + # @param [Integer] num_dims + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_shape, :TF_OperationGetAttrShape, [Operation, :string, :pointer, :int, Status], :void + + # Fails if storage_size is insufficient to hold the requested shapes. + # + # @method operation_get_attr_shape_list(oper, attr_name, dims, num_dims, num_shapes, storage, storage_size, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(**LongLong)] dims + # @param [FFI::Pointer(*Int)] num_dims + # @param [Integer] num_shapes + # @param [FFI::Pointer(*LongLong)] storage + # @param [Integer] storage_size + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_shape_list, :TF_OperationGetAttrShapeList, [Operation, :string, :pointer, :pointer, :int, :pointer, :int, Status], :void + + # `attr_name` attribute of `oper`'. + # + # @method operation_get_attr_tensor_shape_proto(oper, attr_name, value, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [Buffer] value + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_tensor_shape_proto, :TF_OperationGetAttrTensorShapeProto, [Operation, :string, Buffer, Status], :void + + # TF_OperationGetAttrMetadata(oper, attr_name)). + # + # @method operation_get_attr_tensor_shape_proto_list(oper, attr_name, values, max_values, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(**Buffer)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_tensor_shape_proto_list, :TF_OperationGetAttrTensorShapeProtoList, [Operation, :string, :pointer, :int, Status], :void + + # ownership of (and can deallocate using TF_DeleteTensor). + # + # @method operation_get_attr_tensor(oper, attr_name, value, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(**Tensor)] value + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_tensor, :TF_OperationGetAttrTensor, [Operation, :string, :pointer, Status], :void + + # (which can be deleted using TF_DeleteTensor(values(i))). + # + # @method operation_get_attr_tensor_list(oper, attr_name, values, max_values, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [FFI::Pointer(**Tensor)] values + # @param [Integer] max_values + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_tensor_list, :TF_OperationGetAttrTensorList, [Operation, :string, :pointer, :int, Status], :void + + # representation of the value of the `attr_name` attr of `oper`. + # + # @method operation_get_attr_value_proto(oper, attr_name, output_attr_value, status) + # @param [Operation] oper + # @param [String] attr_name + # @param [Buffer] output_attr_value + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_get_attr_value_proto, :TF_OperationGetAttrValueProto, [Operation, :string, Buffer, Status], :void + + # no operation found. + # + # @method graph_operation_by_name(graph, oper_name) + # @param [Graph] graph + # @param [String] oper_name + # @return [Operation] + # @scope class + attach_function :graph_operation_by_name, :TF_GraphOperationByName, [Graph, :string], Operation + + # } + # + # @method graph_next_operation(graph, pos) + # @param [Graph] graph + # @param [FFI::Pointer(*SizeT)] pos + # @return [Operation] + # @scope class + attach_function :graph_next_operation, :TF_GraphNextOperation, [Graph, :pointer], Operation + + # May fail on very large graphs in the future. + # + # @method graph_to_graph_def(graph, output_graph_def, status) + # @param [Graph] graph + # @param [Buffer] output_graph_def + # @param [Status] status + # @return [nil] + # @scope class + attach_function :graph_to_graph_def, :TF_GraphToGraphDef, [Graph, Buffer, Status], :void + + # TF_GraphImportGraphDef. + module ImportGraphDefOptionsWrappers + # @param [String] prefix + # @return [nil] + def set_prefix(prefix) + TensorflowAPI.import_graph_def_options_set_prefix(self, prefix) + end + + # @param [String] src_name + # @param [Integer] src_index + # @param [Output] dst + # @return [nil] + def add_input_mapping(src_name, src_index, dst) + TensorflowAPI.import_graph_def_options_add_input_mapping(self, src_name, src_index, dst) + end + + # @param [Operation] oper + # @return [nil] + def add_control_dependency(oper) + TensorflowAPI.import_graph_def_options_add_control_dependency(self, oper) + end + + # @param [String] oper_name + # @param [Integer] index + # @return [nil] + def add_return_output(oper_name, index) + TensorflowAPI.import_graph_def_options_add_return_output(self, oper_name, index) + end + + # @return [Integer] + def num_return_outputs() + TensorflowAPI.import_graph_def_options_num_return_outputs(self) + end + end + + class ImportGraphDefOptions < FFI::Struct + include ImportGraphDefOptionsWrappers + layout :dummy, :char + end + + # (Not documented) + # + # @method new_import_graph_def_options() + # @return [ImportGraphDefOptions] + # @scope class + attach_function :new_import_graph_def_options, :TF_NewImportGraphDefOptions, [], ImportGraphDefOptions + + # (Not documented) + # + # @method delete_import_graph_def_options(opts) + # @param [ImportGraphDefOptions] opts + # @return [nil] + # @scope class + attach_function :delete_import_graph_def_options, :TF_DeleteImportGraphDefOptions, [ImportGraphDefOptions], :void + + # be imported into `graph`. + # + # @method import_graph_def_options_set_prefix(opts, prefix) + # @param [ImportGraphDefOptions] opts + # @param [String] prefix + # @return [nil] + # @scope class + attach_function :import_graph_def_options_set_prefix, :TF_ImportGraphDefOptionsSetPrefix, [ImportGraphDefOptions, :string], :void + + # `dst` references a node already existing in the graph being imported into. + # + # @method import_graph_def_options_add_input_mapping(opts, src_name, src_index, dst) + # @param [ImportGraphDefOptions] opts + # @param [String] src_name + # @param [Integer] src_index + # @param [Output] dst + # @return [nil] + # @scope class + attach_function :import_graph_def_options_add_input_mapping, :TF_ImportGraphDefOptionsAddInputMapping, [ImportGraphDefOptions, :string, :int, Output.by_value], :void + + # should exist in the graph being imported into. + # + # @method import_graph_def_options_add_control_dependency(opts, oper) + # @param [ImportGraphDefOptions] opts + # @param [Operation] oper + # @return [nil] + # @scope class + attach_function :import_graph_def_options_add_control_dependency, :TF_ImportGraphDefOptionsAddControlDependency, [ImportGraphDefOptions, Operation], :void + + # mapping, the corresponding existing tensor in `graph` will be returned. + # + # @method import_graph_def_options_add_return_output(opts, oper_name, index) + # @param [ImportGraphDefOptions] opts + # @param [String] oper_name + # @param [Integer] index + # @return [nil] + # @scope class + attach_function :import_graph_def_options_add_return_output, :TF_ImportGraphDefOptionsAddReturnOutput, [ImportGraphDefOptions, :string, :int], :void + + # TF_ImportGraphDefOptionsAddReturnOutput(). + # + # @method import_graph_def_options_num_return_outputs(opts) + # @param [ImportGraphDefOptions] opts + # @return [Integer] + # @scope class + attach_function :import_graph_def_options_num_return_outputs, :TF_ImportGraphDefOptionsNumReturnOutputs, [ImportGraphDefOptions], :int + + # `num_return_outputs`. Otherwise it can be null. + # + # @method graph_import_graph_def_with_return_outputs(graph, graph_def, options, return_outputs, num_return_outputs, status) + # @param [Graph] graph + # @param [Buffer] graph_def + # @param [ImportGraphDefOptions] options + # @param [Output] return_outputs + # @param [Integer] num_return_outputs + # @param [Status] status + # @return [nil] + # @scope class + attach_function :graph_import_graph_def_with_return_outputs, :TF_GraphImportGraphDefWithReturnOutputs, [Graph, Buffer, ImportGraphDefOptions, Output, :int, Status], :void + + # Convenience function for when no return outputs have been added. + # + # @method graph_import_graph_def(graph, graph_def, options, status) + # @param [Graph] graph + # @param [Buffer] graph_def + # @param [ImportGraphDefOptions] options + # @param [Status] status + # @return [nil] + # @scope class + attach_function :graph_import_graph_def, :TF_GraphImportGraphDef, [Graph, Buffer, ImportGraphDefOptions, Status], :void + + # Note: The following function may fail on very large protos in the future. + # + # @method operation_to_node_def(oper, output_node_def, status) + # @param [Operation] oper + # @param [Buffer] output_node_def + # @param [Status] status + # @return [nil] + # @scope class + attach_function :operation_to_node_def, :TF_OperationToNodeDef, [Operation, Buffer, Status], :void + + # API for driving Graph execution. + module SessionWrappers + # @param [Buffer] run_options + # @param [Output] inputs + # @param [FFI::Pointer(**Tensor)] input_values + # @param [Integer] ninputs + # @param [Output] outputs + # @param [FFI::Pointer(**Tensor)] output_values + # @param [Integer] noutputs + # @param [FFI::Pointer(**Operation)] target_opers + # @param [Integer] ntargets + # @param [Buffer] run_metadata + # @param [Status] status + # @return [nil] + def run(run_options, inputs, input_values, ninputs, outputs, output_values, noutputs, target_opers, ntargets, run_metadata, status) + TensorflowAPI.session_run(self, run_options, inputs, input_values, ninputs, outputs, output_values, noutputs, target_opers, ntargets, run_metadata, status) + end + + # @param [Output] inputs + # @param [Integer] ninputs + # @param [Output] outputs + # @param [Integer] noutputs + # @param [FFI::Pointer(**Operation)] target_opers + # @param [Integer] ntargets + # @param [FFI::Pointer(**CharS)] handle + # @param [Status] status + # @return [nil] + def p_run_setup(inputs, ninputs, outputs, noutputs, target_opers, ntargets, handle, status) + TensorflowAPI.session_p_run_setup(self, inputs, ninputs, outputs, noutputs, target_opers, ntargets, handle, status) + end + + # @param [String] handle + # @param [Output] inputs + # @param [FFI::Pointer(**Tensor)] input_values + # @param [Integer] ninputs + # @param [Output] outputs + # @param [FFI::Pointer(**Tensor)] output_values + # @param [Integer] noutputs + # @param [FFI::Pointer(**Operation)] target_opers + # @param [Integer] ntargets + # @param [Status] status + # @return [nil] + def p_run(handle, inputs, input_values, ninputs, outputs, output_values, noutputs, target_opers, ntargets, status) + TensorflowAPI.session_p_run(self, handle, inputs, input_values, ninputs, outputs, output_values, noutputs, target_opers, ntargets, status) + end + end + + class Session < FFI::Struct + include SessionWrappers + layout :dummy, :char + end + + # Does not take ownership of opts. + # + # @method new_session(graph, opts, status) + # @param [Graph] graph + # @param [SessionOptions] opts + # @param [Status] status + # @return [Session] + # @scope class + attach_function :new_session, :TF_NewSession, [Graph, SessionOptions, Status], Session + + # `meta_graph_def` with the MetaGraphDef of the loaded model. + # + # @method load_session_from_saved_model(session_options, run_options, export_dir, tags, tags_len, graph, meta_graph_def, status) + # @param [SessionOptions] session_options + # @param [Buffer] run_options + # @param [String] export_dir + # @param [FFI::Pointer(**CharS)] tags + # @param [Integer] tags_len + # @param [Graph] graph + # @param [Buffer] meta_graph_def + # @param [Status] status + # @return [Session] + # @scope class + attach_function :load_session_from_saved_model, :TF_LoadSessionFromSavedModel, [SessionOptions, Buffer, :string, :pointer, :int, Graph, Buffer, Status], Session + + # May not be called after TF_DeleteSession(). + # + # @method close_session(session, status) + # @param [Session] session + # @param [Status] status + # @return [nil] + # @scope class + attach_function :close_session, :TF_CloseSession, [Session, Status], :void + + # corresponding graph). + # + # @method delete_session(session, status) + # @param [Session] session + # @param [Status] status + # @return [nil] + # @scope class + attach_function :delete_session, :TF_DeleteSession, [Session, Status], :void + + # On failure, output_values() contains NULLs. + # + # @method session_run(session, run_options, inputs, input_values, ninputs, outputs, output_values, noutputs, target_opers, ntargets, run_metadata, status) + # @param [Session] session + # @param [Buffer] run_options + # @param [Output] inputs + # @param [FFI::Pointer(**Tensor)] input_values + # @param [Integer] ninputs + # @param [Output] outputs + # @param [FFI::Pointer(**Tensor)] output_values + # @param [Integer] noutputs + # @param [FFI::Pointer(**Operation)] target_opers + # @param [Integer] ntargets + # @param [Buffer] run_metadata + # @param [Status] status + # @return [nil] + # @scope class + attach_function :session_run, :TF_SessionRun, [Session, Buffer, Output, :pointer, :int, Output, :pointer, :int, :pointer, :int, Buffer, Status], :void + + # NOTE: This is EXPERIMENTAL and subject to change. + # + # @method session_p_run_setup(session, inputs, ninputs, outputs, noutputs, target_opers, ntargets, handle, status) + # @param [Session] session + # @param [Output] inputs + # @param [Integer] ninputs + # @param [Output] outputs + # @param [Integer] noutputs + # @param [FFI::Pointer(**Operation)] target_opers + # @param [Integer] ntargets + # @param [FFI::Pointer(**CharS)] handle + # @param [Status] status + # @return [nil] + # @scope class + attach_function :session_p_run_setup, :TF_SessionPRunSetup, [Session, Output, :int, Output, :int, :pointer, :int, :pointer, Status], :void + + # NOTE: This is EXPERIMENTAL and subject to change. + # + # @method session_p_run(session, handle, inputs, input_values, ninputs, outputs, output_values, noutputs, target_opers, ntargets, status) + # @param [Session] session + # @param [String] handle + # @param [Output] inputs + # @param [FFI::Pointer(**Tensor)] input_values + # @param [Integer] ninputs + # @param [Output] outputs + # @param [FFI::Pointer(**Tensor)] output_values + # @param [Integer] noutputs + # @param [FFI::Pointer(**Operation)] target_opers + # @param [Integer] ntargets + # @param [Status] status + # @return [nil] + # @scope class + attach_function :session_p_run, :TF_SessionPRun, [Session, :string, Output, :pointer, :int, Output, :pointer, :int, :pointer, :int, Status], :void + + # Once called, no more calls to TF_SessionPRun should be made. + # + # @method delete_p_run_handle(handle) + # @param [String] handle + # @return [nil] + # @scope class + attach_function :delete_p_run_handle, :TF_DeletePRunHandle, [:string], :void + + # notice. + class DeprecatedSession < FFI::Struct + layout :dummy, :char + end + + # (Not documented) + # + # @method new_deprecated_session(session_options, status) + # @param [SessionOptions] session_options + # @param [Status] status + # @return [DeprecatedSession] + # @scope class + attach_function :new_deprecated_session, :TF_NewDeprecatedSession, [SessionOptions, Status], DeprecatedSession + + # (Not documented) + # + # @method close_deprecated_session(deprecated_session, status) + # @param [DeprecatedSession] deprecated_session + # @param [Status] status + # @return [nil] + # @scope class + attach_function :close_deprecated_session, :TF_CloseDeprecatedSession, [DeprecatedSession, Status], :void + + # (Not documented) + # + # @method delete_deprecated_session(deprecated_session, status) + # @param [DeprecatedSession] deprecated_session + # @param [Status] status + # @return [nil] + # @scope class + attach_function :delete_deprecated_session, :TF_DeleteDeprecatedSession, [DeprecatedSession, Status], :void + + # (Not documented) + # + # @method reset(opt, containers, ncontainers, status) + # @param [SessionOptions] opt + # @param [FFI::Pointer(**CharS)] containers + # @param [Integer] ncontainers + # @param [Status] status + # @return [nil] + # @scope class + attach_function :reset, :TF_Reset, [SessionOptions, :pointer, :int, Status], :void + + # Prefer use of TF_Session and TF_GraphImportGraphDef over this. + # + # @method extend_graph(deprecated_session, proto, proto_len, status) + # @param [DeprecatedSession] deprecated_session + # @param [FFI::Pointer(*Void)] proto + # @param [Integer] proto_len + # @param [Status] status + # @return [nil] + # @scope class + attach_function :extend_graph, :TF_ExtendGraph, [DeprecatedSession, :pointer, :ulong, Status], :void + + # See TF_SessionRun() above. + # + # @method run(deprecated_session, run_options, input_names, inputs, ninputs, output_names, outputs, noutputs, target_oper_names, ntargets, run_metadata, status) + # @param [DeprecatedSession] deprecated_session + # @param [Buffer] run_options + # @param [FFI::Pointer(**CharS)] input_names + # @param [FFI::Pointer(**Tensor)] inputs + # @param [Integer] ninputs + # @param [FFI::Pointer(**CharS)] output_names + # @param [FFI::Pointer(**Tensor)] outputs + # @param [Integer] noutputs + # @param [FFI::Pointer(**CharS)] target_oper_names + # @param [Integer] ntargets + # @param [Buffer] run_metadata + # @param [Status] status + # @return [nil] + # @scope class + attach_function :run, :TF_Run, [DeprecatedSession, Buffer, :pointer, :pointer, :int, :pointer, :pointer, :int, :pointer, :int, Buffer, Status], :void + + # See TF_SessionPRunSetup() above. + # + # @method p_run_setup(deprecated_session, input_names, ninputs, output_names, noutputs, target_oper_names, ntargets, handle, status) + # @param [DeprecatedSession] deprecated_session + # @param [FFI::Pointer(**CharS)] input_names + # @param [Integer] ninputs + # @param [FFI::Pointer(**CharS)] output_names + # @param [Integer] noutputs + # @param [FFI::Pointer(**CharS)] target_oper_names + # @param [Integer] ntargets + # @param [FFI::Pointer(**CharS)] handle + # @param [Status] status + # @return [nil] + # @scope class + attach_function :p_run_setup, :TF_PRunSetup, [DeprecatedSession, :pointer, :int, :pointer, :int, :pointer, :int, :pointer, Status], :void + + # See TF_SessionPRun above. + # + # @method p_run(deprecated_session, handle, input_names, inputs, ninputs, output_names, outputs, noutputs, target_oper_names, ntargets, status) + # @param [DeprecatedSession] deprecated_session + # @param [String] handle + # @param [FFI::Pointer(**CharS)] input_names + # @param [FFI::Pointer(**Tensor)] inputs + # @param [Integer] ninputs + # @param [FFI::Pointer(**CharS)] output_names + # @param [FFI::Pointer(**Tensor)] outputs + # @param [Integer] noutputs + # @param [FFI::Pointer(**CharS)] target_oper_names + # @param [Integer] ntargets + # @param [Status] status + # @return [nil] + # @scope class + attach_function :p_run, :TF_PRun, [DeprecatedSession, :string, :pointer, :pointer, :int, :pointer, :pointer, :int, :pointer, :int, Status], :void + + # TF_Library holds information about dynamically loaded TensorFlow plugins. + class Library < FFI::Struct + layout :dummy, :char + end + + # On failure, place an error status in status and return NULL. + # + # @method load_library(library_filename, status) + # @param [String] library_filename + # @param [Status] status + # @return [Library] + # @scope class + attach_function :load_library, :TF_LoadLibrary, [:string, Status], Library + + # ops defined in the library. + # + # @method get_op_list(lib_handle) + # @param [Library] lib_handle + # @return [Buffer] + # @scope class + attach_function :get_op_list, :TF_GetOpList, [Library], Buffer.by_value + + # Does NOT unload the library. + # + # @method delete_library_handle(lib_handle) + # @param [Library] lib_handle + # @return [nil] + # @scope class + attach_function :delete_library_handle, :TF_DeleteLibraryHandle, [Library], :void + + # in this address space. + # + # @method get_all_op_list() + # @return [Buffer] + # @scope class + attach_function :get_all_op_list, :TF_GetAllOpList, [], Buffer + +end diff --git a/lib/tensorflow/tensorflow_wrap.rb b/lib/tensorflow/tensorflow_wrap.rb new file mode 100644 index 0000000..393846a --- /dev/null +++ b/lib/tensorflow/tensorflow_wrap.rb @@ -0,0 +1,32 @@ +require 'tensorflow/tensorflow_api' + +module Tensorflow + TensorflowAPI.enum_type(:data_type).to_h.each do |k,v| + const_set "TF_" + k.to_s.upcase, v + end + + def self.String_encoder(string, offset) + nbytes = 8 + TensorflowAPI.string_encoded_size(string.length) + shapePtr = FFI::MemoryPointer.new(:long_long, 1) + + tensor = TensorflowAPI.allocate_tensor(TF_STRING, shapePtr, 0, nbytes) + cbytes = TensorflowAPI.tensor_data(tensor) + length = TensorflowAPI.tensor_byte_size(tensor) + + src_len = string.length; + dst_len = src_len+1 + + offset_num = offset.to_i.abs + cbytes.write_long_long(offset_num) + dst_str = cbytes+8; + status = TensorflowAPI.new_status + TensorflowAPI::string_encode(string, src_len, dst_str, dst_len, status) + tensor + end + + def self.input(operation, index) + output = TensorflowAPI::Output.new + output[:oper] = operation + output[:index] = index + end +end \ No newline at end of file diff --git a/tools/generate_ffi.rb b/tools/generate_ffi.rb new file mode 100644 index 0000000..788d15a --- /dev/null +++ b/tools/generate_ffi.rb @@ -0,0 +1,13 @@ +# May need to specify paths to libs and llvm, as follows: +# LD_LIBRARY_PATH=/Applications/Xcode.app/Contents/Frameworks/ PATH=$PATH:/usr/local/Cellar/llvm/4.0.0_1/bin/ ruby tools/generate_ffi.rb + +require "ffi_gen" + +FFIGen.generate( + module_name: "TensorflowAPI", + ffi_lib: "tensorflow", + headers: ["ext/sciruby/tensorflow_c/files/tensor_c_api.h"], + cflags: `llvm-config --cflags`.split(" "), + prefixes: ["TF_", "TensorFlow"], + output: "lib/tensorflow/tensorflow_api.rb" +)