Skip to content

tensor_input_output_sizes() reports non-argument SSA names, and omits the real parameter #204

Description

@WarningRan

Two things here, and they resolve independently:

  1. 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.
  2. 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 capacitymax(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?

  1. Inference follows pointer arithmetic to the parameter, and segment-style parameters get a
    defined sizing semantics (capacity rather than shape).
  2. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions