44// This source code is licensed under the BSD-style license found in the
55// LICENSE file in the root directory of this source tree.
66
7- #include < executorch/backends/vulkan/runtime/graph/ops/impl/Common.h>
8- #include < executorch/backends/vulkan/runtime/graph/ops/utils/ShaderNameUtils.h>
97#include < iostream>
108#include < vector>
11- #include " conv2d_utils.h"
12- #include " utils.h"
9+
10+ #include < executorch/backends/vulkan/runtime/graph/ops/impl/Common.h>
11+ #include < executorch/backends/vulkan/runtime/graph/ops/utils/ShaderNameUtils.h>
1312
1413#include < executorch/backends/vulkan/runtime/graph/ops/impl/Staging.h>
1514
15+ #include " conv2d_utils.h"
16+ #include " utils.h"
17+
1618// #define DEBUG_MODE
1719
1820using namespace executorch ::vulkan::prototyping;
@@ -24,22 +26,14 @@ static constexpr int64_t kRefDimSizeLimit = 100;
2426// Utility function to create a test case from a Conv2dConfig
2527TestCase create_test_case_from_config (
2628 const Conv2dConfig& config,
27- utils::StorageType storage_type,
2829 vkapi::ScalarType input_dtype,
29- utils::StorageType interm_storage_type) {
30+ utils::StorageType fp_storage_type,
31+ utils::StorageType int8_storage_type) {
3032 TestCase test_case;
31-
32- // Create a descriptive name for the test case
33- std::string storage_str =
34- (storage_type == utils::kTexture3D ) ? " Texture3D" : " Buffer" ;
35- std::string dtype_str = (input_dtype == vkapi::kFloat ) ? " Float" : " Half" ;
36-
37- std::string test_name =
38- config.test_case_name + " _" + storage_str + " _" + dtype_str;
39- test_case.set_name (test_name);
33+ test_case.set_name (config.test_case_name );
4034
4135 std::string operator_suffix = " .test" ;
42- if (interm_storage_type == utils::kTexture3D ) {
36+ if (int8_storage_type == utils::kTexture3D ) {
4337 operator_suffix += " _texture" ;
4438 } else {
4539 operator_suffix += " _buffer" ;
@@ -57,15 +51,15 @@ TestCase create_test_case_from_config(
5751 std::vector<int64_t > input_size = {
5852 1 , config.channels .in , config.input_size .h , config.input_size .w };
5953
60- utils::GPUMemoryLayout io_memory_layout = storage_type == utils::kBuffer
54+ utils::GPUMemoryLayout fp_memory_layout = fp_storage_type == utils::kBuffer
6155 ? utils::kWidthPacked
6256 : utils::kChannelsPacked ;
6357
6458 ValueSpec input_tensor (
6559 input_size,
6660 input_dtype,
67- storage_type ,
68- io_memory_layout ,
61+ fp_storage_type ,
62+ fp_memory_layout ,
6963#ifdef DEBUG_MODE
7064 DataGenType::RANDOM
7165#else
@@ -93,7 +87,7 @@ TestCase create_test_case_from_config(
9387 ValueSpec quantized_weight (
9488 weight_size,
9589 vkapi::kChar , // int8 for quantized weights
96- storage_type ,
90+ fp_storage_type ,
9791 utils::kWidthPacked ,
9892 DataGenType::RANDINT8);
9993 quantized_weight.set_constant (true );
@@ -108,15 +102,15 @@ TestCase create_test_case_from_config(
108102 ValueSpec weight_scales (
109103 {aligned_out_channels}, // Per output channel
110104 input_dtype,
111- storage_type ,
105+ fp_storage_type ,
112106 utils::kWidthPacked ,
113107 DataGenType::RANDOM_SCALES);
114108 weight_scales.set_constant (true );
115109
116110 ValueSpec weight_sums (
117111 {aligned_out_channels}, // Per output channel
118112 vkapi::kInt ,
119- storage_type ,
113+ fp_storage_type ,
120114 utils::kWidthPacked ,
121115 DataGenType::ZEROS);
122116 weight_sums.set_constant (true );
@@ -129,13 +123,12 @@ TestCase create_test_case_from_config(
129123 ValueSpec bias (
130124 {aligned_out_channels}, // Per output channel
131125 input_dtype,
132- storage_type ,
126+ fp_storage_type ,
133127 utils::kWidthPacked ,
134128 DataGenType::ZEROS);
135129 bias.set_constant (true );
136130
137131 // Output quantization parameters
138- // float output_scale_val = 0.01432;
139132 float output_scale_val = 0.05314 ;
140133 ValueSpec output_scale (output_scale_val);
141134
@@ -157,8 +150,8 @@ TestCase create_test_case_from_config(
157150 ValueSpec output (
158151 {1 , config.channels .out , H_out, W_out},
159152 input_dtype,
160- storage_type ,
161- io_memory_layout ,
153+ fp_storage_type ,
154+ fp_memory_layout ,
162155 DataGenType::ZEROS);
163156
164157 // Add all specs to test case for q8ta_q8csw_q8to operation
@@ -200,18 +193,16 @@ std::vector<TestCase> generate_quantized_conv2d_easy_cases() {
200193 };
201194 config.op_name = " conv2d_q8ta_q8csw_q8to" ;
202195
203- // Test with both storage types and data types for completeness
204196 std::vector<utils::StorageType> storage_types = {
205197 utils::kTexture3D , utils::kBuffer };
206- std::vector<vkapi::ScalarType> float_types = {vkapi::kFloat };
207198
208199 // Generate test cases for each combination
209- for (const auto & storage_type : storage_types) {
210- for (const auto & input_dtype : float_types) {
200+ for (const utils::StorageType fp_storage_type : storage_types) {
201+ for (const utils::StorageType int8_storage_type : storage_types) {
202+ config.test_case_name = make_test_case_name (
203+ config, false , fp_storage_type, int8_storage_type);
211204 test_cases.push_back (create_test_case_from_config (
212- config, storage_type, input_dtype, utils::kBuffer ));
213- test_cases.push_back (create_test_case_from_config (
214- config, storage_type, input_dtype, utils::kTexture3D ));
205+ config, vkapi::kFloat , fp_storage_type, int8_storage_type));
215206 }
216207 }
217208
@@ -221,6 +212,9 @@ std::vector<TestCase> generate_quantized_conv2d_easy_cases() {
221212// Generate test cases for quantized conv2d operation
222213std::vector<TestCase> generate_quantized_conv2d_test_cases () {
223214 std::vector<TestCase> test_cases;
215+ if (!vkcompute::api::context ()->adapter_ptr ()->supports_int8_dot_product ()) {
216+ return test_cases;
217+ }
224218
225219 std::vector<Conv2dConfig> configs = {
226220 // Pointwise convolutions: kernel size 1x1
@@ -317,7 +311,7 @@ std::vector<TestCase> generate_quantized_conv2d_test_cases() {
317311 Padding (2 , 2 ),
318312 Dilation (1 , 1 ),
319313 4 },
320- // Performance cases (pointwise)
314+ // Performance cases (pointwise - will use im2col )
321315 {OutInChannels (128 , 128 ),
322316 InputSize2D (128 , 128 ),
323317 KernelSize (1 , 1 ),
@@ -332,7 +326,7 @@ std::vector<TestCase> generate_quantized_conv2d_test_cases() {
332326 Padding (0 , 0 ),
333327 Dilation (1 , 1 ),
334328 1 },
335- // Performance cases (general 2d convs)
329+ // Performance cases (3x3 convs - will use im2col )
336330 {OutInChannels (32 , 3 ),
337331 InputSize2D (256 , 256 ),
338332 KernelSize (3 , 3 ),
@@ -354,6 +348,21 @@ std::vector<TestCase> generate_quantized_conv2d_test_cases() {
354348 Padding (1 , 1 ),
355349 Dilation (1 , 1 ),
356350 1 },
351+ // Performance cases (grouped convs)
352+ {OutInChannels (64 , 64 ),
353+ InputSize2D (128 , 128 ),
354+ KernelSize (3 , 3 ),
355+ Stride (1 , 1 ),
356+ Padding (1 , 1 ),
357+ Dilation (1 , 1 ),
358+ 2 },
359+ {OutInChannels (96 , 96 ),
360+ InputSize2D (128 , 128 ),
361+ KernelSize (3 , 3 ),
362+ Stride (2 , 2 ),
363+ Padding (1 , 1 ),
364+ Dilation (1 , 1 ),
365+ 3 },
357366 {OutInChannels (128 , 128 ),
358367 InputSize2D (128 , 128 ),
359368 KernelSize (5 , 5 ),
@@ -368,32 +377,19 @@ std::vector<TestCase> generate_quantized_conv2d_test_cases() {
368377
369378 // Generate test cases for each combination
370379 for (auto & config : configs) {
371- for (const auto & storage_type : storage_types) {
372- // Generate test case name programmatically
373- bool is_performance = config.channels .out > kRefDimSizeLimit ||
374- config.channels .in > kRefDimSizeLimit ||
375- config.input_size .h > kRefDimSizeLimit ||
376- config.input_size .w > kRefDimSizeLimit ;
377- std::string prefix = is_performance ? " performance_" : " correctness_" ;
378- std::string suffix = std::to_string (config.channels .out ) + " /" +
379- std::to_string (config.channels .in ) + " _" +
380- std::to_string (config.input_size .h ) + " /" +
381- std::to_string (config.input_size .w ) + " _" +
382- std::to_string (config.kernel .h ) + " /" +
383- std::to_string (config.kernel .w );
384-
385- config.op_name = " conv2d_q8ta_q8csw_q8to" ;
386- config.test_case_name = prefix + suffix;
387-
388- // Only test q8ta_q8csw_q8to if the int8 dot product extension is
389- // supported
390- if (vkcompute::api::context ()
391- ->adapter_ptr ()
392- ->supports_int8_dot_product ()) {
393- test_cases.push_back (create_test_case_from_config (
394- config, storage_type, vkapi::kFloat , utils::kBuffer ));
380+ bool is_performance = config.channels .out > kRefDimSizeLimit ||
381+ config.channels .in > kRefDimSizeLimit ||
382+ config.input_size .h > kRefDimSizeLimit ||
383+ config.input_size .w > kRefDimSizeLimit ;
384+
385+ config.op_name = " conv2d_q8ta_q8csw_q8to" ;
386+
387+ for (const utils::StorageType fp_storage_type : storage_types) {
388+ for (const utils::StorageType int8_storage_type : storage_types) {
389+ config.test_case_name = make_test_case_name (
390+ config, is_performance, fp_storage_type, int8_storage_type);
395391 test_cases.push_back (create_test_case_from_config (
396- config, storage_type, vkapi::kFloat , utils:: kTexture3D ));
392+ config, vkapi::kFloat , fp_storage_type, int8_storage_type ));
397393 }
398394 }
399395 }
0 commit comments