diff --git a/projects/hip-tests/utils/coverage/Makefile b/projects/hip-tests/utils/coverage/Makefile index ee590bb186..f81c71037d 100644 --- a/projects/hip-tests/utils/coverage/Makefile +++ b/projects/hip-tests/utils/coverage/Makefile @@ -30,9 +30,9 @@ all: ${SRC} ${CC} ${CPPFLAGS} $^ -o ${OBJ} clean: - rm ${OBJ} - rm *.xml - rm -r ./coverageReportHTML/testModules - rm -r ./coverageReportHTML/testAPIs - rm ./coverageReportHTML/*.html + rm -f ${OBJ} + rm -f *.xml + rm -fr ./coverageReportHTML/testModules + rm -fr ./coverageReportHTML/testAPIs + rm -f ./coverageReportHTML/*.html .PHONY : clean diff --git a/projects/hip-tests/utils/coverage/coverageReportHTML/resources/coverage.css b/projects/hip-tests/utils/coverage/coverageReportHTML/resources/coverage.css index 67a8a40b76..d92a870e3a 100644 --- a/projects/hip-tests/utils/coverage/coverageReportHTML/resources/coverage.css +++ b/projects/hip-tests/utils/coverage/coverageReportHTML/resources/coverage.css @@ -169,6 +169,18 @@ td.coverBarOutline background-color: #000000; } +/* Directory view/File view (all): line count entry for files with + deprecated functions */ +td.coverDeprecated +{ + text-align: center; + padding-left: 10px; + padding-right: 10px; + background-color: #d2d2d2; + white-space: nowrap; + font-family: sans-serif; +} + /* Directory view/File view (all): line count entry for files with high coverage rate */ td.coverNumHi diff --git a/projects/hip-tests/utils/coverage/device_api_list.txt b/projects/hip-tests/utils/coverage/device_api_list.txt new file mode 100644 index 0000000000..7588950886 --- /dev/null +++ b/projects/hip-tests/utils/coverage/device_api_list.txt @@ -0,0 +1,733 @@ +Atomics [ + atomicCAS + atomicCAS_system + atomicAdd + atomicAdd_system + unsafeAtomicAdd + safeAtomicAdd + atomicSub + atomicSub_system + atomicExch + atomicExch_system + atomicMin + atomicMin_system + unsafeAtomicMin + safeAtomicMin + atomicMax + atomicMax_system + unsafeAtomicMax + safeAtomicMax + atomicInc + atomicDec + atomicAnd + atomicAnd_system + atomicOr + atomicOr_system + atomicXor + atomicXor_system +] + +Builtin atomics [ + __hip_atomic_load + __hip_atomic_store + __hip_atomic_compare_exchange_weak + __hip_atomic_compare_exchange_strong + __hip_atomic_exchange + __hip_atomic_fetch_add + __hip_atomic_fetch_and + __hip_atomic_fetch_or + __hip_atomic_fetch_xor + __hip_atomic_fetch_min + __hip_atomic_fetch_max +] + +Cooperative groups [ + File restriction: cooperative_groups + Device groups: ( + coalesced_group_tile + coalesced_group + grid_group + multi_grid_group + thread_block_tile + thread_block + ) + size + thread_rank + group_index + thread_index + shfl + shfl_up + shfl_down + shfl_xor + sync +] + +Warp [ + File restriction: cooperative_groups + Device groups: ( + ballot + any + all + shfl_down + shfl_up + shfl + shfl_xor + ) + __ballot + __any + __all + __shfl_down + __shfl_up + __shfl + __shfl_xor +] + +Launch bounds [ + Device groups: ( + launch_bounds + ) + __launch_bounds__ +] + +Channel descriptor [ + hipCreateChannelDesc + hipCreateChannelDescHalf + hipCreateChannelDescHalf1 + hipCreateChannelDescHalf2 +] + +Device assert [ + assert + static_assert +] + +Device clock [ + Device groups: ( + clock + ) + clock + clock64 + wall_clock64 +] + +Device printf [ + printf +] + +HIP specific [ + Device groups: ( + hip_hc_8pk + ) + __hip_hc_add8pk + __hip_hc_sub8pk + __hip_hc_mul8pk +] + +Device synchronization [ + __syncthreads + __syncthreads_and + __syncthreads_count + __syncthreads_or +] + +Memory fence [ + __threadfence + __threadfence_block + __threadfence_system +] + +Device memory [ + memcpy + memset +] + +Device math [ + rsqrt + sqrt + cbrt + rcbrt + hypot + rhypot + norm3d + rnorm3d + norm4d + rnorm4d + norm + rnorm + rsqrtf + sqrtf + cbrtf + rcbrtf + hypotf + rhypotf + norm3df + rnorm3df + norm4df + rnorm4df + normf + rnormf + rsqrt + sqrt + cbrt + rcbrt + hypot + rhypot + norm3d + rnorm3d + norm4d + rnorm4d + norm + rnorm + expf + exp2f + exp10f + expm1f + frexpf + ldexpf + powf + powif + scalbnf + scalblnf + log + log2 + log10 + log1p + logb + ilogb + logf + log2f + log10f + log1pf + logbf + ilogbf + sin + cos + tan + sincos + sinpi + cospi + sincospi + asin + acos + atan + atan2 + sinh + cosh + tanh + asinh + acosh + atanh + sinf + cosf + tanf + sincosf + sinpif + cospif + sincospif + asinf + acosf + atanf + atan2f + sinhf + coshf + tanhf + asinhf + acoshf + atanhf + erf + erfc + erfinv + erfcinv + erfcx + normcdf + normcdfinv + lgamma + tgamma + j0 + j1 + jn + y0 + y1 + yn + cyl_bessel_i0 + cyl_bessel_i1 + erff + erfcf + erfinvf + erfcinvf + erfcxf + normcdff + normcdfinvf + lgammaf + tgammaf + j0f + j1f + jnf + y0f + y1f + ynf + cyl_bessel_i0f + cyl_bessel_i1f + fmod + remainder + remquo + modf + fdim + trunc + round + rint + nearbyint + ceil + floor + lrint + lround + llrint + llround + fmodf + remainderf + remquof + modff + fdimf + truncf + roundf + rintf + nearbyintf + ceilf + floorf + lrintf + lroundf + llrintf + llroundf + fma + abs + fabs + copysign + fmax + fmin + nan + nextafter + signbit + fmaf + abs + fabsf + copysignf + fdividef + fmaxf + fminf + isfinite + isinf + isnan + nanf + nextafterf + signbit + __brev + __brevll + __clz + __clzll + __ffs + __ffsll + __popc + __popcll + __mul24 + __umul24 + __dadd_rn + __dsub_rn + __dmul_rn + __fma_rn + __drcp_rn + __dsqrt_rn + __ddiv_rn + __fadd_rn + __fsub_rn + __fmul_rn + __fmaf_rn + __frcp_rn + __fsqrt_rn + __frsqrt_rn + __fdiv_rn + __fdividef + __expf + __exp10f + __logf + __log2f + __log10f + __sinf + __cosf + __sincosf + __tanf + __powf +] + +Device conversion functions [ + __double2float_rd + __double2float_rn + __double2float_ru + __double2float_rz + __double2hiint + __double2loint + __double2int_rd + __double2int_rn + __double2int_ru + __double2int_rz + __double2ll_rd + __double2ll_rn + __double2ll_ru + __double2ll_rz + __double2uint_rd + __double2uint_rn + __double2uint_ru + __double2uint_rz + __double2ull_rd + __double2ull_rn + __double2ull_ru + __double2ull_rz + __double_as_longlong + __float2int_rd + __float2int_rn + __float2int_ru + __float2int_rz + __float2ll_rd + __float2ll_rn + __float2ll_ru + __float2ll_rz + __float2uint_rd + __float2uint_rn + __float2uint_ru + __float2uint_rz + __float2ull_rd + __float2ull_rn + __float2ull_ru + __float2ull_rz + __float_as_int + __float_as_uint + __hiloint2double + __int2double_rn + __int2float_rd + __int2float_rn + __int2float_ru + __int2float_rz + __int_as_float + __ll2double_rd + __ll2double_rn + __ll2double_ru + __ll2double_rz + __ll2float_rd + __ll2float_rn + __ll2float_ru + __ll2float_rz + __longlong_as_double + __uint2double_rn + __uint2float_rd + __uint2float_rn + __uint2float_ru + __uint2float_rz + __uint_as_float + __ull2double_rd + __ull2double_rn + __ull2double_ru + __ull2double_rz + __ull2float_rd + __ull2float_rn + __ull2float_ru + __ull2float_rz +] + +Device complex type functions [ + hipCrealf + hipCimagf + make_hipFloatComplex + hipConjf + hipCsqabsf + hipCaddf + hipCsubf + hipCmulf + hipCdivf + hipCabsf + hipCreal + hipCimag + make_hipDoubleComplex + hipConj + hipCsqabs + hipCadd + hipCsub + hipCmul + hipCdiv + hipCabs + make_hipComplex + hipComplexDoubleToFloat + hipComplexFloatToDouble + hipCfmaf + hipCfma +] + +Device vector types [ + make_uchar1 + make_uchar2 + make_uchar3 + make_uchar4 + make_char1 + make_char2 + make_char3 + make_char4 + make_ushort1 + make_ushort2 + make_ushort3 + make_ushort4 + make_short1 + make_short2 + make_short3 + make_short4 + make_uint1 + make_uint2 + make_uint3 + make_uint4 + make_int1 + make_int2 + make_int3 + make_int4 + make_float1 + make_float2 + make_float3 + make_float4 + make_double1 + make_double2 + make_double3 + make_double4 + make_ulong1 + make_ulong2 + make_ulong3 + make_ulong4 + make_long1 + make_long2 + make_long3 + make_long4 + make_ulonglong1 + make_ulonglong2 + make_ulonglong3 + make_ulonglong4 + make_longlong1 + make_longlong2 + make_longlong3 + make_longlong4 +] + +Device surface functions [ + __hipGetPixelAddr + __hipMapToNativeFloat4 + __hipMapFromNativeFloat4 + surf1Dread + surf1Dwrite + surf2Dread + surf2Dwrite + surf3Dread + surf3Dwrite + surf1DLayeredread + surf1DLayeredwrite + surf2DLayeredread + surf2DLayeredwrite + surfCubemapread + surfCubemapwrite + surfCubemapLayeredread + surfCubemapLayeredwrite +] + +Device texture functions [ + tex1Dfetch + tex1D + tex2D + tex1DLayered + tex2DLayered + tex3D + texCubemap + tex1DLod + tex2DLod + tex1DLayeredLod + tex2DLayeredLod + tex3DLod + texCubemapLod + texCubemapLayered + texCubemapLayeredLod + texCubemapGrad + texCubemapLayeredGrad + tex1DGrad + tex2DGrad + tex1DLayeredGrad + tex2DLayeredGrad + tex3DGrad + tex2Dgather +] + +Device float16 functions [ + make_half2 + __low2half + __high2half + __half2half2 + __halves2half2 + __low2half2 + __high2half2 + __lows2half2 + __highs2half2 + __lowhigh2highlow + __half_as_short + __half_as_ushort + __short_as_half + __ushort_as_half + __float2half + __float2half_rn + __float2half_rz + __float2half_rd + __float2half_ru + __float2half2_rn + __floats2half2_rn + __float22half2_rn + __half2float + __low2float + __high2float + __half22float2 + __half2int_rn + __half2int_rz + __half2int_rd + __half2int_ru + __int2half_rn + __int2half_rz + __int2half_rd + __int2half_ru + __half2short_rn + __half2short_rz + __half2short_rd + __half2short_ru + __short2half_rn + __short2half_rz + __short2half_rd + __short2half_ru + __half2ll_rn + __half2ll_rz + __half2ll_rd + __half2ll_ru + __ll2half_rn + __ll2half_rz + __ll2half_rd + __ll2half_ru + __half2uint_rn + __half2uint_rz + __half2uint_rd + __half2uint_ru + __uint2half_rn + __uint2half_rz + __uint2half_rd + __uint2half_ru + __half2ushort_rn + __half2ushort_rz + __half2ushort_rd + __half2ushort_ru + __ushort2half_rn + __ushort2half_rz + __ushort2half_rd + __ushort2half_ru + __half2ull_rn + __half2ull_rz + __half2ull_rd + __half2ull_ru + __ull2half_rn + __ull2half_rz + __ull2half_rd + __ull2half_ru + __ldg + __ldcg + __ldca + __ldcs + __heq + __hne + __hle + __hge + __hlt + __hgt + __hequ + __hneu + __hleu + __hgeu + __hltu + __hgtu + __heq2 + __hne2 + __hle2 + __hge2 + __hlt2 + __hgt2 + __hequ2 + __hneu2 + __hleu2 + __hgeu2 + __hltu2 + __hgtu2 + __hbeq2 + __hbne2 + __hble2 + __hbge2 + __hblt2 + __hbgt2 + __hbequ2 + __hbneu2 + __hbleu2 + __hbgeu2 + __hbltu2 + __hbgtu2 + __clamp_01 + __hadd + __habs + __hsub + __hmul + __hadd_sat + __hsub_sat + __hmul_sat + __hfma + __hfma_sat + __hdiv + __hadd2 + __habs2 + __hsub2 + __hmul2 + __hadd2_sat + __hsub2_sat + __hmul2_sat + __hfma2 + __hfma2_sat + __h2div + amd_mixed_dot + htrunc + hceil + hfloor + hrint + hsin + hcos + hexp + hexp2 + hexp10 + hlog2 + hlog + hlog10 + hrcp + hrsqrt + hsqrt + __hisinf + __hisnan + __hneg + h2trunc + h2ceil + h2floor + h2rint + h2sin + h2cos + h2exp + h2exp2 + h2exp10 + h2log2 + h2log + h2log10 + h2rcp + h2rsqrt + h2sqrt + __hisinf2 + __hisnan2 + __hneg2 +] diff --git a/projects/hip-tests/utils/coverage/hipAPI.cpp b/projects/hip-tests/utils/coverage/hipAPI.cpp index 39ef99e4a2..5fa1c96798 100644 --- a/projects/hip-tests/utils/coverage/hipAPI.cpp +++ b/projects/hip-tests/utils/coverage/hipAPI.cpp @@ -22,11 +22,20 @@ THE SOFTWARE. #include "hipAPI.h" -FileOccurrence::FileOccurrence(std::string file_name, int line_number): - file_name{file_name}, line_number{line_number} {} +FileOccurrence::FileOccurrence(std::string file_name, int line_number) + : file_name{file_name}, line_number{line_number} {} -TestCaseOccurrence::TestCaseOccurrence(std::string test_case_name, std::string file_name, int line_number): - FileOccurrence{file_name, line_number}, test_case_name{test_case_name} {} +TestCaseOccurrence::TestCaseOccurrence(std::string test_case_name, std::string file_name, + int line_number) + : FileOccurrence{file_name, line_number}, test_case_name{test_case_name} {} + +bool operator==(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test) { + return l_test.test_case_name == r_test.test_case_name; +} + +bool operator<(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test) { + return l_test.test_case_name < r_test.test_case_name; +} bool operator==(const HipAPI& l_hip_api, const HipAPI& r_hip_api) { return l_hip_api.api_name == r_hip_api.api_name; @@ -36,54 +45,53 @@ bool operator<(const HipAPI& l_hip_api, const HipAPI& r_hip_api) { return l_hip_api.api_name < r_hip_api.api_name; } -HipAPI::HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name): - api_name{api_name}, deprecated{deprecated_flag}, api_group_name{api_group_name} {} - -std::string HipAPI::getName() const { - return api_name; +HipAPI::HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name, + std::string file_restriction) + : api_name{api_name}, + deprecated{deprecated_flag}, + api_group_name{api_group_name}, + file_restriction{file_restriction} { + test_cases.clear(); } -std::string HipAPI::getGroupName() const { - return api_group_name; -} +std::string HipAPI::getName() const { return api_name; } -int HipAPI::getNumberOfCalls() const { - return file_occurrences.size(); -} +std::string HipAPI::getGroupName() const { return api_group_name; } -int HipAPI::getNumberOfTestCases() const { - return test_cases.size(); -} +int HipAPI::getNumberOfCalls() const { return file_occurrences.size(); } + +std::vector HipAPI::getTestCases() const { return test_cases; } void HipAPI::addFileOccurrence(FileOccurrence file_occurrence) { file_occurrences.push_back(file_occurrence); } void HipAPI::addTestCase(TestCaseOccurrence test_case) { - test_cases.push_back(test_case); + if (std::find(test_cases.begin(), test_cases.end(), test_case) == test_cases.end()) { + test_cases.push_back(test_case); + } } -bool HipAPI::isDeprecated() const -{ - return deprecated; -} +bool HipAPI::isDeprecated() const { return deprecated; } -std::string HipAPI::getBasicStatsXML() const -{ +std::string HipAPI::getBasicStatsXML() const { std::stringstream xml_node; xml_node << "\t\t\n"; if (!deprecated) { xml_node << "\t\t\t" << api_name << "\n"; } else { - xml_node << "\t\t\t" << "[DEPRECATED] " << api_name << "\n"; + xml_node << "\t\t\t" + << "[DEPRECATED] " << api_name << "\n"; } if (!file_occurrences.empty()) { - xml_node << "\t\t\t" << file_occurrences.size() << "\n"; + xml_node << "\t\t\t" << file_occurrences.size() + << "\n"; xml_node << "\t\t\t\n"; - for (auto const& file_occurrence: file_occurrences) { - xml_node << "\t\t\t\t" << file_occurrence.file_name << ":" << file_occurrence.line_number << "\n"; + for (auto const& file_occurrence : file_occurrences) { + xml_node << "\t\t\t\t" << file_occurrence.file_name << ":" + << file_occurrence.line_number << "\n"; } xml_node << "\t\t\t\n"; } @@ -102,13 +110,20 @@ std::string HipAPI::createHTMLReport() const { std::string six_tabs{"\n\t\t\t\t\t\t"}; html_report << ""; - html_report << "" << one_tab << ""; - html_report << one_tab << "" << api_name << " Coverage report" << one_tab << "" << one_tab<< ""; - html_report << one_tab << "" << one_tab << ""; + html_report << "" << one_tab + << ""; + html_report << one_tab << "" << api_name << " Coverage 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 << ""; - for (auto const& test_case: test_cases) { + for (auto const& test_case : test_cases) { html_report << two_tabs << ""; - html_report << three_tabs << ""; + html_report << three_tabs << ""; html_report << three_tabs << ""; - html_report << three_tabs << ""; + html_report << three_tabs << ""; html_report << two_tabs << ""; } } else { html_report << two_tabs << ""; - html_report << three_tabs << ""; + html_report << three_tabs + << ""; html_report << two_tabs << ""; } html_report << one_tab << "
" << api_name << " Coverage report
" << four_tabs << "\n"; + html_report << two_tabs << "" << three_tabs << ""; html_report << two_tabs << ""; - html_report << two_tabs << "\n"; + html_report << two_tabs + << "\n"; html_report << one_tab << "
" << four_tabs + << ""; html_report << six_tabs << ""; @@ -124,7 +139,8 @@ std::string HipAPI::createHTMLReport() const { html_report << five_tabs << ""; html_report << six_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; @@ -135,13 +151,16 @@ std::string HipAPI::createHTMLReport() const { html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; - - html_report << five_tabs << ""; + + html_report << five_tabs + << ""; html_report << four_tabs << "
"; html_report << six_tabs << "
Calls within test source files:" << file_occurrences.size() << "" << file_occurrences.size() + << "
"; html_report << three_tabs << "
"; html_report << one_tab << "
"; @@ -160,23 +179,29 @@ std::string HipAPI::createHTMLReport() const { html_report << three_tabs << "
Line number
" << test_case.test_case_name << "" << test_case.test_case_name + << "" << test_case.file_name << "" << test_case.line_number << "" << test_case.line_number + << "

There are no test cases detected within doxygen comments.

There are no test " + "cases detected within doxygen comments.
"; html_report << one_tab << "
"; html_report << one_tab << ""; - html_report << two_tabs << ""; + html_report + << two_tabs + << ""; html_report << one_tab << "
"; // Add info about API occurrences in the test files. @@ -192,15 +217,19 @@ std::string HipAPI::createHTMLReport() const { html_report << three_tabs << "Line number"; html_report << two_tabs << ""; - for (auto const& file_occurrence: file_occurrences) { + for (auto const& file_occurrence : file_occurrences) { html_report << two_tabs << ""; - html_report << three_tabs << "" << file_occurrence.file_name << ""; - html_report << three_tabs << "" << file_occurrence.line_number << ""; + html_report << three_tabs << "" << file_occurrence.file_name + << ""; + html_report << three_tabs << "" + << file_occurrence.line_number << ""; html_report << two_tabs << ""; } } else { html_report << two_tabs << ""; - html_report << three_tabs << "
There are no occurrences within test source files."; + html_report << three_tabs + << "
There are no " + "occurrences within test source files."; html_report << two_tabs << ""; } html_report << one_tab << ""; @@ -208,7 +237,9 @@ std::string HipAPI::createHTMLReport() const { html_report << one_tab << "
"; html_report << one_tab << ""; - html_report << two_tabs << ""; + html_report + << two_tabs + << ""; time_t now{time(nullptr)}; std::string date{asctime(gmtime(&now))}; @@ -220,3 +251,5 @@ std::string HipAPI::createHTMLReport() const { return html_report.str(); } + +std::string HipAPI::getFileRestriction() const { return file_restriction; } diff --git a/projects/hip-tests/utils/coverage/hipAPI.h b/projects/hip-tests/utils/coverage/hipAPI.h index b14d3b7c6e..ffedf0ae44 100644 --- a/projects/hip-tests/utils/coverage/hipAPI.h +++ b/projects/hip-tests/utils/coverage/hipAPI.h @@ -23,6 +23,7 @@ THE SOFTWARE. #include #include #include +#include /* Helper class used to store information in what file has HIP API been detected, @@ -40,6 +41,9 @@ Helper class used to store information in what file has the API Test Case been d and on what line of code in that file. */ class TestCaseOccurrence : public FileOccurrence { + friend bool operator==(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test); + friend bool operator<(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test); + public: std::string test_case_name; TestCaseOccurrence(std::string test_case_name, std::string file_name, int line_number); @@ -55,18 +59,23 @@ class HipAPI { friend bool operator<(const HipAPI& l_hip_api, const HipAPI& r_hip_api); public: - HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name); + HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name, + std::string file_restriction = ""); std::string getName() const; std::string getGroupName() const; int getNumberOfCalls() const; - int getNumberOfTestCases() const; + std::vector getTestCases() const; void addFileOccurrence(FileOccurrence file_occurence); void addTestCase(TestCaseOccurrence test_case); bool isDeprecated() const; std::string getBasicStatsXML() const; std::string createHTMLReport() const; + std::string getFileRestriction() const; + std::vector device_groups; + private: std::string api_name; + std::string file_restriction; int number_of_calls; bool deprecated; std::string api_group_name; diff --git a/projects/hip-tests/utils/coverage/hipAPICoverageUtils.cpp b/projects/hip-tests/utils/coverage/hipAPICoverageUtils.cpp index 022815768c..aaf19dd906 100644 --- a/projects/hip-tests/utils/coverage/hipAPICoverageUtils.cpp +++ b/projects/hip-tests/utils/coverage/hipAPICoverageUtils.cpp @@ -42,13 +42,34 @@ void findAPICallInFile(HipAPI& hip_api, std::string test_module_file) { std::string api_call_with_assert{"(" + hip_api.getName() + "("}; std::string api_call_with_assignment{"= " + hip_api.getName() + "("}; std::string api_call_with_parameter{", " + hip_api.getName() + "("}; + std::string api_call_with_return{"return " + hip_api.getName() + "("}; + std::string api_call_in_line("{ " + hip_api.getName() + "("); + std::string api_member{"." + hip_api.getName() + "("}; + std::string api_newline{" " + hip_api.getName() + "("}; + std::string api_templated{" " + hip_api.getName() + "<"}; + + std::string api_restriction{hip_api.getFileRestriction()}; + bool found_restriction{false}; while (std::getline(test_module_file_handler, line)) { ++line_number; + + if (api_restriction != "" && line.find(api_restriction) != std::string::npos) { + found_restriction = true; + } + if ((line.find(api_call_with_assert) != std::string::npos) || (line.find(api_call_with_assignment) != std::string::npos) || - (line.find(api_call_with_parameter) != std::string::npos)) { - hip_api.addFileOccurrence(FileOccurrence(test_module_file, line_number)); + (line.find(api_call_with_parameter) != std::string::npos) || + (line.find(api_call_with_return) != std::string::npos) || + (line.find(api_call_in_line) != std::string::npos) || + (line.find(api_member) != std::string::npos) || + (line.find(api_newline) != std::string::npos) || + (line.find(hip_api.getName() + "(") == 0) || + (line.find(api_templated) != std::string::npos)) { + if (api_restriction == "" || found_restriction) { + hip_api.addFileOccurrence(FileOccurrence(test_module_file, line_number)); + } } } @@ -59,7 +80,7 @@ void findAPICallInFile(HipAPI& hip_api, std::string test_module_file) { Used to find all HIP API test cases within the passed test .cc files. Matching test case is detected when the HIP API in defined within doxygen comment. */ -void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file) { +void findAPITestCaseInFileByDoxygen(HipAPI& hip_api, std::string test_module_file) { std::fstream test_module_file_handler; test_module_file_handler.open(test_module_file); @@ -80,7 +101,10 @@ void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file) { } if (hip_api.getName() != current_api_name) { - continue; + if (std::find(hip_api.device_groups.begin(), hip_api.device_groups.end(), current_api_name) == + hip_api.device_groups.end()) { + continue; + } } if (line.find(ref_test_case) != std::string::npos) { @@ -99,15 +123,45 @@ void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file) { test_module_file_handler.close(); } +/* +Used to find all HIP API test cases within the passed test .cc files. +Matching test case is detected when the HIP API in defined within doxygen comment. +*/ +void findAPITestCaseInFileByAPIName(HipAPI& hip_api, std::string test_module_file) { + std::fstream test_module_file_handler; + test_module_file_handler.open(test_module_file); + + int line_number{0}; + std::string line; + + std::string test_case_definition{"TEST_CASE("}; + std::string test_case{"None"}; + + while (std::getline(test_module_file_handler, line)) { + ++line_number; + + if (line.find(test_case_definition) != std::string::npos) { + test_case = line.substr(line.find("\"") + 1); + test_case = test_case.substr(0, test_case.find("\"")); + if (test_case.find("_" + hip_api.getName() + "_") != std::string::npos) { + hip_api.addTestCase(TestCaseOccurrence{test_case, test_module_file, line_number}); + } + } + } + + test_module_file_handler.close(); +} + /* Used to iterate through all passed test .cc files and search for passed HIP API instance. This instance shall be used to update occurrences. */ void searchForAPI(HipAPI& hip_api, std::vector& test_module_files) { std::cout << "Searching for " << hip_api.getName() << " in test module files." << std::endl; - for (auto const& test_module_file: test_module_files) { + for (auto const& test_module_file : test_module_files) { findAPICallInFile(hip_api, test_module_file); - findAPITestCaseInFile(hip_api, test_module_file); + findAPITestCaseInFileByDoxygen(hip_api, test_module_file); + findAPITestCaseInFileByAPIName(hip_api, test_module_file); } } @@ -115,7 +169,7 @@ void searchForAPI(HipAPI& hip_api, std::vector& test_module_files) Used to extract all HIP APIs from the passed header file. */ std::vector extractHipAPIs(std::string& hip_api_header_file, - std::vector& api_group_names, bool start_groups) { + std::vector& api_group_names, bool start_groups) { std::fstream hip_header_file_handler; hip_header_file_handler.open(hip_api_header_file); @@ -148,8 +202,9 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, ++line_number; // Declarations of the HIP APIs start after the HIP API group has been defined. - if ((line.find(group_definition) != std::string::npos || line.find(add_group_definition) != std::string::npos) - && line.find(start_of_api_groups) != std::string::npos) { + if ((line.find(group_definition) != std::string::npos || + line.find(add_group_definition) != std::string::npos) && + line.find(start_of_api_groups) != std::string::npos) { api_group_names_start = true; continue; } @@ -167,24 +222,21 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, /* If the API is deprecated, raise a flag and go to the next line where the API is declared. - */ + */ if (line.find(deprecated_line) != std::string::npos) { - std::getline(hip_header_file_handler, line); - ++line_number; deprecated_flag = true; - } else { - deprecated_flag = false; + continue; } if (line.find(group_definition) != std::string::npos) { - std::string group_name = line.substr(line.find(group_definition) + group_definition.length() + 1); + std::string group_name = + line.substr(line.find(group_definition) + group_definition.length() + 1); group_name = group_name.substr(group_name.find(' ') + 1); api_group_names.push_back(group_name); api_group_names_tracker.push_back(group_name); - } - else if (line.find(add_group_definition) != std::string::npos) - { - std::string group_name = line.substr(line.find(add_group_definition) + add_group_definition.length() + 1); + } else if (line.find(add_group_definition) != std::string::npos) { + std::string group_name = + line.substr(line.find(add_group_definition) + add_group_definition.length() + 1); group_name = group_name.substr(group_name.find(' ') + 1); api_group_names.push_back(group_name); api_group_names_tracker.push_back(group_name); @@ -196,7 +248,9 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, to track the last defined group, because of the nested cases. */ if (line.find(end_group_definition) != std::string::npos) { - api_group_names_tracker.pop_back(); + if (!api_group_names_tracker.empty()) { + api_group_names_tracker.pop_back(); + } } /* @@ -207,16 +261,14 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, - Extract the name from that substring by finding the last "hip". Avoid comments. */ - if (line.find(hip_api_prefix) != std::string::npos && - line.find("(") != std::string::npos && - line.find(" ") != 0 && - line.find(" *") != 0) { + if (line.find(hip_api_prefix) != std::string::npos && line.find("(") != std::string::npos && + line.find(" ") != 0 && line.find(" *") != 0) { std::string api_name_no_brackets{line.substr(0, line.find("("))}; /* If there is no hip substring, then there is no valid API in that line. */ if (api_name_no_brackets.rfind(hip_api_prefix) == std::string::npos) { - continue; + continue; } /* @@ -233,13 +285,15 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, If the API is not present in the global list of HIP APIs, add it. */ HipAPI hip_api{api_name, deprecated_flag, api_group_names_tracker.back()}; - if(std::find(hip_apis.begin(), hip_apis.end(), hip_api) == hip_apis.end()) - { - hip_apis.push_back(hip_api); + if (std::find(hip_apis.begin(), hip_apis.end(), hip_api) == hip_apis.end()) { + hip_apis.push_back(hip_api); } } else { std::cout << "[SKIP_FROM_COV] Group not detected for \"" << api_name << "\" in file \"" - << hip_api_header_file << "\", line " << line_number << std::endl; + << hip_api_header_file << "\", line " << line_number << std::endl; + } + if (deprecated_flag) { + deprecated_flag = false; } } } @@ -248,14 +302,83 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, return hip_apis; } +/* +Used to extract all HIP APIs from the passed header file. +*/ +std::vector extractDeviceAPIs(std::string& apis_list_file, + std::vector& api_group_names) { + std::fstream apis_list_file_handler; + apis_list_file_handler.open(apis_list_file); + + std::string line; + std::vector device_apis; + + /* + Each HIP API has prefix hip in the name. Groups are marked with @defgroup, and the + main group that shall be considered is HIP API. Before that group is defined, lines + of code shall not be considered. + */ + int line_number{0}; + bool group_start{false}; + bool device_groups_start{false}; + std::string restriction{""}; + std::string file_restriction_definition{"File restriction: "}; + std::string device_groups_definition{"Device groups: ("}; + std::vector device_groups; + + while (std::getline(apis_list_file_handler, line)) { + ++line_number; + + if (line.find("[") != std::string::npos) { + std::string group_name = line.substr(0, line.rfind(" ")); + api_group_names.push_back(group_name); + group_start = true; + continue; + } + + if (line.find("]") != std::string::npos) { + group_start = false; + device_groups.clear(); + restriction = ""; + continue; + } + + if (line.find(file_restriction_definition) != std::string::npos) { + restriction = + line.substr(line.find(file_restriction_definition) + file_restriction_definition.size()); + continue; + } + + if (line.find(device_groups_definition) != std::string::npos) { + std::getline(apis_list_file_handler, line); + while (line.find(")") == std::string::npos) { + std::string group_name = line; + group_name.erase(std::remove(group_name.begin(), group_name.end(), ' '), group_name.end()); + device_groups.push_back(group_name); + std::getline(apis_list_file_handler, line); + } + std::getline(apis_list_file_handler, line); + } + + if (group_start) { + std::string api_name = line.substr(line.rfind(" ") + 1); + HipAPI hip_api{api_name, false, api_group_names.back(), restriction}; + hip_api.device_groups = device_groups; + device_apis.push_back(hip_api); + } + } + + apis_list_file_handler.close(); + return device_apis; +} + /* Used to extract test .cc files from the passed tests root directory. Goes through all subdirectories and searches for .cc and .hh files for HIP API invocations. Implements BFS algorithm to avoid recursion. */ -std::vector extractTestModuleFiles(std::string& tests_root_directory) -{ +std::vector extractTestModuleFiles(std::string& tests_root_directory) { std::vector directory_queue; directory_queue.push_back(tests_root_directory); std::vector test_module_files; @@ -263,11 +386,11 @@ std::vector extractTestModuleFiles(std::string& tests_root_director while (!directory_queue.empty()) { std::string processed_entry = directory_queue.back(); directory_queue.pop_back(); - for (const auto& entry: std::filesystem::directory_iterator(processed_entry)) { + for (const auto& entry : std::filesystem::directory_iterator(processed_entry)) { if (std::filesystem::is_directory(entry.path())) { directory_queue.push_back(entry.path()); } else { - if (entry.path().string().find(".cc") != std::string::npos || + if (entry.path().string().find(".cc") != std::string::npos || entry.path().string().find(".hh") != std::string::npos) { test_module_files.push_back(entry.path()); } @@ -278,7 +401,6 @@ std::vector extractTestModuleFiles(std::string& tests_root_director return test_module_files; } -std::string findAbsolutePathOfFile(std::string file_path) -{ +std::string findAbsolutePathOfFile(std::string file_path) { return std::filesystem::canonical(std::filesystem::absolute(file_path)); } diff --git a/projects/hip-tests/utils/coverage/hipAPICoverageUtils.h b/projects/hip-tests/utils/coverage/hipAPICoverageUtils.h index 68454fd863..a62c9485d7 100644 --- a/projects/hip-tests/utils/coverage/hipAPICoverageUtils.h +++ b/projects/hip-tests/utils/coverage/hipAPICoverageUtils.h @@ -25,8 +25,12 @@ THE SOFTWARE. #include "hipAPIGroup.h" void findAPICallInFile(HipAPI& hip_api, std::string test_module_file); -void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file); +void findAPITestCaseInFileByDoxygen(HipAPI& hip_api, std::string test_module_file); +void findAPITestCaseInFileByAPIName(HipAPI& hip_api, std::string test_module_file); void searchForAPI(HipAPI& hip_api, std::vector& test_module_files); -std::vector extractHipAPIs(std::string& hip_api_header_file, std::vector& api_group_names, bool start_groups); +std::vector extractHipAPIs(std::string& hip_api_header_file, + std::vector& api_group_names, bool start_groups); +std::vector extractDeviceAPIs(std::string& apis_list_file, + std::vector& api_group_names); std::vector extractTestModuleFiles(std::string& tests_root_directory); std::string findAbsolutePathOfFile(std::string file_path); diff --git a/projects/hip-tests/utils/coverage/hipAPIGroup.cpp b/projects/hip-tests/utils/coverage/hipAPIGroup.cpp index b24e2f1baa..5ec5174874 100644 --- a/projects/hip-tests/utils/coverage/hipAPIGroup.cpp +++ b/projects/hip-tests/utils/coverage/hipAPIGroup.cpp @@ -26,11 +26,14 @@ bool operator==(const HipAPIGroup& l_hip_api_group, const HipAPIGroup& r_hip_api 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}, number_of_api_calls{0}, percentage_of_called_apis{0.f}, - total_number_of_apis{0}, number_of_test_cases{0} -{ - for (auto const& hip_api: hip_apis) { +HipAPIGroup::HipAPIGroup(std::string group_name, std::vector& hip_apis) + : group_name{group_name}, + number_of_api_calls{0}, + percentage_of_called_apis{0.f}, + total_number_of_apis{0}, + number_of_test_cases{0} { + std::vector test_cases; + for (auto const& hip_api : hip_apis) { if (hip_api.getGroupName() != group_name) { continue; } @@ -46,47 +49,43 @@ HipAPIGroup::HipAPIGroup(std::string group_name, std::vector& hip_apis): } number_of_api_calls += hip_api.getNumberOfCalls(); - number_of_test_cases += hip_api.getNumberOfTestCases(); + + 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()); + percentage_of_called_apis = + 100.f * called_apis.size() / (total_number_of_apis - deprecated_apis.size()); } } -std::string HipAPIGroup::getName() const { - return group_name; -} +std::string HipAPIGroup::getName() const { return group_name; } -int HipAPIGroup::getTotalNumberOfAPIs() const { - return total_number_of_apis; -} +int HipAPIGroup::getTotalNumberOfAPIs() const { return total_number_of_apis; } -int HipAPIGroup::getTotalNumberOfCalls() const { - return number_of_api_calls; -} +int HipAPIGroup::getTotalNumberOfCalls() const { return number_of_api_calls; } -int HipAPIGroup::getTotalNumberOfTestCases() const { - return number_of_test_cases; -} +int HipAPIGroup::getTotalNumberOfTestCases() const { return number_of_test_cases; } -int HipAPIGroup::getNumberOfCalledAPIs() const { - return called_apis.size(); -} +int HipAPIGroup::getNumberOfCalledAPIs() const { return called_apis.size(); } -int HipAPIGroup::getNumberOfNotCalledAPIs() const { - return not_called_apis.size(); -} +int HipAPIGroup::getNumberOfNotCalledAPIs() const { return not_called_apis.size(); } -int HipAPIGroup::getNumberOfDeprecatedAPIs() const { - return deprecated_apis.size(); -} +int HipAPIGroup::getNumberOfDeprecatedAPIs() const { return deprecated_apis.size(); } -float HipAPIGroup::getPercentageOfCalledAPIs() const { - return percentage_of_called_apis; +float HipAPIGroup::getPercentageOfCalledAPIs() const { return percentage_of_called_apis; } + +bool HipAPIGroup::isDeprecated() const { + return (deprecated_apis.size() == total_number_of_apis) ? true : false; } std::string HipAPIGroup::getBasicStatsXML() const { @@ -100,16 +99,18 @@ std::string HipAPIGroup::getBasicStatsXML() const { 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" << 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\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) { + for (auto const& hip_api : called_apis) { xml_node << hip_api.getBasicStatsXML(); } xml_node << "\t"; @@ -117,7 +118,7 @@ std::string HipAPIGroup::getBasicStatsXML() const { if (!not_called_apis.empty()) { xml_node << "\n\t\n"; - for (auto const& hip_api: not_called_apis) { + for (auto const& hip_api : not_called_apis) { xml_node << hip_api.getBasicStatsXML(); } xml_node << "\t"; @@ -125,7 +126,7 @@ std::string HipAPIGroup::getBasicStatsXML() const { if (!deprecated_apis.empty()) { xml_node << "\n\t\n"; - for (auto const& hip_api: deprecated_apis) { + for (auto const& hip_api : deprecated_apis) { xml_node << hip_api.getBasicStatsXML(); } xml_node << "\t"; @@ -135,8 +136,7 @@ std::string HipAPIGroup::getBasicStatsXML() const { return xml_node.str(); } -std::string HipAPIGroup::getBasicStatsHTML() const -{ +std::string HipAPIGroup::getBasicStatsHTML() const { std::stringstream html_object; std::string two_tabs{"\n\t\t"}; std::string three_tabs{"\n\t\t\t"}; @@ -158,29 +158,42 @@ std::string HipAPIGroup::getBasicStatsHTML() const color_bar = "resources/emerald.png"; } + if (isDeprecated()) { + font_class = "coverDeprecated"; + } + html_object << two_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; html_object << three_tabs << "
" << group_name << "" << total_number_of_apis << "" << number_of_api_calls << "" << number_of_test_cases << "" << called_apis.size() << "" << not_called_apis.size() << "" << deprecated_apis.size() << "" << std::fixed << std::setprecision(2) << percentage_of_called_apis << "%" << group_name << "" << total_number_of_apis + << "" << number_of_api_calls + << "" << number_of_test_cases + << "" << called_apis.size() + << "" << not_called_apis.size() + << "" << deprecated_apis.size() + << "" << std::fixed + << std::setprecision(2) << percentage_of_called_apis << "%"; html_object << four_tabs << ""; html_object << five_tabs << "
\"""; - html_object << "\""
"; + html_object << color_bar << "\" width=" << percentage_of_called_apis << " height=10 alt=\"" + << percentage_of_called_apis << "%\">"; + html_object << "\""
"; html_object << four_tabs << ""; html_object << three_tabs << ""; return html_object.str(); } -std::string HipAPIGroup::createHTMLReport() const -{ +std::string HipAPIGroup::createHTMLReport() const { std::stringstream html_report; std::string one_tab{"\n\t"}; std::string two_tabs{"\n\t\t"}; @@ -190,14 +203,22 @@ std::string HipAPIGroup::createHTMLReport() const std::string six_tabs{"\n\t\t\t\t\t\t"}; html_report << ""; - html_report << "" << one_tab << ""; + 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 << six_tabs << ""; html_report << five_tabs << ""; - for (auto const& hip_api: called_apis) { + for (auto const& hip_api : called_apis) { html_report << five_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs << ""; html_report << five_tabs << ""; } @@ -293,9 +328,10 @@ std::string HipAPIGroup::createHTMLReport() const html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; - for (auto const& hip_api: not_called_apis) { + for (auto const& hip_api : not_called_apis) { html_report << five_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs << ""; html_report << five_tabs << ""; } html_report << four_tabs << "
" << group_name << " Coverage report
" << four_tabs << "" + << 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 << two_tabs + << "\n"; html_report << one_tab << "
" << group_name + << " Coverage report
" << four_tabs + << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; @@ -206,37 +227,44 @@ std::string HipAPIGroup::createHTMLReport() const html_report << five_tabs << ""; html_report << six_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 << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_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 << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_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 << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; @@ -251,17 +279,23 @@ std::string HipAPIGroup::createHTMLReport() const } html_report << five_tabs << ""; - html_report << six_tabs << ""; - html_report << six_tabs << ""; + html_report + << six_tabs + << ""; + html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; - html_report << five_tabs << ""; + html_report << five_tabs + << ""; html_report << four_tabs << "
Value
Total number of detected HIP APIs:" << total_number_of_apis << "" << total_number_of_apis + << "
HIP API calls within test source files:HIP API calls within test source files:" << number_of_api_calls << "
Total number of test cases:" << number_of_test_cases << "" << number_of_test_cases + << "
HIP APIs that are called at least once:HIP APIs that are called at least once:" << called_apis.size() << "
HIP APIs that are not called at all:" << not_called_apis.size() << "" << not_called_apis.size() + << "
HIP APIs that are marked as deprecated:" << deprecated_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 << "%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. @@ -279,9 +313,10 @@ std::string HipAPIGroup::createHTMLReport() const html_report << five_tabs << "
Called APIs
" << hip_api.getName() << "" << hip_api.getName() << "
Not called APIs
" << hip_api.getName() << "" << hip_api.getName() << "
"; @@ -306,9 +342,10 @@ std::string HipAPIGroup::createHTMLReport() const html_report << five_tabs << ""; html_report << six_tabs << "Deprecated APIs"; html_report << five_tabs << ""; - for (auto const& hip_api: deprecated_apis) { + for (auto const& hip_api : deprecated_apis) { html_report << five_tabs << ""; - html_report << six_tabs << "" << hip_api.getName() << ""; + html_report << six_tabs << "" << hip_api.getName() << ""; html_report << five_tabs << ""; } html_report << four_tabs << ""; @@ -321,7 +358,9 @@ std::string HipAPIGroup::createHTMLReport() const html_report << one_tab << "
"; html_report << one_tab << ""; - html_report << two_tabs << ""; + html_report + << two_tabs + << ""; time_t now{time(nullptr)}; std::string date{asctime(gmtime(&now))}; diff --git a/projects/hip-tests/utils/coverage/hipAPIGroup.h b/projects/hip-tests/utils/coverage/hipAPIGroup.h index c9b07b8656..7687f623ac 100644 --- a/projects/hip-tests/utils/coverage/hipAPIGroup.h +++ b/projects/hip-tests/utils/coverage/hipAPIGroup.h @@ -21,10 +21,9 @@ THE SOFTWARE. */ #include "hipAPI.h" -#include #include -class HipAPIGroup{ +class HipAPIGroup { friend bool operator==(const HipAPIGroup& l_hip_api_group, const HipAPIGroup& r_hip_api_group); public: @@ -40,6 +39,8 @@ class HipAPIGroup{ std::string getBasicStatsXML() const; std::string getBasicStatsHTML() const; std::string createHTMLReport() const; + bool isDeprecated() const; + private: std::string group_name; int total_number_of_apis; diff --git a/projects/hip-tests/utils/coverage/mainCoverage.cpp b/projects/hip-tests/utils/coverage/mainCoverage.cpp index 65de5890a8..cc35cab075 100644 --- a/projects/hip-tests/utils/coverage/mainCoverage.cpp +++ b/projects/hip-tests/utils/coverage/mainCoverage.cpp @@ -22,10 +22,11 @@ THE SOFTWARE. #include "reportGenerators.h" -int main(int argc, char** argv) -{ +int main(int argc, char** argv) { if (argc != 2) { - std::cout << "Please provide the path to the cloned HIP/include/ directory as an argument! Only one argument supported." << std::endl; + std::cout << "Please provide the path to the cloned HIP/include/ directory as an argument! " + "Only one argument supported." + << std::endl; std::cout << "\tExample: ./generateHipAPICoverage /workspace/user1/HIP/include/" << std::endl; return -1; } @@ -34,33 +35,44 @@ int main(int argc, char** argv) Relative paths to all needed files, as it is expected that the application is called from the HIP/tests/catch/coverage directory. */ - std::string hip_api_header_file{findAbsolutePathOfFile(hip_include_path + "/hip/hip_runtime_api.h")}; + std::string hip_api_header_file{ + findAbsolutePathOfFile(hip_include_path + "/hip/hip_runtime_api.h")}; std::string hip_rtc_header_file{findAbsolutePathOfFile(hip_include_path + "/hip/hiprtc.h")}; std::string tests_root_directory{findAbsolutePathOfFile("../../catch")}; + std::string device_api_file{"device_api_list.txt"}; std::vector api_group_names; // Extract all HIP API declarations from the HIP API header file. std::vector hip_apis{extractHipAPIs(hip_api_header_file, api_group_names, false)}; - std::cout << "Number of detected HIP APIs from " << hip_api_header_file << ": " << hip_apis.size() << std::endl; + std::cout << "Number of detected HIP APIs from " << hip_api_header_file << ": " << hip_apis.size() + << std::endl; std::vector hip_rtc_apis{extractHipAPIs(hip_rtc_header_file, api_group_names, true)}; - std::cout << "Number of detected HIP APIs from " << hip_rtc_header_file << ": " << hip_rtc_apis.size() << std::endl; + std::cout << "Number of detected HIP APIs from " << hip_rtc_header_file << ": " + << hip_rtc_apis.size() << std::endl; hip_apis.insert(hip_apis.end(), hip_rtc_apis.begin(), hip_rtc_apis.end()); + std::vector device_apis{extractDeviceAPIs(device_api_file, api_group_names)}; + std::cout << "Number of detected device APIs from " << device_api_file << ": " + << device_apis.size() << std::endl; + hip_apis.insert(hip_apis.end(), device_apis.begin(), device_apis.end()); + // Extract all test module .cc files that shall be used for API searching. - std::cout << "Searching for HIP API calls in source files within " << tests_root_directory << "." << std::endl; + std::cout << "Searching for HIP API calls in source files within " << tests_root_directory << "." + << std::endl; std::vector test_module_files{extractTestModuleFiles(tests_root_directory)}; // Search for each HIP API in the extracted test .cc files. - for(HipAPI& hip_api: hip_apis) { + for (HipAPI& hip_api : hip_apis) { searchForAPI(hip_api, test_module_files); } std::vector hip_api_groups; - for (auto const& api_group_name: api_group_names) { + for (auto const& api_group_name : api_group_names) { HipAPIGroup hip_api_group{api_group_name, hip_apis}; // Avoid having duplicated groups. - if (std::find(hip_api_groups.begin(), hip_api_groups.end(), hip_api_group) == hip_api_groups.end()) { + if (std::find(hip_api_groups.begin(), hip_api_groups.end(), hip_api_group) == + hip_api_groups.end()) { hip_api_groups.push_back(hip_api_group); } } @@ -68,7 +80,8 @@ int main(int argc, char** argv) std::cout << "Generating XML report files." << std::endl; generateXMLReportFiles(hip_apis, hip_api_groups); std::cout << "Generating HTML report files." << std::endl; - generateHTMLReportFiles(hip_apis, hip_api_groups, tests_root_directory, hip_api_header_file, hip_rtc_header_file); + generateHTMLReportFiles(hip_apis, hip_api_groups, tests_root_directory, hip_api_header_file, + hip_rtc_header_file); return 0; } diff --git a/projects/hip-tests/utils/coverage/reportGenerators.cpp b/projects/hip-tests/utils/coverage/reportGenerators.cpp index 7b74282929..f086aee536 100644 --- a/projects/hip-tests/utils/coverage/reportGenerators.cpp +++ b/projects/hip-tests/utils/coverage/reportGenerators.cpp @@ -22,38 +22,43 @@ THE SOFTWARE. #include "reportGenerators.h" -BasicAPIStats::BasicAPIStats(std::vector& hip_api_groups): - number_of_called_apis{0}, number_of_not_called_apis{0}, - number_of_deprecated_apis{0}, total_number_of_api_calls{0}, - total_number_of_test_cases{0} -{ - for (auto const& hip_api_group: hip_api_groups) { +BasicAPIStats::BasicAPIStats(std::vector& hip_api_groups) + : number_of_called_apis{0}, + number_of_not_called_apis{0}, + number_of_deprecated_apis{0}, + total_number_of_api_calls{0}, + total_number_of_test_cases{0} { + for (auto const& hip_api_group : hip_api_groups) { number_of_called_apis += hip_api_group.getNumberOfCalledAPIs(); number_of_not_called_apis += hip_api_group.getNumberOfNotCalledAPIs(); number_of_deprecated_apis += hip_api_group.getNumberOfDeprecatedAPIs(); total_number_of_api_calls += hip_api_group.getTotalNumberOfCalls(); total_number_of_test_cases += hip_api_group.getTotalNumberOfTestCases(); } - total_number_of_apis = number_of_called_apis + number_of_not_called_apis + number_of_deprecated_apis; - tests_coverage_percentage = 100.f * number_of_called_apis / (number_of_called_apis + number_of_not_called_apis); + total_number_of_apis = + number_of_called_apis + number_of_not_called_apis + number_of_deprecated_apis; + tests_coverage_percentage = + 100.f * number_of_called_apis / (number_of_called_apis + number_of_not_called_apis); } -float BasicAPIStats::getLowCoverageLimit() const { - return 40.f; -} +float BasicAPIStats::getLowCoverageLimit() const { return 40.f; } -float BasicAPIStats::getMediumCoverageLimit() const { - return 80.f; -} +float BasicAPIStats::getMediumCoverageLimit() const { return 80.f; } -void generateXMLReportFiles(std::vector& hip_apis, std::vector& hip_api_groups) { +void generateXMLReportFiles(std::vector& hip_apis, + std::vector& hip_api_groups) { BasicAPIStats basic_stats{hip_api_groups}; - std::cout << "Total number of HIP API calls: " << basic_stats.total_number_of_api_calls << std::endl; - std::cout << "Number of the HIP APIs that are called at least once: " << basic_stats.number_of_called_apis << std::endl; - std::cout << "Number of the HIP APIs that are not called at all: " << basic_stats.number_of_not_called_apis << std::endl; - std::cout << "Number of the HIP APIs that are marked as deprecated: " << basic_stats.number_of_deprecated_apis << std::endl; - std::cout << "Test coverage by implemented tests, for the HIP APIs that are not marked as deprecated: "; + std::cout << "Total number of HIP API calls: " << basic_stats.total_number_of_api_calls + << std::endl; + std::cout << "Number of the HIP APIs that are called at least once: " + << basic_stats.number_of_called_apis << std::endl; + std::cout << "Number of the HIP APIs that are not called at all: " + << basic_stats.number_of_not_called_apis << std::endl; + std::cout << "Number of the HIP APIs that are marked as deprecated: " + << basic_stats.number_of_deprecated_apis << std::endl; + std::cout + << "Test coverage by implemented tests, for the HIP APIs that are not marked as deprecated: "; std::cout << basic_stats.tests_coverage_percentage << "%" << std::endl; /* @@ -71,36 +76,51 @@ void generateXMLReportFiles(std::vector& hip_apis, std::vector\n"; - coverage_report << "\t\n\t\tTotal number of detected HIP APIs."; - coverage_report << "\n\t\t" << hip_apis.size() << "\n\t\n"; + coverage_report << "\t\n\t\tTotal number of detected HIP " + "APIs."; + coverage_report << "\n\t\t" << hip_apis.size() + << "\n\t\n"; - coverage_report << "\t\n\t\tTotal number of HIP API calls within test source files."; - coverage_report << "\n\t\t" << basic_stats.total_number_of_api_calls << "\n\t\n"; + coverage_report << "\t\n\t\tTotal number of HIP API " + "calls within test source files."; + coverage_report << "\n\t\t" << basic_stats.total_number_of_api_calls + << "\n\t\n"; - coverage_report << "\t\n\t\tNumber of the HIP APIs that are called at least once."; - coverage_report << "\n\t\t" << basic_stats.number_of_called_apis << "\n\t\n"; + coverage_report << "\t\n\t\tNumber of the HIP APIs that are called at " + "least once."; + coverage_report << "\n\t\t" << basic_stats.number_of_called_apis + << "\n\t\n"; - coverage_report << "\t\n\t\tNumber of the HIP APIs that are not called at all."; - coverage_report << "\n\t\t" << basic_stats.number_of_not_called_apis << "\n\t\n"; + coverage_report << "\t\n\t\tNumber of the HIP APIs that are not " + "called at all."; + coverage_report << "\n\t\t" << basic_stats.number_of_not_called_apis + << "\n\t\n"; - coverage_report << "\t\n\t\tNumber of the HIP APIs that are marked as deprecated."; - coverage_report << "\n\t\t" << basic_stats.number_of_deprecated_apis << "\n\t\n"; + coverage_report << "\t\n\t\tNumber of the HIP APIs that are marked " + "as deprecated."; + coverage_report << "\n\t\t" << basic_stats.number_of_deprecated_apis + << "\n\t\n"; - coverage_report << "\t\n\t\tTest coverage by implemented tests for the HIP APIs that are not marked as deprecated."; - coverage_report << "\n\t\t" << basic_stats.tests_coverage_percentage << "%\n\t"; + coverage_report << "\t\n\t\tTest coverage by implemented tests " + "for the HIP APIs that are not marked as deprecated."; + coverage_report << "\n\t\t" << basic_stats.tests_coverage_percentage + << "%\n\t"; coverage_report << "\n"; - for (auto const& hip_api_group: hip_api_groups) { - coverage_report << hip_api_group.getBasicStatsHTML(); + for (auto const& hip_api_group : hip_api_groups) { + coverage_report << hip_api_group.getBasicStatsHTML(); } coverage_report.close(); - std::cout << "Generated XML report file " << findAbsolutePathOfFile(report_file_name) << std::endl; + std::cout << "Generated XML report file " << findAbsolutePathOfFile(report_file_name) + << std::endl; } -void generateHTMLReportFiles(std::vector& hip_apis, std::vector& hip_api_groups, - std::string tests_root_directory, std::string hipApiHeaderFile, std::string hip_rtc_header_file) { +void generateHTMLReportFiles(std::vector& hip_apis, + std::vector& hip_api_groups, + std::string tests_root_directory, std::string hipApiHeaderFile, + std::string hip_rtc_header_file) { BasicAPIStats basic_stats{hip_api_groups}; std::fstream coverage_report; @@ -130,17 +150,26 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector"; - coverage_report << "" << one_tab << ""; + coverage_report << "" << one_tab + << ""; coverage_report << one_tab << "HIP API Coverage report"; - coverage_report << one_tab << "" << one_tab << ""; - coverage_report << one_tab << "" << one_tab << "
"; + coverage_report << one_tab + << "" + << one_tab << ""; + coverage_report << one_tab << "" << one_tab + << "
"; coverage_report << two_tabs << ""; - coverage_report << two_tabs << "\n"; - coverage_report << two_tabs << "" << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; coverage_report << three_tabs << ""; coverage_report << two_tabs << ""; @@ -282,7 +336,57 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector"; coverage_report << one_tab << "
HIP API Coverage report
" << four_tabs << "\n"; + coverage_report << two_tabs << "" << three_tabs << ""; coverage_report << two_tabs << ""; - coverage_report << two_tabs << "\n"; + coverage_report + << two_tabs + << "\n"; coverage_report << one_tab << "
" << four_tabs + << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; @@ -150,15 +179,18 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vectorSource files included:"; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; coverage_report << five_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; @@ -166,31 +198,38 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector"; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; coverage_report << five_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; coverage_report << five_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; coverage_report << five_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; @@ -198,29 +237,32 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector"; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report + << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; - - coverage_report << five_tabs << ""; + + coverage_report << five_tabs + << ""; coverage_report << four_tabs << "
Catch2 tests location:" << tests_root_directory << "Catch2 tests location:" << tests_root_directory + << "Value" << hipApiHeaderFile << "Total number of detected HIP APIs:" << basic_stats.total_number_of_apis << "" + << basic_stats.total_number_of_apis << "
" << hip_rtc_header_file << "HIP API calls within test source files:" << basic_stats.total_number_of_api_calls << "HIP API calls within test source files:" + << basic_stats.total_number_of_api_calls << "
Total number of test cases:" << basic_stats.total_number_of_test_cases << "" + << basic_stats.total_number_of_test_cases << "
HIP APIs that are called at least once:" << basic_stats.number_of_called_apis << "HIP APIs that are called at least once:" + << basic_stats.number_of_called_apis << "
HIP APIs that are not called at all:" << basic_stats.number_of_not_called_apis << "HIP APIs that are not called at all:" + << basic_stats.number_of_not_called_apis << "
HIP APIs that are marked as deprecated:" << basic_stats.number_of_deprecated_apis << "HIP APIs that are marked as deprecated:" + << basic_stats.number_of_deprecated_apis << "
Test coverage by implemented tests for the HIP APIs:" << - std::fixed << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%Test coverage by implemented tests for the HIP APIs:" << std::fixed + << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%
"; coverage_report << three_tabs << "
"; // Add info about HIP API Groups. @@ -254,11 +296,17 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector& hip_apis, std::vector"; coverage_report << three_tabs << "
" << basic_stats.total_number_of_apis << "" << basic_stats.total_number_of_api_calls << "" << basic_stats.total_number_of_test_cases << "" << basic_stats.number_of_called_apis << "" << basic_stats.number_of_not_called_apis << "" << basic_stats.number_of_deprecated_apis << "" << - std::fixed << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%" + << basic_stats.total_number_of_apis << "" + << basic_stats.total_number_of_api_calls << "" + << basic_stats.total_number_of_test_cases << "" + << basic_stats.number_of_called_apis << "" + << basic_stats.number_of_not_called_apis << "" + << basic_stats.number_of_deprecated_apis << "" << std::fixed + << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%
"; - coverage_report << two_tabs << ""; + coverage_report + << two_tabs + << ""; + coverage_report << one_tab << "
"; + coverage_report << one_tab << "
"; + + coverage_report << one_tab << "
"; + coverage_report << one_tab << ""; + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report + << three_tabs + << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs + << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs + << ""; + coverage_report << two_tabs << ""; + + coverage_report << one_tab << "
Color legend
Module is deprecated
Percentage of called APIs within a module is less than 40%
Percentage of called APIs within a module is between " + "40% and 80%
Percentage of called APIs within a module is larger " + "than 80%
"; + coverage_report << one_tab << "
"; + coverage_report << one_tab << "
"; + + coverage_report << one_tab << ""; + coverage_report + << two_tabs + << ""; time_t now{time(nullptr)}; std::string date{asctime(gmtime(&now))}; @@ -295,7 +399,7 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector& hip_apis, std::vector& hip_apis, std::vector& hip_api_groups); -void generateHTMLReportFiles(std::vector& hip_apis, std::vector& hip_api_groups, - std::string tests_root_directory, std::string hipApiHeaderFile, std::string hip_rtc_header_file); +void generateXMLReportFiles(std::vector& hip_apis, + std::vector& hip_api_groups); +void generateHTMLReportFiles(std::vector& hip_apis, + std::vector& hip_api_groups, + std::string tests_root_directory, std::string hipApiHeaderFile, + std::string hip_rtc_header_file);