Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[RELAY] IR Wellform Checker (#1748)
- Loading branch information
1 parent
e22ac6b
commit 7beafdd
Showing
8 changed files
with
100 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/*! | ||
* Copyright (c) 2018 by Contributors | ||
* \file well_formed.cc | ||
* \brief check that expression is well formed. | ||
*/ | ||
#include <tvm/relay/pass.h> | ||
#include <tvm/relay/expr_functor.h> | ||
#include <unordered_set> | ||
|
||
namespace tvm { | ||
namespace relay { | ||
|
||
struct NotWellFormed { }; | ||
|
||
//! brief make sure each Var is bind at most once. | ||
class WellFormedChecker : private ExprVisitor { | ||
bool well_formed = true; | ||
|
||
std::unordered_set<Var, NodeHash, NodeEqual> s; | ||
|
||
void Check(const Var & v) { | ||
if (s.count(v) != 0) { | ||
well_formed = false; | ||
} | ||
s.insert(v); | ||
} | ||
|
||
void VisitExpr_(const LetNode * l) final { | ||
// we do letrec only for FunctionNode, | ||
// but shadowing let in let binding is likely programming error, and we should forbidden it. | ||
Check(l->var); | ||
CheckWellFormed(l->value); | ||
CheckWellFormed(l->body); | ||
} | ||
|
||
void VisitExpr_(const FunctionNode * f) final { | ||
for (const Param & p : f->params) { | ||
Check(p->var); | ||
} | ||
CheckWellFormed(f->body); | ||
} | ||
|
||
public: | ||
bool CheckWellFormed(const Expr & e) { | ||
this->VisitExpr(e); | ||
return well_formed; | ||
} | ||
}; | ||
|
||
bool WellFormed(const Expr & e) { | ||
return WellFormedChecker().CheckWellFormed(e); | ||
} | ||
|
||
TVM_REGISTER_API("relay._ir_pass.well_formed") | ||
.set_body([](TVMArgs args, TVMRetValue *ret) { | ||
Expr e = args[0]; | ||
*ret = WellFormed(e); | ||
}); | ||
|
||
} // namespace relay | ||
} // namespace tvm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,4 +24,3 @@ def test_op_level1(): | |
if __name__ == "__main__": | ||
test_op_attr() | ||
test_op_level1() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import tvm | ||
from tvm import relay | ||
from tvm.relay.ir_pass import well_formed | ||
|
||
def test_well_formed(): | ||
x = relay.Var("x") | ||
assert well_formed(x) | ||
v = relay.Constant(tvm.nd.array(10)) | ||
ty = None | ||
let = relay.Let(x, v, x, ty) | ||
assert well_formed(let) | ||
assert not well_formed(relay.Let(x, v, let, ty)) | ||
f = relay.Function([relay.Param(x, ty)], ty, x) | ||
assert well_formed(f) | ||
# this test should pass in case of weak uniqueness (only test for shadowing) | ||
# but we want all binder to be distinct from each other. | ||
assert not well_formed(relay.Let(relay.Var("y"), f, | ||
relay.Let(relay.Var("z"), f, v, ty), ty)) |