Two things here, and they resolve independently:
- A defect.
tensor_input_output_sizes() returns keys that are not function arguments. This is
wrong against the method's own documented contract, whatever the answer to (2) is.
- An open question. What a segment-style parameter — one buffer carrying several views at
different offsets — should report, if inference did reach it.
1. The defect
The method documents itself as "shape and dtype for each tensor argument", returning a "Dict
mapping argument name (without %)". When a view's base is computed rather than passed in, the
key is the computed SSA name and the real argument is absent.
from ktir_cpu.interpreter import KTIRInterpreter
interp = KTIRInterpreter()
interp.load("""
module {
func.func @f(%pool: index) attributes {grid = [1]} {
%off = arith.constant 64 : index
%base = arith.addi %pool, %off : index
%v = ktdp.construct_memory_view %base, sizes: [4, 64], strides: [64, 1] {
coordinate_set = affine_set<(d0, d1) : (d0 >= 0, -d0 + 3 >= 0, d1 >= 0, -d1 + 63 >= 0)>,
memory_space = #ktdp.spyre_memory_space<HBM>
} : memref<4x64xf16>
return
}
}
""")
print(interp.module.get_function("f").arg_names) # ['pool']
print(interp.tensor_input_output_sizes("f")) # {'base': {'shape': (4, 64), 'dtype': 'f16'}}
%base is the result of arith.addi, not a parameter. %pool, the only parameter, is absent.
IRFunction.__post_init__ (ir_types.py:561) keys the dict on op.operands[0].lstrip("%") for
each ktdp.construct_memory_view, with no check that the name is a function argument.
A driver that builds inputs from this dict allocates a buffer for an SSA temporary and none for the
parameter it actually has to pass. The check is one line — reported keys should be a subset of
arg_names.
2. The open question
Walking up through the pointer arithmetic is not obviously the fix, because there is no shape to
report at the top. A segment-style parameter carries several views at different offsets, so what it
needs is a byte capacity — max(offset + span) over its views — not a shape, and the same
segment can hold different values at different points in a chain.
So which is intended?
- Inference follows pointer arithmetic to the parameter, and segment-style parameters get a
defined sizing semantics (capacity rather than shape).
- Segment-style parameters are explicitly out of scope for inference, and the driver sizes them
itself.
Option 2 is what a caller can do today, and costs a documented sentence rather than a design
change. Either way it is orthogonal to §1: a dict documented as argument-keyed shouldn't contain
non-arguments under either answer.
Scope
Independent of #202 — that one cross-contaminates this dict via the wrong function body; here the
body is correct and the keys still aren't arguments. Also outside #187: this is in ir_types.py,
not the parser, so replacing the parser would not touch it.
Two things here, and they resolve independently:
tensor_input_output_sizes()returns keys that are not function arguments. This iswrong against the method's own documented contract, whatever the answer to (2) is.
different offsets — should report, if inference did reach it.
1. The defect
The method documents itself as "shape and dtype for each tensor argument", returning a "Dict
mapping argument name (without
%)". When a view's base is computed rather than passed in, thekey is the computed SSA name and the real argument is absent.
%baseis the result ofarith.addi, not a parameter.%pool, the only parameter, is absent.IRFunction.__post_init__(ir_types.py:561) keys the dict onop.operands[0].lstrip("%")foreach
ktdp.construct_memory_view, with no check that the name is a function argument.A driver that builds inputs from this dict allocates a buffer for an SSA temporary and none for the
parameter it actually has to pass. The check is one line — reported keys should be a subset of
arg_names.2. The open question
Walking up through the pointer arithmetic is not obviously the fix, because there is no shape to
report at the top. A segment-style parameter carries several views at different offsets, so what it
needs is a byte capacity —
max(offset + span)over its views — not a shape, and the samesegment can hold different values at different points in a chain.
So which is intended?
defined sizing semantics (capacity rather than shape).
itself.
Option 2 is what a caller can do today, and costs a documented sentence rather than a design
change. Either way it is orthogonal to §1: a dict documented as argument-keyed shouldn't contain
non-arguments under either answer.
Scope
Independent of #202 — that one cross-contaminates this dict via the wrong function body; here the
body is correct and the keys still aren't arguments. Also outside #187: this is in
ir_types.py,not the parser, so replacing the parser would not touch it.