Module: Kumi::Core::LIR::Build

Defined in:
lib/kumi/core/lir/build.rb

Class Method Summary collapse

Class Method Details

.accumulate(accumulator:, function:, value_register:, dtype:, location: nil) ⇒ Object

Accumulate Params:

accumulator: Symbol accumulator name
function:    String function id (e.g., "core.add")
value_register: register providing the value to accumulate
location:      optional Location

Result: does not produce



245
246
247
248
249
250
251
252
253
254
255
# File 'lib/kumi/core/lir/build.rb', line 245

def accumulate(accumulator:, function:, value_register:, dtype:, location: nil)
  Instruction.new(
    opcode: :Accumulate,
    result_register: accumulator.to_sym,
    stamp: Stamp.new(dtype: dtype),
    inputs: [value_register],
    immediates: [],
    attributes: { fn: function.to_s },
    location:
  )
end

.constant(value:, dtype:, as: nil, ids: nil, location: nil) ⇒ Object

Constant Params:

value:     literal value
dtype:     dtype of the literal
as:        result register symbol/name
location:  optional Location

Result: produces(result_register, stamp(dtype))



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/kumi/core/lir/build.rb', line 16

def constant(value:, dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :Constant,
    result_register: as,
    stamp: Stamp.new(dtype: dtype),
    inputs: [],
    immediates: [Literal.new(value: value, dtype: dtype)],
    attributes: {},
    location:
  )
end

.declare_accumulator(dtype:, location: nil, ids: nil, name: nil) ⇒ Object

DeclareAccumulator Params:

name:     Symbol accumulator name
initial:  Literal identity value
location: optional Location

Result: does not produce



225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/kumi/core/lir/build.rb', line 225

def declare_accumulator(dtype:, location: nil, ids: nil, name: nil)
  name ||= ids.generate_acc
  Instruction.new(
    opcode: :DeclareAccumulator,
    result_register: name.to_sym,
    stamp: Stamp.new(dtype: dtype),
    inputs: [],
    immediates: [],
    attributes: {},
    location:
  )
end

.fold(function:, arg:, out_dtype:, as: nil, ids: nil, location: nil) ⇒ Object

Fold Params:

function:   String function id (e.g., "core.mul")
arg:        Collection being folded register
out_dtype:  dtype of the result
as:         result register
location:   optional Location

Result: produces



184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/kumi/core/lir/build.rb', line 184

def fold(function:, arg:, out_dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :Fold,
    result_register: as,
    stamp: Stamp.new(dtype: out_dtype),
    inputs: Array(arg),
    immediates: [],
    attributes: { fn: function.to_s },
    location:
  )
end

.gather(collection_register:, index_register:, dtype:, as: nil, ids: nil, location: nil) ⇒ Object



347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/kumi/core/lir/build.rb', line 347

def gather(collection_register:, index_register:, dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :Gather,
    result_register: as,
    stamp: Stamp.new(dtype: dtype),
    inputs: [collection_register, index_register],
    immediates: [],
    attributes: {},
    location:
  )
end

.import_schema_call(fn_name:, source_module:, args:, input_mapping_keys:, out_dtype:, as: nil, ids: nil, location: nil) ⇒ Object

ImportSchemaCall Params:

fn_name:           imported function name
source_module:     the module containing the imported schema
args:              argument registers (mapped parameter values)
input_mapping_keys:keys of input mapping in order of args
out_dtype:         dtype of the result
as:                result register
location:          optional Location

Result: produces



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/kumi/core/lir/build.rb', line 159

def import_schema_call(fn_name:, source_module:, args:, input_mapping_keys:, out_dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :ImportSchemaCall,
    result_register: as,
    stamp: Stamp.new(dtype: out_dtype),
    inputs: args,
    immediates: [],
    attributes: {
      fn_name: fn_name.to_s,
      source_module: source_module.to_s,
      input_mapping_keys: Array(input_mapping_keys).map(&:to_s)
    },
    location:
  )
