/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #include "hipAPIGroup.h" bool operator==(const HipAPIGroup& l_hip_api_group, const HipAPIGroup& r_hip_api_group) { return l_hip_api_group.group_name == r_hip_api_group.group_name; } HipAPIGroup::HipAPIGroup(std::string group_name, std::vector& hip_apis) : group_name{group_name}, total_number_of_apis{0}, number_of_api_calls{0}, percentage_of_called_apis{0.f}, number_of_test_cases{0} { std::vector test_cases; for (auto const& hip_api : hip_apis) { if (hip_api.getGroupName() != group_name) { continue; } if (hip_api.isDeprecated()) { deprecated_apis.push_back(hip_api); } else { if (hip_api.getNumberOfCalls()) { called_apis.push_back(hip_api); } else { not_called_apis.push_back(hip_api); } } number_of_api_calls += hip_api.getNumberOfCalls(); std::vector api_test_cases = hip_api.getTestCases(); test_cases.insert(test_cases.end(), api_test_cases.begin(), api_test_cases.end()); } std::sort(test_cases.begin(), test_cases.end()); auto last = std::unique(test_cases.begin(), test_cases.end()); test_cases.erase(last, test_cases.end()); number_of_test_cases = test_cases.size(); total_number_of_apis = called_apis.size() + not_called_apis.size() + deprecated_apis.size(); if (not_called_apis.empty()) { percentage_of_called_apis = 100.f; } else { percentage_of_called_apis = 100.f * called_apis.size() / (total_number_of_apis - deprecated_apis.size()); } } std::string HipAPIGroup::getName() const { return group_name; } int HipAPIGroup::getTotalNumberOfAPIs() const { return total_number_of_apis; } int HipAPIGroup::getTotalNumberOfCalls() const { return number_of_api_calls; } int HipAPIGroup::getTotalNumberOfTestCases() const { return number_of_test_cases; } int HipAPIGroup::getNumberOfCalledAPIs() const { return called_apis.size(); } int HipAPIGroup::getNumberOfNotCalledAPIs() const { return not_called_apis.size(); } int HipAPIGroup::getNumberOfDeprecatedAPIs() const { return deprecated_apis.size(); } float HipAPIGroup::getPercentageOfCalledAPIs() const { return percentage_of_called_apis; } bool HipAPIGroup::isDeprecated() const { return (static_cast(deprecated_apis.size()) == total_number_of_apis) ? true : false; } std::string HipAPIGroup::getBasicStatsXML() const { std::stringstream xml_node; std::string tag_name; std::transform(group_name.begin(), group_name.end(), std::back_inserter(tag_name), ::toupper); std::replace(tag_name.begin(), tag_name.end(), ' ', '-'); xml_node << "\n<" << tag_name << ">"; xml_node << "\n\t"; xml_node << "\n\t\t" << total_number_of_apis << ""; xml_node << "\n\t\t" << number_of_api_calls << ""; xml_node << "\n\t\t" << called_apis.size() << ""; xml_node << "\n\t\t" << not_called_apis.size() << ""; xml_node << "\n\t\t" << deprecated_apis.size() << ""; xml_node << "\n\t\t" << percentage_of_called_apis << "%"; xml_node << "\n\t"; if (!called_apis.empty()) { xml_node << "\n\t\n"; for (auto const& hip_api : called_apis) { xml_node << hip_api.getBasicStatsXML(); } xml_node << "\t"; } if (!not_called_apis.empty()) { xml_node << "\n\t\n"; for (auto const& hip_api : not_called_apis) { xml_node << hip_api.getBasicStatsXML(); } xml_node << "\t"; } if (!deprecated_apis.empty()) { xml_node << "\n\t\n"; for (auto const& hip_api : deprecated_apis) { xml_node << hip_api.getBasicStatsXML(); } xml_node << "\t"; } xml_node << "\n"; return xml_node.str(); } std::string HipAPIGroup::getBasicStatsHTML() const { std::stringstream html_object; std::string two_tabs{"\n\t\t"}; std::string three_tabs{"\n\t\t\t"}; std::string four_tabs{"\n\t\t\t\t"}; std::string five_tabs{"\n\t\t\t\t\t"}; // Determine font class from coverage.css and image for color bar. std::string font_class; std::string color_bar; if (percentage_of_called_apis < 40.f) { font_class = "coverNumLo"; color_bar = "resources/ruby.png"; } else if (percentage_of_called_apis < 80.f) { font_class = "coverNumMed"; color_bar = "resources/amber.png"; } else { font_class = "coverNumHi"; color_bar = "resources/emerald.png"; } if (isDeprecated()) { font_class = "coverDeprecated"; } html_object << two_tabs << ""; html_object << three_tabs << "" << group_name << ""; html_object << three_tabs << "" << total_number_of_apis << ""; html_object << three_tabs << "" << number_of_api_calls << ""; html_object << three_tabs << "" << number_of_test_cases << ""; html_object << three_tabs << "" << called_apis.size() << ""; html_object << three_tabs << "" << not_called_apis.size() << ""; html_object << three_tabs << "" << deprecated_apis.size() << ""; html_object << three_tabs << "" << std::fixed << std::setprecision(2) << percentage_of_called_apis << "%"; html_object << three_tabs << ""; html_object << four_tabs << ""; html_object << five_tabs << "
\"""; html_object << "\""
"; html_object << four_tabs << ""; html_object << three_tabs << ""; return html_object.str(); } std::string HipAPIGroup::createHTMLReport() const { std::stringstream html_report; std::string one_tab{"\n\t"}; std::string two_tabs{"\n\t\t"}; std::string three_tabs{"\n\t\t\t"}; std::string four_tabs{"\n\t\t\t\t"}; std::string five_tabs{"\n\t\t\t\t\t"}; std::string six_tabs{"\n\t\t\t\t\t\t"}; html_report << ""; html_report << "" << one_tab << ""; html_report << one_tab << "" << group_name << " Coverage report"; html_report << one_tab << "" << one_tab << ""; html_report << one_tab << "" << one_tab << ""; html_report << two_tabs << ""; html_report << two_tabs << "\n"; html_report << two_tabs << "" << three_tabs << ""; html_report << two_tabs << ""; html_report << two_tabs << "\n"; html_report << one_tab << "
" << group_name << " Coverage report
" << four_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; // Determine font class from coverage.css file based on coverage percentage. std::string font_class; if (percentage_of_called_apis < 40.f) { font_class = "headerCovTableEntryLo"; } else if (percentage_of_called_apis < 80.f) { font_class = "headerCovTableEntryMed"; } else { font_class = "headerCovTableEntryHi"; } html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << four_tabs << "
Value
Total number of detected HIP APIs:" << total_number_of_apis << "
HIP API calls within test source files:" << number_of_api_calls << "
Total number of test cases:" << number_of_test_cases << "
HIP APIs that are called at least once:" << called_apis.size() << "
HIP APIs that are not called at all:" << not_called_apis.size() << "
HIP APIs that are marked as deprecated:" << deprecated_apis.size() << "
Test coverage by implemented tests for the HIP APIs:" << std::fixed << std::setprecision(2) << percentage_of_called_apis << "%
"; html_report << three_tabs << "
"; // Add info about Test module APIs. html_report << one_tab << "
"; html_report << one_tab << ""; html_report << two_tabs << ""; html_report << three_tabs << ""; html_report << three_tabs << ""; html_report << two_tabs << ""; html_report << two_tabs << ""; html_report << three_tabs << ""; html_report << three_tabs << ""; html_report << three_tabs << ""; html_report << two_tabs << ""; html_report << one_tab << "

"; html_report << three_tabs << "
"; html_report << four_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; for (auto const& hip_api : called_apis) { html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; } html_report << four_tabs << "
Called APIs
" << hip_api.getName() << "
"; html_report << three_tabs << "
"; html_report << four_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; for (auto const& hip_api : not_called_apis) { html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; } html_report << four_tabs << "
Not called APIs
" << hip_api.getName() << "
"; html_report << three_tabs << "
"; html_report << four_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; for (auto const& hip_api : deprecated_apis) { html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; } html_report << four_tabs << "
Deprecated APIs
" << hip_api.getName() << "
"; html_report << three_tabs << "
"; html_report << one_tab << "
"; html_report << one_tab << "
"; html_report << one_tab << ""; html_report << two_tabs << ""; time_t now{time(nullptr)}; std::string date{asctime(gmtime(&now))}; html_report << two_tabs << ""; html_report << one_tab << "
Generated: " << date; html_report << two_tabs << " UTC
"; html_report << one_tab << "
"; html_report << "\n\n"; return html_report.str(); }