Skip to content

[RFC][Codegen] Broadcast ops with symbolic shape #3390

Description

@yzhliu

We are trying to use TVM to generate operator definitions for MXNet.

The gap is, despite the fact that TVM compute/schedule can deal with symbolic shape, some compute definition strongly rely on a fixed shape. For example, broadcast ops,

A = tvm.placeholder(shape=(tvm.var("a1"), tvm.var("a2")))
B = tvm.placeholder(shape=(tvm.var("b1"), tvm.var("b2")))
C = A + B

Currently topi's broadcast implement will not work as it needs to check whether each dim equal to ONE. e.g., https://github.com/dmlc/tvm/blob/master/topi/include/topi/detail/broadcast.h#L59

While in the case of AOT for MXNet (instead of JIT), we don't know the shape at the compile time.

My proposal is, introduce a new type of buffer (e.g., broadcast buffer), insert stride[i] = (shape[i] == 1) ? 0 : stride[i] in arg_binder.cc, for example,

C[i * s1 + j] = A[i * sa1 + j] + B[i * sb1 + j]

if shape(A) = [10, 3] and shape(B) = [1, 3], then the previous code will set sb1 = 0, which will be correct.

And the compute definition can be,

m0, m1 = tvm.var("m0"), tvm.var("m1")
n0, n1 = tvm.var("n0"), tvm.var("n1")
o0, o1 = tvm.var("o0"), tvm.var("o1")

A = tvm.placeholder((m0, m1), name='A')
B = tvm.placeholder((n0, n1), name='B')

C = tvm.compute((o0, o1), lambda i, j: A[i, j] + B[i, j], name='C')

Ab = tvm.decl_buffer(A.shape, A.dtype, type="broadcast")
Bb = tvm.decl_buffer(B.shape, B.dtype, type="broadcast")
s = tvm.create_schedule(C.op)
f = tvm.lower(sch, [A, B, C], binds={A:Ab, B:Bb})

Related PR: #3389

@tqchen @reminisce @junrushao1994

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions