def METHOD_NAME(self, call):
    # Keep track of our current depth and layer count
    # so we can know whether to skip this layer or not.
    current_depth = self.depth_count
    current_layer = self.valid_op_count - current_depth - 1
    if call.op in self.valid_ops:
        self.depth_count += 1
    # Visit current call operation
    new_fn = self.visit(call.op)
    # Visit current arguments
    args = []
    for arg in call.args:
        args.append(self.visit(arg))
        self.depth_count = current_depth
    # Downcast this op if its the correct type and not skipped.
    if call.op in self.valid_ops and current_layer not in self.skip_layers:
        # Recast inputs to specified type.
        if call.op == relay.op.get("concatenate"):
            if len(call.args) != 1 or not isinstance(call.args[0], relay.expr.Tuple):
                return Call(new_fn, args, call.attrs)
            tuple_args = [self.visit(arg) for arg in call.args[0].fields]
            new_args = list()
            for arg in tuple_args:
                new_args.append(relay.cast(arg, dtype=self.dtype))
            new_args = [relay.expr.Tuple(new_args)]
        else:
            args = [self.visit(arg) for arg in call.args]
            new_args = list()
            for arg in args:
                new_args.append(relay.cast(arg, dtype=self.dtype))
        # If out_dtype is in the attributes, we need to update it.
        orig_dtype = None
        if call.attrs is not None and "out_dtype" in call.attrs.keys():
            new_attr_dict = {}
            for attr in call.attrs.keys():
                attr_value = call.attrs[attr]
                if isinstance(attr_value, tvm.ir.container.Array):
                    attr_value = tuple(attr_value)
                new_attr_dict[str(attr)] = attr_value
            new_attr_dict["out_dtype"] = self.out_dtype
            attr_type = str(call.attrs).split("(")[0]
            new_attrs = tvm.ir.make_node(attr_type, **new_attr_dict)
            if call.attrs["out_dtype"] != "":
                orig_dtype = call.attrs["out_dtype"]
        else:
            new_attrs = call.attrs
        if orig_dtype is None:
            # Perform type inference to determine the original type.
            new_mod = IRModule.from_expr(call)
            new_mod = InferType()(new_mod)
            checked_arg = new_mod["main"].body
            orig_dtype = checked_arg.checked_type.dtype
        # Recast the output for compatibility with other graph operations.
        return relay.cast(Call(new_fn, new_args, new_attrs), orig_dtype)
    # Otherwise return the unchanged call.
    return Call(new_fn, args, call.attrs)