def METHOD_NAME(op):
    if op.tag == "dense":
        vec_size = [1, 2, 4, 8, 16]
        max_unroll = 32
        dense_out = op.output(0)
        output = outs[0]
        y, x = s[output].op.axis
        c = s[dense_out].op.reduce_axis[0]
        ##### space definition begin #####
        cfg.define_split("tile_y", y, num_outputs=3)
        cfg.define_split("tile_x", x, num_outputs=3)
        cfg.define_split("c_unroll", c, num_outputs=2, max_factor=64)
        # fallback support
        if cfg.is_fallback:
            ref_log = autotvm.tophub.load_reference_log("mali", "rk3399", "dense.mali")
            cfg.fallback_with_reference_log(ref_log)
        ##### space definition end #####
        if dense_out.op in s.outputs:
            dense_out = s.cache_write(output, "local")
        by, ty, yi = cfg["tile_y"].apply(s, output, y)
        bx, tx, xi = cfg["tile_x"].apply(s, output, x)
        s[output].bind(by, te.thread_axis("blockIdx.y"))
        s[output].bind(bx, te.thread_axis("blockIdx.x"))
        s[output].bind(ty, te.thread_axis("threadIdx.y"))
        s[output].bind(tx, te.thread_axis("threadIdx.x"))
        if cfg["tile_y"].size[-1] < max_unroll:
            s[output].unroll(yi)
        if cfg["tile_x"].size[-1] in vec_size:
            s[output].vectorize(xi)
        s[dense_out].compute_at(s[output], tx)
        k = s[dense_out].op.reduce_axis[0]
        y, x = s[dense_out].op.axis
        k, k_unroll = cfg["c_unroll"].apply(s, dense_out, k)
        s[dense_out].reorder(k, k_unroll, y, x)
        s[dense_out].unroll(k_unroll)
        if cfg["tile_y"].size[-1] < max_unroll:
            s[dense_out].unroll(y)
        if cfg["tile_x"].size[-1] in vec_size:
            s[dense_out].vectorize(x)