Hi, I am a new user of TVM. After going through TVM’s tutorials, I found that there are many ways to execute a compiled module.
Style 1: relay.(build_module).build
+ tvm.contrib.graph_executor
example
with tvm.transform.PassContext(opt_level=3):
lib = relay.build(mod, target=target, params=params)
m = graph_executor.GraphModule(lib["default"](dev))
m.set_input(input_name, tvm.nd.array(img.astype(dtype)))
m.run()
tvm_output = m.get_output(0)
Here we only use the graph executor. (but in build
's source code we also have an AOT option?)
Style 2: relay.build_module.create_executor(...).evaluate().(input, ...)
example
with tvm.transform.PassContext(opt_level=1):
intrp = relay.build_module.create_executor("graph", mod, tvm.cpu(0), target)
tvm_output = intrp.evaluate()(tvm.nd.array(x.astype(dtype)), **params).numpy()
Here we can use ‘graph’, ‘vm’, and ‘debug’ as the executor.
I am curious about:
- will the
build
process intrigue optimization? or what is the relationship between executors and the optimization passes? (b.c. in codes insidebuild_module.build
will callAOTExecutorFactoryModule
orGraphExecutorFactoryModule
). - what is the difference between
tvm.contrib.graph_executor.GraphExecutor
andbuild_module.GraphExecutor
(which is inherited from_interpreter.Executor
saying that it was for debugging purpose?)