def slice_by_size(const_context, builder, op):
    """
    If the inputs satisfy
    1. op.x has static input shape for those dimension whose size is not -1
    2. op.begin and op.size are both known during compile time
    we use add_slice_static directly

    Otherwise, build a block of ops achieving slice_by_size with dynamic input x and size.
    """

    # The static case
    if op.begin.val is not None and op.size.val is not None:
        begin = op.begin.val
        size = op.size.val
        rank = op.x.rank
        end = []

        for i in range(rank):
            if size[i] == -1:
                end.append(op.x.shape[i])
            else:
                end.append(begin[i] + size[i])

        if not any_symbolic(end):
            builder.add_slice_static(
                name=op.name,
                input_name=make_input(const_context, builder, op.x),
                output_name=op.outputs[0].name,
                begin_ids=begin,
                end_ids=end,
                strides=[1] * rank,
                begin_masks=[False] * rank,
                end_masks=[False] * rank,
                squeeze_masks=[False] * rank,
            )
            return

    # The dynamic case
    # get the end_index of input x
    # for instance, x with shape [2,3,4] results in [2,3,4]
    end_index_name = op.name + "_end_index"
    builder.add_get_shape(
        name=end_index_name,
        input_name=make_input(const_context, builder, op.x),
        output_name=end_index_name,
    )

    # get the mask where size = -1
    # for instance, size = [-1,1,2] results in [1,0,0]
    const_name = op.name + "_const_name"
    add_const(const_context, builder, const_name, _np.array([-1] * op.x.rank))

    is_end_mask_name = op.name + "_is_end_mask"
    builder.add_equal(
        name=is_end_mask_name,
        input_names=make_input(const_context, builder, [const_name, op.size]),
        output_name=is_end_mask_name,
    )

    # get the mask where size != -1
    # for instance, size = [-1,1,2] results in [0,1,1]
    is_not_end_mask_name = op.name + "_is_not_end_mask"
    builder.add_not_equal(
        name=is_not_end_mask_name,
        input_names=make_input(const_context, builder, [const_name, op.size]),
        output_name=is_not_end_mask_name,
    )

    # get the end index for dimensions i where size[i] = -1
    # for size[i] != -1, just make it 0
    # for instance, x with shape [2,3,4] and size = [-1,1,2]
    # results in [2,0,0]
    end_index_with_mask_name = op.name + "_end_index_with_mask"
    builder.add_elementwise(
        name=end_index_with_mask_name,
        input_names=[end_index_name, is_end_mask_name],
        output_name=end_index_with_mask_name,
        mode="MULTIPLY",
    )

    # get the end index for dimension i where size[i] != -1
    # for size[i] = 1, just make it 0
    # for instance, x with shape [2,3,4], size = [-1,1,2],
    # begin = [0,1,1] results in [0,2,3]
    end_ids = op.name + "_end_ids"
    builder.add_elementwise(
        name=end_ids,
        input_names=make_input(const_context, builder, [op.begin, op.size]),
        output_name=end_ids,
        mode="ADD",
    )

    end_index_without_mask_name = op.name + "_end_index_without_mask"
    builder.add_elementwise(
        name=end_index_without_mask_name,
        input_names=make_input(const_context, builder, [is_not_end_mask_name, end_ids]),
        output_name=end_index_without_mask_name,
        mode="MULTIPLY",
    )

    # add two end index array together to get the final index
    final_end_index_name = op.name + "_final_index"
    builder.add_elementwise(
        name=final_end_index_name,
        input_names=make_input(
            const_context,
            builder,
            [end_index_with_mask_name, end_index_without_mask_name],
        ),
        output_name=final_end_index_name,
        mode="ADD",
    )

    input_names = make_input(
        const_context, builder, [op.x, op.begin, final_end_index_name]
    )
    builder.add_slice_dynamic(
        name=op.name, input_names=input_names, output_name=op.outputs[0].name
    )

    If the inputs satisfy
    1. op.x has static input shape for those dimension whose size is not -1
    2. op.begin and op.size are both known during compile time
    we use add_slice_static directly

    Otherwise, build a block of ops achieving slice_by_size with dynamic input x and size.
    
coremltools/converters/mil/backend/nn/op_mapping.py