Home | History | Annotate | Download | only in stats
      1 // Copyright (c) 2017 Google Inc.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Tests for unique type declaration rules validator.
     16 
     17 #include <string>
     18 #include <unordered_map>
     19 
     20 #include "test/test_fixture.h"
     21 #include "test/unit_spirv.h"
     22 #include "tools/stats/spirv_stats.h"
     23 
     24 namespace spvtools {
     25 namespace stats {
     26 namespace {
     27 
     28 using spvtest::ScopedContext;
     29 
     30 void DiagnosticsMessageHandler(spv_message_level_t level, const char*,
     31                                const spv_position_t& position,
     32                                const char* message) {
     33   switch (level) {
     34     case SPV_MSG_FATAL:
     35     case SPV_MSG_INTERNAL_ERROR:
     36     case SPV_MSG_ERROR:
     37       std::cerr << "error: " << position.index << ": " << message << std::endl;
     38       break;
     39     case SPV_MSG_WARNING:
     40       std::cout << "warning: " << position.index << ": " << message
     41                 << std::endl;
     42       break;
     43     case SPV_MSG_INFO:
     44       std::cout << "info: " << position.index << ": " << message << std::endl;
     45       break;
     46     default:
     47       break;
     48   }
     49 }
     50 
     51 // Calls AggregateStats for binary compiled from |code|.
     52 void CompileAndAggregateStats(const std::string& code, SpirvStats* stats,
     53                               spv_target_env env = SPV_ENV_UNIVERSAL_1_1) {
     54   spvtools::Context ctx(env);
     55   ctx.SetMessageConsumer(DiagnosticsMessageHandler);
     56   spv_binary binary;
     57   ASSERT_EQ(SPV_SUCCESS, spvTextToBinary(ctx.CContext(), code.c_str(),
     58                                          code.size(), &binary, nullptr));
     59 
     60   ASSERT_EQ(SPV_SUCCESS, AggregateStats(ctx.CContext(), binary->code,
     61                                         binary->wordCount, nullptr, stats));
     62   spvBinaryDestroy(binary);
     63 }
     64 
     65 TEST(AggregateStats, CapabilityHistogram) {
     66   const std::string code1 = R"(
     67 OpCapability Addresses
     68 OpCapability Kernel
     69 OpCapability GenericPointer
     70 OpCapability Linkage
     71 OpMemoryModel Physical32 OpenCL
     72 )";
     73 
     74   const std::string code2 = R"(
     75 OpCapability Shader
     76 OpCapability Linkage
     77 OpMemoryModel Logical GLSL450
     78 )";
     79 
     80   SpirvStats stats;
     81 
     82   CompileAndAggregateStats(code1, &stats);
     83   EXPECT_EQ(4u, stats.capability_hist.size());
     84   EXPECT_EQ(0u, stats.capability_hist.count(SpvCapabilityShader));
     85   EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityAddresses));
     86   EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityKernel));
     87   EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityGenericPointer));
     88   EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityLinkage));
     89 
     90   CompileAndAggregateStats(code2, &stats);
     91   EXPECT_EQ(5u, stats.capability_hist.size());
     92   EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityShader));
     93   EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityAddresses));
     94   EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityKernel));
     95   EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityGenericPointer));
     96   EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityLinkage));
     97 
     98   CompileAndAggregateStats(code1, &stats);
     99   EXPECT_EQ(5u, stats.capability_hist.size());
    100   EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityShader));
    101   EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityAddresses));
    102   EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityKernel));
    103   EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityGenericPointer));
    104   EXPECT_EQ(3u, stats.capability_hist.at(SpvCapabilityLinkage));
    105 
    106   CompileAndAggregateStats(code2, &stats);
    107   EXPECT_EQ(5u, stats.capability_hist.size());
    108   EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityShader));
    109   EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityAddresses));
    110   EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityKernel));
    111   EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityGenericPointer));
    112   EXPECT_EQ(4u, stats.capability_hist.at(SpvCapabilityLinkage));
    113 }
    114 
    115 TEST(AggregateStats, ExtensionHistogram) {
    116   const std::string code1 = R"(
    117 OpCapability Addresses
    118 OpCapability Kernel
    119 OpCapability GenericPointer
    120 OpCapability Linkage
    121 OpExtension "SPV_KHR_16bit_storage"
    122 OpMemoryModel Physical32 OpenCL
    123 )";
    124 
    125   const std::string code2 = R"(
    126 OpCapability Shader
    127 OpCapability Linkage
    128 OpExtension "SPV_NV_viewport_array2"
    129 OpExtension "greatest_extension_ever"
    130 OpMemoryModel Logical GLSL450
    131 )";
    132 
    133   SpirvStats stats;
    134 
    135   CompileAndAggregateStats(code1, &stats);
    136   EXPECT_EQ(1u, stats.extension_hist.size());
    137   EXPECT_EQ(0u, stats.extension_hist.count("SPV_NV_viewport_array2"));
    138   EXPECT_EQ(1u, stats.extension_hist.at("SPV_KHR_16bit_storage"));
    139 
    140   CompileAndAggregateStats(code2, &stats);
    141   EXPECT_EQ(3u, stats.extension_hist.size());
    142   EXPECT_EQ(1u, stats.extension_hist.at("SPV_NV_viewport_array2"));
    143   EXPECT_EQ(1u, stats.extension_hist.at("SPV_KHR_16bit_storage"));
    144   EXPECT_EQ(1u, stats.extension_hist.at("greatest_extension_ever"));
    145 
    146   CompileAndAggregateStats(code1, &stats);
    147   EXPECT_EQ(3u, stats.extension_hist.size());
    148   EXPECT_EQ(1u, stats.extension_hist.at("SPV_NV_viewport_array2"));
    149   EXPECT_EQ(2u, stats.extension_hist.at("SPV_KHR_16bit_storage"));
    150   EXPECT_EQ(1u, stats.extension_hist.at("greatest_extension_ever"));
    151 
    152   CompileAndAggregateStats(code2, &stats);
    153   EXPECT_EQ(3u, stats.extension_hist.size());
    154   EXPECT_EQ(2u, stats.extension_hist.at("SPV_NV_viewport_array2"));
    155   EXPECT_EQ(2u, stats.extension_hist.at("SPV_KHR_16bit_storage"));
    156   EXPECT_EQ(2u, stats.extension_hist.at("greatest_extension_ever"));
    157 }
    158 
    159 TEST(AggregateStats, VersionHistogram) {
    160   const std::string code1 = R"(
    161 OpCapability Shader
    162 OpCapability Linkage
    163 OpMemoryModel Logical GLSL450
    164 )";
    165 
    166   SpirvStats stats;
    167 
    168   CompileAndAggregateStats(code1, &stats);
    169   EXPECT_EQ(1u, stats.version_hist.size());
    170   EXPECT_EQ(1u, stats.version_hist.at(0x00010100));
    171 
    172   CompileAndAggregateStats(code1, &stats, SPV_ENV_UNIVERSAL_1_0);
    173   EXPECT_EQ(2u, stats.version_hist.size());
    174   EXPECT_EQ(1u, stats.version_hist.at(0x00010100));
    175   EXPECT_EQ(1u, stats.version_hist.at(0x00010000));
    176 
    177   CompileAndAggregateStats(code1, &stats);
    178   EXPECT_EQ(2u, stats.version_hist.size());
    179   EXPECT_EQ(2u, stats.version_hist.at(0x00010100));
    180   EXPECT_EQ(1u, stats.version_hist.at(0x00010000));
    181 
    182   CompileAndAggregateStats(code1, &stats, SPV_ENV_UNIVERSAL_1_0);
    183   EXPECT_EQ(2u, stats.version_hist.size());
    184   EXPECT_EQ(2u, stats.version_hist.at(0x00010100));
    185   EXPECT_EQ(2u, stats.version_hist.at(0x00010000));
    186 }
    187 
    188 TEST(AggregateStats, GeneratorHistogram) {
    189   const std::string code1 = R"(
    190 OpCapability Shader
    191 OpCapability Linkage
    192 OpMemoryModel Logical GLSL450
    193 )";
    194 
    195   const uint32_t kGeneratorKhronosAssembler = SPV_GENERATOR_KHRONOS_ASSEMBLER
    196                                               << 16;
    197 
    198   SpirvStats stats;
    199 
    200   CompileAndAggregateStats(code1, &stats);
    201   EXPECT_EQ(1u, stats.generator_hist.size());
    202   EXPECT_EQ(1u, stats.generator_hist.at(kGeneratorKhronosAssembler));
    203 
    204   CompileAndAggregateStats(code1, &stats);
    205   EXPECT_EQ(1u, stats.generator_hist.size());
    206   EXPECT_EQ(2u, stats.generator_hist.at(kGeneratorKhronosAssembler));
    207 }
    208 
    209 TEST(AggregateStats, OpcodeHistogram) {
    210   const std::string code1 = R"(
    211 OpCapability Addresses
    212 OpCapability Kernel
    213 OpCapability Int64
    214 OpCapability Linkage
    215 OpMemoryModel Physical32 OpenCL
    216 %u64 = OpTypeInt 64 0
    217 %u32 = OpTypeInt 32 0
    218 %f32 = OpTypeFloat 32
    219 )";
    220 
    221   const std::string code2 = R"(
    222 OpCapability Shader
    223 OpCapability Linkage
    224 OpExtension "SPV_NV_viewport_array2"
    225 OpMemoryModel Logical GLSL450
    226 )";
    227 
    228   SpirvStats stats;
    229 
    230   CompileAndAggregateStats(code1, &stats);
    231   EXPECT_EQ(4u, stats.opcode_hist.size());
    232   EXPECT_EQ(4u, stats.opcode_hist.at(SpvOpCapability));
    233   EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpMemoryModel));
    234   EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpTypeInt));
    235   EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpTypeFloat));
    236 
    237   CompileAndAggregateStats(code2, &stats);
    238   EXPECT_EQ(5u, stats.opcode_hist.size());
    239   EXPECT_EQ(6u, stats.opcode_hist.at(SpvOpCapability));
    240   EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpMemoryModel));
    241   EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpTypeInt));
    242   EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpTypeFloat));
    243   EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpExtension));
    244 
    245   CompileAndAggregateStats(code1, &stats);
    246   EXPECT_EQ(5u, stats.opcode_hist.size());
    247   EXPECT_EQ(10u, stats.opcode_hist.at(SpvOpCapability));
    248   EXPECT_EQ(3u, stats.opcode_hist.at(SpvOpMemoryModel));
    249   EXPECT_EQ(4u, stats.opcode_hist.at(SpvOpTypeInt));
    250   EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpTypeFloat));
    251   EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpExtension));
    252 
    253   CompileAndAggregateStats(code2, &stats);
    254   EXPECT_EQ(5u, stats.opcode_hist.size());
    255   EXPECT_EQ(12u, stats.opcode_hist.at(SpvOpCapability));
    256   EXPECT_EQ(4u, stats.opcode_hist.at(SpvOpMemoryModel));
    257   EXPECT_EQ(4u, stats.opcode_hist.at(SpvOpTypeInt));
    258   EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpTypeFloat));
    259   EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpExtension));
    260 }
    261 
    262 TEST(AggregateStats, OpcodeMarkovHistogram) {
    263   const std::string code1 = R"(
    264 OpCapability Shader
    265 OpCapability Linkage
    266 OpExtension "SPV_NV_viewport_array2"
    267 OpMemoryModel Logical GLSL450
    268 )";
    269 
    270   const std::string code2 = R"(
    271 OpCapability Addresses
    272 OpCapability Kernel
    273 OpCapability Int64
    274 OpCapability Linkage
    275 OpMemoryModel Physical32 OpenCL
    276 %u64 = OpTypeInt 64 0
    277 %u32 = OpTypeInt 32 0
    278 %f32 = OpTypeFloat 32
    279 )";
    280 
    281   SpirvStats stats;
    282   stats.opcode_markov_hist.resize(2);
    283 
    284   CompileAndAggregateStats(code1, &stats);
    285   ASSERT_EQ(2u, stats.opcode_markov_hist.size());
    286   EXPECT_EQ(2u, stats.opcode_markov_hist[0].size());
    287   EXPECT_EQ(2u, stats.opcode_markov_hist[0].at(SpvOpCapability).size());
    288   EXPECT_EQ(1u, stats.opcode_markov_hist[0].at(SpvOpExtension).size());
    289   EXPECT_EQ(
    290       1u, stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpCapability));
    291   EXPECT_EQ(1u,
    292             stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpExtension));
    293   EXPECT_EQ(
    294       1u, stats.opcode_markov_hist[0].at(SpvOpExtension).at(SpvOpMemoryModel));
    295 
    296   EXPECT_EQ(1u, stats.opcode_markov_hist[1].size());
    297   EXPECT_EQ(2u, stats.opcode_markov_hist[1].at(SpvOpCapability).size());
    298   EXPECT_EQ(1u,
    299             stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpExtension));
    300   EXPECT_EQ(
    301       1u, stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpMemoryModel));
    302 
    303   CompileAndAggregateStats(code2, &stats);
    304   ASSERT_EQ(2u, stats.opcode_markov_hist.size());
    305   EXPECT_EQ(4u, stats.opcode_markov_hist[0].size());
    306   EXPECT_EQ(3u, stats.opcode_markov_hist[0].at(SpvOpCapability).size());
    307   EXPECT_EQ(1u, stats.opcode_markov_hist[0].at(SpvOpExtension).size());
    308   EXPECT_EQ(1u, stats.opcode_markov_hist[0].at(SpvOpMemoryModel).size());
    309   EXPECT_EQ(2u, stats.opcode_markov_hist[0].at(SpvOpTypeInt).size());
    310   EXPECT_EQ(
    311       4u, stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpCapability));
    312   EXPECT_EQ(1u,
    313             stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpExtension));
    314   EXPECT_EQ(
    315       1u, stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpMemoryModel));
    316   EXPECT_EQ(
    317       1u, stats.opcode_markov_hist[0].at(SpvOpExtension).at(SpvOpMemoryModel));
    318   EXPECT_EQ(1u,
    319             stats.opcode_markov_hist[0].at(SpvOpMemoryModel).at(SpvOpTypeInt));
    320   EXPECT_EQ(1u, stats.opcode_markov_hist[0].at(SpvOpTypeInt).at(SpvOpTypeInt));
    321   EXPECT_EQ(1u,
    322             stats.opcode_markov_hist[0].at(SpvOpTypeInt).at(SpvOpTypeFloat));
    323 
    324   EXPECT_EQ(3u, stats.opcode_markov_hist[1].size());
    325   EXPECT_EQ(4u, stats.opcode_markov_hist[1].at(SpvOpCapability).size());
    326   EXPECT_EQ(1u, stats.opcode_markov_hist[1].at(SpvOpMemoryModel).size());
    327   EXPECT_EQ(1u, stats.opcode_markov_hist[1].at(SpvOpTypeInt).size());
    328   EXPECT_EQ(
    329       2u, stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpCapability));
    330   EXPECT_EQ(1u,
    331             stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpExtension));
    332   EXPECT_EQ(
    333       2u, stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpMemoryModel));
    334   EXPECT_EQ(1u,
    335             stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpTypeInt));
    336   EXPECT_EQ(1u,
    337             stats.opcode_markov_hist[1].at(SpvOpMemoryModel).at(SpvOpTypeInt));
    338   EXPECT_EQ(1u,
    339             stats.opcode_markov_hist[1].at(SpvOpTypeInt).at(SpvOpTypeFloat));
    340 }
    341 
    342 TEST(AggregateStats, ConstantLiteralsHistogram) {
    343   const std::string code1 = R"(
    344 OpCapability Addresses
    345 OpCapability Kernel
    346 OpCapability GenericPointer
    347 OpCapability Linkage
    348 OpCapability Float64
    349 OpCapability Int16
    350 OpCapability Int64
    351 OpMemoryModel Physical32 OpenCL
    352 %u16 = OpTypeInt 16 0
    353 %u32 = OpTypeInt 32 0
    354 %u64 = OpTypeInt 64 0
    355 %f32 = OpTypeFloat 32
    356 %f64 = OpTypeFloat 64
    357 %1 = OpConstant %f32 0.1
    358 %2 = OpConstant %f32 -2
    359 %3 = OpConstant %f64 -2
    360 %4 = OpConstant %u16 16
    361 %5 = OpConstant %u16 2
    362 %6 = OpConstant %u32 32
    363 %7 = OpConstant %u64 64
    364 )";
    365 
    366   const std::string code2 = R"(
    367 OpCapability Shader
    368 OpCapability Linkage
    369 OpCapability Int16
    370 OpCapability Int64
    371 OpMemoryModel Logical GLSL450
    372 %f32 = OpTypeFloat 32
    373 %u16 = OpTypeInt 16 0
    374 %s16 = OpTypeInt 16 1
    375 %u32 = OpTypeInt 32 0
    376 %s32 = OpTypeInt 32 1
    377 %u64 = OpTypeInt 64 0
    378 %s64 = OpTypeInt 64 1
    379 %1 = OpConstant %f32 0.1
    380 %2 = OpConstant %f32 -2
    381 %3 = OpConstant %u16 1
    382 %4 = OpConstant %u16 16
    383 %5 = OpConstant %u16 2
    384 %6 = OpConstant %s16 -16
    385 %7 = OpConstant %u32 32
    386 %8 = OpConstant %s32 2
    387 %9 = OpConstant %s32 -32
    388 %10 = OpConstant %u64 64
    389 %11 = OpConstant %s64 -64
    390 )";
    391 
    392   SpirvStats stats;
    393 
    394   CompileAndAggregateStats(code1, &stats);
    395   EXPECT_EQ(2u, stats.f32_constant_hist.size());
    396   EXPECT_EQ(1u, stats.f64_constant_hist.size());
    397   EXPECT_EQ(1u, stats.f32_constant_hist.at(0.1f));
    398   EXPECT_EQ(1u, stats.f32_constant_hist.at(-2.f));
    399   EXPECT_EQ(1u, stats.f64_constant_hist.at(-2));
    400 
    401   EXPECT_EQ(2u, stats.u16_constant_hist.size());
    402   EXPECT_EQ(0u, stats.s16_constant_hist.size());
    403   EXPECT_EQ(1u, stats.u32_constant_hist.size());
    404   EXPECT_EQ(0u, stats.s32_constant_hist.size());
    405   EXPECT_EQ(1u, stats.u64_constant_hist.size());
    406   EXPECT_EQ(0u, stats.s64_constant_hist.size());
    407   EXPECT_EQ(1u, stats.u16_constant_hist.at(16));
    408   EXPECT_EQ(1u, stats.u16_constant_hist.at(2));
    409   EXPECT_EQ(1u, stats.u32_constant_hist.at(32));
    410   EXPECT_EQ(1u, stats.u64_constant_hist.at(64));
    411 
    412   CompileAndAggregateStats(code2, &stats);
    413   EXPECT_EQ(2u, stats.f32_constant_hist.size());
    414   EXPECT_EQ(1u, stats.f64_constant_hist.size());
    415   EXPECT_EQ(2u, stats.f32_constant_hist.at(0.1f));
    416   EXPECT_EQ(2u, stats.f32_constant_hist.at(-2.f));
    417   EXPECT_EQ(1u, stats.f64_constant_hist.at(-2));
    418 
    419   EXPECT_EQ(3u, stats.u16_constant_hist.size());
    420   EXPECT_EQ(1u, stats.s16_constant_hist.size());
    421   EXPECT_EQ(1u, stats.u32_constant_hist.size());
    422   EXPECT_EQ(2u, stats.s32_constant_hist.size());
    423   EXPECT_EQ(1u, stats.u64_constant_hist.size());
    424   EXPECT_EQ(1u, stats.s64_constant_hist.size());
    425   EXPECT_EQ(2u, stats.u16_constant_hist.at(16));
    426   EXPECT_EQ(2u, stats.u16_constant_hist.at(2));
    427   EXPECT_EQ(1u, stats.u16_constant_hist.at(1));
    428   EXPECT_EQ(1u, stats.s16_constant_hist.at(-16));
    429   EXPECT_EQ(2u, stats.u32_constant_hist.at(32));
    430   EXPECT_EQ(1u, stats.s32_constant_hist.at(2));
    431   EXPECT_EQ(1u, stats.s32_constant_hist.at(-32));
    432   EXPECT_EQ(2u, stats.u64_constant_hist.at(64));
    433   EXPECT_EQ(1u, stats.s64_constant_hist.at(-64));
    434 }
    435 
    436 }  // namespace
    437 }  // namespace stats
    438 }  // namespace spvtools
    439