C++ 调用 Python

C++ 调用 Python#

由于 PackedFunc 可以接受另一个 PackedFunc 作为参数,因此可以将 Python 中的函数(作为 PackedFunc)传递给 C++。

#include <tvm/runtime/packed_func.h>
#include <tvm/runtime/registry.h>

using namespace tvm::runtime;

namespace tvm_ext {
TVM_REGISTER_GLOBAL("callhello")
.set_body([](TVMArgs args, TVMRetValue* rv) {
  PackedFunc f = args[0];
  f("hello world");
});

} // namespace tvm_ext
# 部署 TVM 模块 的 Makefile 样例
# =================================================================================
IDIR = include
TVM_ROOT=$(shell cd /media/pc/data/lxw/ai/tvm; pwd)
PKG_CXXFLAGS = -std=c++17 -O2 -fPIC\
	-I${TVM_ROOT}/include\
	-I${TVM_ROOT}/3rdparty/dmlc-core/include\
	-I${TVM_ROOT}/3rdparty/dlpack/include\
	-I${IDIR}\
	-DDMLC_USE_LOGGING_LIBRARY=\<tvm/runtime/logging.h\>

PKG_LDFLAGS = -ldl -pthread
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Darwin)
	PKG_LDFLAGS += -undefined dynamic_lookup
endif

.PHONY: clean all

all: outputs/libs/libtvm_ext.so

# 定制 tvm 拓展运行时
# =================================================================================
outputs/libs/libtvm_ext.so: src/tvm_ext.cc
	@mkdir -p $(@D)
	$(CXX) $(PKG_CXXFLAGS) -shared -o $@ $^ $(PKG_LDFLAGS) -L${TVM_ROOT}/build

clean:
	rm -rf outputs/*
%%bash
cd cpp/python_ext
make clean
make
rm -rf outputs/*
/media/pc/data/lxw/envs/anaconda3a/envs/ai/bin/x86_64-conda-linux-gnu-c++ -std=c++17 -O2 -fPIC -I/media/pc/data/lxw/ai/tvm/include -I/media/pc/data/lxw/ai/tvm/3rdparty/dmlc-core/include -I/media/pc/data/lxw/ai/tvm/3rdparty/dlpack/include -Iinclude -DDMLC_USE_LOGGING_LIBRARY=\<tvm/runtime/logging.h\> -shared -o outputs/libs/libtvm_ext.so src/tvm_ext.cc -ldl -pthread -L/media/pc/data/lxw/ai/tvm/build
import set_env
import tvm
from tvm_book.tvm_ext.libinfo import _load_lib
_LIB_EXT, _LIB_EXT_NAME = _load_lib(name="libtvm_ext.so", search_path=["cpp/python_ext/outputs/libs"])

def callback(msg):
  print(msg)

# convert to PackedFunc
f = tvm.runtime.convert(callback)
callhello = tvm.get_global_func("callhello")
# prints hello world
callhello(f)
hello world
tvm.