Class: Kumi::IR::Base::Instruction

Inherits:
Object
  • Object
show all
Defined in:
lib/kumi/ir/base/instruction.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opcode:, result: nil, inputs: [], attributes: {}, metadata: {}, effects: Effects::NONE) ⇒ Instruction

Returns a new instance of Instruction.



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/kumi/ir/base/instruction.rb', line 22

def initialize(opcode:, result: nil, inputs: [], attributes: {}, metadata: {}, effects: Effects::NONE)
  @opcode     = opcode.to_sym
  @result     = result
  @inputs     = Array(inputs).freeze
  @attributes = attributes.freeze
  @metadata   = .freeze
  @effects    = normalize_effects(effects)
  @axes       = [:axes] || []
  @dtype      = [:dtype]
  validate!
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



19
20
21
# File 'lib/kumi/ir/base/instruction.rb', line 19

def attributes
  @attributes
end

#axesObject (readonly)

Returns the value of attribute axes.



20
21
22
# File 'lib/kumi/ir/base/instruction.rb', line 20

def axes
  @axes
end

#dtypeObject (readonly)

Returns the value of attribute dtype.



20
21
22
# File 'lib/kumi/ir/base/instruction.rb', line 20

def dtype
  @dtype
end

#effectsObject (readonly)

Returns the value of attribute effects.



19
20
21
# File 'lib/kumi/ir/base/instruction.rb', line 19

def effects
  @effects
end

#inputsObject (readonly)

Returns the value of attribute inputs.



19
20
21
# File 'lib/kumi/ir/base/instruction.rb', line 19

def inputs
  @inputs
end

#metadataObject (readonly)

Returns the value of attribute metadata.



19
20
21
# File 'lib/kumi/ir/base/instruction.rb', line 19

def 
  @metadata
end

#opcodeObject (readonly)

Returns the value of attribute opcode.



19
20
21
# File 'lib/kumi/ir/base/instruction.rb', line 19

def opcode
  @opcode
end

#resultObject (readonly)

Returns the value of attribute result.



19
20
21
# File 'lib/kumi/ir/base/instruction.rb', line 19

def result
  @result
end

Instance Method Details

#control_effect?Boolean

Returns:

  • (Boolean)


40
# File 'lib/kumi/ir/base/instruction.rb', line 40

def control_effect? = @effects.include?(Effects::CONTROL)

#defsObject



49
50
51
# File 'lib/kumi/ir/base/instruction.rb', line 49

def defs
  @result ? [@result] : []
end

#effectful?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/kumi/ir/base/instruction.rb', line 36

def effectful?
  !@effects.empty?
end

#io_effect?Boolean

Returns:

  • (Boolean)


43
# File 'lib/kumi/ir/base/instruction.rb', line 43

def io_effect?      = @effects.include?(Effects::IO)

#memory_effect?Boolean

Returns:

  • (Boolean)


42
# File 'lib/kumi/ir/base/instruction.rb', line 42

def memory_effect?  = @effects.include?(Effects::MEMORY)

#normalized_attributesObject



57
58
59
60
61
# File 'lib/kumi/ir/base/instruction.rb', line 57

def normalized_attributes
  return attributes unless attributes.is_a?(Hash)

  attributes.sort_by { |k, _| k.to_s }
end

#printer_attributesObject



152
153
154
# File 'lib/kumi/ir/base/instruction.rb', line 152

def printer_attributes
  attributes
end

#printer_axesObject



156
# File 'lib/kumi/ir/base/instruction.rb', line 156

def printer_axes = axes

#printer_dtypeObject



157
# File 'lib/kumi/ir/base/instruction.rb', line 157

def printer_dtype = dtype

#produces?Boolean

Returns:

  • (Boolean)


34
# File 'lib/kumi/ir/base/instruction.rb', line 34

def produces? = !@result.nil?

#stampObject



53
54
55
# File 'lib/kumi/ir/base/instruction.rb', line 53