end

.kernel_call(function:, args:, out_dtype:, as: nil, ids: nil, location: nil) ⇒ Object

KernelCall Params:

function:   String function id (e.g., "core.mul")
args:       Array of register names
out_dtype:  dtype of the result
as:         result register
location:   optional Location

Result: produces



136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/kumi/core/lir/build.rb', line 136

def kernel_call(function:, args:, out_dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :KernelCall,
    result_register: as,
    stamp: Stamp.new(dtype: out_dtype),
    inputs: args,
    immediates: [],
    attributes: { fn: function.to_s },
    location:
  )
end

.length(collection_register:, as: nil, ids: nil, location: nil) ⇒ Object



334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/kumi/core/lir/build.rb', line 334

def length(collection_register:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :Length,
    result_register: as,
    stamp: Stamp.new(dtype: :integer),
    inputs: [collection_register],
    immediates: [],
    attributes: {},
    location:
  )
end

.load_accumulator(accumulator:, dtype:, ids:, location: nil) ⇒ Object

LoadAccumulator Params:

name:     Symbol accumulator name
dtype:    dtype of the accumulator
as:       result register
location: optional Location

Result: produces



264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/kumi/core/lir/build.rb', line 264

def load_accumulator(accumulator:, dtype:, ids:, location: nil)
  as = ids.generate_temp
  Instruction.new(
    opcode: :LoadAccumulator,
    result_register: as,
    stamp: Stamp.new(dtype: dtype),
    inputs: [accumulator.to_sym],
    immediates: [],
    attributes: {},
    location:
  )
end

.load_declaration(name:, dtype:, axes:, as: nil, ids: nil, location: nil) ⇒ Object

LoadDeclaration Params:

name:      declaration name
dtype:     dtype of referenced declaration result
axes:      axes of referenced declaration
as:        result register
location:  optional Location

Result: produces



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/kumi/core/lir/build.rb', line 57

def load_declaration(name:, dtype:, axes:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :LoadDeclaration,
    result_register: as,
    stamp: Stamp.new(dtype: dtype),
    inputs: [],
    immediates: [Literal.new(value: name.to_s, dtype: :string)],
    attributes: { axes: Array(axes).map!(&:to_sym) },
    location:
  )
end

.load_field(object_register:, key:, dtype:, as: nil, ids: nil, location: nil) ⇒ Object

LoadField Params:

object_register: register holding a Hash-like object
key:             field key to access
dtype:           dtype of the field
as:              result register
location:        optional Location

Result: produces



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/kumi/core/lir/build.rb', line 78

def load_field(object_register:, key:, dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :LoadField,
    result_register: as,
    stamp: Stamp.new(dtype: dtype),
    inputs: [object_register],
    immediates: [Literal.new(value: key.to_s, dtype: :string)],
    attributes: {},
    location:
  )
end

.load_input(key:, dtype:, as: nil, ids: nil, location: nil) ⇒ Object

LoadInput Params:

key:       String|Symbol top-level input key
dtype:     dtype of the loaded field
as:        result register
location:  optional Location

Result: produces



36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/kumi/core/lir/build.rb', line 36

def load_input(key:, dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :LoadInput,
    result_register: as,
    stamp: Stamp.new(dtype: dtype),
    inputs: [],
    immediates: [Literal.new(value: key.to_s, dtype: :string)],
    attributes: {},
    location:
  )
end

.loop_end(location: nil) ⇒ Object

LoopEnd Params:

location: optional Location

Result: does not produce



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/kumi/core/lir/build.rb', line 116

def loop_end(location: nil)
  Instruction.new(
    opcode: :LoopEnd,
    result_register: nil,
    stamp: nil,
    inputs: [],
    immediates: [],
    attributes: {},
    location:
  )
end

.loop_start(collection_register:, axis:, as_element:, as_index:, id: nil, ids: nil, location: nil) ⇒ Object

LoopStart Params:

