Browse Source

add ut of profiler timeline

tags/v1.1.0
gzhcv 5 years ago
parent
commit
8c624ae1ec
4 changed files with 172 additions and 118 deletions
  1. +0
    -112
      mindinsight/profiler/common/_utils.py
  2. +10
    -4
      tests/st/func/profiler/test_validator.py
  3. +66
    -0
      tests/ut/profiler/analyser/test_timeline_analyser.py
  4. +96
    -2
      tests/ut/profiler/common/validator/test_validator.py

+ 0
- 112
mindinsight/profiler/common/_utils.py View File

@@ -1,112 +0,0 @@
# 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.
# ============================================================================
"""Profiler utils."""
import os
import re


def fwrite_format(output_data_path, data_source=None, is_print=False, is_start=False):
"""
Write data to the output file.

Args:
output_data_path (str): The output file path of the data.
data_source (list): The data to write.
is_print (bool): whether to print the data to stdout.
is_start (bool): Whether is the first line of the output file, will remove the old file if True."
"""

if is_start is True and os.path.exists(output_data_path):
os.remove(output_data_path)

if data_source.startswith("title:"):
title_label = '=' * 20
data_source = title_label + data_source[6:] + title_label

with open(output_data_path, 'a+') as f:
f.write(data_source)
f.write("\n")

if is_print:
print(data_source)


def get_log_slice_id(file_name):
pattern = re.compile(r'(?<=slice_)\d+')
slice_list = pattern.findall(file_name)
index = re.findall(r'\d+', slice_list[0])
return int(index[0])


def get_file_join_name(input_path, file_name):
"""
Search files under the special path, and will join all the files to one file.

Args:
input_path (str): The source path, will search files under it.
file_name (str): The target of the filename, such as 'hwts.log.data.45.dev'.

Returns:
str, the join file name.
"""
name_list = []
file_join_name = ''
input_path = os.path.realpath(input_path)
if os.path.exists(input_path):
files = os.listdir(input_path)
for f in files:
if file_name in f and not f.endswith('.done') and not f.endswith('.join') \
and not f.endswith('.zip'):
name_list.append(f)

# resort name_list
name_list.sort(key=get_log_slice_id)

if len(name_list) == 1:
file_join_name = os.path.join(input_path, name_list[0])
elif len(name_list) > 1:
file_join_name = os.path.join(input_path, '%s.join' % file_name)
if os.path.exists(file_join_name):
os.remove(file_join_name)
with open(file_join_name, 'ab') as bin_data:
for i in name_list:
file = input_path + os.sep + i
with open(file, 'rb') as txt:
bin_data.write(txt.read())
return file_join_name

def get_file_names(input_path, file_name):
"""
Search files under the special path.

Args:
input_path (str): The source path, will search files under it.
file_name (str): The target of the filename, such as 'host_start_log'.

Returns:
list, file name list.
"""

input_path = os.path.realpath(input_path)
name_list = []
if os.path.exists(input_path):
files = os.listdir(input_path)
for f in files:
if file_name in f and not f.endswith('.done') \
and not f.endswith('.zip'):
name_list.append(f)
break

return name_list

+ 10
- 4
tests/st/func/profiler/test_validator.py View File

@@ -61,8 +61,8 @@ class TestValidate:
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_x86_ascend_training
def test_validate_condition_exception(self):
"""Test the exception of validate condition."""
def test_validate_op_type_exception(self):
"""Test the operate type exception."""
condition = "not a dict"
exception_message = 'Param type error. Invalid search_condition type, it should be dict.'
with pytest.raises(ProfilerParamTypeErrorException) as exc_info:
@@ -70,7 +70,6 @@ class TestValidate:
assert exc_info.value.error_code == '50546082'
assert exc_info.value.message == exception_message

# test the ProfilerOpTypeException
condition_list = [{'op_type': "xxx"}, {}]
exception_message = "The op_type in search_condition error, The op_type must in " \
"['aicpu_type','aicpu_detail', 'aicore_type', 'aicore_detail', "\
@@ -81,7 +80,14 @@ class TestValidate:
assert exc_info.value.error_code == '50546183'
assert exc_info.value.message == exception_message