def stamp
  { axes:, dtype: }
end

#state_effect?Boolean

Returns:

  • (Boolean)


41
# File 'lib/kumi/ir/base/instruction.rb', line 41

def state_effect?   = @effects.include?(Effects::STATE)

#to_hObject



131
132
133
134
135
136
137
138
139
140
# File 'lib/kumi/ir/base/instruction.rb', line 131

def to_h
  {
    opcode:,
    result:,
    inputs:,
    attributes:,
    metadata:,
    effects: @effects.to_a
  }
end

#to_print_string(_printer = nil) ⇒ Object



142
143
144
145
146
147
148
149
150
# File 'lib/kumi/ir/base/instruction.rb', line 142

def to_print_string(_printer = nil)
  parts = []
  parts << "%#{result} =" if result
  parts << opcode.to_s
  parts << format_inputs(inputs)
  parts << format_attributes(printer_attributes)
  parts << format_axes_dtype
  parts.compact.join(" ")
end

#usesObject



45
46
47
# File 'lib/kumi/ir/base/instruction.rb', line 45

def uses
  @inputs.select { |input| input.is_a?(Symbol) }
end

#validate!Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/kumi/ir/base/instruction.rb', line 73

def validate!
  unless @opcode.is_a?(Symbol)
    raise ArgumentError, "invalid #{self.class}: opcode must be a Symbol"
  end

  if @result && !@result.is_a?(Symbol)
    raise ArgumentError, "invalid #{self.class}: result must be a Symbol or nil"
  end

  unless @inputs.is_a?(Array)
    raise ArgumentError, "invalid #{self.class}: inputs must be an Array"
  end

  bad_inputs = @inputs.reject { |input| input.is_a?(Symbol) }
  if bad_inputs.any?
    raise ArgumentError, "invalid #{self.class}: inputs must be Symbols (bad: #{bad_inputs.inspect})"
  end

  unless @attributes.is_a?(Hash)
    raise ArgumentError, "invalid #{self.class}: attributes must be a Hash"
  end

  unless @attributes.keys.all? { |key| key.is_a?(Symbol) }
    raise ArgumentError, "invalid #{self.class}: attributes keys must be Symbols"
  end

  unless @metadata.is_a?(Hash)
    raise ArgumentError, "invalid #{self.class}: metadata must be a Hash"
  end

  axes = @metadata[:axes]
  if axes && !(axes.is_a?(Array) && axes.all? { |axis| axis.is_a?(Symbol) })
    raise ArgumentError, "invalid #{self.class}: axes must be an Array of Symbols"
  end

  dtype = @metadata[:dtype]
  if dtype
    type_class = defined?(Kumi::Core::Types::Type) ? Kumi::Core::Types::Type : nil
    valid_dtype = dtype.is_a?(Symbol) || (type_class && dtype.is_a?(type_class))
    unless valid_dtype
      raise ArgumentError, "invalid #{self.class}: dtype must be a Symbol or Types::Type"
    end
  end

  self
end

#value_signature(inputs: @inputs, include_axes: false, include_dtype: false, allow_effectful: false) ⇒ Object



63
64
65
66
67
68
69
70
71
# File 'lib/kumi/ir/base/instruction.rb', line 63

def value_signature(inputs: @inputs, include_axes: false, include_dtype: false, allow_effectful: false)
  return nil unless @result
  return nil if effectful? && !allow_effectful

  signature = [opcode, inputs, normalized_attributes]
  signature << axes if include_axes
  signature << dtype if include_dtype
  signature
end

#with_metadata(extra) ⇒ Object



120
121
122
123
124
125
126
127
128
129
# File 'lib/kumi/ir/base/instruction.rb', line 120

def (extra)
  self.class.new(
    opcode: @opcode,
    result: @result,
    inputs: @inputs,
    attributes: @attributes,
    metadata: @metadata.merge(extra),
    effects: @effects
  )
end