Where is the Halide IR generated?

Hello! i’m new user of TVM.

after finishing tutorial, i make simple network using Relay.

L1 = relay.nn.conv2d(X_input, param_1, channels=6, kernel_size=[3, 3])
L2 = relay.nn.bias_add(L1, param_2)
L3 = relay.nn.relu(L2)
L4 = relay.nn.conv2d(L3, param_3, channels=6, kernel_size=[3, 3])
L5 = relay.nn.bias_add(L4, param_4)
L6 = relay.nn.relu(L5)
L7 = relay.nn.softmax(L6, axis=1) 

The L1, L4 are same conv2d and when i lower them in Halide IR, generate just one Halide IR code. but i want to modify Halide IR just L4’s conv2d not L1.

so my plan is modify the code where generate Halide IR from graph. but i can’t easily find the code that generate Halide IR in TVM.

If anyone knows about this part, can someone give me a hint ???

My understanding is that Halide IR is created through TOPI. TOPI is the mechanism which defines compute and schedules for each backend for different Relay IR operators.

By the way – ‘Halide IR’ is now TVM IR as I see it, since the Halide dependency has been removed completely from TVM. It’s also been evolved internally.

3 Likes

Thank you! abd!!

Good information. Thank you. plus… Can you tell me where to get that information?

Hey,

I might be wrong about this but, the lowered code are the same because:

  1. The operators are the same (i.e. both are conv2d of the same class) and therefore both are defined by the same TOPI conv2d compute definition
  2. The TOPI schedule for conv2d (I guess, the vanilla one without any HW information I cant be sure) is independent on the tensor sizes of the inputs/weights

So (at a high level) what you need to do is the following:

  1. Define a way to discriminate between these two conv2ds (I dont think you can do this by where it happens in a graph, but rather by some value of the parameters of both calls)
if channel_size<=3:
    #This is L1
else:
    #This is L4
  1. Rewrite/overload/replace the link between the conv2d computation rule and which scheduling rule corresponds
    • In layman’s terms you need to “call” two different scheduling rules depending on your discrimination logic
    • I think the standard practice is to use decorators to register schedules
  2. Implement both scheduling rules to make them different
    • Obviously you could just implement one of the two since you mention L4 should be different to L1 (assuming the generic schedule in TOPI works for your L1)

I know this is kind of cryptic (since you seem to be new to TVM), but the best “real” example I can give you as starting point is here which is how the VTA discriminates between using the arm schedule (for specific conv2d layers which are not computable on the VTA) and those which can and require a “vta specific” schedule.

Hope this helps

1 Like

Thank you aca88! It really useful to me.

The solution that you presented really helped me a lot. Also, the VTA code seems to have a lot of really useful information. I wasn’t interested in VTA, but I think i should study that.

thank you!