Policy mechanism
As mentioned in #86 #90 #92 , there are several discussions about how to support the policy switch.
I think the principle is not to have policy switch during runtime. We could have some static switch like MINPY_POLICY=AUTO_BLACKLIST python some_minpy_program.py. The change will include:
- Remove
set_global_policyAPI. Policy choose could only be specified through environment. - Policy object could not be created by users. There will be only one policy object throughout minpy's lifetime, which is created according to environment.
- Query API is not an object method, but a global function. For ABL only queries #92, simply returns the ABL that will be loaded if
MINPY_POLICY=AUTO_BLACKLISTis specified. - Make sure that auto blacklist policy will workout if fallback fail, because now we don't have policy switch to save (or hack) us during runtime.
@lryta @ZihengJiang
Agree. BTW, should PreferMXNetPolicy utilize the black list information?
I think so. Another question is whether we allow different policies for different modules (e.g. numpy and numpy.random). My suggestion is to disallow this. @lryta ?
We already have a working mechanism of policy system. I think we may just keep it. I've fixed the bug that prohibits policy switching. Therefore, we are good now.
For allowing different policies for different modules, I think current solution is viable, since our major API globally changes policy. If they find our internal API that changes policies of individual modules, I think that's ok. They can simply use it and it indeed works.
We may just fix everything that matters and move to next stage.
The problem is it leaves more questions than before. It is undefined behavior if we have two policy objects, if the policy is changed during runtime. I think leaving these issues for future is dangerous. This restriction in fact gets rid of these questions once for all since these situations cannot happen at all. It is hard to fix "everything" since the more complicated the rule is, the more coverage we need to deal with. I think the restriction eases our burden a lot.
@jermainewang Multiple policy objects won't cause any problem. I ensure singleton in stateful policy.
p1 = ABLPolicy()
p2 = ABLPolicy()
The interface gives users the idea that they have different internal states. However, in current implementation, they are not, which is weird. In fact, creating policy object is weird. What if
np.set_global(p1)
# do something
p1.report_status()
np.set_global(p2)
# do something
p2.report_status()
Should their reports be the same or not? The interface looks like they should not be the same, but in fact they should.
And changing global variable throughout the code is dangerous. If somebody have:
# some_module.py
np.set_global(some_policy)
def foo()
# meant to do something under `some_policy`
# main.py
import some_module
np.set_global(other_policy)
foo() # will foo() be run under `some_policy` or `other_policy`?
This temporarily achieved by changes in #117