diff --git a/bashi/globals.py b/bashi/globals.py index a914a29..f3fa401 100644 --- a/bashi/globals.py +++ b/bashi/globals.py @@ -2,21 +2,21 @@ from typing import List import packaging.version - +from bashi.types import Parameter, ValueName, ValueVersion # parameter key names, whit special meaning -HOST_COMPILER: str = "host_compiler" -DEVICE_COMPILER: str = "device_compiler" +HOST_COMPILER: Parameter = "host_compiler" +DEVICE_COMPILER: Parameter = "device_compiler" # name of the used compilers -GCC: str = "gcc" -CLANG: str = "clang" -NVCC: str = "nvcc" -CLANG_CUDA: str = "clang-cuda" -HIPCC: str = "hipcc" -ICPX: str = "icpx" +GCC: ValueName = "gcc" +CLANG: ValueName = "clang" +NVCC: ValueName = "nvcc" +CLANG_CUDA: ValueName = "clang-cuda" +HIPCC: ValueName = "hipcc" +ICPX: ValueName = "icpx" -COMPILERS: List[str] = [GCC, CLANG, NVCC, CLANG_CUDA, HIPCC, ICPX] +COMPILERS: List[ValueName] = [GCC, CLANG, NVCC, CLANG_CUDA, HIPCC, ICPX] # alpaka backend names ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLE: str = "alpaka_ACC_CPU_B_SEQ_T_SEQ_ENABLE" @@ -47,5 +47,10 @@ OFF: str = "0.0.0" ON: str = "1.0.0" -OFF_VER: packaging.version.Version = packaging.version.parse(OFF) -ON_VER: packaging.version.Version = packaging.version.parse(ON) +OFF_VER: ValueVersion = packaging.version.parse(OFF) +ON_VER: ValueVersion = packaging.version.parse(ON) + +# values are used for remove_parameter_value_pair +ANY_PARAM: Parameter = "*" +ANY_NAME: ValueName = "*" +ANY_VERSION: str = "*" diff --git a/bashi/utils.py b/bashi/utils.py index 90afef4..75b4321 100644 --- a/bashi/utils.py +++ b/bashi/utils.py @@ -4,7 +4,7 @@ import sys import copy from collections import OrderedDict -from typing import IO, Dict, List, Optional, Union +from typing import IO, Dict, List, Optional, Union, Callable import packaging.version from typeguard import typechecked @@ -18,6 +18,7 @@ ParameterValuePair, ParameterValueSingle, ParameterValueTuple, + ValueName, ) from bashi.versions import COMPILERS, VERSIONS, NVCC_GCC_MAX_VERSION, NVCC_CLANG_MAX_VERSION from bashi.globals import * # pylint: disable=wildcard-import,unused-wildcard-import @@ -263,6 +264,91 @@ def filter_function(param_val_pair: ParameterValuePair) -> bool: return len_before != len(param_val_pairs) +@typechecked +def remove_parameter_value_pair_2( # pylint: disable=too-many-arguments + parameter_value_pairs: List[ParameterValuePair], + parameter1: Parameter = ANY_PARAM, + value_name1: ValueName = ANY_NAME, + value_version1: Union[int, float, str] = ANY_VERSION, + parameter2: Parameter = ANY_PARAM, + value_name2: ValueName = ANY_NAME, + value_version2: Union[int, float, str] = ANY_VERSION, + symmetric: bool = True, +) -> bool: + """Removes a parameter-value-pair from a list based on the specified search criteria. A + parameter-value pair must match all specified search criteria to be removed if none of the + criteria is `ANY_*`. If a criterion is `ANY_*`, it is ignored and it is always a match. + + Args: + parameter_value_pairs (List[ParameterValuePair]): list where parameter-value-pairs will be + removed + parameter1 (Parameter, optional): Name of the first parameter. Defaults to ANY_PARAM. + value_name1 (ValueName, optional): Name of the first value-name. Defaults to ANY_NAME. + value_version1 (Union[int, float, str], optional): Name of the first value-version. Defaults + to ANY_VERSION. + parameter2 (Parameter, optional): Name of the second parameter. Defaults to ANY_PARAM. + value_name2 (ValueName, optional): Name of the second value-name. Defaults to ANY_NAME. + value_version2 (Union[int, float, str], optional): Name of the second value-name. Defaults + to ANY_VERSION. + symmetric (bool, optional): If symmetric is true, it does not matter whether a group of + parameters, value-name and value-version was found in the first or second + parameter-value. If false, it is taken into account whether the search criterion was + found in the first or second parameter value. Defaults to True. + + Returns: + bool: Return True, if parameter-value-pair was removed. + """ + filter_list: List[Callable[[ParameterValuePair], bool]] = [] + if parameter1 != ANY_PARAM: + filter_list.append(lambda param_val: param_val.first.parameter == parameter1) + + if value_name1 != ANY_NAME: + filter_list.append(lambda param_val: param_val.first.parameterValue.name == value_name1) + + if value_version1 != ANY_VERSION: + parsed_value_version1 = packaging.version.parse(str(value_version1)) + filter_list.append( + lambda param_val: param_val.first.parameterValue.version == parsed_value_version1 + ) + + if parameter2 != ANY_PARAM: + filter_list.append(lambda param_val: param_val.second.parameter == parameter2) + + if value_name2 != ANY_NAME: + filter_list.append(lambda param_val: param_val.second.parameterValue.name == value_name2) + + if value_version2 != ANY_VERSION: + parsed_value_version2 = packaging.version.parse(str(value_version2)) + filter_list.append( + lambda param_val: param_val.second.parameterValue.version == parsed_value_version2 + ) + + def filter_func(param_value_pair: ParameterValuePair) -> bool: + return_value = True + + for f in filter_list: + return_value = return_value and f(param_value_pair) + + return not return_value + + len_before = len(parameter_value_pairs) + parameter_value_pairs[:] = list(filter(filter_func, parameter_value_pairs)) + + if symmetric: + remove_parameter_value_pair_2( + parameter_value_pairs, + parameter2, + value_name2, + value_version2, + parameter1, + value_name1, + value_version1, + symmetric=False, + ) + + return len_before != len(parameter_value_pairs) + + @typechecked def check_parameter_value_pair_in_combination_list( combination_list: CombinationList, diff --git a/tests/test_expected_parameter_value_pairs.py b/tests/test_expected_parameter_value_pairs.py index 555cce0..6947ee1 100644 --- a/tests/test_expected_parameter_value_pairs.py +++ b/tests/test_expected_parameter_value_pairs.py @@ -2,7 +2,7 @@ import unittest import copy from typing import List, Dict -from collections import OrderedDict +from collections import OrderedDict as OD import io import packaging.version as pkv @@ -21,6 +21,7 @@ get_expected_parameter_value_pairs, check_parameter_value_pair_in_combination_list, remove_parameter_value_pair, + remove_parameter_value_pair_2, create_parameter_value_pair, ) @@ -180,7 +181,7 @@ def test_create_parameter_value_pair_type_mixed(self): class TestExpectedValuePairs(unittest.TestCase): @classmethod def setUpClass(cls): - cls.param_matrix: ParameterValueMatrix = OrderedDict() + cls.param_matrix: ParameterValueMatrix = OD() cls.param_matrix[HOST_COMPILER] = parse_param_vals( [(GCC, 10), (GCC, 11), (GCC, 12), (CLANG, 16), (CLANG, 17)] @@ -195,8 +196,6 @@ def setUpClass(cls): get_expected_parameter_value_pairs(cls.param_matrix) ) - OD = OrderedDict - cls.expected_param_val_pairs: List[ParameterValuePair] = parse_expected_val_pairs( [ OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), @@ -360,8 +359,6 @@ def test_check_parameter_value_pair_in_combination_list_empty_input(self): ) def test_check_parameter_value_pair_in_combination_list_less_valid_input(self): - OD = OrderedDict - # all pairs exists in the combination list, but not all pairs are tested self.assertTrue( check_parameter_value_pair_in_combination_list( @@ -385,8 +382,6 @@ def test_check_parameter_value_pair_in_combination_list_complete_valid_input(sel ) def test_check_parameter_value_pair_in_combination_list_single_wrong_input(self): - OD = OrderedDict - single_wrong_pair = parse_expected_val_pairs( [ OD({HOST_COMPILER: (GCC, 11), DEVICE_COMPILER: (NVCC, 11.2)}), @@ -413,8 +408,6 @@ def test_check_parameter_value_pair_in_combination_list_single_wrong_input(self) ) def test_check_parameter_value_pair_in_combination_list_many_wrong_input(self): - OD = OrderedDict - many_wrong_pairs = parse_expected_val_pairs( [ OD({HOST_COMPILER: (GCC, 11), DEVICE_COMPILER: (NVCC, 11.2)}), @@ -450,8 +443,6 @@ def test_check_parameter_value_pair_in_combination_list_many_wrong_input(self): self.assertEqual(output_wrong_many_pairs_list, expected_output_many_wrong_pairs_list) def test_check_parameter_value_pair_in_combination_list_complete_list_plus_wrong_input(self): - OD = OrderedDict - many_wrong_pairs = parse_expected_val_pairs( [ OD({HOST_COMPILER: (GCC, 11), DEVICE_COMPILER: (NVCC, 11.2)}), @@ -497,7 +488,7 @@ def test_unrestricted_covertable_generator(self): ) # type: ignore for all_pair in all_pairs: - comb_list.append(OrderedDict(all_pair)) + comb_list.append(OD(all_pair)) self.assertTrue( check_parameter_value_pair_in_combination_list(comb_list, self.expected_param_val_pairs) @@ -506,8 +497,6 @@ def test_unrestricted_covertable_generator(self): class TestRemoveExpectedParameterValuePair(unittest.TestCase): def test_remove_parameter_value_pair(self): - OD = OrderedDict - expected_param_value_pairs: List[ParameterValuePair] = parse_expected_val_pairs( [ OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), @@ -543,7 +532,6 @@ def test_remove_parameter_value_pair(self): self.assertEqual(len(expected_param_value_pairs), original_length - 2) def test_remove_parameter_value_single(self): - OD = OrderedDict ppv = parse_param_val expected_param_value_pairs: List[ParameterValuePair] = parse_expected_val_pairs( @@ -618,7 +606,7 @@ def test_remove_parameter_value_pair_all_versions(self): BOOST: [1.80, 1.81, 1.82], } - param_val_matrix: ParameterValueMatrix = OrderedDict() + param_val_matrix: ParameterValueMatrix = OD() for compiler in [HOST_COMPILER, DEVICE_COMPILER]: param_val_matrix[compiler] = [] for compiler_name in [GCC, CLANG, NVCC, HIPCC]: @@ -747,3 +735,406 @@ def filter_function2(param_val_pair: ParameterValuePair) -> bool: reduced_param_value_pairs.sort() expected_reduced_param_value_pairs.sort() self.assertEqual(reduced_param_value_pairs, expected_reduced_param_value_pairs) + + +class TestRemoveExpectedParameterValuePair2(unittest.TestCase): + def test_remove_parameter_value_pair(self): + test_param_value_pairs: List[ParameterValuePair] = parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + ] + ) + original_length = len(test_param_value_pairs) + + self.assertFalse( + remove_parameter_value_pair_2( + test_param_value_pairs, + HOST_COMPILER, + GCC, + 9, + DEVICE_COMPILER, + NVCC, + 11.2, + ) + ) + self.assertEqual(len(test_param_value_pairs), original_length) + self.assertEqual( + sorted(test_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + ] + ) + ), + ) + + self.assertTrue( + remove_parameter_value_pair_2( + test_param_value_pairs, + HOST_COMPILER, + GCC, + 10, + DEVICE_COMPILER, + NVCC, + 12.0, + ) + ) + self.assertEqual(len(test_param_value_pairs), original_length - 1) + self.assertEqual( + sorted(test_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + ] + ) + ), + ) + + self.assertTrue( + remove_parameter_value_pair_2( + test_param_value_pairs, + CMAKE, + CMAKE, + 3.23, + BOOST, + BOOST, + 1.83, + ) + ) + self.assertEqual(len(test_param_value_pairs), original_length - 2) + self.assertEqual( + sorted(test_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (NVCC, 12.0)}), + ] + ) + ), + ) + + def test_all_white_card(self): + test_param_value_pairs: List[ParameterValuePair] = parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + ] + ) + + self.assertTrue( + remove_parameter_value_pair_2( + test_param_value_pairs, + parameter1=ANY_PARAM, + value_name1=ANY_NAME, + value_version1=ANY_VERSION, + parameter2=ANY_PARAM, + value_name2=ANY_NAME, + value_version2=ANY_VERSION, + ) + ) + + self.assertEqual(len(test_param_value_pairs), 0) + + def test_single_white_card(self): + test_param_value_pairs: List[ParameterValuePair] = parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (CLANG, 17)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (GCC, 17)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({HOST_COMPILER: (CLANG, 10), BOOST: (BOOST, 1.83)}), + OD({HOST_COMPILER: (CLANG, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + ] + ) + test_original_len = len(test_param_value_pairs) + + t1_any_version1_param_value_pairs = copy.deepcopy(test_param_value_pairs) + self.assertTrue( + remove_parameter_value_pair_2( + t1_any_version1_param_value_pairs, + parameter1=HOST_COMPILER, + value_name1=GCC, + value_version1=ANY_VERSION, + parameter2=DEVICE_COMPILER, + value_name2=NVCC, + value_version2=12.0, + ) + ) + self.assertEqual(len(t1_any_version1_param_value_pairs), test_original_len - 2) + self.assertEqual( + sorted(t1_any_version1_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (CLANG, 17)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (GCC, 17)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({HOST_COMPILER: (CLANG, 10), BOOST: (BOOST, 1.83)}), + OD({HOST_COMPILER: (CLANG, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + ] + ) + ), + ) + + t2_any_name1_param_value_pairs = copy.deepcopy(test_param_value_pairs) + self.assertTrue( + remove_parameter_value_pair_2( + t2_any_name1_param_value_pairs, + parameter1=HOST_COMPILER, + value_name1=ANY_NAME, + value_version1=10, + parameter2=DEVICE_COMPILER, + value_name2=NVCC, + value_version2=12.0, + ) + ) + self.assertEqual(len(t2_any_name1_param_value_pairs), test_original_len - 2) + self.assertEqual( + sorted(t2_any_name1_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (CLANG, 17)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (GCC, 17)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({HOST_COMPILER: (CLANG, 10), BOOST: (BOOST, 1.83)}), + ] + ) + ), + ) + + def test_white_card_multi_parameter(self): + t1_any_parameter_param_value_pairs: List[ParameterValuePair] = parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({BOOST: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (CLANG, 17)}), + OD({HOST_COMPILER: (CLANG, 17), DEVICE_COMPILER: (CLANG, 16)}), + OD({CMAKE: (GCC, 10), UBUNTU: (NVCC, 11.2)}), + ] + ) + test_original_len = len(t1_any_parameter_param_value_pairs) + + self.assertTrue( + remove_parameter_value_pair_2( + t1_any_parameter_param_value_pairs, + parameter1=ANY_PARAM, + value_name1=GCC, + value_version1=10, + parameter2=ANY_PARAM, + value_name2=NVCC, + value_version2=11.2, + ) + ) + self.assertEqual(len(t1_any_parameter_param_value_pairs), test_original_len - 3) + self.assertEqual( + sorted(t1_any_parameter_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (CLANG, 17)}), + OD({HOST_COMPILER: (CLANG, 17), DEVICE_COMPILER: (CLANG, 16)}), + ] + ) + ), + ) + + def test_remove_all_gcc_host(self): + test_param_value_pairs: List[ParameterValuePair] = parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (CLANG, 17)}), + OD({HOST_COMPILER: (GCC, 9), DEVICE_COMPILER: (GCC, 17)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({HOST_COMPILER: (CLANG, 10), BOOST: (BOOST, 1.83)}), + OD({HOST_COMPILER: (CLANG, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + ] + ) + test_original_len = len(test_param_value_pairs) + + self.assertTrue( + remove_parameter_value_pair_2( + test_param_value_pairs, + parameter1=HOST_COMPILER, + value_name1=GCC, + value_version1=ANY_VERSION, + ) + ) + self.assertEqual(len(test_param_value_pairs), test_original_len - 5) + self.assertEqual( + sorted(test_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({HOST_COMPILER: (CLANG, 10), BOOST: (BOOST, 1.83)}), + OD({HOST_COMPILER: (CLANG, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + ] + ) + ), + ) + + def test_symmetric(self): + test_param_value_pairs: List[ParameterValuePair] = parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({DEVICE_COMPILER: (NVCC, 11.2), HOST_COMPILER: (GCC, 10)}), + OD({DEVICE_COMPILER: (NVCC, 12.0), HOST_COMPILER: (GCC, 10)}), + OD({BOOST: (BOOST, 1.83), CMAKE: (CMAKE, 3.23)}), + ] + ) + test_original_len = len(test_param_value_pairs) + + t1_single_hit_symmetric_param_value_pairs = copy.deepcopy(test_param_value_pairs) + self.assertTrue( + remove_parameter_value_pair_2( + t1_single_hit_symmetric_param_value_pairs, + parameter1=HOST_COMPILER, + value_name1=GCC, + value_version1=10, + parameter2=DEVICE_COMPILER, + value_name2=NVCC, + value_version2=12.0, + ) + ) + self.assertEqual(len(t1_single_hit_symmetric_param_value_pairs), test_original_len - 2) + self.assertEqual( + sorted(t1_single_hit_symmetric_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({DEVICE_COMPILER: (NVCC, 11.2), HOST_COMPILER: (GCC, 10)}), + OD({BOOST: (BOOST, 1.83), CMAKE: (CMAKE, 3.23)}), + ] + ) + ), + ) + + t2_single_hit_no_symmetric_param_value_pairs = copy.deepcopy(test_param_value_pairs) + self.assertTrue( + remove_parameter_value_pair_2( + t2_single_hit_no_symmetric_param_value_pairs, + parameter1=HOST_COMPILER, + value_name1=GCC, + value_version1=10, + parameter2=DEVICE_COMPILER, + value_name2=NVCC, + value_version2=12.0, + symmetric=False, + ) + ) + self.assertEqual(len(t2_single_hit_no_symmetric_param_value_pairs), test_original_len - 1) + self.assertEqual( + sorted(t2_single_hit_no_symmetric_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({DEVICE_COMPILER: (NVCC, 11.2), HOST_COMPILER: (GCC, 10)}), + OD({DEVICE_COMPILER: (NVCC, 12.0), HOST_COMPILER: (GCC, 10)}), + OD({BOOST: (BOOST, 1.83), CMAKE: (CMAKE, 3.23)}), + ] + ) + ), + ) + + t3_single_hit_no_symmetric_param_value_pairs = copy.deepcopy(test_param_value_pairs) + self.assertTrue( + remove_parameter_value_pair_2( + t3_single_hit_no_symmetric_param_value_pairs, + parameter1=DEVICE_COMPILER, + value_name1=NVCC, + value_version1=12.0, + parameter2=HOST_COMPILER, + value_name2=GCC, + value_version2=10, + symmetric=False, + ) + ) + self.assertEqual(len(t3_single_hit_no_symmetric_param_value_pairs), test_original_len - 1) + self.assertEqual( + sorted(t3_single_hit_no_symmetric_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({DEVICE_COMPILER: (NVCC, 11.2), HOST_COMPILER: (GCC, 10)}), + OD({BOOST: (BOOST, 1.83), CMAKE: (CMAKE, 3.23)}), + ] + ) + ), + ) + + t4_multi_hit_symmetric_param_value_pairs = copy.deepcopy(test_param_value_pairs) + self.assertTrue( + remove_parameter_value_pair_2( + t4_multi_hit_symmetric_param_value_pairs, + parameter1=HOST_COMPILER, + value_name1=GCC, + value_version1=ANY_VERSION, + ) + ) + self.assertEqual(len(t4_multi_hit_symmetric_param_value_pairs), test_original_len - 4) + self.assertEqual( + sorted(t4_multi_hit_symmetric_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({BOOST: (BOOST, 1.83), CMAKE: (CMAKE, 3.23)}), + ] + ) + ), + ) + + t5_multi_hit_no_symmetric_param_value_pairs = copy.deepcopy(test_param_value_pairs) + self.assertTrue( + remove_parameter_value_pair_2( + t5_multi_hit_no_symmetric_param_value_pairs, + parameter2=HOST_COMPILER, + value_name2=GCC, + value_version2=ANY_VERSION, + symmetric=False, + ) + ) + self.assertEqual(len(t5_multi_hit_no_symmetric_param_value_pairs), test_original_len - 2) + self.assertEqual( + sorted(t5_multi_hit_no_symmetric_param_value_pairs), + sorted( + parse_expected_val_pairs( + [ + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 11.2)}), + OD({HOST_COMPILER: (GCC, 10), DEVICE_COMPILER: (NVCC, 12.0)}), + OD({CMAKE: (CMAKE, 3.23), BOOST: (BOOST, 1.83)}), + OD({BOOST: (BOOST, 1.83), CMAKE: (CMAKE, 3.23)}), + ] + ) + ), + )