MergeComposite Error when defining custom pattern

Hi,

I want to define a custom pattern, and then use the MergeComposite function, but I met some problem.

The pattern I defined is a sequence of nested ops including reshape,add,…My question is that why I got error when passing the is_var pattern to the callback of is_op, but it is fine with wildcard? what’s the difference between this two? is_op("reshape")(is_var("x")) and is_op("reshape")(wildcard())

The latter one works but I want to specify the name_hint of the variable because I want to use it somewhere. But the former one can not pass the transform module.

My full test code is

inp = relay.var('inp', shape=(1,64,512))
r = relay.reshape(inp, [-1,64,512])
test_pattern = is_op("reshape")(is_var("inp"))
assert test_pattern.match(r) # True
pattern_table = [("test", test_pattern)]
mod = tvm.IRModule.from_expr(r)
mod = relay.transform.MergeComposite(pattern_table)(mod) 

Error:

mod = relay.transform.MergeComposite(pattern_table)(mod)
  File "C:\Anaconda\envs\tvm1\lib\site-packages\tvm-0.7.0-py3.6-win-amd64.egg\tvm\ir\transform.py", line 127, in __call__
    return _ffi_transform_api.RunPass(self, mod)
  File "C:\Anaconda\envs\tvm1\lib\site-packages\tvm-0.7.0-py3.6-win-amd64.egg\tvm\_ffi\_ctypes\packed_func.py", line 237, in __call__
    raise get_last_ffi_error()
tvm._ffi.base.TVMError: Traceback (most recent call last):
  File "C:\Users\t-meli\Documents\t-meli\projects\git-projects\dlis-TVM\TVM_MG\src\relay\ir\dataflow_matcher.cc", line 647
TVMError: Check failed: DFPatternMatcher(body).Match(pattern_, body):

Appreciate for any advice!

This is an interesting case and thanks for pointing out. I investigated it a bit and identified that this is not the problem of MergeComposite but the pattern partition. Specifically, you can reproduce this problem by replacing assert test_pattern.match(r) # True with assert test_pattern.partition(r).

In pattern partition, for each matched pattern, it creates 1) a set of new parameters with FunctionVar_<group ID>_<var_ID> as their names, and 2) a new set of nodes to be the partitioned function body. Finally, it uses the above two to create a partition function. The problem comes from dataflow_matcher.cc:647, where it tries to check if the new sets of nodes still matches the pattern. However, since the parameter names are changed, it doesn’t match your variable name x anymore. That’s why it throws the exception.

The fastest workaround is commenting out dataflow_matcher.cc:647 in case you need to move forward now. We should still solve this problem. At the first glance, I can think of two approaches.

  1. Simply remove this check.
  2. Canoncialize the pattern used in L647 by removing name specific matching.

@mbrookhart do you have any suggestion? Thanks.

Ooh, good catch, sorry for this. I mostly left that check in as a debug tool for developing passes, but you’re right, the partitioned graph won’t match anymore if we’re doing more specific things, like matching on names, or possibly matching on types. I think maybe we should just remove the check, or leave it there but comment it out so it’s only used for pass development, not user-facing workloads.

Make sense. PR filed:

2 Likes

Thanks for your quick response and fix!