| // Copyright (c) 2017 Google Inc. | |
| // | |
| // 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. | |
| // Tests for unique type declaration rules validator. | |
| #include <sstream> | |
| #include <string> | |
| #include "source/latest_version_spirv_header.h" | |
| #include "test/test_fixture.h" | |
| #include "tools/stats/stats_analyzer.h" | |
| namespace spvtools { | |
| namespace stats { | |
| namespace { | |
| // Fills |stats| with some synthetic header stats, as if aggregated from 100 | |
| // modules (100 used for simpler percentage evaluation). | |
| void FillDefaultStats(SpirvStats* stats) { | |
| *stats = SpirvStats(); | |
| stats->version_hist[0x00010000] = 40; | |
| stats->version_hist[0x00010100] = 60; | |
| stats->generator_hist[0x00000000] = 64; | |
| stats->generator_hist[0x00010000] = 1; | |
| stats->generator_hist[0x00020000] = 2; | |
| stats->generator_hist[0x00030000] = 3; | |
| stats->generator_hist[0x00040000] = 4; | |
| stats->generator_hist[0x00050000] = 5; | |
| stats->generator_hist[0x00060000] = 6; | |
| stats->generator_hist[0x00070000] = 7; | |
| stats->generator_hist[0x00080000] = 8; | |
| int num_version_entries = 0; | |
| for (const auto& pair : stats->version_hist) { | |
| num_version_entries += pair.second; | |
| } | |
| int num_generator_entries = 0; | |
| for (const auto& pair : stats->generator_hist) { | |
| num_generator_entries += pair.second; | |
| } | |
| EXPECT_EQ(num_version_entries, num_generator_entries); | |
| } | |
| TEST(StatsAnalyzer, Version) { | |
| SpirvStats stats; | |
| FillDefaultStats(&stats); | |
| StatsAnalyzer analyzer(stats); | |
| std::stringstream ss; | |
| analyzer.WriteVersion(ss); | |
| const std::string output = ss.str(); | |
| const std::string expected_output = "Version 1.1 60%\nVersion 1.0 40%\n"; | |
| EXPECT_EQ(expected_output, output); | |
| } | |
| TEST(StatsAnalyzer, Generator) { | |
| SpirvStats stats; | |
| FillDefaultStats(&stats); | |
| StatsAnalyzer analyzer(stats); | |
| std::stringstream ss; | |
| analyzer.WriteGenerator(ss); | |
| const std::string output = ss.str(); | |
| const std::string expected_output = | |
| "Khronos 64%\nKhronos Glslang Reference Front End 8%\n" | |
| "Khronos SPIR-V Tools Assembler 7%\nKhronos LLVM/SPIR-V Translator 6%" | |
| "\nARM 5%\nNVIDIA 4%\nCodeplay 3%\nValve 2%\nLunarG 1%\n"; | |
| EXPECT_EQ(expected_output, output); | |
| } | |
| TEST(StatsAnalyzer, Capability) { | |
| SpirvStats stats; | |
| FillDefaultStats(&stats); | |
| stats.capability_hist[SpvCapabilityShader] = 25; | |
| stats.capability_hist[SpvCapabilityKernel] = 75; | |
| StatsAnalyzer analyzer(stats); | |
| std::stringstream ss; | |
| analyzer.WriteCapability(ss); | |
| const std::string output = ss.str(); | |
| const std::string expected_output = "Kernel 75%\nShader 25%\n"; | |
| EXPECT_EQ(expected_output, output); | |
| } | |
| TEST(StatsAnalyzer, Extension) { | |
| SpirvStats stats; | |
| FillDefaultStats(&stats); | |
| stats.extension_hist["greatest_extension_ever"] = 1; | |
| stats.extension_hist["worst_extension_ever"] = 10; | |
| StatsAnalyzer analyzer(stats); | |
| std::stringstream ss; | |
| analyzer.WriteExtension(ss); | |
| const std::string output = ss.str(); | |
| const std::string expected_output = | |
| "worst_extension_ever 10%\ngreatest_extension_ever 1%\n"; | |
| EXPECT_EQ(expected_output, output); | |
| } | |
| TEST(StatsAnalyzer, Opcode) { | |
| SpirvStats stats; | |
| FillDefaultStats(&stats); | |
| stats.opcode_hist[SpvOpCapability] = 20; | |
| stats.opcode_hist[SpvOpConstant] = 80; | |
| stats.opcode_hist[SpvOpDecorate] = 100; | |
| StatsAnalyzer analyzer(stats); | |
| std::stringstream ss; | |
| analyzer.WriteOpcode(ss); | |
| const std::string output = ss.str(); | |
| const std::string expected_output = | |
| "Total unique opcodes used: 3\nDecorate 50%\n" | |
| "Constant 40%\nCapability 10%\n"; | |
| EXPECT_EQ(expected_output, output); | |
| } | |
| TEST(StatsAnalyzer, OpcodeMarkov) { | |
| SpirvStats stats; | |
| FillDefaultStats(&stats); | |
| stats.opcode_hist[SpvOpFMul] = 400; | |
| stats.opcode_hist[SpvOpFAdd] = 200; | |
| stats.opcode_hist[SpvOpFSub] = 400; | |
| stats.opcode_markov_hist.resize(1); | |
| auto& hist = stats.opcode_markov_hist[0]; | |
| hist[SpvOpFMul][SpvOpFAdd] = 100; | |
| hist[SpvOpFMul][SpvOpFSub] = 300; | |
| hist[SpvOpFAdd][SpvOpFMul] = 100; | |
| hist[SpvOpFAdd][SpvOpFAdd] = 100; | |
| StatsAnalyzer analyzer(stats); | |
| std::stringstream ss; | |
| analyzer.WriteOpcodeMarkov(ss); | |
| const std::string output = ss.str(); | |
| const std::string expected_output = | |
| "FMul -> FSub 75% (base rate 40%, pair occurrences 300)\n" | |
| "FMul -> FAdd 25% (base rate 20%, pair occurrences 100)\n" | |
| "FAdd -> FAdd 50% (base rate 20%, pair occurrences 100)\n" | |
| "FAdd -> FMul 50% (base rate 40%, pair occurrences 100)\n"; | |
| EXPECT_EQ(expected_output, output); | |
| } | |
| } // namespace | |
| } // namespace stats | |
| } // namespace spvtools |