diff options
Diffstat (limited to 'tests/validation/CL')
-rw-r--r-- | tests/validation/CL/Convolution.cpp | 239 |
1 files changed, 207 insertions, 32 deletions
diff --git a/tests/validation/CL/Convolution.cpp b/tests/validation/CL/Convolution.cpp index ccb0abcbd1..56f391965d 100644 --- a/tests/validation/CL/Convolution.cpp +++ b/tests/validation/CL/Convolution.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -48,16 +48,15 @@ namespace TEST_SUITE(CL) TEST_SUITE(CustomConvolution) TEST_SUITE(CustomConvolutionSquare) -TEST_SUITE(CustomConvolution3x3) - -DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), +TEST_SUITE(CustomConvolutionSquare3x3) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })), datasets::BorderModes()), framework::dataset::make("filter_size", { 3 })), - shape, data_type, border_mode, filter_size) + shape, output_data_type, border_mode, filter_size) { // Create tensors - CLTensor src = create_tensor<CLTensor>(shape, data_type); - CLTensor dst = create_tensor<CLTensor>(shape, data_type); + CLTensor src = create_tensor<CLTensor>(shape, DataType::U8); + CLTensor dst = create_tensor<CLTensor>(shape, output_data_type); // Create conv matrix int16_t conv[9]; @@ -92,6 +91,7 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combi template <typename T> using CLConvolutionFixture = ConvolutionSquareValidationFixture<CLTensor, CLAccessor, CLConvolution3x3, T>; +TEST_SUITE(CustomConvolutionSqaure3x3_U8) FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), datasets::BorderModes()), @@ -109,18 +109,37 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::Datas // Validate output validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); } -TEST_SUITE_END() /* Custom_Convolution 3x3 */ +TEST_SUITE_END() -TEST_SUITE(CustomConvolution5x5) +TEST_SUITE(CustomConvolutionSqaure3x3_S16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 3 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} +FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 3 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} +TEST_SUITE_END() +TEST_SUITE_END() /* Custom_Convolution 3x3 */ -DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), +TEST_SUITE(CustomConvolutionSquare5x5) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })), datasets::BorderModes()), framework::dataset::make("filter_size", { 5 })), - shape, data_type, border_mode, filter_size) + shape, output_data_type, border_mode, filter_size) { // Create tensors - CLTensor src = create_tensor<CLTensor>(shape, data_type); - CLTensor dst = create_tensor<CLTensor>(shape, data_type); + CLTensor src = create_tensor<CLTensor>(shape, DataType::U8); + CLTensor dst = create_tensor<CLTensor>(shape, output_data_type); // Create conv matrix int16_t conv[25]; @@ -154,6 +173,8 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combi template <typename T> using CLConvolutionFixture = ConvolutionSquareValidationFixture<CLTensor, CLAccessor, CLConvolution5x5, T>; + +TEST_SUITE(CustomConvolutionSqaure5x5_U8) FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), datasets::BorderModes()), @@ -171,17 +192,38 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::Datas // Validate output validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); } +TEST_SUITE_END() + +TEST_SUITE(CustomConvolutionSqaure5x5_S16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 5 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 5 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} +TEST_SUITE_END() TEST_SUITE_END() /* Custom Convolution 5x5 */ -TEST_SUITE(CustomConvolution7x7) -DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), +TEST_SUITE(CustomConvolutionSquare7x7) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })), datasets::BorderModes()), framework::dataset::make("filter_size", { 7 })), - shape, data_type, border_mode, filter_size) + shape, output_data_type, border_mode, filter_size) { // Create tensors - CLTensor src = create_tensor<CLTensor>(shape, data_type); - CLTensor dst = create_tensor<CLTensor>(shape, data_type); + CLTensor src = create_tensor<CLTensor>(shape, DataType::U8); + CLTensor dst = create_tensor<CLTensor>(shape, output_data_type); // Create conv matrix int16_t conv[49]; @@ -216,6 +258,7 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combi template <typename T> using CLConvolutionFixture = ConvolutionSquareValidationFixture<CLTensor, CLAccessor, CLConvolution7x7, T>; +TEST_SUITE(CustomConvolutionSquare7x7_U8) FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), datasets::BorderModes()), @@ -233,17 +276,38 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::Datas // Validate output validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); } +TEST_SUITE_END() + +TEST_SUITE(CustomConvolutionSquare7x7_S16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 7 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 7 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} +TEST_SUITE_END() TEST_SUITE_END() /* Custom Convolution 7x7 */ -TEST_SUITE(CustomConvolution9x9) -DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), +TEST_SUITE(CustomConvolutionSquare9x9) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })), datasets::BorderModes()), framework::dataset::make("filter_size", { 9 })), - shape, data_type, border_mode, filter_size) + shape, output_data_type, border_mode, filter_size) { // Create tensors - CLTensor src = create_tensor<CLTensor>(shape, data_type); - CLTensor dst = create_tensor<CLTensor>(shape, data_type); + CLTensor src = create_tensor<CLTensor>(shape, DataType::U8); + CLTensor dst = create_tensor<CLTensor>(shape, output_data_type); // Create conv matrix int16_t conv[81]; @@ -278,6 +342,7 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combi template <typename T> using CLConvolutionFixture = ConvolutionSquareValidationFixture<CLTensor, CLAccessor, CLConvolution9x9, T>; +TEST_SUITE(CustomConvolutionSquare9x9_U8) FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), datasets::BorderModes()), @@ -295,21 +360,41 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::Datas // Validate output validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); } +TEST_SUITE_END() + +TEST_SUITE(CustomConvolutionSquare9x9_S16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 9 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 9 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} +TEST_SUITE_END() TEST_SUITE_END() /* Custom Convolution 9x9 */ TEST_SUITE_END() /* Custom Convolution Square */ TEST_SUITE(CustomConvolutionRectangle) - DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", - DataType::U8)), - datasets::BorderModes()), - framework::dataset::make("filter_width", { 3, 5, 7, 9 })), - framework::dataset::make("filter_height", { 3, 5, 7, 9 })), - shape, data_type, border_mode, filter_width, filter_height) +{ DataType::U8, DataType::S16 })), +datasets::BorderModes()), +framework::dataset::make("filter_width", { 3, 5, 7, 9 })), +framework::dataset::make("filter_height", { 3, 5, 7, 9 })), +shape, output_data_type, border_mode, filter_width, filter_height) { // Create tensors - CLTensor src = create_tensor<CLTensor>(shape, data_type); - CLTensor dst = create_tensor<CLTensor>(shape, data_type); + CLTensor src = create_tensor<CLTensor>(shape, DataType::U8); + CLTensor dst = create_tensor<CLTensor>(shape, output_data_type); // Create conv matrix int16_t conv[filter_width * filter_height]; @@ -348,6 +433,7 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combi template <typename T> using CLConvolutionFixture = ConvolutionRectangleValidationFixture<CLTensor, CLAccessor, CLConvolutionRectangle, T>; +TEST_SUITE(CustomConvolutionRectangle_U8) FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), datasets::BorderModes()), @@ -367,6 +453,29 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::Datas // Validate output validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); } +TEST_SUITE_END() + +TEST_SUITE(CustomConvolutionRectangle_S16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_width", { 3, 5, 7, 9 })), + framework::dataset::make("filter_height", { 3, 5, 7, 9 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_width", { 3, 5, 7, 9 })), + framework::dataset::make("filter_height", { 3, 5, 7, 9 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} +TEST_SUITE_END() TEST_SUITE_END() /* Custom Convolution Rectangle */ TEST_SUITE(CustomConvolutionSeparable) @@ -374,6 +483,7 @@ TEST_SUITE(CustomConvolutionSeparable5x5) template <typename T> using CLConvolutionFixture = ConvolutionSeparableValidationFixture<CLTensor, CLAccessor, CLConvolution5x5, T>; +TEST_SUITE(CustomConvolutionSeparable5x5_U8) FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), datasets::BorderModes()), @@ -391,12 +501,34 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::Datas // Validate output validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); } +TEST_SUITE_END() + +TEST_SUITE(CustomConvolutionSeparable5x5_S16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 5 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 5 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} +TEST_SUITE_END() TEST_SUITE_END() /* Custom Convolution Separable 5x5 */ -TEST_SUITE(CustomConvolutionSeparablex7x7) +TEST_SUITE(CustomConvolutionSeparable7x7) template <typename T> using CLConvolutionFixture = ConvolutionSeparableValidationFixture<CLTensor, CLAccessor, CLConvolution7x7, T>; +TEST_SUITE(CustomConvolutionSeparable7x7_U8) FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), datasets::BorderModes()), @@ -414,12 +546,34 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::Datas // Validate output validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); } +TEST_SUITE_END() + +TEST_SUITE(CustomConvolutionSeparable7x7_S16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 7 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 7 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} +TEST_SUITE_END() TEST_SUITE_END() /* Custom Convolution Separable 7x7 */ TEST_SUITE(CustomConvolutionSeparable9x9) template <typename T> using CLConvolutionFixture = ConvolutionSeparableValidationFixture<CLTensor, CLAccessor, CLConvolution9x9, T>; +TEST_SUITE(CustomConvolutionSeparable9x9_U8) FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), datasets::BorderModes()), @@ -437,6 +591,27 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::Datas // Validate output validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); } +TEST_SUITE_END() + +TEST_SUITE(CustomConvolutionSeparable9x9_S16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 9 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::S16)), + datasets::BorderModes()), + framework::dataset::make("filter_size", { 9 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2))); +} +TEST_SUITE_END() TEST_SUITE_END() /* Custom Convolution Separable 9x9 */ TEST_SUITE_END() /* Custom Convolution Separable */ |