[VirtualMachine] fix raw pointer using by VirtualMachine#9980
[VirtualMachine] fix raw pointer using by VirtualMachine#9980tqchen merged 3 commits intoapache:mainfrom
Conversation
| ObjectPtr(const ObjectPtr<U>& other) // NOLINT(*) | ||
| : ObjectPtr(other.data_) { | ||
| static_assert(std::is_base_of<T, U>::value, | ||
| "can only assign of child class ObjectPtr to parent"); |
There was a problem hiding this comment.
Likely we want to keep this static assert
There was a problem hiding this comment.
Agree with TQ this should not be remove
| ObjectRef return_register_; | ||
| /*! \brief The executable the VM will operate on. */ | ||
| Executable* exec_; | ||
| ObjectPtr<Executable> exec_; |
There was a problem hiding this comment.
If you get Executable an ObjectRef wrapper like the rest of the code base you can then use the down casting machinery built on-top of ObjectRef. It might make working with this type easier.
There was a problem hiding this comment.
I have gotten idea, I will try
include/tvm/runtime/vm/vm.h
Outdated
| * \param exec The executable. | ||
| */ | ||
| virtual void LoadExecutable(Executable* exec); | ||
| virtual void LoadExecutable(const ObjectRef& exec); |
There was a problem hiding this comment.
consider change to ObjectPtr<Executable> which can be constructed via https://github.com/apache/tvm/blob/main/include/tvm/runtime/object.h#L877
There was a problem hiding this comment.
It was advice from @jroesch to use ObjectRef. And it seems the simplest way from possible ones. I agree that using of ObjectPtr is preferable but to get it correctly is not so simple task (see below).
src/runtime/vm/executable.cc
Outdated
| return PackedFunc([sptr_to_self, this](TVMArgs args, TVMRetValue* rv) { | ||
| auto vm = make_object<VirtualMachine>(); | ||
| vm->LoadExecutable(this); | ||
| vm->LoadExecutable(ObjectRef(sptr_to_self)); |
There was a problem hiding this comment.
As I know sptr_to_self is already ObjectPtr<Object>, if it is immediatly ObjectPtr<Executable> or can be simply converted to ObjectPtr<Executable> it will be nice, but it is not so. Unfortunately your approach is bad due to GetObjectPtr(...) creates new ObjectPtr<> object which contains copy of raw pointer. There is no any connection between origin and new ObjectPtr. It means that if origin object was released (e.g. when python session where it was generated is closed) we will have pointer to broken object and can not use it. just my PR solves this problem, but your approach does not as I think.
There was a problem hiding this comment.
Sorry for the delayed reply. sptr_to_self actually is guanranteed to point to this in this particular case. So actually GetObjectPtr<Executable>(...) should work in this case. This is mainly because ObjectPtr is an intrusive pointer that directly leverages the object data structure.
To confirm, we can add ICHECK(sptr_to_self.get() == this);
|
cc @YuchenJin @yongwww since this is VM related |
|
Hello @tqchen @jroesch @yongwww @YuchenJin, any questions? May be we merge this PR? |
|
@vvchernov there seems to be a CI issue - from the looks of it it might be flaky - can you re-trigger? |
|
Docs were broken for a while earlier, @vvchernov could you rebase ( |
|
Thanks @driazati ! It works |
|
@driazati does this error seem like a flaky issue to you?
|
|
At first sight the CI error seems completely unrelated to the PR... |
|
@vvchernov would be great if you can confirm my latest comment, which should be a better fix |
…xecutable object for correct work of VirtualMachine on c++ side
|
Thanks @tqchen for your help, I've used your approch with GetObjectPtr. It looks like CI tests should pass soon. May be you recheck my last changes. |
|
Thanks @vvchernov ! |
Use ObjectPtr<Executable> instead of Executable* to solid saving of Executable object for correct work of VirtualMachine on c++ side Co-authored-by: Valery Chernov <valery.chernov@deelvin.com>
The issue was observed during generation of VirtulaMachine Module on python side and using it on c++ one.
Work case: when we work in one python session the lib (exec) object is generated and used for VirtualMachine compilation. Inside VM the raw pointer to the lib (exec) is copied. Due to the lib object is alive along the session the VM object can use the pointer and execute different methods like "set_input", "invoke" and so on.
Unworkable case: if we use python session for generation VM and try to use it on c++ side it does not work. The reason is the lib object died after the session is closed. Thus VM uses the pointer to the spoiled object and it leads to failure.
To fix this problem new field in VM (ObjectPtr) is used instead of Executable* exec_. ObjectPtr object is constructed by GetObjectPtr() and used as before.
There is shorter workaround: use
this->IncRef()in executable.cc. But it looks no so good and I followed @tqchen advice@jwfromm @tmoreau89 please see