What's the difference between tvm extern and hybrid script?


#1

Both tvm extern and hybrid script can define python function by userself, like below:

(1) tvm extern

@tvm.register_func(“tvm.contrib.my_tvm_addone”)
def my_tvm_addone(x, y):
print(“my_tvm_addone signatures: %s, %s” % (type(x), type(y)))
tvm.nd.array(x.asnumpy() + 1).copyto(y)

A = tvm.placeholder((n,), name=‘A’)
B = tvm.extern(A.shape, [A], lambda ins, outs: tvm.call_packed( “tvm.contrib.my_tvm_addone”, ins[0], outs[0]), name=“C”)
s = tvm.create_schedule(B.op)

(2) hybrid script

@tvm.hybrid.script
def outer_product(a, b, c):
c = output_tensor((100, 99), ‘float32’)
for i in range(a.shape[0]):
for j in range(b.shape[0]):
c[i, j] = a[i] * b[j]
return c

a = numpy.random.randn(100)
b = numpy.random.randn(99)
c = outer_product(a, b)
i, j = c.op.axis
sch = tvm.create_schedule(op)
jo, ji = sch.split(j, 4)
sch.vectorize(ji)

The clear point is that Hybrid script support schedule primitives and tvm extern don’t,How about the other differences?


#2

They are pretty much different thing. tvm.extern basically allows you plug-in anything as long as they are packed function, while hybrid script is like yet another way to build tvm’s low-level ir.

CC @were the author of hybrid script


#3

extern still calls the python function.
hybrid will lower it to machine cpu native.


#4

Thanks!
I meet with another question,i use hybrid script and bind in/out tensor with decl_buffer specified with strides, then build error occurred:

File “/home/zhoujian/TVM/tvm_github/tvm/src/pass/storage_flatten.cc”, line 429
TVMError: Check failed: slice->strides.size() == 0U (2 vs. 0) : Trying to bind compact buffer to strided one strides=[VA0,

Refer to “tvm/python/hybrid/runtime.py”, the hybrid output_tensor is realized with numpy array that don’t support strides.

In contrast, tvm.extern support binding input and output with decl_buffer using strides.

Will the hybrid support strides buffer in the future? @were


#5

i did not test that but i suppose it will work.

tvm.build(hybrid_op, args, binds={in: buffer})

did you use binds in this fashion?


#6

I have already test it in many cases.
It doesn’t work if hybrid op’s in or out tensor is binded with a strided decl_buffer outside.
@were