diff --git a/tests/ut/profiler/parser/__init__.py b/tests/ut/profiler/parser/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e30774307ca2107b3a81c071ad33c042ef924790 --- /dev/null +++ b/tests/ut/profiler/parser/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2020 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. +# ============================================================================ diff --git a/tests/ut/profiler/parser/resource/JOB1/Framework.host.vm.graph_desc_info.0.slice_0 b/tests/ut/profiler/parser/resource/JOB1/Framework.host.vm.graph_desc_info.0.slice_0 new file mode 100644 index 0000000000000000000000000000000000000000..9b3e7b322c5cb97b1a85e28e327c52ee9ce29824 --- /dev/null +++ b/tests/ut/profiler/parser/resource/JOB1/Framework.host.vm.graph_desc_info.0.slice_0 @@ -0,0 +1,4 @@ +op_name:Default/Cast-op6 op_type:Cast input_id:0 input_format:DefaultFormat input_data_type:40 input_shape:"32,3,224,224" output_id:0 output_format:DefaultFormat output_data_type:39 output_shape:"32,3,224,224" +op_name:Default/TransData-op7 op_type:TransData input_id:0 input_format:DefaultFormat input_data_type:39 input_shape:"32,3,224,224" output_id:0 output_format:NC1HWC0 output_data_type:39 output_shape:"32,1,224,224,16" +op_name:Default/network-WithLossCell/_backbone-ResNet/conv1-Conv2d/Cast-op5 op_type:Cast input_id:0 input_format:FracZ input_data_type:40 input_shape:"49,4,16,16" output_id:0 output_format:FracZ output_data_type:39 output_shape:"49,4,16,16" +op_name:Default/network-WithLossCell/_backbone-ResNet/layer1-SequentialCell/0-ResidualBlock/conv1-Conv2d/Cast-op28 op_type:Cast input_id:0 input_format:FracZ input_data_type:40 input_shape:"4,4,16,16" output_id:0 output_format:FracZ output_data_type:39 output_shape:"4,4,16,16" diff --git a/tests/ut/profiler/parser/resource/JOB1/Framework.host.vm.graph_desc_info.0.slice_0.done b/tests/ut/profiler/parser/resource/JOB1/Framework.host.vm.graph_desc_info.0.slice_0.done new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/ut/profiler/parser/resource/JOB1/Framework.host.vm.task_desc_info.0.slice_0 b/tests/ut/profiler/parser/resource/JOB1/Framework.host.vm.task_desc_info.0.slice_0 new file mode 100644 index 0000000000000000000000000000000000000000..e786b35e22b200fb891668cb06a2f5f50fd7e7d8 --- /dev/null +++ b/tests/ut/profiler/parser/resource/JOB1/Framework.host.vm.task_desc_info.0.slice_0 @@ -0,0 +1,4 @@ +Default/Cast-op6 32 51517 0 +Default/TransData-op7 32 51518 0 +Default/network-WithLossCell/_backbone-ResNet/conv1-Conv2d/Cast-op5 32 51519 0 +Default/network-WithLossCell/_backbone-ResNet/layer1-SequentialCell/0-ResidualBlock/conv1-Conv2d/Cast-op28 4 51522 0 diff --git a/tests/ut/profiler/parser/resource/container/0/data/Framework.host.vm.graph_desc_info.0.JOB2.slice_0 b/tests/ut/profiler/parser/resource/container/0/data/Framework.host.vm.graph_desc_info.0.JOB2.slice_0 new file mode 100644 index 0000000000000000000000000000000000000000..9b3e7b322c5cb97b1a85e28e327c52ee9ce29824 --- /dev/null +++ b/tests/ut/profiler/parser/resource/container/0/data/Framework.host.vm.graph_desc_info.0.JOB2.slice_0 @@ -0,0 +1,4 @@ +op_name:Default/Cast-op6 op_type:Cast input_id:0 input_format:DefaultFormat input_data_type:40 input_shape:"32,3,224,224" output_id:0 output_format:DefaultFormat output_data_type:39 output_shape:"32,3,224,224" +op_name:Default/TransData-op7 op_type:TransData input_id:0 input_format:DefaultFormat input_data_type:39 input_shape:"32,3,224,224" output_id:0 output_format:NC1HWC0 output_data_type:39 output_shape:"32,1,224,224,16" +op_name:Default/network-WithLossCell/_backbone-ResNet/conv1-Conv2d/Cast-op5 op_type:Cast input_id:0 input_format:FracZ input_data_type:40 input_shape:"49,4,16,16" output_id:0 output_format:FracZ output_data_type:39 output_shape:"49,4,16,16" +op_name:Default/network-WithLossCell/_backbone-ResNet/layer1-SequentialCell/0-ResidualBlock/conv1-Conv2d/Cast-op28 op_type:Cast input_id:0 input_format:FracZ input_data_type:40 input_shape:"4,4,16,16" output_id:0 output_format:FracZ output_data_type:39 output_shape:"4,4,16,16" diff --git a/tests/ut/profiler/parser/resource/container/0/data/Framework.host.vm.task_desc_info.0.JOB2.slice_0 b/tests/ut/profiler/parser/resource/container/0/data/Framework.host.vm.task_desc_info.0.JOB2.slice_0 new file mode 100644 index 0000000000000000000000000000000000000000..e786b35e22b200fb891668cb06a2f5f50fd7e7d8 --- /dev/null +++ b/tests/ut/profiler/parser/resource/container/0/data/Framework.host.vm.task_desc_info.0.JOB2.slice_0 @@ -0,0 +1,4 @@ +Default/Cast-op6 32 51517 0 +Default/TransData-op7 32 51518 0 +Default/network-WithLossCell/_backbone-ResNet/conv1-Conv2d/Cast-op5 32 51519 0 +Default/network-WithLossCell/_backbone-ResNet/layer1-SequentialCell/0-ResidualBlock/conv1-Conv2d/Cast-op28 4 51522 0 diff --git a/tests/ut/profiler/parser/resource/framework_raw_0.csv b/tests/ut/profiler/parser/resource/framework_raw_0.csv new file mode 100644 index 0000000000000000000000000000000000000000..762bc693469eed4dbadca152674aa5498e6d6d0e --- /dev/null +++ b/tests/ut/profiler/parser/resource/framework_raw_0.csv @@ -0,0 +1,5 @@ +task_id,stream_id,block_dim,full_op_name,op_name,op_type,subgraph,op_info +51517,0,32,Default/Cast-op6,Cast-op6,Cast,Default,"{""input_0"": {""format"": ""DefaultFormat"", ""data_type"": ""NUMBER_TYPE_FLOAT32"", ""shape"": ""32,3,224,224""}, ""output_0"": {""format"": ""DefaultFormat"", ""data_type"": ""NUMBER_TYPE_FLOAT16"", ""shape"": ""32,3,224,224""}}" +51518,0,32,Default/TransData-op7,TransData-op7,TransData,Default,"{""input_0"": {""format"": ""DefaultFormat"", ""data_type"": ""NUMBER_TYPE_FLOAT16"", ""shape"": ""32,3,224,224""}, ""output_0"": {""format"": ""NC1HWC0"", ""data_type"": ""NUMBER_TYPE_FLOAT16"", ""shape"": ""32,1,224,224,16""}}" +51519,0,32,Default/network-WithLossCell/_backbone-ResNet/conv1-Conv2d/Cast-op5,Cast-op5,Cast,Default,"{""input_0"": {""format"": ""FracZ"", ""data_type"": ""NUMBER_TYPE_FLOAT32"", ""shape"": ""49,4,16,16""}, ""output_0"": {""format"": ""FracZ"", ""data_type"": ""NUMBER_TYPE_FLOAT16"", ""shape"": ""49,4,16,16""}}" +51522,0,4,Default/network-WithLossCell/_backbone-ResNet/layer1-SequentialCell/0-ResidualBlock/conv1-Conv2d/Cast-op28,Cast-op28,Cast,Default,"{""input_0"": {""format"": ""FracZ"", ""data_type"": ""NUMBER_TYPE_FLOAT32"", ""shape"": ""4,4,16,16""}, ""output_0"": {""format"": ""FracZ"", ""data_type"": ""NUMBER_TYPE_FLOAT16"", ""shape"": ""4,4,16,16""}}" diff --git a/tests/ut/profiler/parser/test_framework_parser.py b/tests/ut/profiler/parser/test_framework_parser.py new file mode 100644 index 0000000000000000000000000000000000000000..e794b37a994a5381a8076fc04d2d31b1bfa6103c --- /dev/null +++ b/tests/ut/profiler/parser/test_framework_parser.py @@ -0,0 +1,140 @@ +# Copyright 2020 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. +# ============================================================================ +"""Test the framework parser module.""" +import csv +import os +import shutil +import tempfile +from unittest import mock + +import pytest +from marshmallow import ValidationError + +from mindinsight.profiler.common.exceptions.exceptions import \ + ProfilerPathErrorException, ProfilerDirNotFoundException, \ + ProfilerFileNotFoundException +from mindinsight.profiler.parser.framework_parser import FrameworkParser + + +def get_framework_result(file_path): + """ + Get framework result from the framework file. + + Args: + file_path (str): The framework file path. + + Returns: + list[list], the parsed framework information. + """ + result = [] + with open(file_path, 'r') as file: + csv_reader = csv.reader(file) + for row in csv_reader: + result.append(row) + return result + + +class TestFrameworkParser: + """Test the class of `FrameworkParser`.""" + def setup_method(self): + """Initialization before test case execution.""" + raw_dir = os.path.join(os.path.dirname(__file__), 'resource') + FrameworkParser._raw_data_dir = raw_dir + + self._output_path_1 = tempfile.mkdtemp(prefix='test_framework_parser_') + self._parser_1 = FrameworkParser('JOB1', '0', self._output_path_1) + + os.makedirs(os.path.join(raw_dir, 'JOB2'), exist_ok=True) + self._output_path_2 = tempfile.mkdtemp(prefix='test_framework_parser_') + self._parser_2 = FrameworkParser('JOB2', '0', self._output_path_2) + + def teardown_method(self) -> None: + """Clear up after test case execution.""" + shutil.rmtree(self._output_path_1) + shutil.rmtree(self._output_path_2) + FrameworkParser._raw_data_dir = '/var/log/npu/profiling' + + def test_save_path(self): + """Test the querying save path function.""" + expect_result = os.path.join(self._output_path_1, 'framework_raw_0.csv') + assert expect_result == self._parser_1.save_path + + expect_result = os.path.join(self._output_path_2, 'framework_raw_0.csv') + assert expect_result == self._parser_2.save_path + + def test_to_task_id_full_op_name_dict(self): + """Test the querying task id and full operator name dict function.""" + expect_result = { + '51517': 'Default/Cast-op6', + '51518': 'Default/TransData-op7', + '51519': 'Default/network-WithLossCell/_backbone-ResNet/conv1-Conv2d/Cast-op5', + '51522': 'Default/network-WithLossCell/_backbone-ResNet/' + 'layer1-SequentialCell/0-ResidualBlock/conv1-Conv2d/Cast-op28' + } + assert self._parser_1.to_task_id_full_op_name_dict(), expect_result + assert self._parser_2.to_task_id_full_op_name_dict(), expect_result + + def test_parse(self): + """Test the parse function.""" + expect_framework_file = os.path.join( + os.path.dirname(__file__), 'resource', 'framework_raw_0.csv' + ) + expect_result = get_framework_result(expect_framework_file) + + self._parser_1.parse() + framework_file = os.path.join(self._output_path_1, 'framework_raw_0.csv') + result = get_framework_result(framework_file) + assert expect_result == result + + self._parser_2.parse() + framework_file = os.path.join(self._output_path_2, 'framework_raw_0.csv') + result = get_framework_result(framework_file) + assert expect_result == result + + @mock.patch('mindinsight.profiler.parser.framework_parser.validate_and_normalize_path') + def test_create_framework_parser_fail_1(self, *args): + """Test the function of fail to create framework parser.""" + args[0].side_effect = ValidationError({'profiler': {"The path is invalid!"}}) + + with pytest.raises(ProfilerPathErrorException) as exc_info: + FrameworkParser('JOB1', '0') + assert exc_info.value.error_code == '50546081' + assert exc_info.value.message == 'Path error. Profiling path is invalid.' + + @mock.patch('os.path.isdir') + def test_create_framework_parser_fail_2(self, *args): + """Test the function of fail to create framework parser.""" + args[0].return_value = False + FrameworkParser._raw_data_dir = '/var/log/npu/profiling' + + with pytest.raises(ProfilerDirNotFoundException) as exc_info: + FrameworkParser('JOB1', '0') + assert exc_info.value.error_code == '50546083' + assert exc_info.value.message == \ + 'The dir not found.' + + @mock.patch('os.listdir') + @mock.patch('os.path.isdir') + def test_create_framework_parser_fail_3(self, *args): + """Test the function of fail to create framework parser.""" + args[0].return_value = True + args[1].return_value = [] + FrameworkParser._raw_data_dir = '/var/log/npu/profiling' + + with pytest.raises(ProfilerFileNotFoundException) as exc_info: + FrameworkParser('JOB1', '0') + print(exc_info.value) + assert exc_info.value.error_code == '50546084' + assert exc_info.value.message == 'The file not found.'