def _tensor_field_by_type(tensor_val, builtin_type): if builtin_type == types.bool: return tensor_val.bools.values elif types.is_int(builtin_type): if (builtin_type == types.int64 or builtin_type == types.uint64): return tensor_val.longInts.values if builtin_type in (types.int8, types.uint8, types.uint32): return tensor_val.bytes.values return tensor_val.ints.values elif types.is_float(builtin_type): if (builtin_type == types.fp64): return tensor_val.doubles.values elif (builtin_type == types.fp32): return tensor_val.floats.values elif (builtin_type == types.fp16): return tensor_val.bytes.values else: raise TypeError( "Unsupported float dtype for MIL proto serialization: {}". format(builtin_to_string(builtin_type))) elif builtin_type == types.str: return tensor_val.strings.values else: raise NotImplementedError("Unimplemented tensor type for: " + str(builtin_type))
def _adjust_main_inputs(func): first_op = func.operations[0] if len(func.operations) > 0 else None for input_name, input_var in func.inputs.items(): if (types.is_tensor(input_var.sym_type) or types.is_scalar(input_var.sym_type)) \ and input_var.dtype != types.fp32 \ and input_var.dtype != types.int32: input_dtype_str = types.builtin_to_string(input_var.dtype) if types.is_int(input_var.dtype): # Replace non-int32 input type with int32. logging.warning("Input" + input_var.name + " is of dtype " + input_dtype_str +\ ". Only integer variables of bit width 32 are supported by the CoreML runtime. " +\ "This input will be assigned a dtype of int32. " +\ "No cast will be inserted; the previous dtype will be replaced.") _adjust_var_dtype_helper(input_var, types.int32) elif input_var.dtype == types.fp64: # Replace float64 input type with fp32. logging.warning("Input '" + input_var.name + "' is of dtype fp64. 64 bit float inputs are " +\ "not supported by ML program models. This input will be assigned a dtype " +\ "of fp32. No cast will be inserted; the previous dtype will be replaced.") _adjust_var_dtype_helper(input_var, types.fp32) elif input_var.dtype == types.fp16 \ and func.opset_version >= target.iOS16: pass # do nothing, since fp16 is a valid input type for CoreML else: # This is some other dtype. Change the type to fp32 and add a cast. # This is only a limitation of main--other functions do not represent CoreML model inputs # and do not have the same limitation on input types. supported_dtypes = "{int32, fp32, fp64}" if func.opset_version < target.iOS16 else \ "{int32, fp16, fp32, fp64}" msg = "\nInput '{}' is of dtype {}. The " +\ "CoreML runtime does not support inputs with this dtype " +\ "(supported dtypes are: {}). This input will be assigned a dtype of " +\ "fp32. A cast will be inserted at the beginning of the program to " +\ "convert the input to the originally defined dtype.\n" if input_var.dtype == types.fp16: msg += "fp16 dtype input is supported if the function.opset_version is chosen to be at least " \ "iOS16/macOS13.\n" logging.warning( msg.format(input_var.name, input_dtype_str, supported_dtypes)) casted_input_var = mb.cast(x=input_var, dtype=input_dtype_str, before_op=first_op) func.replace_uses_of_var_after_op( anchor_op=casted_input_var.op, old_var=input_var, new_var=casted_input_var) _adjust_var_dtype_helper(input_var, types.fp32)
def _adjust_main_inputs(func): first_op = func.operations[0] if len(func.operations) > 0 else None for input_name, input_var in func.inputs.items(): if (_types.is_tensor(input_var.sym_type) or _types.is_scalar(input_var.sym_type)) \ and input_var.dtype != _types.fp32 \ and input_var.dtype != _types.int32: input_dtype_str = _types.builtin_to_string(input_var.dtype) if _types.is_int(input_var.dtype): # Replace non-int32 input type with int32. _warnings.warn("Input" + input_var.name + " is of dType " + input_dtype_str +\ ". Only integer variables of bit width 32 are supported by the CoreML runtime. " +\ "This input will be assigned a dType of int32. " +\ "No cast will be inserted; the previous dtype will be replaced.") _adjust_var_dtype_helper(input_var, _types.int32) elif input_var.dtype == _types.fp64: # Replace float64 input type with fp32. _warnings.warn("Input" + input_var.name + " is of dtype fp64. 64 bit float inputs are " +\ "not supported by ML program models. This input will be assigned a dType " +\ "of fp32. No cast will be inserted; the previous dtype will be replaced.") _adjust_var_dtype_helper(input_var, _types.fp32) else: # This is some other dType. Change the type to fp32 and add a cast. # This is only a limitation of main--other functions do not represent CoreML model inputs # and do not have the same limitation on input types. _warnings.warn("Input" + input_var.name + " is of dType " + input_dtype_str + ". The " +\ "CoreML runtime does not support inputs with this dType (only fp32 and " +\ "int32 inputs are supported). This input will be assigned a dType of " +\ "fp32. A cast will be inserted at the beginning of the program to " +\ "convert the input to the originally defined dType.") with func: casted_input_var = _mb.cast(x=input_var, dtype=input_dtype_str, before_op=first_op) func.replace_uses_of_var_after_op( anchor_op=casted_input_var.op, old_var=input_var, new_var=casted_input_var) _adjust_var_dtype_helper(input_var, _types.fp32)
def _adjust_var(var): """ Changes the dtype of the provided variable according to the rules outlined in the top level pass comment (see adjust_io_to_supported_types). """ if (types.is_tensor(var.sym_type) or types.is_scalar(var.sym_type)) \ and var.dtype not in __RUNTIME_SUPPORTED_TYPES: dtype_str = types.builtin_to_string(var.dtype) if types.is_int(var.dtype): # Replace non-int32 input type with int32. logging.warning("Input '" + var.name + "' is of dtype " + dtype_str +\ ". Only integer variables of bit width 32 are supported by the CoreML runtime. " +\ "This input will be assigned a dtype of int32. " +\ "No cast will be inserted; the previous dtype will be replaced.") _adjust_var_dtype_helper(var, types.int32) else: # This is some other unsupported dtype. Change the input type to fp32. logging.warning("Var " + var.name + " is of dtype " + dtype_str + ". The CoreML runtime " +\ "does not support this dtype (only fp16, fp32, bool, and int32 are supported). " +\ "This input will be assigned a dtype of fp32. No cast will be inserted; " +\ "the previous dtype will be replaced.") _adjust_var_dtype_helper(var, types.fp32)