Skip to content

[REFACTOR][IR] Unify StructInfo and Type#19852

Closed
tqchen wants to merge 9 commits into
apache:mainfrom
tqchen:tvm-type-refactor-unify-expr-type-field-with-relax-structinfo
Closed

[REFACTOR][IR] Unify StructInfo and Type#19852
tqchen wants to merge 9 commits into
apache:mainfrom
tqchen:tvm-type-refactor-unify-expr-type-field-with-relax-structinfo

Conversation

@tqchen

@tqchen tqchen commented Jun 21, 2026

Copy link
Copy Markdown
Member

This PR consolidates Relax's StructInfo vocabulary into the unified Type surface and moves Relax expression type storage to Expr.ty.

Summary:

  • Adds common expression ty storage and migrates Relax type storage/users away from struct_info_.
  • Renames the canonical Relax dependent-type surface from StructInfo/*_sinfo vocabulary to Type/*_ty.
  • Removes the unused shared IR type functor files after auditing usage.
  • Collapses Relax tuple typing onto the shared IR TupleType representation while keeping Relax-specific PrimType and FuncType behavior.

Validation:

  • ninja -C build -j$(nproc) passed.
  • Focused parser/printer/type pytest passed: 709 passed, 1 xfailed.
  • Touched-file pre-commit passed after automatic formatting.
  • git diff --check passed.

Additional broad validation recorded in the task notes includes Relax op/distributed and analysis/transform/TVMScript/VM pytest sweeps.

tqchen added 9 commits June 20, 2026 01:21
The Relax dependent type refactor needs the helper and analysis surfaces to use the consolidated type vocabulary instead of keeping StructInfo compatibility shims around.

This removes the remaining renamed helper wrappers, updates the public analysis and transform entry points to Type names, and tightens final stale-name cleanup in the nested-message and analysis internals.
@tqchen tqchen changed the title [REFACTOR][Relax] Unify StructInfo into Type [REFACTOR][IR] Unify StructInfo and Type Jun 21, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors TVM's Relax compiler framework by replacing the StructInfo abstraction with a unified Type system, renaming related classes (e.g., TensorStructInfo to TensorType, ShapeStructInfo to ShapeType, and DTensorStructInfo to DTensorType) and updating fields from struct_info to ty across both C++ and Python APIs. The review comments identify several critical issues, including a C++ compilation error in the Adreno backend due to incorrect type casting and pointer usage, multiple incorrect Python type annotations in the parser proxies, and a syntax error in a docstring example.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +361 to +364
if (auto tensor_ty = ty.as<TensorType>()) {
bool is_texture =
i < is_texture_supported.size() ? is_texture_supported[i] : is_texture_supported[0];
auto scope =
is_texture ? Scope(GetShapeFromTensorStructInfo(tensor_sinfo.value())) : "global";
auto scope = is_texture ? Scope(GetShapeFromTensorType(tensor_ty.value())) : "global";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using ty.as<TensorType>() will result in a compilation error because TensorType is an ObjectRef subclass, not an Object subclass. It should be ty.as<TensorTypeNode>(). Additionally, tensor_ty is a pointer (const TensorTypeNode*), so calling .value() on it is invalid. Instead, use ffi::GetRef<TensorType>(tensor_ty) to pass the reference to GetShapeFromTensorType.

Suggested change
if (auto tensor_ty = ty.as<TensorType>()) {
bool is_texture =
i < is_texture_supported.size() ? is_texture_supported[i] : is_texture_supported[0];
auto scope =
is_texture ? Scope(GetShapeFromTensorStructInfo(tensor_sinfo.value())) : "global";
auto scope = is_texture ? Scope(GetShapeFromTensorType(tensor_ty.value())) : "global";
if (auto tensor_ty = ty.as<TensorTypeNode>()) {
bool is_texture =
i < is_texture_supported.size() ? is_texture_supported[i] : is_texture_supported[0];
auto scope = is_texture ? Scope(GetShapeFromTensorType(ffi::GetRef<TensorType>(tensor_ty))) : "global";


def as_struct_info(self, dict_globals: dict[str, Any] | None = None) -> ShapeStructInfo:
return ObjectStructInfo()
def as_ty(self, dict_globals: dict[str, Any] | None = None) -> ShapeType:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The return type annotation of as_ty in ObjectProxy is incorrectly specified as ShapeType instead of ObjectType. This appears to be a copy-paste error from ShapeProxy.

Suggested change
def as_ty(self, dict_globals: dict[str, Any] | None = None) -> ShapeType:
def as_ty(self, dict_globals: dict[str, Any] | None = None) -> ObjectType:

return set()

def as_struct_info(self, dict_globals: dict[str, Any] | None = None) -> ShapeStructInfo:
def as_ty(self, dict_globals: dict[str, Any] | None = None) -> ShapeType:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The return type annotation of as_ty in PrimProxy is incorrectly specified as ShapeType instead of PrimType. This appears to be a copy-paste error from ShapeProxy.

Suggested change
def as_ty(self, dict_globals: dict[str, Any] | None = None) -> ShapeType:
def as_ty(self, dict_globals: dict[str, Any] | None = None) -> PrimType:

def as_struct_info(self, dict_globals: dict[str, Any] | None = None) -> TensorStructInfo:
return DTensorStructInfo(
self.tensor_sinfo_proxy.as_struct_info(dict_globals),
def as_ty(self, dict_globals: dict[str, Any] | None = None) -> TensorType:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The return type annotation of as_ty in DTensorProxy is incorrectly specified as TensorType instead of DTensorType. Since DTensorType inherits from Type (not TensorType), this is a type annotation mismatch.

Suggested change
def as_ty(self, dict_globals: dict[str, Any] | None = None) -> TensorType:
def as_ty(self, dict_globals: dict[str, Any] | None = None) -> DTensorType:

x = rx.Var("x", rx.TensorStructInfo([m, n], "float16"))
y = rx.Var("y", rx.TensorStructInfo([n], "float16")
x = rx.Var("x", rx.TensorType([m, n], "float16"))
y = rx.Var("y", rx.TensorType([n], "float16")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is a missing closing parenthesis ) at the end of the line in the docstring example.

Suggested change
y = rx.Var("y", rx.TensorType([n], "float16")
y = rx.Var("y", rx.TensorType([n], "float16"))

@tqchen tqchen closed this Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant