-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
[Relay][Parser] Improve Relay parser and pretty printing, including CMAKE #2377
Conversation
@@ -1,7 +1,9 @@ | |||
if(USE_ANTLR) | |||
if(EXISTS /usr/local/lib/antlr-4.7.1-complete.jar) | |||
set(ANTLR4 "/usr/local/lib/antlr-4.7.1-complete.jar") | |||
file(GLOB_RECURSE ANTLR4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this find a list of all matching files? What if there are multiple jars?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed. see below
DEPENDS ${RELAY_PARSER_DIR}/Relay.g4 | ||
WORKING_DIRECTORY ${RELAY_PARSER_DIR}) | ||
|
||
add_custom_target(relay_parser ALL DEPENDS ${RELAY_PARSER}) | ||
else() | ||
message(FATAL_ERROR "Can't find ANTLR4!") | ||
message(FATAL_ERROR "Can't find ANTLR4: ANTLR4=" ${ANTLR4}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What could ANTLR4 be set to if it's not defined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we were using exists the variable would be set, but then not work, good to just print it out.
@@ -76,21 +78,35 @@ def lookup(scopes, name): | |||
return val | |||
return None | |||
|
|||
def spanify(f): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a docstring?
python/tvm/relay/_parser.py
Outdated
@@ -410,6 +440,14 @@ def visitFuncType(self, ctx): | |||
|
|||
return ty.FuncType(arg_types, ret_type, [], None) | |||
|
|||
def visitGraphExpr(self, ctx): | |||
graph_nid = int(ctx.LOCAL_VAR().getText()[1:]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will fail with an internal python message if the user accidentally uses a CNAME
python/tvm/relay/grammar/Relay.g4
Outdated
@@ -20,7 +20,7 @@ NE: '!=' ; | |||
|
|||
opIdent: CNAME ; | |||
GLOBAL_VAR: '@' CNAME ; | |||
LOCAL_VAR: '%' CNAME ; | |||
LOCAL_VAR: '%' (CNAME | INT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo LOCAL_VAR and GRAPH_VAR should be separated at the lexing stage. This will simplify code paths in _parser.py
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to have a GRAPH_VAR
definition. It would be clearer to write and read the parser code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For sure, I was just hacking to try and get errors working.
python/tvm/relay/grammar/Relay.g4
Outdated
@@ -83,8 +83,9 @@ expr | |||
|
|||
| ident # identExpr | |||
| scalar # scalarExpr | |||
// | expr '.' INT # project | |||
// | 'debug' # debug | |||
| LOCAL_VAR '=' expr ';' expr # graphExpr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| LOCAL_VAR '=' expr ';' expr # graphExpr | |
| var '=' expr ';' expr # seq |
LOCAL_VAR/GRAPH_VAR should be enforced in _parser.py
. Also I think this case should be added to visitSeq
, since it shares a lot of code with the other sequencing cases.
python/tvm/relay/grammar/Relay.g4
Outdated
@@ -131,7 +132,7 @@ identType: CNAME ; | |||
// Float16, Float32, Float64 | |||
// Bool | |||
|
|||
body: '{' expr '}' ; | |||
body: '{' expr ';' '}' ; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This syntax change my deserve a bit of discussion. We could add it, have it be optional, or not add it at all. There original justification for not having it is that ;
was a logical replacement for in
for let expressions, separating it from the imperative use of semicolons. To me, imperative uses of semicolons serve to separate individual statements, whereas the functional use here indicates chaining. It also opens up the question of whether to require/allow/forbid semicolons between global definitions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a fan of using semi-colons everywhere because it makes parsing simpler. The text format should be relatively straight forward to parse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it should go in this PR. It needs to be added in several places and test cases need to be updated. Could you open an issue?
python/tvm/relay/_parser.py
Outdated
@@ -410,6 +440,14 @@ def visitFuncType(self, ctx): | |||
|
|||
return ty.FuncType(arg_types, ret_type, [], None) | |||
|
|||
def visitGraphExpr(self, ctx): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be consistent with other visit*
functions, add the function's type as a comment.
python/tvm/relay/_parser.py
Outdated
if isinstance(source_name, str): | ||
source_name = SourceName(source_name) | ||
|
||
import pdb; pdb.set_trace() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove debug statement?
python/tvm/relay/grammar/Relay.g4
Outdated
@@ -20,7 +20,7 @@ NE: '!=' ; | |||
|
|||
opIdent: CNAME ; | |||
GLOBAL_VAR: '@' CNAME ; | |||
LOCAL_VAR: '%' CNAME ; | |||
LOCAL_VAR: '%' (CNAME | INT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to have a GRAPH_VAR
definition. It would be clearer to write and read the parser code.
@joshpoll what else is required for this? |
Please do fix the lint errors, ping reviewers to do another round of review and when things get approved, let us merge it in |
@jroesch you should add a doc comment for spanify and we need to fix some erroring tests I think. that's it. |
also the changes to text_printer.cc should be reverted since |
don't we need semi-colon to parse? the whole point of this is to move towards round-tripping |
I'm not super familiar with how the text printer works now, but it should only be necessary to print semicolons between the two expressions in a let node and after an interstitial temp var. |
@joshpoll can we remove the semicolon for now and try to make CI green? |
f0f25d6
to
9213897
Compare
9213897
to
a6e0b96
Compare
python/tvm/relay/_parser.py
Outdated
@@ -172,6 +205,7 @@ def visitTerminal(self, node): | |||
raise ParseError("Unrecognized BOOL_LIT: `{}`".format(node_text)) | |||
|
|||
else: | |||
print(node_text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove
tests/python/relay/test_ir_parser.py
Outdated
@@ -48,6 +49,11 @@ | |||
"float16x4", | |||
} | |||
|
|||
def parses_as(code, expr): | |||
# type: (str, relay.Expr) -> bool | |||
print(relay.fromtext(SEMVER + "\n" + code)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove
python/tvm/relay/_parser.py
Outdated
@@ -420,6 +499,14 @@ def visitFuncType(self, ctx): | |||
|
|||
return ty.FuncType(arg_types, ret_type, [], None) | |||
|
|||
def visitGraphExpr(self, ctx): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it doesn't seem like antlr
will generate this function.
@joshpoll @wweic, please take another look and https://docs.tvm.ai/contribute/code_review.html#approve-and-request-changes-explicitly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Contingent on successful integration tests pass.
As per a conversation between @tqchen from last week we decided to split up my new work on error reporting into a couple different pieces. This is the first pieces which includes some fixes and improvements to the parser and text format.
I also fixed the CMAKE formula to correctly build locally on Macbooks which have set up ANTLR via Homebrew.
cc @tqchen @wweic @joshpoll