Can I compile my own relay pass in to dynamic link library?

I use the below command to compile my_own_pass.cc into libpassrelay.so, and which can be success.

g++ my_own_pass.cc -fPIC -shared -o libpassrelay.so -I /tvm/include/ -I tvm/3rdparty/dmlc-core/include/ -I tvm/3rdparty/dlpack/include -ltvm_runtime -L tvm/build/

but error happened when I load libpassrelay.so in the python code.

I use ctypes.cdll.LoadLibrary(“libparserelay.so”) to load library. how can i fix this , thx.

The error report shows that the __tvm_set_device function has been registered for multiple times.

Check your my_own_pass.cc to see where may introduce an extra function registration.

Below is my code, when I add my_own_pass.cc into the TVM project tvm/src/relay/transform and compile together with TVM source. there is no problem。 Problem happened when I only compile my_own_pass.cc into libpassrelay.so。 I can’t find problem in my code, please helo to take a look at my code. thx.

`#include <tvm/relay/analysis.h>
 #include <tvm/relay/attrs/transform.h>
 #include <tvm/relay/expr_functor.h>
 #include <tvm/relay/interpreter.h>
 #include <tvm/relay/op.h>
 #include <tvm/relay/op_attr_types.h>
 #include <tvm/relay/transform.h>
 #include <tvm/runtime/container.h>
 #include <tvm/runtime/ndarray.h>
 #include <tvm/runtime/object.h>

namespace tvm {
namespace relay {


 class ToolChain1 : public ExprVisitor {
 public:

 private:
      std::unordered_map<Expr, bool, ObjectPtrHash, ObjectPtrEqual> memo_;

      void VisitExpr_(const CallNode* call) final {
           //memo_[GetRef<Tuple>(n)] = result;
          ExprVisitor::VisitExpr_(call);
          std::cout << "call happened " << std::endl;
          std::cout << AsText(GetRef<Expr>(call), false, nullptr) << std::endl;
      }
  };

 Expr ToolChainParse1(const Expr& expr, const IRModule& mod) {
    ToolChain1().VisitExpr(expr);
    return expr;
 }

  namespace transform {
  Pass ToolChainParse1() {
          runtime::TypedPackedFunc<Function(Function, IRModule, PassContext)> pass_func =
          [=](Function f, IRModule m, PassContext pc) {
          return Downcast<Function>(ToolChainParse1(f, m));
      };
     return CreateFunctionPass(pass_func, 2, "ToolChainParse1", {});
  }


 TVM_REGISTER_GLOBAL   ("relay._transform.ToolChainParse1").set_body_typed(ToolChainParse1);

  }
 }
 }

`