# test the ProfilerGroupConditionException
@pytest.mark.level0
@pytest.mark.env_single
@pytest.mark.platform_x86_cpu
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_x86_ascend_training
def test_validate_group_condition_exception(self):
"""test the group condition exception."""
condition_list = [
{
'op_type': 'aicpu_type',


+ 66
- 0
tests/ut/profiler/analyser/test_timeline_analyser.py View File

@@ -0,0 +1,66 @@
# 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.
# ============================================================================
"""
Function:
Test profiler to watch the performance of training.
Usage:
pytest tests/st/func/profiler
"""
import os
import pytest

from mindinsight.profiler.analyser.analyser_factory import AnalyserFactory
from tests.st.func.profiler import PROFILER_DIR
from tests.utils.tools import compare_result_with_file


class TestTimelineAnalyser:
"""Test timeline analyser module."""
def setup_method(self):
"""Create analyser."""
self.profiler = PROFILER_DIR
self.device_id = 0
self._analyser = AnalyserFactory.instance().get_analyser(
'timeline', self.profiler, self.device_id)

@pytest.mark.parametrize(
"device_target, filename",
[('gpu', 'gpu_timeline_display_{}.json'),
('ascend', 'ascend_timeline_display_{}.json')]
)
def test_get_display_timeline(self, device_target, filename):
"""Test the function of get timeline detail data for UI display."""
file_path = os.path.join(
self.profiler,
filename.format(self.device_id)
)

result = self._analyser.get_display_timeline(device_target)
compare_result_with_file(result, file_path)

@pytest.mark.parametrize(
"device_target, filename",
[('gpu', 'gpu_timeline_summary_{}.json'),
('ascend', 'ascend_timeline_summary_{}.json')]
)
def test_get_timeline_summary(self, device_target, filename):
"""Test the function of get timeline summary data for UI display."""
file_path = os.path.join(
self.profiler,
filename.format(self.device_id)
)

result = self._analyser.get_timeline_summary(device_target)
compare_result_with_file(result, file_path)

+ 96
- 2
tests/ut/profiler/common/validator/test_validator.py View File

@@ -18,9 +18,9 @@ import pytest
from mindinsight.profiler.common.exceptions.exceptions import \
ProfilerParamTypeErrorException, ProfilerDeviceIdException, \
ProfilerGroupConditionException, ProfilerSortConditionException, \
ProfilerFilterConditionException
ProfilerFilterConditionException, ProfilerOpTypeException
from mindinsight.profiler.common.validator.validate import \
validate_minddata_pipeline_condition
validate_minddata_pipeline_condition, validate_condition


class TestMinddataPipelineCondition:
@@ -210,3 +210,97 @@ class TestMinddataPipelineCondition:
assert exc_info.value.error_code == '50546186'
assert exc_info.value.message == 'The filter_condition in search_condition error, ' \
'The item in filter value must be int.'


class TestValidateCondition:
"""Test the function of validate condition."""
def test_validate_condition_normal(self):
"""Test the validate condition of normal input."""
op_type_list = ['aicpu_type', 'aicpu_detail', 'aicore_type', 'aicore_detail',
'gpu_op_type', 'gpu_op_info', 'gpu_cuda_activity']
sort_name_list = ['op_type', 'serial_number', 'op_type', 'op_name',
'op_type', 'op_side', 'name']
for idx, op_type in enumerate(op_type_list):
condition = {
'device_id': '0',
'op_type': op_type,
'filter_condition': {
'op_id': 0
},
'group_condition': {
'limit': 1,
'offset': 1
},
'sort_condition': {
'name': sort_name_list[idx],
'type': 'ascending'
}
}
validate_condition(condition)

def test_validate_condition_param_type_error_exception(self):
"""Test the exception of parameter type error."""
condition = "not a dict"
exception_message = 'Param type error. Invalid search_condition type, it should be dict.'
with pytest.raises(ProfilerParamTypeErrorException) as exc_info:
validate_condition(condition)
assert exc_info.value.error_code == '50546082'
assert exc_info.value.message == exception_message

def test_validate_condition_op_type_exception(self):
"""Test the exception of profiler operation type."""
condition_list = [{'op_type': "xxx"}, {}]
exception_message = "The op_type in search_condition error, The op_type must in " \
"['aicpu_type','aicpu_detail', 'aicore_type', 'aicore_detail', "\
"'gpu_op_type', 'gpu_op_info', 'gpu_cuda_activity']"
for condition in condition_list:
with pytest.raises(ProfilerOpTypeException) as exc_info:
validate_condition(condition)
assert exc_info.value.error_code == '50546183'
assert exc_info.value.message == exception_message

def test_validate_condition_group_exception(self):
"""Test the exception of group condition related."""
condition_list = [
{
'op_type': 'aicpu_type',
'group_condition': 0
},
{
'op_type': 'aicpu_type',
'group_condition': {'limit': True}
},
{
'op_type': 'aicpu_type',
'group_condition': {'limit': 0}
},
{
'op_type': 'aicpu_type',
'group_condition': {'offset': True}
},
{
'op_type': 'aicpu_type',
'group_condition': {'offset': -1}
},
{
'op_type': 'aicpu_type',
'group_condition': {'offset': 10000000}
},
]
exception_message_list = [
"The group condition must be dict.",
"The limit must be int.",
"The limit must in [1, 100].",
"The offset must be int.",
"The offset must ge 0.",
"The offset must le 1000000."
]
exception_message_list = [
'The group_condition in search_condition error, ' + message
for message in exception_message_list
]
for idx, condition in enumerate(condition_list):
with pytest.raises(ProfilerGroupConditionException) as exc_info:
validate_condition(condition)
assert exc_info.value.error_code == '50546184'
assert exc_info.value.message == exception_message_list[idx]

Loading…
Cancel
Save