forked from huawei/mindspore2022
!23584 Optimize the exception info of tensor index
Merge pull request !23584 from zhangzhaoju/master_syntax
This commit is contained in:
commit
e30715d4e5
|
|
@ -1603,20 +1603,21 @@ def check_is_tensor_bool_cond(shp):
|
|||
"""check if tensor is a bool condition"""
|
||||
if shp in ((), (1,)):
|
||||
return True
|
||||
raise ValueError("The truth value of an array with several elements is ambiguous.")
|
||||
raise ValueError(f"Only tensor which shape is () or (1,) can be converted to bool, but got tensor shape is {shp}")
|
||||
|
||||
|
||||
@constexpr
|
||||
def const_tensor_to_bool(x):
|
||||
"""convert bool tensor to bool condition"""
|
||||
if x is None:
|
||||
raise ValueError("Only constant tensor bool can be converted to bool")
|
||||
raise ValueError("Only tensor which shape is () or (1,) can be converted to bool, but got None")
|
||||
x = x.asnumpy()
|
||||
if x.shape == ():
|
||||
return bool(x)
|
||||
if x.shape == (1,):
|
||||
return bool(x[0])
|
||||
raise ValueError("The truth value of an array with several elements is ambiguous.")
|
||||
raise ValueError(
|
||||
f"Only tensor which shape is () or (1,) can be converted to bool, but got tensor shape is {x.shape}")
|
||||
|
||||
|
||||
@constexpr
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ def tensor_item(data, *args):
|
|||
def tensor_itemset(data, *args):
|
||||
"""Tensor setitem by index and value."""
|
||||
if not args:
|
||||
const_utils.raise_value_error("itemset must have at least one argument")
|
||||
const_utils.raise_value_error("'Tensor.itemset()' must have at least one argument, but got None.")
|
||||
if len(args) == 2:
|
||||
if const_utils.judge_index_type(F.typeof(args[0]), mstype.int64):
|
||||
return tensor_itemset_by_number_with_number(data, args[0], args[1])
|
||||
|
|
@ -172,7 +172,9 @@ def tensor_itemset(data, *args):
|
|||
return tensor_itemset_by_tuple_with_number(data, args[0], args[1])
|
||||
const_utils.raise_type_error("The index object cannot be interpreted as an integer")
|
||||
if len(args) > 2:
|
||||
const_utils.raise_value_error("incorrect number of indices for array")
|
||||
exp_msg = const_utils.gen_exception_msg("'Tensor.itemset()' must have at most 2 argument, but got {}.",
|
||||
len(args))
|
||||
const_utils.raise_value_error(exp_msg)
|
||||
return tensor_itemset_with_number(data, args[0])
|
||||
|
||||
|
||||
|
|
@ -181,10 +183,16 @@ tensor_operator_registry.register("itemset", tensor_itemset)
|
|||
|
||||
|
||||
def tensor_itemset_with_number(data, number_value):
|
||||
"""set value of tensor whose shape is (1,)"""
|
||||
if not const_utils.judge_index_type(F.typeof(number_value), mstype.number_type):
|
||||
const_utils.raise_index_error("The Tensor could only use the number value for itemset")
|
||||
exp_msg = const_utils.gen_exception_msg(
|
||||
"'Tensor.itemset()' only support number input, but got {}", number_value)
|
||||
const_utils.raise_index_error(exp_msg)
|
||||
if data.shape != (1,):
|
||||
const_utils.raise_index_error("The Tensor without shape (1,) could not use the itemset api with only one args")
|
||||
exp_msg = const_utils.gen_exception_msg(
|
||||
"Only tensor which shape is (1,) support 1 arg that means omit index, "
|
||||
"but the tensor shape is {} and got 1 input.", data.shape)
|
||||
const_utils.raise_index_error(exp_msg)
|
||||
return const_utils.make_tensor((number_value,), F.dtype(data))
|
||||
|
||||
|
||||
|
|
@ -197,7 +205,9 @@ def tensor_itemset_by_number_with_number(data, int_index, number_value):
|
|||
|
||||
def tensor_itemset_by_tuple_with_number(data, tuple_index, nubmer_value):
|
||||
if len(tuple_index) != data.ndim:
|
||||
const_utils.raise_value_error("incorrect number of indices for array")
|
||||
exp_msg = const_utils.gen_exception_msg(
|
||||
"Tuple index len({}) is not same to tensor dimension({})", len(tuple_index), data.ndim)
|
||||
const_utils.raise_index_error(exp_msg)
|
||||
return tensor_setitem_by_tuple_with_number(data, tuple_index, nubmer_value)
|
||||
|
||||
|
||||
|
|
@ -234,7 +244,9 @@ def _transform_ellipsis_to_slice(data, tuple_index, op_name):
|
|||
ellipsis_cnt = len(ellipsis_positions)
|
||||
# pylint: disable=chained-comparison
|
||||
if ellipsis_occupy_dims < 0 and ellipsis_cnt >= 0:
|
||||
const_utils.raise_index_error("too many indices for array")
|
||||
exp_msg = const_utils.gen_exception_msg(
|
||||
"Tuple index {} out rang of tensor shape {}.", tuple_index, data_shape)
|
||||
const_utils.raise_index_error(exp_msg)
|
||||
|
||||
tuple_index_new = ()
|
||||
for i, index in enumerate(tuple_index):
|
||||
|
|
@ -257,7 +269,7 @@ def _expand_data_dims(data, tuple_index):
|
|||
expand_positions += (i,)
|
||||
elif const_utils.judge_index_type(index_type, mstype.bool_):
|
||||
if not index:
|
||||
const_utils.raise_index_error("Dose not support 'False'.")
|
||||
const_utils.raise_index_error("Bool element of tuple index must be 'True', but got 'False'.")
|
||||
tuple_index_new += (const_utils.make_tensor([0], mstype.int64),)
|
||||
expand_positions += (i,)
|
||||
else:
|
||||
|
|
@ -284,7 +296,9 @@ def tensor_index_by_number(data, number_index):
|
|||
return _tensor_index_by_bool(data, number_index)
|
||||
if isinstance(number_index, int):
|
||||
return _tensor_index_by_integer(data, number_index)
|
||||
return const_utils.raise_index_error("Only support integers, slices(`:`), ellipsis(`...`), None and bool.")
|
||||
exp_msg = const_utils.gen_exception_msg(
|
||||
"Number index of tensor must be int or bool, but got {}.", number_index)
|
||||
return const_utils.raise_index_error(exp_msg)
|
||||
|
||||
|
||||
def _tensor_index_by_bool(data, bool_value):
|
||||
|
|
@ -326,7 +340,7 @@ def tensor_index_by_list(data, list_index):
|
|||
if const_utils.judge_indexes_types(indexes_types, mstype.int_type + (mstype.bool_,)):
|
||||
tensor_index = const_utils.sequence_to_index(list_index, data_shape[0])
|
||||
if tensor_index is False:
|
||||
const_utils.raise_index_error("Getitem does not support empty list, this will reference shape '0'.")
|
||||
const_utils.raise_index_error("When tensor is indexed by list, the list can't be empty.")
|
||||
return F.gather(data, tensor_index, 0)
|
||||
|
||||
tuple_index_new = ()
|
||||
|
|
@ -408,12 +422,17 @@ def _tensor_getitem_by_tuple(data, tuple_index, op_name):
|
|||
elif i in sequence_positions:
|
||||
tensor_index = const_utils.sequence_to_index(index, dim_size)
|
||||
if tensor_index is False:
|
||||
const_utils.raise_index_error('Tensor with size 0 is not supported')
|
||||
const_utils.raise_index_error("The sequence element(tuple/list) in tuple index can't be empty.")
|
||||
tuple_index_new += (tensor_index,)
|
||||
tensor_indexes.append(tensor_index)
|
||||
tensor_positions += (i,)
|
||||
elif i in tensor_positions:
|
||||
const_utils.check_type_valid(F.dtype(index), mstype.int_type, op_name)
|
||||
invalid = const_utils.check_type_invalid(F.dtype(index), mstype.int_type)
|
||||
if invalid:
|
||||
exp_msg = const_utils.gen_exception_msg(
|
||||
"The tensor element in tuple index must be int type, but got {}.", F.dtype(index))
|
||||
const_utils.raise_index_error(exp_msg)
|
||||
tensor_index = F.cast(index, mstype.int64)
|
||||
tuple_index_new += (tensor_index,)
|
||||
tensor_indexes.append(tensor_index)
|
||||
|
|
@ -488,7 +507,11 @@ def _generate_indices_from_tuple(data, tuple_index, op_name, fancy_position):
|
|||
tensor_indexes.append(tensor_index)
|
||||
tensor_positions += (i,)
|
||||
elif i in tensor_positions:
|
||||
const_utils.check_type_valid(F.dtype(index), mstype.int_type, op_name)
|
||||
invalid = const_utils.check_type_invalid(F.dtype(index), mstype.int_type)
|
||||
if invalid:
|
||||
exp_msg = const_utils.gen_exception_msg(
|
||||
"The tensor element in tuple index must be int type, but got {}.", F.dtype(index))
|
||||
const_utils.raise_index_error(exp_msg)
|
||||
tensor_index = F.cast(index, mstype.int64)
|
||||
tuple_index_new += (tensor_index,)
|
||||
tensor_indexes.append(tensor_index)
|
||||
|
|
@ -645,7 +668,10 @@ def tensor_setitem_by_tensor_with_number(data, index, value):
|
|||
def tensor_setitem_by_tensor_with_sequence(data, index, value):
|
||||
"""Assigns the tensor by tensor with tuple value."""
|
||||
index_dtype = F.dtype(index)
|
||||
const_utils.check_type_valid(index_dtype, (mstype.int32, mstype.int64), const_utils.TENSOR_SETITEM)
|
||||
invalid = const_utils.check_type_invalid(index_dtype, (mstype.int32, mstype.int64))
|
||||
if invalid:
|
||||
exp_msg = const_utils.gen_exception_msg("The tensor index must be int type, but got {}.", index_dtype)
|
||||
const_utils.raise_index_error(exp_msg)
|
||||
return _tensor_setitem_by_tensor_with_sequence(data, index, value)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -276,15 +276,21 @@ def judge_indexes_types(dtypes, target_type):
|
|||
return True
|
||||
|
||||
|
||||
@constexpr
|
||||
def check_type_invalid(dtype, target_type):
|
||||
"""Checks whether the dtype is valid."""
|
||||
return dtype != target_type and (isinstance(target_type, (list, tuple)) and dtype not in target_type)
|
||||
|
||||
|
||||
@constexpr
|
||||
def check_type_valid(dtype, target_type, op_name):
|
||||
"""Checks whether the dtype is valid."""
|
||||
if dtype != target_type and (isinstance(target_type, (list, tuple)) and dtype not in target_type):
|
||||
if op_name in (TENSOR_GETITEM, TENSOR_SETITEM):
|
||||
raise IndexError(
|
||||
f"The '{op_name}' doesn't supoort {dtype}' and expect to receive {target_type}.")
|
||||
f"The '{op_name}' doesn't support {dtype}' and expect to receive {target_type}.")
|
||||
raise TypeError(
|
||||
f"The '{op_name}' doesn't supoort {dtype}' and expect to receive {target_type}.")
|
||||
f"The '{op_name}' doesn't support {dtype}' and expect to receive {target_type}.")
|
||||
|
||||
|
||||
@constexpr
|
||||
|
|
@ -834,3 +840,8 @@ def use_copy_slice(tuple_index):
|
|||
isinstance(tuple_index[1], slice) and tuple_index[1].step in (1, None) and
|
||||
all(x == slice(None, None, None) for x in tuple_index[2:]))
|
||||
return False
|
||||
|
||||
|
||||
@constexpr
|
||||
def gen_exception_msg(msg_format, *args):
|
||||
return msg_format.format(args)
|
||||
|
|
|
|||
Loading…
Reference in New Issue