def METHOD_NAME(ib, sequence_offset, search_range, sorted_sequence, value, right, out_dtype):
    """Common IR generator for binary search used by CPU and GPU backends.
    `sorted_sequence` is a N-D Buffer whose innermost dimension we want to search for `value`,
    and `search_range` is the size of the innermost dimension. `sequence_offset` is
    a 1-D linearlized offset specifying which of innermost sequences to search.
    So the search for `value` is performed over
    `sorted_sequence[sequence_offset:(sequence_offset + search_range)]`.
    Note that we index N-D Buffer by 1-D linearlized indices.
    """
    lo = ib.allocate(out_dtype, (1,), name="lo", scope="local")
    hi = ib.allocate(out_dtype, (1,), name="hi", scope="local")
    lo[0] = cast(0, out_dtype)
    hi[0] = cast(search_range, out_dtype)
    # Reference: pytorch/aten/src/ATen/native/cuda/Bucketization.cu
    def condition(current_val, target_val):
        if right:
            return current_val <= target_val
        return current_val < target_val
    with ib.while_loop(lo[0] < hi[0]):
        mid = lo[0] + (hi[0] - lo[0] >> 1)
        with ib.if_scope(condition(sorted_sequence[sequence_offset + mid], value)):
            lo[0] = mid + 1
        with ib.else_scope():
            hi[0] = mid
    return lo[0]