Lunderberg commented on PR #15807:
URL: https://github.com/apache/tvm/pull/15807#issuecomment-1788849978

   > Then b is an unused var (by your definition), but not an impure call, so 
it will be removed, which breaks the program.
   
   Thank you, and I can reproduce the error with the test case below.
   
   ```python
   def test_binding_block_keep_pure_func_used_only_for_impure():
       """Remove unused dataflow bindings
   
       Removal of unused bindings may not remove side effects.  Unused
       bindings whose value is an impure operation (e.g. `R.call_packed`)
       may not be removed, nor may any of their inputs.
       """
   
       @R.function(private=True)
       def before(x: R.Tensor((32, 32), "int32")):
           y = x * R.const(2)
           z = R.call_packed(
               "function_maybe_with_side_effects", y, sinfo_args=(R.Tensor((32, 
32), "int32"))
           )
           return R.tuple()
   
       expected = before
   
       after = remove_all_unused(before)
       tvm.ir.assert_structural_equal(expected, after)
   ```
   
   For the purpose of removing unused bindings, an argument to an impure 
function is equivalent to an output, and should be retained.  Thankfully, this 
should be a pretty straightforward change to make.
   
   > btw, since we have an assumption that binding block is impure, why do we 
try to remove unused in binding block?
   
   I'd phrase it slightly differently: A `BindingBlock` has no assumptions 
about the purity of its bound values, where a `DataflowBlock` may assume that 
all bound values are pure.  That is, we don't need to assume that every step of 
a `BindingBlock` is impure, but we also cannot assume that any step is pure.  
Simplifications that require bound values to be pure are still legal within a 
`BindingBlock`, so long as the purity is validated before making a change.  The 
advantage of the `DataflowBlock` is that it lets us skip that validation step, 
because the contents are required to be pure.
   
   In context of this PR, this check is encoded 
[here](https://github.com/apache/tvm/pull/15807/files#diff-1f74c84f9a522574f3529c92e5eb683811e6c62c83412cf8575ff8e5b66167ecR249-R250).
  A binding is removable if it is unused, and if it's computation is pure, 
where purity can be established either from being within a `DataflowBlock`, or 
from checking the purity explicitly.  The bug is that the set of `unused_vars_` 
is determined by flowing backwards from function outputs, where it should be 
determined by flowing backwards from function outputs *and* arguments to impure 
functions.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to