Class: Graph

Inherits:
Object
  • Object
show all
Defined in:
lib/graph.rb

Overview

A TensorFlow computation, represented as a dataflow graph. A Graph contains a set of Operation objects, which represent units of computation; and Tensor objects, which represent the units of data that flow between operations.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGraph

Returns a new instance of Graph.


6
7
8
9
# File 'lib/graph.rb', line 6

def initialize()
	self.availableOps = loadAvailableOps()
  self.graph_def = Tensorflow::GraphDef.new() 
end

Instance Attribute Details

#availableOpsObject

Returns the value of attribute availableOps


5
6
7
# File 'lib/graph.rb', line 5

def availableOps
  @availableOps
end

#constantsObject

Returns the value of attribute constants


5
6
7
# File 'lib/graph.rb', line 5

def constants
  @constants
end

#graph_defObject

Returns the value of attribute graph_def


5
6
7
# File 'lib/graph.rb', line 5

def graph_def
  @graph_def
end

#graph_def_rawObject

Returns the value of attribute graph_def_raw


5
6
7
# File 'lib/graph.rb', line 5

def graph_def_raw
  @graph_def_raw
end

#opObject

Returns the value of attribute op


5
6
7
# File 'lib/graph.rb', line 5

def op
  @op
end

#placeholder(name, type_enum, dims) ⇒ Object

adds a placeholder to the Graph, a placeholder is an operation that must be fed with data on execution.


43
44
45
# File 'lib/graph.rb', line 43

def placeholder
  @placeholder
end

#variablesObject

Returns the value of attribute variables


5
6
7
# File 'lib/graph.rb', line 5

def variables
  @variables
end

Instance Method Details

#graph_from_reader(filename) ⇒ Object

Loads a graph stored in pb file into a graph def. This way you can define the graph in python / ruby, save it in pb file and load it in ruby. The limitation of google-protoc gem is that it can only read binary wire format for protocol buffer messages In order to debug convoluted messages in ruby its always a good idea to convert the format to a readable form using pb_to_pbtxt.py file in the gem and specifying the file name of the .pb file to be converted.


35
36
37
38
39
# File 'lib/graph.rb', line 35

def graph_from_reader(filename)
	reader = File.read(filename)
	self.graph_def = Tensorflow::GraphDef.decode(reader)
  self.graph_def_raw = reader
end

#loadAvailableOpsObject

Loads the available ops from ops.pb file and then decodes into a list of operations.

  • Returns :

    • A hashmap with name of the op as key and value as the op.


17
18
19
20
21
22
23
24
25
# File 'lib/graph.rb', line 17

def loadAvailableOps()
	ops_reader = File.read(File.dirname(__FILE__)+'/ops.pb')
  op_list = Tensorflow::OpList.decode(ops_reader)
  availableOps = Hash.new
  (0..op_list.op.length - 1).each do |i|
    availableOps[op_list.op[i].name.downcase] = op_list.op[i]
  end
  availableOps
end

#make_attr_value(attribute_type, value) ⇒ Object


91
92
93
94
95
96
97
98
# File 'lib/graph.rb', line 91

def make_attr_value(attribute_type, value)
    # TODO -> Add support for all types
    result = nil
    if attribute_type == "T"
      result = Tensorflow::AttrValue.new(:type => value)
    end
    result
end

#matchTypes(input, outnode, attrs, op) ⇒ Object

Matches input/output parameters with corresponding data types.


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/graph.rb', line 109

def matchTypes(input, outnode, attrs, op)
  (0..op.input_arg.length - 1).each do |i|
    inType = input[i].outDataTypes[input[i].def.name]
    attrs[op.input_arg[i].type_attr] = inType   if inType != 0 and op.input_arg[i].type_attr
  end

  (0..op.output_arg.length - 1).each do |i|
    argType = type_to_enum(op.output_arg[i].type)
    if op.output_arg[i].type_attr != ""  and argType != 0
      attrs[op.output_arg[i].type_attr] = argType  # TODO
    end
  end

  op.attr.each do |attribute|
    if attribute.type == "type"
      isTypeProvided = attrs[attribute.name]
      attrs[attribute.name] = type_to_enum(attribute.default_value)  if !isTypeProvided
    end
  end

  op.output_arg.each do |arg|
    argType = type_to_enum(arg.type)
    outnode.outDataTypes[outnode.def.name] = attrs[arg.type_attr]    # TODO

  end
  nil
end

#op_definer(opName, name, input, device, attrs) ⇒ Object

TensorFlow represents computations as graphs. Nodes in the graph are called ops (short for operations). An op takes zero or more Tensors, performs some computation, and produces zero or more Tensors. This function helps to define ops directly in ruby and uses the support of google protoc gem.

  • Returns :

    • Graph with ops defined


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/graph.rb', line 67

def op_definer(opName, name , input, device, attrs)
  op = self.availableOps[opName.downcase]
  raise ("Operation does not exist.") if !op
  opName = op.name   # This ensures that case-sensitivity does not become an issue
  raise ("Invalid number of inputs.") if op.input_arg.length != input.length
  inputs = []
  input.each do |node|
    inputs.push(node.def.name)
  end
  node = GraphNode.new()
  node.def = Tensorflow::NodeDef.new(:name => name, :op => opName, :input => inputs, :device => device , :attr => Hash.new)
  attrs = Hash.new if attrs == nil
  matchTypes(input, node, attrs, op)
  op.attr.each do |attribute|
    if attrs[attribute.name]
      node.def.attr[attribute.name] = make_attr_value(attribute.name, attrs[attribute.name]) #make_attr_value(attribute.type, attrs[attribute.name])
    elsif attribute.default_value
      node.def.attr[attribute.name] = attribute.default_value
    end
  end
  self.graph_def.node.push(node.def)
  node
end

#type_to_enum(type) ⇒ Object


100
101
102
103
104
105
106
# File 'lib/graph.rb', line 100

def type_to_enum(type)
  type_val = 0
  type_val = Tensorflow::TF_FLOAT if type == :DT_FLOAT
  type_val = Tensorflow::TF_DOUBLE if type == :DT_DOUBLE
  type_val = Tensorflow::TF_INT64 if type == :DT_INT64
  type_val
end