Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Unity][Draft][WIP] Relax language specification #14148

Closed
wants to merge 47 commits into from

Conversation

slyubomirsky
Copy link
Contributor

Rendered view.

(Transferred from tlc-pack/relax#273, see the old PR for older discussions and comments.)

This document is a draft language specification for Relax. The purpose of the language specification is to serve as a technical reference describing the language's behavior in sufficient detail as to clarify the intended behavior of the compiler, hence it is by design a very detailed document rather than an accessible tutorial for the language. Its focus is the "what" and "how" of Relax, but not always the "why," though we can add more sections giving design reasons if that is desired.

Note that «double caret marks» (guillemets) are used to denote parts of the specification discussing functionality that the present prototype doesn't yet support. This notation is somewhat cumbersome, but I wasn't sure how else to proceed because Github Markdown does not support changing the text color (which was how my initial document indicated these areas). The caret marks may look strange in the text, but they have the benefit of being easy to find by text search.

Out of scope, for now, in this document is the subject of parsing: We should eventually document how we intend to parse Python into Relax, but the parser itself is being greatly reworked. We can revisit the issue of documenting its behavior once that work has been completed. Additionally, this specification is intended (for now) to focus on the user-visible behavior of Relax rather than specifying lower-level interfaces or the precise mechanisms of Relax's implementation.

Aspects Requiring Review or Still to be Determined

Since this document is a draft, any part of it is up for review and open to revision, but certain parts of the document have proven particularly challenging to describe and could benefit the most from community discussions.

  1. The StructInfo system has been a great challenge to specify and there are many questions as to how it should work. One question is whether "strong shaping" might lead to too many error messages for something that could be checked dynamically. Additionally, many potential shape mismatches could be eliminated using constant propagation or other transformations: If we check shapes without applying transformations, we would force users to add lots of redundant shape checks. On the other hand, if we require these transformations first, that might make the code harder for users to reason about.
  2. The run-time representations of values in the language will be important for determining how PackedFuncs can interact with Relax values. However, embedded targets do not support the TVM object system, so describing values in terms of the TVM object system directly may not work for all settings. Additionally, it should be determined how much detail about the representations should be included in the specification.
  3. Operators used for core language functions (like call_tir) should be described in the specification. I am not certain the descriptions presently in the last section are entirely correct, so more review of them should be appreciated. Additionally, are there operators that should be there but are presently missing?
  4. Finally, there is the question of process: How will we permit the specification to be revised? Does any change require a fresh RFC? Is there a threshold for changes that can be done as a direct PR? I have not considered this question directly, but the language specification is an important document for the community and changes to the language specification should not be taken lightly.

There are also some more minor TODOs throughout the document.

The Future of This Document

Eventually, we will want this document to be part of the Relax documentation, in which case it will be placed into a different location in the repo and probably be formatted as an rst file. Before that, we will officially RFC the spec into TVM to allow for maximum public discussion as to the design decisions underlying the specification. Hence, I am going to leave this document as a "WIP PR" until it is officially RFC'd.

@tvm-bot
Copy link
Collaborator

tvm-bot commented Feb 28, 2023

Thanks for contributing to TVM! Please refer to the contributing guidelines https://tvm.apache.org/docs/contribute/ for useful information and tips. Please request code reviews from Reviewers by @-ing them in a comment.

Generated by tvm-bot

relax_spec.md Outdated

We also define the following special notation for datatypes, to be used in the rest of the specification:
1. `Bool()`: This is shorthand for `UInt(bits=1, lanes=1)`, since TIR does not have a separate Boolean type. "True" refers to a value of 1 in this datatype and "false" refers to a value of 0. For convenience, we will refer to Boolean values as a separate datatype in the specification, due to their significance in `If` nodes.
2. `Void()`: This is shorthand for `Handle(bits=64, lanes=0)`. TIR uses this datatype to refer to opaque objects; in Relax, it is used to denote an unknown datatype.
Copy link
Contributor

Choose a reason for hiding this comment

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

In TIR void has bits=0 and lanes=0. Why the deviation in Relax?

Also, void in TIR doesn't mean "opaque", it means "nothing". The use of "kHandle" for it doesn't carry any special meaning. If void in Relax is intended to mean something else, then we should pick a different name to avoid confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was my understanding from TIR; from what I have gathered in discussions with others, void dtypes in TIR can be used to refer to objects that TIR should not operate on except through builtins/intrinsics. Whatever we use for Void in Relax should match TIR; I will check the resulting ASTs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As for whether we should use a different name, that would be worth discussing. My impression is that void was chosen for convenience (reusing the same dtype AST from TIR).

relax_spec.md Outdated Show resolved Hide resolved
relax_spec.md Show resolved Hide resolved
@slyubomirsky slyubomirsky changed the title [Unity][Draft][WIP] Relax language specification [WIP][Unity][Draft] Relax language specification Mar 2, 2023
@slyubomirsky slyubomirsky changed the title [WIP][Unity][Draft] Relax language specification [Draft][WIP][Unity] Relax language specification Mar 2, 2023
@slyubomirsky slyubomirsky marked this pull request as draft March 2, 2023 22:39
@slyubomirsky slyubomirsky changed the title [Draft][WIP][Unity] Relax language specification [Unity][Draft][WIP] Relax language specification Mar 2, 2023
@tqchen tqchen force-pushed the unity branch 2 times, most recently from a425bc7 to 5c8b7af Compare April 1, 2023 20:00
@slyubomirsky
Copy link
Contributor Author

Updated to account for #14394, please review.

@slyubomirsky
Copy link
Contributor Author

Specified FuncStructInfo for PrimFuncs and direct calls to PrimFuncs based on this PR: #15026

relax_spec.md Outdated

### Checking Structural Information at the Start and End of a Function

«Shape variables are bound at the start and end of a function or in `MatchCast` bindings. This checking is done similarly to `MatchCast`, though with a slight difference: per rule #6 in under the [well-formedness criteria](#well-formedness-criteria), we allow shape variables to appear in arguments in any order so long as shape variables appear in a binding position at least once. This requires us to check the shapes of arguments dimension by dimension in a specific order.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This approach was discussed here: #15577 (comment)

I am not sure this is the best policy, since it makes the checking of function signatures more complex. However, I am led to understand that this is more convenient in certain situations. We should be sure the implementation follows this policy.

@slyubomirsky
Copy link
Contributor Author

Added semantics for heterogenous computation per #15823. Please have a look @yongwww! Some of the proposed rules haven't been implemented yet but I think we might need to introduce new invariants to keep things consistent and address some cases that the current unit tests don't check.

@slyubomirsky
Copy link
Contributor Author

slyubomirsky commented Jan 22, 2024

Now that Unity is in mainline I will work to make this an RFC instead, so see the upcoming RFC for future updates.

@slyubomirsky
Copy link
Contributor Author

Closing the PR so discussion can move to the RFC instead.

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

Successfully merging this pull request may close these issues.

None yet

3 participants