forked from huawei/mindspore2022
fix sparse argcheck
This commit is contained in:
parent
56183ab741
commit
81a8716afd
|
|
@ -15,7 +15,7 @@ mindspore.CSRTensor
|
|||
- **indptr** (Tensor) - 形状为 `[M]` 的一维整数张量,其中M等于 `shape[0] + 1` , 表示每行非零元素的在 `values` 中存储的起止位置。默认值:None。支持的数据类型为 `int16` , `int32` 和 `int64` 。
|
||||
- **indices** (Tensor) - 形状为 `[N]` 的一维整数张量,其中N等于非零元素数量,表示每个元素的列索引值。默认值:None。支持的数据类型为 `int16` , `int32` 和 `int64` 。
|
||||
- **values** (Tensor) - 形状为 `[N]` 的一维张量,用来表示索引对应的数值。默认值:None。
|
||||
- **shape** (tuple(int)) - 形状为ndims的整数元组,用来指定稀疏矩阵的稠密形状。目前只支持2维CSRTensor,所以 `shape` 长度只能为2。`shape[0]` 表示行数,因此必须和 `indptr[0] - 1` 值相等。默认值:None。
|
||||
- **shape** (tuple(int)) - 形状为ndims的整数元组,用来指定稀疏矩阵的稠密形状。目前只支持2维CSRTensor,所以 `shape` 长度只能为2。`shape[0]` 表示行数,因此必须和 `M - 1` 值相等。默认值:None。
|
||||
- **csr_tensor** (CSRTensor) - CSRTensor对象,用来初始化新的CSRTensor。默认值:None。
|
||||
|
||||
**输出:**
|
||||
|
|
@ -69,7 +69,7 @@ mindspore.CSRTensor
|
|||
|
||||
**参数:**
|
||||
|
||||
- **dense_vector** (Tensor) - 形状为 `[N,1]` 的一维张量,其中N等于CSRTensor的列数。
|
||||
- **dense_vector** (Tensor) - 形状为 `[N,1]` 的二维张量,其中N等于CSRTensor的列数。
|
||||
|
||||
**返回:**
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,19 @@ inline void CheckSparseShape(ShapeVector sparse_shp, ShapeVector dense_shp) {
|
|||
}
|
||||
}
|
||||
}
|
||||
inline void CheckSparseShape(const size_t shape_size, const size_t expected_dim, const std::string &arg_name) {
|
||||
if (shape_size != expected_dim) {
|
||||
MS_EXCEPTION(mindspore::ValueError) << arg_name << " must be a " << expected_dim
|
||||
<< "-dimensional tensor, but got a " << shape_size << "-dimensional tensor.";
|
||||
}
|
||||
}
|
||||
inline void CheckSparseIndicesDtype(const mindspore::TypePtr data_type, const std::string &arg_name) {
|
||||
if (!(data_type->equal(mindspore::kInt16) || data_type->equal(mindspore::kInt32) ||
|
||||
data_type->equal(mindspore::kInt64))) {
|
||||
MS_EXCEPTION(mindspore::TypeError) << "The dtype of " << arg_name << " must be Int16 or Int32 or Int64, but got "
|
||||
<< data_type->ToString() << ".";
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace mindspore {
|
||||
|
|
@ -370,19 +383,14 @@ AbstractBasePtr InferImplMakeCOOTensor(const AnalysisEnginePtr &, const Primitiv
|
|||
auto dense_shape = CheckArg<AbstractTuple>(op_name, args_spec_list, kIndexTwo);
|
||||
|
||||
auto indices_dtype = indices->element()->BuildType();
|
||||
if (!indices_dtype->isa<Int>()) {
|
||||
MS_EXCEPTION(TypeError) << "The dtype of indices must be a Int, but got " << indices_dtype->ToString();
|
||||
}
|
||||
CheckSparseIndicesDtype(indices_dtype, "indices");
|
||||
|
||||
auto indices_shp = indices->shape()->shape();
|
||||
if (indices_shp.size() != kSizeTwo) {
|
||||
MS_EXCEPTION(TypeError) << "Indices must be a 2 dimensional tensor, but got a " << indices_shp.size()
|
||||
<< " dimension tensor";
|
||||
}
|
||||
CheckSparseShape(indices_shp.size(), kSizeTwo, "Indices");
|
||||
|
||||
auto values_shp = values->shape()->shape();
|
||||
if (values_shp.size() != kSizeOne) {
|
||||
MS_EXCEPTION(TypeError) << "Values must be a 1 dimensional tensor, but got a " << values_shp.size()
|
||||
<< " dimension tensor";
|
||||
}
|
||||
CheckSparseShape(values_shp.size(), kSizeOne, "Values");
|
||||
|
||||
if (indices_shp[kIndexZero] != values_shp[kIndexZero]) {
|
||||
MS_EXCEPTION(TypeError) << "Indices and values must equal in their shape, but got indices shape: " << indices_shp[0]
|
||||
<< ", values shape: " << values_shp[kIndexZero];
|
||||
|
|
@ -505,14 +513,19 @@ AbstractBasePtr InferImplCSRMV(const AnalysisEnginePtr &, const PrimitivePtr &pr
|
|||
<< "but sparse tensor has " << sparse_shape.size() << " dimensions, "
|
||||
<< "and dense tensor has " << dense_shape.size() << " dimensions, ";
|
||||
}
|
||||
if (dense_shape[kIndexZero] != sparse_shape[kIndexOne] || dense_shape[kIndexOne] != 1) {
|
||||
MS_EXCEPTION(ValueError) << "The dense_vector's shape should be (" << sparse_shape[kIndexOne] << ", 1)"
|
||||
<< ", but its current shape is: "
|
||||
<< "(" << dense_shape[kIndexZero] << ", " << dense_shape[kIndexOne] << ").";
|
||||
}
|
||||
|
||||
MS_EXCEPTION_IF_NULL(sparse->values()->element());
|
||||
ShapeVector out_shape = {sparse_shape[0], dense_shape[1]};
|
||||
ShapeVector out_shape = {sparse_shape[kIndexZero], dense_shape[kIndexOne]};
|
||||
auto ret = std::make_shared<AbstractTensor>(sparse->values()->element()->BuildType(), out_shape);
|
||||
|
||||
MS_EXCEPTION_IF_NULL(sparse->indices()->shape());
|
||||
auto nnz_vec = sparse->indices()->shape()->shape();
|
||||
auto csr_avg_rows = nnz_vec[0] / dense_shape[0];
|
||||
auto csr_avg_rows = nnz_vec[kIndexZero] / dense_shape[kIndexZero];
|
||||
primitive->set_attr(kCSRAvgRows, MakeValue(csr_avg_rows));
|
||||
primitive->set_attr(kCSRDenseShape, MakeValue(sparse_shape));
|
||||
primitive->set_attr(kIsCSR, MakeValue(true));
|
||||
|
|
@ -668,34 +681,25 @@ AbstractBasePtr InferImplMakeCSRTensor(const AnalysisEnginePtr &, const Primitiv
|
|||
auto values = CheckArg<AbstractTensor>(op_name, args_spec_list, kIndexTwo);
|
||||
auto shape = CheckArg<AbstractTuple>(op_name, args_spec_list, kIndexThree);
|
||||
|
||||
auto indptr_dtype = indptr->element()->BuildType();
|
||||
auto indices_dtype = indices->element()->BuildType();
|
||||
if (!indices_dtype->isa<Int>()) {
|
||||
MS_EXCEPTION(TypeError) << "The dtype of indices must be a Int, but got " << indices_dtype->ToString();
|
||||
}
|
||||
CheckSparseIndicesDtype(indptr_dtype, "indptr");
|
||||
CheckSparseIndicesDtype(indices_dtype, "indices");
|
||||
|
||||
auto indptr_shp = indptr->shape()->shape();
|
||||
if (indptr_shp.size() != 1) {
|
||||
MS_EXCEPTION(ValueError) << "Indptr must be a 1-dimensional tensor, but got a " << indptr_shp.size()
|
||||
<< "-dimensional tensor";
|
||||
}
|
||||
CheckSparseShape(indptr_shp.size(), kSizeOne, "Indptr");
|
||||
|
||||
auto indices_shp = indices->shape()->shape();
|
||||
if (indices_shp.size() != 1) {
|
||||
MS_EXCEPTION(ValueError) << "Indices must be a 1-dimensional tensor, but got a " << indices_shp.size()
|
||||
<< "-dimensional tensor";
|
||||
}
|
||||
CheckSparseShape(indices_shp.size(), kSizeOne, "Indices");
|
||||
|
||||
auto values_shp = values->shape()->shape();
|
||||
if (values_shp.size() != 1) {
|
||||
MS_EXCEPTION(ValueError) << "Values must be a 1-dimensional tensor, but got a " << values_shp.size()
|
||||
<< "-dimensional tensor";
|
||||
}
|
||||
if (indices_shp[0] != values_shp[0]) {
|
||||
MS_EXCEPTION(ValueError) << "Indices and values must have same size, but got: values length: " << values_shp[0]
|
||||
<< ", indices length " << indices_shp[0];
|
||||
}
|
||||
for (const auto &elem_type : shape->ElementsType()) {
|
||||
if (!elem_type->isa<Int>()) {
|
||||
MS_EXCEPTION(TypeError) << "The element type of shape must be Int, but got " << elem_type->ToString();
|
||||
}
|
||||
CheckSparseShape(values_shp.size(), kSizeOne, "Values");
|
||||
|
||||
if (indices_shp[kIndexZero] != values_shp[kIndexZero]) {
|
||||
MS_EXCEPTION(ValueError) << "Indices and values must have same size, but got: values length: "
|
||||
<< values_shp[kIndexZero] << ", indices length " << indices_shp[kIndexZero];
|
||||
}
|
||||
|
||||
auto shape_value = shape->BuildValue()->cast<ValueTuplePtr>();
|
||||
MS_EXCEPTION_IF_NULL(shape_value);
|
||||
auto shp = shape_value->value();
|
||||
|
|
@ -704,19 +708,33 @@ AbstractBasePtr InferImplMakeCSRTensor(const AnalysisEnginePtr &, const Primitiv
|
|||
auto elem = GetValue<int64_t>(e);
|
||||
return elem;
|
||||
});
|
||||
if (shape_vec.size() != kSizeTwo) {
|
||||
MS_EXCEPTION(ValueError) << "Currently only supports 2-dimensional csr tensor, got shape length = "
|
||||
<< shape_vec.size() << ".";
|
||||
}
|
||||
if (values_shp.size() + 1 != shape_vec.size()) {
|
||||
MS_EXCEPTION(ValueError) << "Values' dimension should equal to csr_tensor's dimension - 1.";
|
||||
}
|
||||
if (shape_vec[0] + 1 != indptr_shp[0]) {
|
||||
MS_EXCEPTION(ValueError) << "Indptr must have length (1 + shape[0]), but got: " << indptr_shp[0];
|
||||
if (shape_vec[kIndexZero] + 1 != indptr_shp[kIndexZero]) {
|
||||
MS_EXCEPTION(ValueError) << "Indptr must have length (1 + shape[0]), but got: " << indptr_shp[kIndexZero];
|
||||
}
|
||||
size_t shape_size = 1;
|
||||
auto shape_types = shape->ElementsType();
|
||||
for (size_t i = 0; i < shape_vec.size(); ++i) {
|
||||
if (shape_vec[i] <= 0) {
|
||||
MS_EXCEPTION(TypeError) << "The element of shape must be positive, but got " << shape_value->ToString();
|
||||
MS_EXCEPTION(ValueError) << "The element of shape must be positive, but got " << shape_value->ToString();
|
||||
}
|
||||
if ((i > 1) && (shape_vec[i] != values_shp[i - 1])) {
|
||||
MS_EXCEPTION(ValueError) << "csr_tensor's shape should match with values' shape.";
|
||||
}
|
||||
if (!shape_types[i]->isa<Int>()) {
|
||||
MS_EXCEPTION(TypeError) << "The element type of shape must be Int, but got " << shape_types[i]->ToString();
|
||||
}
|
||||
shape_size *= shape_vec[i];
|
||||
}
|
||||
if (static_cast<int64_t>(shape_size) < values_shp[kIndexZero]) {
|
||||
MS_EXCEPTION(ValueError) << "Shape total size: " << shape_size << " is too small to hold " << values_shp[kIndexZero]
|
||||
<< " non-zero values.";
|
||||
}
|
||||
auto ret = std::make_shared<AbstractCSRTensor>(values->element()->BuildType(), shape_vec);
|
||||
ret->set_indptr(indptr);
|
||||
|
|
|
|||
|
|
@ -873,19 +873,23 @@ class Validator:
|
|||
def check_csr_tensor_input(indptr, indices, values, shape):
|
||||
"""Checks inputs type for CSRTensor."""
|
||||
if not isinstance(indptr, Tensor_):
|
||||
raise TypeError(f"indptr should be Tensor, but got {type(indices)}.")
|
||||
raise TypeError(f"indptr should be Tensor, but got {type(indptr)}.")
|
||||
Validator.check_sparse_tensor_input(indices, values, shape)
|
||||
|
||||
@staticmethod
|
||||
def check_csr_tensor_shape(indptr_shp, indices_shp, values_shp, csr_shp):
|
||||
"""Checks input tensors' shapes for CSRTensor."""
|
||||
if len(csr_shp) != 2:
|
||||
raise ValueError("Currently only supports 2-dimensional csr tensor.")
|
||||
raise ValueError(f"Currently only supports 2-dimensional csr tensor, got `shape length`={len(csr_shp)}.")
|
||||
shape_size = 1
|
||||
for item in csr_shp:
|
||||
if item <= 0:
|
||||
raise ValueError(f"The element of shape must be positive, but got {item}")
|
||||
if not isinstance(item, int):
|
||||
raise TypeError(f"The element type of shape must be int, but got {type(item)}")
|
||||
shape_size *= item
|
||||
if shape_size < values_shp[0]:
|
||||
raise ValueError(f"Shape total size: {shape_size} is too small to hold {values_shp[0]} non-zero values.")
|
||||
if len(values_shp) != 1:
|
||||
raise ValueError(f"Values must be a 1-dimensional tensor, but got a {len(values_shp)} dimension tensor.")
|
||||
if len(indices_shp) != 1:
|
||||
|
|
@ -903,9 +907,9 @@ class Validator:
|
|||
def check_csr_tensor_dtype(indptr_dtype, indices_dtype):
|
||||
"""Checks input tensors' data types for CSRTensor."""
|
||||
if indptr_dtype not in (mstype.int16, mstype.int32, mstype.int64):
|
||||
raise TypeError("Indptr must have integer data type.")
|
||||
raise TypeError(f"Indptr must have int16 or int32 or int64 data type, but got {indptr_dtype}.")
|
||||
if indices_dtype not in (mstype.int16, mstype.int32, mstype.int64):
|
||||
raise TypeError("Indices must have integer data type.")
|
||||
raise TypeError(f"Indices must have int16 or int32 or int64 data type, but got {indices_dtype}.")
|
||||
|
||||
@staticmethod
|
||||
def check_coo_tensor_input(indices, values, shape):
|
||||
|
|
@ -937,7 +941,7 @@ class Validator:
|
|||
def check_coo_tensor_dtype(indices_dtype):
|
||||
"""Checks input tensors' data types for COOTensor."""
|
||||
if indices_dtype not in (mstype.int16, mstype.int32, mstype.int64):
|
||||
raise TypeError("Indices must have integer data type.")
|
||||
raise TypeError(f"Indices must have int16 or int32 or int64 data type, but got {indices_dtype}.")
|
||||
|
||||
|
||||
def check_input_format(input_param):
|
||||
|
|
|
|||
|
|
@ -1929,6 +1929,7 @@ def csr_abs(x):
|
|||
|
||||
def csr_mv(x, dense_vector):
|
||||
"""Implementation of `abs` for CSRTensor."""
|
||||
check_value_type('dense_vector', dense_vector, (Tensor_,), 'Tensor')
|
||||
return F.csr_mv(x, dense_vector)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2631,17 +2631,17 @@ class CSRTensor(CSRTensor_):
|
|||
If the length of values or indices exceeds the range indicated by indptr, its behavior will be undefined.
|
||||
|
||||
Args:
|
||||
indptr (Tensor): 1-D Tensor of size `shape[0] + 1`, which indicates the
|
||||
indptr (Tensor): 1-D Tensor of shape `[M]`, which equals to `shape[0] + 1`, which indicates the
|
||||
start and end point for `values` in each row. Default: None. If provided,
|
||||
must be :class:`mindspore.int16`, :class:`mindspore.int32` or :class:`mindspore.int64`.
|
||||
indices (Tensor): 1-D Tensor, which has the same length as `values`. `indices`
|
||||
indices (Tensor): 1-D Tensor of shape `[N]`, which has the same length as `values`. `indices`
|
||||
indicates the which column `values` should be placed. Default: None. If provided,
|
||||
must be :class:`mindspore.int16`, :class:`mindspore.int32` or :class:`mindspore.int64`.
|
||||
values (Tensor): 1-D Tensor, which has the same length as `indices`. `values`
|
||||
values (Tensor): 1-D Tensor of shape `[N]`, which has the same length as `indices`. `values`
|
||||
stores the data for CSRTensor. Default: None.
|
||||
shape (Tuple): A tuple indicates the shape of the CSRTensor, its length must
|
||||
be `2`, as only 2-D CSRTensor is currently supported, and `shape[0]` must
|
||||
equal to `indptr[0] - 1`, which all equal to number of rows of the CSRTensor. Default: None.
|
||||
equal to `M - 1`, which all equal to number of rows of the CSRTensor. Default: None.
|
||||
csr_tensor (CSRTensor): A CSRTensor object. Default: None.
|
||||
|
||||
Outputs:
|
||||
|
|
@ -2808,7 +2808,7 @@ class CSRTensor(CSRTensor_):
|
|||
Sparse matrix-vector multiplication.
|
||||
|
||||
Args:
|
||||
dense_vector (Tensor) - A dense Tensor.
|
||||
dense_vector (Tensor) - A dense Tensor, its shape must be (csr_tensor.shape[1], 1)
|
||||
|
||||
Returns:
|
||||
Tensor.
|
||||
|
|
@ -2829,6 +2829,7 @@ class CSRTensor(CSRTensor_):
|
|||
[[2.]
|
||||
[1.]]
|
||||
"""
|
||||
validator.check_value_type('dense_vector', dense_vector, (Tensor_,), 'Tensor')
|
||||
return tensor_operator_registry.get("csr_mv")(self, dense_vector)
|
||||
|
||||
def sum(self, axis):
|
||||
|
|
|
|||
Loading…
Reference in New Issue