def test_constexpr_use_inputs_instead_of_attributes(opset_version):
        """Test the constexpr uses inputs instead of attributes starting from iOS18."""

        @mb.program(input_specs=[], opset_version=ct.target.iOS17)
        def prog_ios17():
            return mb.constexpr_lut_to_dense(
                lut=np.array([1.0, 2.0, 3.0, 4.0]),
                indices=np.array([10, 4]).astype(np.uint8),
                shape=np.array([5]).astype(np.uint32),
            )

        @mb.program(input_specs=[], opset_version=ct.target.iOS18)
        def prog_ios18():
            return mb.constexpr_lut_to_dense(
                indices=np.array([4, 8, 10, 13, 24, 5, 6, 9, 13, 31, 17, 7, 2, 8, 3, 1])
                .reshape((2, 4, 2))
                .astype(np.uint8),
                lut=_TestConstexprLut._generate_lut(shape=(1, 2, 1, 256, 3)),
                vector_axis=1,
            )

        mlmodel = ct.convert(
            prog_ios17 if opset_version == ct.target.iOS17 else prog_ios18,
            convert_to="mlprogram",
            minimum_deployment_target=opset_version,
        )

        # Iterates the milproto in mlmodel to make sure lut op uses inputs instead of attributes.
        mil = mlmodel.get_spec().mlProgram
        for function in mil.functions.values():
            for block in function.block_specializations.values():
                for op in block.operations:
                    if op.type == "constexpr_lut_to_dense":
                        # The "attributes" field has at least one value for "name".
                        expected_attributes_num = 1
                        expected_inputs_num = 0
                        if opset_version >= ct.target.iOS18:
                            # Since iOS18, constexpr ops use inputs instead of attributes in milproto.
                            expected_inputs_num += 3
                        else:
                            expected_attributes_num += 3

                        assert len(op.attributes.values()) == expected_attributes_num
                        assert len(op.inputs.values()) == expected_inputs_num
Test the constexpr uses inputs instead of attributes starting from iOS18.
coremltools/converters/mil/backend/mil/test_load.py