Class: TensorStream::OpMaker
- Inherits:
-
Object
- Object
- TensorStream::OpMaker
- Defined in:
- lib/tensor_stream/op_maker.rb
Instance Attribute Summary collapse
-
#aliases ⇒ Object
readonly
Returns the value of attribute aliases.
-
#check_types ⇒ Object
readonly
Returns the value of attribute check_types.
-
#custom ⇒ Object
readonly
Returns the value of attribute custom.
-
#custom_post ⇒ Object
readonly
Returns the value of attribute custom_post.
-
#data_type_block ⇒ Object
readonly
Returns the value of attribute data_type_block.
-
#data_type_coercion ⇒ Object
readonly
Returns the value of attribute data_type_coercion.
-
#description ⇒ Object
readonly
Returns the value of attribute description.
-
#exclude ⇒ Object
readonly
Returns the value of attribute exclude.
-
#gradient ⇒ Object
readonly
Returns the value of attribute gradient.
-
#infer_type_proc ⇒ Object
readonly
Returns the value of attribute infer_type_proc.
-
#operation ⇒ Object
readonly
Returns the value of attribute operation.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#parameters ⇒ Object
readonly
Returns the value of attribute parameters.
-
#supports_broadcast ⇒ Object
readonly
Returns the value of attribute supports_broadcast.
Class Method Summary collapse
- .define_operation(op_code, &block) ⇒ Object
- .each_op(&block) ⇒ Object
-
.gradient_op(context_caller, node, grad) ⇒ Object
call an operations’ gradient definition.
- .infer_data_type(context_caller, tensor, passed_data_type) ⇒ Object
- .infer_shape(context_caller, tensor) ⇒ Object
- .scan ⇒ Object
Instance Method Summary collapse
- #add_custom(custom_code) ⇒ Object
- #add_custom_post(custom_code) ⇒ Object
- #apply_data_type_coercion! ⇒ Object
- #check_types? ⇒ Boolean
- #data_type_coercion? ⇒ Boolean
- #default_with_nil(v) ⇒ Object
- #define_data_type(&block) ⇒ Object
- #define_gradient(&block) ⇒ Object
- #define_shape(&block) ⇒ Object
- #description_lines ⇒ Object
- #exclude! ⇒ Object
- #expand_options(print_defaults) ⇒ Object
- #expand_params(print_defaults) ⇒ Object
- #generate_body ⇒ Object
-
#initialize(op) ⇒ OpMaker
constructor
A new instance of OpMaker.
- #option(name, description, default_value = nil, options = {}) ⇒ Object
- #options_call ⇒ Object
- #other_names(aliases) ⇒ Object
-
#parameter(name, description, default_value = nil, validate: nil) ⇒ Object
adds a parameter to the op.
- #parameters_must_have_same_data_type! ⇒ Object
- #supports_broadcasting! ⇒ Object
- #supports_broadcasting? ⇒ Boolean
- #what_it_does(description) ⇒ Object
- #what_it_does_code(description) ⇒ Object
Constructor Details
#initialize(op) ⇒ OpMaker
Returns a new instance of OpMaker.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/tensor_stream/op_maker.rb', line 8 def initialize(op) @operation = op @parameters = [] @options = {} @gradient = nil @supports_broadcast = false @data_type_coercion = false @exclude = false @description = [] @aliases = [] @custom = [] @custom_post = [] @infer_type_proc = lambda { |tensor| next nil if tensor.inputs[0].nil? next tensor.inputs[0].shape.shape if tensor.inputs.size == 1 TensorStream::TensorShape.infer_shape(tensor.inputs[0].shape.shape, tensor.inputs[1].shape.shape) if tensor.inputs.size == 2 && tensor.inputs[0] && tensor.inputs[1] } end |
Instance Attribute Details
#aliases ⇒ Object (readonly)
Returns the value of attribute aliases.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def aliases @aliases end |
#check_types ⇒ Object (readonly)
Returns the value of attribute check_types.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def check_types @check_types end |
#custom ⇒ Object (readonly)
Returns the value of attribute custom.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def custom @custom end |
#custom_post ⇒ Object (readonly)
Returns the value of attribute custom_post.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def custom_post @custom_post end |
#data_type_block ⇒ Object (readonly)
Returns the value of attribute data_type_block.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def data_type_block @data_type_block end |
#data_type_coercion ⇒ Object (readonly)
Returns the value of attribute data_type_coercion.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def data_type_coercion @data_type_coercion end |
#description ⇒ Object (readonly)
Returns the value of attribute description.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def description @description end |
#exclude ⇒ Object (readonly)
Returns the value of attribute exclude.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def exclude @exclude end |
#gradient ⇒ Object (readonly)
Returns the value of attribute gradient.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def gradient @gradient end |
#infer_type_proc ⇒ Object (readonly)
Returns the value of attribute infer_type_proc.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def infer_type_proc @infer_type_proc end |
#operation ⇒ Object (readonly)
Returns the value of attribute operation.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def operation @operation end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def @options end |
#parameters ⇒ Object (readonly)
Returns the value of attribute parameters.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def parameters @parameters end |
#supports_broadcast ⇒ Object (readonly)
Returns the value of attribute supports_broadcast.
2 3 4 |
# File 'lib/tensor_stream/op_maker.rb', line 2 def supports_broadcast @supports_broadcast end |
Class Method Details
.define_operation(op_code, &block) ⇒ Object
47 48 49 50 51 52 |
# File 'lib/tensor_stream/op_maker.rb', line 47 def self.define_operation(op_code, &block) @ops ||= {} op_maker = TensorStream::OpMaker.new(op_code.to_sym) block.call(op_maker) @ops[op_code.to_sym] = op_maker end |
.each_op(&block) ⇒ Object
83 84 85 86 87 |
# File 'lib/tensor_stream/op_maker.rb', line 83 def self.each_op(&block) @ops.values.sort_by { |op| op.operation }.reject(&:exclude).each do |op| block.call(op) end end |
.gradient_op(context_caller, node, grad) ⇒ Object
call an operations’ gradient definition
55 56 57 58 59 |
# File 'lib/tensor_stream/op_maker.rb', line 55 def self.gradient_op(context_caller, node, grad) raise "No derivative op defined for #{node.operation}" if @ops[node.operation].nil? || @ops[node.operation].gradient.nil? context_caller.instance_exec(grad, node, node.inputs, &@ops[node.operation].gradient) end |
.infer_data_type(context_caller, tensor, passed_data_type) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/tensor_stream/op_maker.rb', line 67 def self.infer_data_type(context_caller, tensor, passed_data_type) return passed_data_type if passed_data_type if @ops[tensor.operation] && @ops[tensor.operation].data_type_block context_caller.instance_exec(tensor, &@ops[tensor.operation].data_type_block) else if tensor.inputs[0] tensor.inputs[0].data_type elsif tensor.inputs[1] tensor.inputs[1].data_type else :unknown end end end |
.infer_shape(context_caller, tensor) ⇒ Object
61 62 63 64 65 |
# File 'lib/tensor_stream/op_maker.rb', line 61 def self.infer_shape(context_caller, tensor) return nil unless @ops[tensor.operation] context_caller.instance_exec(tensor, &@ops[tensor.operation].infer_type_proc) end |
.scan ⇒ Object
40 41 42 43 44 45 |
# File 'lib/tensor_stream/op_maker.rb', line 40 def self.scan op_files = Dir[File.join(File.dirname(__FILE__), "ops", "*.rb")] op_files.each { |file| load File.join("tensor_stream", "ops", File.basename(file)) } end |
Instance Method Details
#add_custom(custom_code) ⇒ Object
32 33 34 |
# File 'lib/tensor_stream/op_maker.rb', line 32 def add_custom(custom_code) @custom << custom_code end |
#add_custom_post(custom_code) ⇒ Object
36 37 38 |
# File 'lib/tensor_stream/op_maker.rb', line 36 def add_custom_post(custom_code) @custom_post << custom_code end |
#apply_data_type_coercion! ⇒ Object
168 169 170 |
# File 'lib/tensor_stream/op_maker.rb', line 168 def apply_data_type_coercion! @data_type_coercion = true end |
#check_types? ⇒ Boolean
188 189 190 |
# File 'lib/tensor_stream/op_maker.rb', line 188 def check_types? @check_types end |
#data_type_coercion? ⇒ Boolean
184 185 186 |
# File 'lib/tensor_stream/op_maker.rb', line 184 def data_type_coercion? @data_type_coercion end |
#default_with_nil(v) ⇒ Object
208 209 210 |
# File 'lib/tensor_stream/op_maker.rb', line 208 def default_with_nil(v) v == :nil ? 'nil' : v end |
#define_data_type(&block) ⇒ Object
154 155 156 |
# File 'lib/tensor_stream/op_maker.rb', line 154 def define_data_type(&block) @data_type_block = block end |
#define_gradient(&block) ⇒ Object
146 147 148 |
# File 'lib/tensor_stream/op_maker.rb', line 146 def define_gradient(&block) @gradient = block end |
#define_shape(&block) ⇒ Object
150 151 152 |
# File 'lib/tensor_stream/op_maker.rb', line 150 def define_shape(&block) @infer_type_proc = block end |
#description_lines ⇒ Object
101 102 103 |
# File 'lib/tensor_stream/op_maker.rb', line 101 def description_lines description.map { |line| line.split("\n") }.flatten end |
#exclude! ⇒ Object
97 98 99 |
# File 'lib/tensor_stream/op_maker.rb', line 97 def exclude! @exclude = true end |
#expand_options(print_defaults) ⇒ Object
192 193 194 195 196 |
# File 'lib/tensor_stream/op_maker.rb', line 192 def (print_defaults) @options.map { |k, v| print_defaults && v[:default_value] ? "#{k}: #{default_with_nil(v[:default_value])}" : "#{k}:" } end |
#expand_params(print_defaults) ⇒ Object
158 159 160 161 162 |
# File 'lib/tensor_stream/op_maker.rb', line 158 def (print_defaults) @parameters.map { |param| print_defaults && param[:default_value] ? "#{param[:name]} = #{default_with_nil(param[:default_value])}" : "#{param[:name]}" } end |
#generate_body ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/tensor_stream/op_maker.rb', line 105 def generate_body body = [] parameters.select { |p| p[:validate] }.each do |p| body << "check_allowed_types(#{p[:name]}, TensorStream::Ops::#{p[:validate]})" end if data_type_coercion? body << "#{(false).join(', ')} = apply_data_type_coercion(#{(false).join(', ')})" end if check_types? body << "check_data_types(#{(false).join(', ')})" end custom.each do |c| body << c end if custom_post.empty? body << "_op(:#{operation}, #{((false) + ).join(', ')})" else body << "result = _op(:#{operation}, #{((false) + ).join(', ')})" end custom_post.each do |c| body << c end body.map { |line| " #{line}"}.join("\n") end |
#option(name, description, default_value = nil, options = {}) ⇒ Object
142 143 144 |
# File 'lib/tensor_stream/op_maker.rb', line 142 def option(name, description, default_value = nil, = {}) @options[name] = { description: description, default_value: default_value, options: } end |
#options_call ⇒ Object
198 199 200 201 202 203 204 205 206 |
# File 'lib/tensor_stream/op_maker.rb', line 198 def @options.reject { |k, v| v.dig(:options, :exclude) }.map { |k, v| if v.dig(:options, :alias) "#{v.dig(:options, :alias)}: #{k}" else "#{k}: #{k}" end } end |
#other_names(aliases) ⇒ Object
28 29 30 |
# File 'lib/tensor_stream/op_maker.rb', line 28 def other_names(aliases) @aliases += aliases end |
#parameter(name, description, default_value = nil, validate: nil) ⇒ Object
adds a parameter to the op
133 134 135 136 137 138 139 140 |
# File 'lib/tensor_stream/op_maker.rb', line 133 def parameter(name, description, default_value = nil, validate: nil) @parameters << { name: name.to_s, description: description, default_value: default_value, validate: validate } end |
#parameters_must_have_same_data_type! ⇒ Object
164 165 166 |
# File 'lib/tensor_stream/op_maker.rb', line 164 def parameters_must_have_same_data_type! @check_types = true end |
#supports_broadcasting! ⇒ Object
172 173 174 175 176 177 178 |
# File 'lib/tensor_stream/op_maker.rb', line 172 def supports_broadcasting! if (@parameters.size> 1) @supports_broadcast = true else raise "Ops with parameters < 2 cannot support broadcasting" end end |
#supports_broadcasting? ⇒ Boolean
180 181 182 |
# File 'lib/tensor_stream/op_maker.rb', line 180 def supports_broadcasting? @supports_broadcast end |
#what_it_does(description) ⇒ Object
89 90 91 |
# File 'lib/tensor_stream/op_maker.rb', line 89 def what_it_does(description) @description << description end |
#what_it_does_code(description) ⇒ Object
93 94 95 |
# File 'lib/tensor_stream/op_maker.rb', line 93 def what_it_does_code(description) @description << "<tt>#{description}</tt>" end |