collection_register: register holding the array to iterate
axis:                Symbol axis name
as_element:          register name for the element within loop body
as_index:            register name for the numeric index
id:                  optional loop id; generated if nil
location:            optional Location

Result: does not produce



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/kumi/core/lir/build.rb', line 100

def loop_start(collection_register:, axis:, as_element:, as_index:, id: nil, ids: nil, location: nil)
  Instruction.new(
    opcode: :LoopStart,
    result_register: nil,
    stamp: nil,
    inputs: [collection_register],
    immediates: [],
    attributes: { axis: axis.to_sym, as_element:, as_index:, id: id || ids.generate_loop_id },
    location:
  )
end

.make_object(keys:, values:, as: nil, ids: nil, location: nil) ⇒ Object

MakeObject Params:

keys:   Array<String|Symbol> in the same order as values
values: Array of registers
out_dtype: object dtype (or :object)
as: result


302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/kumi/core/lir/build.rb', line 302

def make_object(keys:, values:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :MakeObject,
    result_register: as,
    stamp: Stamp.new(dtype: :object),
    inputs: values,
    immediates: keys.map { |k| Literal.new(value: k.to_s, dtype: :string) },
    attributes: {},
    location: location
  )
end

.make_tuple(elements:, out_dtype:, as: nil, ids: nil, location: nil) ⇒ Object

MakeTuple Params:

elements: Array of registers
out_dtype: tuple dtype
as: result register

Result: produces tuple



283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/kumi/core/lir/build.rb', line 283

def make_tuple(elements:, out_dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :MakeTuple,
    result_register: as,
    stamp: Stamp.new(dtype: out_dtype),
    inputs: elements,
    immediates: [],
    attributes: {},
    location:
  )
end

.select(cond:, on_true:, on_false:, out_dtype:, as: nil, ids: nil, location: nil) ⇒ Object

Select Params:

cond:       register name (boolean)
on_true:    register name
on_false:   register name
out_dtype:  dtype of the result
as:         result register
location:   optional Location

Result: produces



206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/kumi/core/lir/build.rb', line 206

def select(cond:, on_true:, on_false:, out_dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :Select,
    result_register: as,
    stamp: Stamp.new(dtype: out_dtype),
    inputs: [cond, on_true, on_false],
    immediates: [],
    attributes: {},
    location:
  )
end

.tuple_get(tuple:, index:, out_dtype:, as: nil, ids: nil, location: nil) ⇒ Object

TupleGet (optional) Params:

tuple: register
index: Integer
out_dtype: element dtype
as: result


321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/kumi/core/lir/build.rb', line 321

def tuple_get(tuple:, index:, out_dtype:, as: nil, ids: nil, location: nil)
  as ||= ids.generate_temp
  Instruction.new(
    opcode: :TupleGet,
    result_register: as,
    stamp: Stamp.new(dtype: out_dtype),
    inputs: [tuple],
    immediates: [Literal.new(value: Integer(index), dtype: :integer)],
    attributes: {},
    location:
  )
end

.yield(result_register:, location: nil) ⇒ Object

Yield Opcode: Yield Semantics:

  • Exactly one per declaration.

  • Must be the last instruction in the declaration.

  • The declaration’s result axes are Γ, the active loop stack at the Yield site (i.e., the sequence of surrounding LoopStart frames).

  • The yielded register’s stamp.dtype is the declaration’s result dtype.

Codegen rule:

  • If Γ == [], return the yielded scalar.

  • If Γ != [], materialize a container shaped by Γ and write the yielded value at each iteration of the surrounding loops.

Params:

result_register: register that holds the final value
location:        optional Location

Result: does not produce



376
377
378
379
380
381
382
383
384
385
386
# File 'lib/kumi/core/lir/build.rb', line 376

def yield(result_register:, location: nil)
  Instruction.new(
    opcode: :Yield,
    result_register: nil,
    stamp: nil,
    inputs: [result_register],
    immediates: [],
    attributes: {},
    location:
  )
end