code: def test_higher_order():
      metatable = {"VirtualDevice": [CPU, GPU]}
  
      # The constraint on %a flows back to %y via %f and %h
      def input():
          return tvm.relay.parse(
              """
              #[version = "0.0.5"]
              def @main(%x: Tensor[(5, 7), float32], %y: Tensor[(5, 7), float32]) {
                let %f = fn (%g) {
                  fn (%a) {
                    %0 = on_device(%a, virtual_device=meta[VirtualDevice][0]);
                    %1 = %g(%0);
                    add(%1, %x)
                  }
                };
                let %h = fn (%b) {
                  negative(%b)
                };
                %2 = %f(%h);
                %3 = %2(%y);
                subtract(%x, %3)
              }
          """,
              "from_string",
              None,
              metatable,
          )
  
      def expected():
          return tvm.relay.parse(
              """
              #[version = "0.0.5"]
              def @main(%x {virtual_device=meta[VirtualDevice][1]}: Tensor[(5, 7), float32], %y {virtual_device=meta[VirtualDevice][0]}: Tensor[(5, 7), float32],
                        virtual_device=meta[VirtualDevice][1]) {
                let %f = fn (%g {virtual_device=meta[VirtualDevice][1]}, virtual_device=meta[VirtualDevice][1]) {
                  fn (%a {virtual_device=meta[VirtualDevice][0]}, virtual_device=meta[VirtualDevice][1]) {
                    %0 = device_copy(%a, src_virtual_device=meta[VirtualDevice][0], dst_virtual_device=meta[VirtualDevice][1]);
                    %1 = %g(%0);
                    add(%1, %x)
                  }
                };
                let %h = fn (%b  {virtual_device=meta[VirtualDevice][1]}, virtual_device=meta[VirtualDevice][1]) {
                  negative(%b)
                };
                %2 = %f(%h);
                %3 = %2(%y);
                subtract(%x, %3)
              }
          """,
              "from_string",
              None,
              metatable,
          )
  
      def ref(x, y):
          def f(g):
              return lambda a: np.add(g(a), x)
  
          def h(b):
              return np.negative(b)
  
          return np.subtract(x, f(h)(y))
  
      exercise(input(), expected(), ref, rands((5, 7), 2))
  
imports: import tvm
  from tvm import relay
  from tvm.script import tir
  import tvm.testing
  import numpy
  import os
label_desc: Use image node_id 15 for calling a global function with example usage: test_higher_order() and returns: tvm, tvm, np, function, np