diff --git a/mindspore/ccsrc/plugin/device/ascend/hal/device/ascend_kernel_runtime.cc b/mindspore/ccsrc/plugin/device/ascend/hal/device/ascend_kernel_runtime.cc index ed9cc9d0eaf..06e99d6bef6 100644 --- a/mindspore/ccsrc/plugin/device/ascend/hal/device/ascend_kernel_runtime.cc +++ b/mindspore/ccsrc/plugin/device/ascend/hal/device/ascend_kernel_runtime.cc @@ -14,6 +14,7 @@ * limitations under the License. */ #include "plugin/device/ascend/hal/device/ascend_kernel_runtime.h" +#include #include #include #include @@ -719,6 +720,23 @@ void AscendKernelRuntime::DumpTaskExceptionInfo(const session::KernelGraph &) { auto full_scope_name = node->fullname_with_scope(); MS_LOG(ERROR) << "Dump node (" << full_scope_name << ") task error input/output data to: " << path << trace::DumpSourceLines(node); + + // full_scope_name: Default/GetNext-op1 + std::string lower_full_scope_name(full_scope_name.length(), ' '); + (void)std::transform(full_scope_name.begin(), full_scope_name.end(), lower_full_scope_name.begin(), ::tolower); + if (lower_full_scope_name.find("getnext") != std::string::npos) { + MS_LOG(WARNING) << "GetNext error may be caused by slow data processing (bigger than 20s / batch) or " + << "transfer data to device error."; + MS_LOG(WARNING) << "Suggestion: "; + MS_LOG(WARNING) << " 1) Set the parameter dataset_sink_mode=False of model.train(...) or " + << "model.eval(...) and try again."; + MS_LOG(WARNING) << " 2) Reduce the batch_size in data processing and try again."; + MS_LOG(WARNING) << " 3) You can create iterator by interface create_dict_iterator() of dataset class to " + << "independently verify the performance of data processing without training. " + << "Refer to the link for data processing optimization suggestions: " + << "https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.6/optimize_data_processing.html"; + } + E2eDump::DumpInputData(node, false, path, &full_scope_name); E2eDump::DumpOutputData(node, false, path, &full_scope_name); } diff --git a/mindspore/python/mindspore/dataset/engine/datasets.py b/mindspore/python/mindspore/dataset/engine/datasets.py index 9a1ef0c58db..7b66e5ecb2a 100644 --- a/mindspore/python/mindspore/dataset/engine/datasets.py +++ b/mindspore/python/mindspore/dataset/engine/datasets.py @@ -1,4 +1,4 @@ -# Copyright 2019-2022 Huawei Technologies Co., Ltd +# Copyright 2022 Huawei Technologies Co., Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -55,6 +55,7 @@ from mindspore import log as logger from mindspore.parallel._ps_context import _is_role_pserver, _is_role_sched from mindspore.dataset.engine.offload import GetOffloadModel +import mindspore.dataset.transforms.c_transforms as c_transforms import mindspore.dataset.transforms.py_transforms as py_transforms from mindspore.dataset.text.utils import SentencePieceModel, DE_C_INTER_SENTENCEPIECE_MODE from mindspore.parallel._utils import _get_device_num @@ -3180,6 +3181,17 @@ class MapDataset(UnionBaseDataset): offload=None): super().__init__(children=input_dataset, num_parallel_workers=num_parallel_workers, cache=cache) self.operations = to_list(operations) + for op in self.operations: + # user define c_vision.HWC2CHW without parentheses is error + if type(op) == type: # pylint: disable=unidiomatic-typecheck + raise ValueError("Parameter operations's element of method map should be a dataset processing " + "operation instance, but got: {}. It may be missing parentheses for " + "instantiation.".format(op)) + if not isinstance(op, (c_transforms.TensorOperation, py_transforms.PyTensorOperation)) \ + and not callable(op): + raise ValueError("Parameter operations's element of method map should be a python function or " + "class method which should be callable, but got: {}. It doesn't need parentheses " + "for python function or class method.".format(op)) self.operations = py_transforms.Compose.reduce(self.operations) self.input_columns = to_list(input_columns) self.output_columns = to_list(output_columns) diff --git a/mindspore/python/mindspore/dataset/transforms/validators.py b/mindspore/python/mindspore/dataset/transforms/validators.py index 8202d57192c..a89b386d6b5 100644 --- a/mindspore/python/mindspore/dataset/transforms/validators.py +++ b/mindspore/python/mindspore/dataset/transforms/validators.py @@ -219,6 +219,7 @@ def check_random_transform_ops(method): raise ValueError("op_list can not be empty.") for ind, op in enumerate(arg_list[0]): check_tensor_op(op, "op_list[{0}]".format(ind)) + check_transform_op_type(ind, op) if len(arg_list) == 2: # random apply takes an additional arg type_check(arg_list[1], (float, int), "prob") check_value(arg_list[1], (0, 1), "prob") @@ -227,6 +228,15 @@ def check_random_transform_ops(method): return new_method +def check_transform_op_type(ind, op): + """Check the operator.""" + # c_vision.HWC2CHW error + # py_vision.HWC2CHW error + if type(op) == type: # pylint: disable=unidiomatic-typecheck + raise ValueError("op_list[{}] should be a dataset processing operation instance, " + "but got: {}. It may be missing parentheses for instantiation.".format(ind, op)) + + def check_compose_list(method): """Wrapper method to check the transform list of Python Compose.""" @@ -240,6 +250,7 @@ def check_compose_list(method): for i, transform in enumerate(transforms): if not callable(transform): raise ValueError("transforms[{}] is not callable.".format(i)) + check_transform_op_type(i, transform) return method(self, *args, **kwargs) return new_method @@ -274,6 +285,7 @@ def check_random_apply(method): raise ValueError( "transforms[{}] is not a py transforms. Should not use a c transform in py transform" \ .format(i)) + check_transform_op_type(i, transform) if prob is not None: type_check(prob, (float, int,), "prob") @@ -297,6 +309,7 @@ def check_transforms_list(method): raise ValueError( "transforms[{}] is not a py transforms. Should not use a c transform in py transform" \ .format(i)) + check_transform_op_type(i, transform) return method(self, *args, **kwargs) return new_method diff --git a/tests/ut/python/dataset/test_map.py b/tests/ut/python/dataset/test_map.py new file mode 100644 index 00000000000..018e37a3271 --- /dev/null +++ b/tests/ut/python/dataset/test_map.py @@ -0,0 +1,125 @@ +# Copyright 2022 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +import pytest +import mindspore.dataset as ds +from mindspore.dataset.transforms import c_transforms +from mindspore.dataset.transforms import py_transforms +import mindspore.dataset.vision.c_transforms as c_vision +import mindspore.dataset.vision.py_transforms as py_vision + +DATA_DIR = "../data/dataset/testPK/data" + + +def test_map_c_transform_exception(): + """ + Feature: test c error op def + Description: op defined like c_vision.HWC2CHW + Expectation: success + """ + data_set = ds.ImageFolderDataset(DATA_DIR, num_parallel_workers=1, shuffle=True) + + train_image_size = 224 + mean = [0.485 * 255, 0.456 * 255, 0.406 * 255] + std = [0.229 * 255, 0.224 * 255, 0.225 * 255] + + # define map operations + random_crop_decode_resize_op = c_vision.RandomCropDecodeResize(train_image_size, + scale=(0.08, 1.0), + ratio=(0.75, 1.333)) + random_horizontal_flip_op = c_vision.RandomHorizontalFlip(prob=0.5) + normalize_op = c_vision.Normalize(mean=mean, std=std) + hwc2chw_op = c_vision.HWC2CHW # exception + + data_set = data_set.map(operations=random_crop_decode_resize_op, input_columns="image", num_parallel_workers=1) + data_set = data_set.map(operations=random_horizontal_flip_op, input_columns="image", num_parallel_workers=1) + data_set = data_set.map(operations=normalize_op, input_columns="image", num_parallel_workers=1) + with pytest.raises(ValueError) as info: + data_set = data_set.map(operations=hwc2chw_op, input_columns="image", num_parallel_workers=1) + assert "Parameter operations's element of method map should be a " in str(info.value) + + # compose exception + with pytest.raises(ValueError) as info: + c_transforms.Compose([ + c_vision.RandomCropDecodeResize(train_image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)), + c_vision.RandomHorizontalFlip, + c_vision.Normalize(mean=mean, std=std), + c_vision.HWC2CHW()]) + assert " should be a " in str(info.value) + + # randomapply exception + with pytest.raises(ValueError) as info: + c_transforms.RandomApply([ + c_vision.RandomCropDecodeResize, + c_vision.RandomHorizontalFlip(prob=0.5), + c_vision.Normalize(mean=mean, std=std), + c_vision.HWC2CHW()]) + assert " should be a " in str(info.value) + + # randomchoice exception + with pytest.raises(ValueError) as info: + c_transforms.RandomChoice([ + c_vision.RandomCropDecodeResize(train_image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)), + c_vision.RandomHorizontalFlip(prob=0.5), + c_vision.Normalize, + c_vision.HWC2CHW()]) + assert " should be a " in str(info.value) + + +def test_map_py_transform_exception(): + """ + Feature: test python error op def + Description: op defined like py_vision.RandomHorizontalFlip + Expectation: success + """ + data_set = ds.ImageFolderDataset(DATA_DIR, num_parallel_workers=1, shuffle=True) + + # define map operations + decode_op = py_vision.Decode() + random_horizontal_flip_op = py_vision.RandomHorizontalFlip # exception + to_tensor_op = py_vision.ToTensor() + trans = [decode_op, random_horizontal_flip_op, to_tensor_op] + + with pytest.raises(ValueError) as info: + data_set = data_set.map(operations=trans, input_columns="image", num_parallel_workers=1) + assert "Parameter operations's element of method map should be a " in str(info.value) + + # compose exception + with pytest.raises(ValueError) as info: + py_transforms.Compose([ + py_vision.Decode, + py_vision.RandomHorizontalFlip(), + py_vision.ToTensor()]) + assert " should be a " in str(info.value) + + # randomapply exception + with pytest.raises(ValueError) as info: + py_transforms.RandomApply([ + py_vision.Decode(), + py_vision.RandomHorizontalFlip, + py_vision.ToTensor()]) + assert " should be a " in str(info.value) + + # randomchoice exception + with pytest.raises(ValueError) as info: + py_transforms.RandomChoice([ + py_vision.Decode(), + py_vision.RandomHorizontalFlip(), + py_vision.ToTensor]) + assert " should be a " in str(info.value) + + +if __name__ == '__main__': + test_map_c_transform_exception() + test_map_py_transform_exception()