Because the bridge uses c++ std::function, it requires a common ABI between the two in order to make things work, so build from source is indeed the best way
Sometimes other programs will call PackedFunc of TVM, so it is unavoidable to meet the problem of ABI compatibility.
Is it possible to provide an API in TVM like this?
It may be available to avoid the problem of ABI compatibility. : )
In include/tvm/runtime/packed_func.h,
The problem of C++ ABI occurs when we build dll using different version of compiler(gcc, clang) because their internal representation of the std::function is different.
The only way to get around it is to use the C API, which is stable across the dll boundaries. In particular, the PackedFunc that crosses ABI boundary need to be registered as CPackedFunc signature. Neve-the-less it is a bit tricky to do so
Thanks!
Is it avaiable to get around the problem of C++ ABI in my code?
The body_ function will be executed in the instruction of the program which generates PackedFunc rather than the caller, so there is no any problem of C++ ABI in FType body_.
Although the internal name of _RemoteCallPacked may be different in different version of compiler, the offsets of _RemoteCallPacked in the class PackedFunc are the same.
In fact, his code should work. Because the lambda _RemoteCallPacked of his code doesn’t capture anything, According to C++ standard, it could assign to function pointer. C++ standard $5.1.2 said:
The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.
OK, thanks @FrozenGene for clarification. I think it might work for simple call. However, it makes intrusive change to the PackedFunc as a pure C object, which I am not sure is the most ideal case. It also did not handle a natural deletion of the code.
To make things really compatible, I think we could make use of the following code in the MX side.
Basically in the MXNet side, we might need to call into these three functions, however, inorder to make it dependency free, we might want to pass the function pointer of these functions into MXNetBridge
I wonder if it is okay for me to add MXTVMFuncCreateFromCFunc and MXTVMFuncCall APIs in mxnet/src/nnvm/tvm_bridge.cc, since the external program needs to create a PackedFunc instance to pass into MXTVMBridge, then uses MXTVMFuncCall to call the returned functions from MXTVMBridge.
sorry for the delayed reply, how about you do a quick proptype to see if the prof of concept work, and we move on from there. It is not hard to test. We can compile mxnet using gcc while tvm using clang and see if things can run
The implementation of the header file <functional> is different among different compiler.
I replace <functional> to the corresponding version to address the ABI compatibility problem.
<functional> header file is GPL license. We should avoid modifying and including it into TVM project.
GCC 4 and GCC 5 has different abi. Since GCC 5, it has dual abi and can control it using _GLIBCXX_USE_CXX11_ABI macro. Could you provide more detail of ABI issue? Maybe we could find a better way.