diff --git a/projects/aqlprofile/CMakeLists.txt b/projects/aqlprofile/CMakeLists.txt index 824542044a..ddcfd0983e 100644 --- a/projects/aqlprofile/CMakeLists.txt +++ b/projects/aqlprofile/CMakeLists.txt @@ -27,6 +27,8 @@ set ( BUILD_VERSION_MINOR ${VERSION_MINOR} ) set ( BUILD_VERSION_PATCH ${VERSION_PATCH} ) set ( BUILD_VERSION_STRING "${BUILD_VERSION_MAJOR}.${BUILD_VERSION_MINOR}.${BUILD_VERSION_PATCH}" ) +get_git_rev(AQLPROFILE_GIT_REVISION) + set ( LIB_VERSION_MAJOR ${VERSION_MAJOR} ) set ( LIB_VERSION_MINOR ${VERSION_MINOR} ) if ( ${ROCM_PATCH_VERSION} ) @@ -41,6 +43,7 @@ set ( TARGET_NAME "${AQLPROFILE_TARGET}" ) set ( ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ) set ( LIB_DIR "${ROOT_DIR}/src" ) set ( TEST_DIR "${ROOT_DIR}/test" ) +set ( AQLPROFILE_BUILD_ROOT "${PROJECT_BINARY_DIR}" ) ## Build library include ( ${LIB_DIR}/CMakeLists.txt ) diff --git a/projects/aqlprofile/cmake_modules/utils.cmake b/projects/aqlprofile/cmake_modules/utils.cmake index 121ef5c8cb..61d1eb8135 100644 --- a/projects/aqlprofile/cmake_modules/utils.cmake +++ b/projects/aqlprofile/cmake_modules/utils.cmake @@ -74,3 +74,33 @@ function ( get_version DEFAULT_VERSION_STRING ) set( VERSION_BUILD "${VERSION_BUILD}" PARENT_SCOPE ) endfunction() + +function(get_git_rev GIT_REVISION_OUT) + find_package(Git) + + if(Git_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --tags + OUTPUT_VARIABLE GIT_DESCRIBE + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE _GIT_DESCRIBE_RESULT + ERROR_QUIET) + if(NOT _GIT_DESCRIBE_RESULT EQUAL 0) + execute_process( + COMMAND ${GIT_EXECUTABLE} describe + OUTPUT_VARIABLE GIT_DESCRIBE + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE _GIT_DESCRIBE_RESULT + ERROR_QUIET) + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_REVISION + OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + set(${GIT_REVISION_OUT} "${GIT_REVISION}" PARENT_SCOPE) + else() + set(${GIT_REVISION_OUT} "" PARENT_SCOPE) + endif() +endfunction() diff --git a/projects/aqlprofile/src/CMakeLists.txt b/projects/aqlprofile/src/CMakeLists.txt index a52ca2d25f..221a747a67 100644 --- a/projects/aqlprofile/src/CMakeLists.txt +++ b/projects/aqlprofile/src/CMakeLists.txt @@ -25,8 +25,19 @@ set ( LIB_SRC ) add_library ( ${TARGET_LIB} SHARED ${LIB_SRC} ) -target_include_directories ( ${TARGET_LIB} PRIVATE ${LIB_DIR} ${API_PATH} ${LIB_DIR}/core/include) -target_link_libraries( ${TARGET_LIB} PRIVATE pthread hsa-runtime64::hsa-runtime64 ) +add_library (aqlprofile::aqlprofile-lib ALIAS ${TARGET_LIB}) +target_include_directories ( ${TARGET_LIB} + PRIVATE ${LIB_DIR} + ${API_PATH} + ${LIB_DIR}/core/include +) +target_link_libraries( ${TARGET_LIB} + PRIVATE + pthread + hsa-runtime64::hsa-runtime64 + PUBLIC + aqlprofile::headers +) ## Generating definitions set ( SCRIPT_DIR "${ROOT_DIR}/script" ) diff --git a/projects/aqlprofile/src/core/counters.cpp b/projects/aqlprofile/src/core/counters.cpp index 36101706cd..1397f98511 100644 --- a/projects/aqlprofile/src/core/counters.cpp +++ b/projects/aqlprofile/src/core/counters.cpp @@ -256,6 +256,17 @@ hsa_status_t _internal_aqlprofile_pmc_create_packets( extern "C" { +PUBLIC_API hsa_status_t aqlprofile_get_version(aqlprofile_version_t* info) { + if (info != nullptr) { + *info = {.major = AQLPROFILE_VERSION_MAJOR, + .minor = AQLPROFILE_VERSION_MINOR, + .patch = AQLPROFILE_VERSION_PATCH}; + return HSA_STATUS_SUCCESS; + } else { + return HSA_STATUS_ERROR_INVALID_ARGUMENT; + } +} + PUBLIC_API hsa_status_t aqlprofile_pmc_create_packets( aqlprofile_handle_t* handle, aqlprofile_pmc_aql_packets_t* packets, aqlprofile_pmc_profile_t profile, aqlprofile_memory_alloc_callback_t alloc_cb, diff --git a/projects/aqlprofile/src/core/include/CMakeLists.txt b/projects/aqlprofile/src/core/include/CMakeLists.txt index 63dc1e35b0..91d895ed84 100644 --- a/projects/aqlprofile/src/core/include/CMakeLists.txt +++ b/projects/aqlprofile/src/core/include/CMakeLists.txt @@ -1,7 +1 @@ -set(AQLPROFILE_HEADER_FILES - aqlprofile-sdk/aql_profile_v2.h -) - -install( - FILES ${AQLPROFILE_HEADER_FILES} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/aqlprofile-sdk) \ No newline at end of file +add_subdirectory(aqlprofile-sdk) diff --git a/projects/aqlprofile/src/core/include/aqlprofile-sdk/CMakeLists.txt b/projects/aqlprofile/src/core/include/aqlprofile-sdk/CMakeLists.txt new file mode 100644 index 0000000000..7424237927 --- /dev/null +++ b/projects/aqlprofile/src/core/include/aqlprofile-sdk/CMakeLists.txt @@ -0,0 +1,22 @@ +set(AQLPROFILE_HEADER_FILES + aql_profile_v2.h + ${CMAKE_CURRENT_BINARY_DIR}/version.h) + +add_library(aqlprofile-headers INTERFACE) +add_library(aqlprofile::headers ALIAS aqlprofile-headers) +target_include_directories(aqlprofile-headers + INTERFACE + $ + $ + $ +) +target_sources(aqlprofile-headers + INTERFACE ${AQLPROFILE_HEADER_FILES}) + +configure_file(${CMAKE_CURRENT_LIST_DIR}/version.h.in + ${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY) + +install(FILES ${AQLPROFILE_HEADER_FILES} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/aqlprofile-sdk + COMPONENT development +) diff --git a/projects/aqlprofile/src/core/include/aqlprofile-sdk/aql_profile_v2.h b/projects/aqlprofile/src/core/include/aqlprofile-sdk/aql_profile_v2.h index 60ce124e0b..f118dc2663 100644 --- a/projects/aqlprofile/src/core/include/aqlprofile-sdk/aql_profile_v2.h +++ b/projects/aqlprofile/src/core/include/aqlprofile-sdk/aql_profile_v2.h @@ -26,6 +26,8 @@ #include #include +#include "aqlprofile-sdk/version.h" + #ifdef __cplusplus extern "C" { #endif @@ -200,6 +202,23 @@ typedef struct { uint64_t handle; } aqlprofile_agent_handle_t; +/** + * @brief Versioning info. + */ +typedef struct aqlprofile_version_t { + uint32_t major; + uint32_t minor; + uint32_t patch; +} aqlprofile_version_t; + +/** + * @brief Query the version of aqlprofile library. + * @param[out] version aqlprofile version info is stored if non-NULL + * @retval HSA_STATUS_SUCCESS returned when version is a valid pointer + * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT if version is a null + */ +hsa_status_t aqlprofile_get_version(aqlprofile_version_t* version); + /** * @brief Registers an agent to be used with AQL profile. * @param[out] agent_id Handle to newly registered agent diff --git a/projects/aqlprofile/src/core/include/aqlprofile-sdk/version.h.in b/projects/aqlprofile/src/core/include/aqlprofile-sdk/version.h.in new file mode 100644 index 0000000000..0f571c5d82 --- /dev/null +++ b/projects/aqlprofile/src/core/include/aqlprofile-sdk/version.h.in @@ -0,0 +1,115 @@ +// MIT License +// +// Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +/** + * @def AQLPROFILE_VERSION_MAJOR + * @brief The major version of the interface as a macro so it can be used + * by the preprocessor. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_VERSION_MINOR + * @brief The minor version of the interface as a macro so it can be used + * by the preprocessor. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_VERSION_PATCH + * @brief The patch version of the interface as a macro so it can be used + * by the preprocessor. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_VERSION + * @brief Numerically increasing version number encoding major, minor, and patch via + computing `((10000 * ) + (100 * ) + )`. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_SOVERSION + * @brief Shared object versioning value whose value is at least `(10000 * )`. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_VERSION_STRING + * @brief Version string in form: `..`. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_GIT_DESCRIBE + * @brief String encoding of `git describe --tags` when aqlprofile was built. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_GIT_REVISION + * @brief String encoding of `git rev-parse HEAD` when aqlprofile was built. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_LIBRARY_ARCH + * @brief Architecture triplet of aqlprofile build. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_SYSTEM_NAME + * @brief Target operating system for aqlprofile build, e.g. Linux. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_SYSTEM_PROCESSOR + * @brief Target architecture for aqlprofile build. + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_SYSTEM_VERSION + * @brief Version of the operating system which built aqlprofile + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_COMPILER_ID + * @brief C++ compiler identifier which built aqlprofile, e.g., GNU + * @addtogroup VERSIONING_GROUP + * + * @def AQLPROFILE_COMPILER_VERSION + * @brief C++ compiler version which built aqlprofile + * @addtogroup VERSIONING_GROUP + * + */ + +// clang-format off +#define AQLPROFILE_VERSION_MAJOR @BUILD_VERSION_MAJOR@ +#define AQLPROFILE_VERSION_MINOR @BUILD_VERSION_MINOR@ +#define AQLPROFILE_VERSION_PATCH @BUILD_VERSION_PATCH@ +#define AQLPROFILE_SOVERSION @BUILD_VERSION_MAJOR@ +#define AQLPROFILE_VERSION_STRING "@VERSION_STRING@" +#define AQLPROFILE_GIT_REVISION "@AQLPROFILE_GIT_REVISION@" + +// system info during compilation +#define AQLPROFILE_LIBRARY_ARCH "@CMAKE_LIBRARY_ARCHITECTURE@" +#define AQLPROFILE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@" +#define AQLPROFILE_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@" +#define AQLPROFILE_SYSTEM_VERSION "@CMAKE_SYSTEM_VERSION@" + +// compiler information +#define AQLPROFILE_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@" +#define AQLPROFILE_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@" +// clang-format on + +#define AQLPROFILE_COMPUTE_VERSION_VALUE(MAX_VERSION_VALUE, MAJOR, MINOR, PATCH) \ + (((MAX_VERSION_VALUE * MAX_VERSION_VALUE) * MAJOR) + (MAX_VERSION_VALUE * MINOR) + (PATCH)) + +#define AQLPROFILE_COMPUTE_VERSION(MAJOR, MINOR, PATCH) \ + AQLPROFILE_COMPUTE_VERSION_VALUE(100, MAJOR, MINOR, PATCH) + +#define AQLPROFILE_VERSION \ + AQLPROFILE_COMPUTE_VERSION(AQLPROFILE_VERSION_MAJOR, AQLPROFILE_VERSION_MINOR, \ + AQLPROFILE_VERSION_PATCH) diff --git a/projects/aqlprofile/src/core/tests/CMakeLists.txt b/projects/aqlprofile/src/core/tests/CMakeLists.txt index 7511fe5d1f..25fd19bb36 100644 --- a/projects/aqlprofile/src/core/tests/CMakeLists.txt +++ b/projects/aqlprofile/src/core/tests/CMakeLists.txt @@ -25,9 +25,15 @@ SET(AQLPROFILE_MEMORYMANAGER_SOURCES ) target_sources(gfx9-memory-manager-test PRIVATE ${AQLPROFILE_MEMORYMANAGER_SOURCES}) -target_include_directories(gfx9-memory-manager-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${LIB_DIR} ${LIB_DIR}/core/include) +target_include_directories(gfx9-memory-manager-test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIB_DIR} + ${LIB_DIR}/core/include) target_link_libraries( gfx9-memory-manager-test + PUBLIC + aqlprofile::headers PRIVATE hsa-runtime64::hsa-runtime64 GTest::gtest @@ -51,10 +57,15 @@ SET(AQLPROFILE_TEST_SOURCES ) target_sources(aqlprofile-test PRIVATE ${AQLPROFILE_TEST_SOURCES}) -target_include_directories(aqlprofile-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${LIB_DIR} ${LIB_DIR}/core/include) +target_include_directories(aqlprofile-test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIB_DIR} + ${LIB_DIR}/core/include) target_link_libraries( aqlprofile-test PRIVATE + aqlprofile::aqlprofile-lib hsa-runtime64::hsa-runtime64 GTest::gtest GTest::gtest_main @@ -79,9 +90,15 @@ SET(AQLPROFILE_COMMAND_BUFFER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/command_buffer_tests.cpp ) target_sources(command-buffer-test PRIVATE ${AQLPROFILE_COMMAND_BUFFER_SOURCES}) -target_include_directories(command-buffer-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${LIB_DIR} ${LIB_DIR}/core/include) +target_include_directories(command-buffer-test PRIVATE + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIB_DIR} + ${LIB_DIR}/core/include) target_link_libraries( command-buffer-test + PUBLIC + aqlprofile::headers PRIVATE hsa-runtime64::hsa-runtime64 GTest::gtest @@ -104,7 +121,12 @@ SET(AQLPROFILE_COUNTERS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/counter_tests.cpp ) target_sources(counters-test PRIVATE ${AQLPROFILE_COUNTERS_SOURCES}) -target_include_directories(counters-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${LIB_DIR} ${LIB_DIR}/core/include) +target_include_directories(counters-test PRIVATE + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIB_DIR} + ${LIB_DIR}/core/include + ) target_link_libraries( counters-test PRIVATE @@ -135,6 +157,7 @@ target_include_directories(pm4-factory-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} target_link_libraries( pm4-factory-test PRIVATE + aqlprofile::aqlprofile-lib hsa-runtime64::hsa-runtime64 GTest::gtest GTest::gtest_main @@ -171,7 +194,7 @@ gtest_add_tests( SOURCES ${AQLPROFILE_LOGGER_SOURCES} TEST_LIST logger-test_TESTS WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - + set_tests_properties( ${logger-test_TESTS} PROPERTIES TIMEOUT 45 LABELS "unittests" FAIL_REGULAR_EXPRESSION "${AQLPROFILE_DEFAULT_FAIL_REGEX}") @@ -203,6 +226,7 @@ target_include_directories(aql-profile-v2-test PRIVATE ${CMAKE_CURRENT_SOURCE_DI target_link_libraries( aql-profile-v2-test PRIVATE + aqlprofile::aqlprofile-lib hsa-runtime64::hsa-runtime64 GTest::gtest GTest::gtest_main @@ -214,8 +238,7 @@ gtest_add_tests( SOURCES ${AQLPROFILE_V2_SOURCES} TEST_LIST aql-profile-v2-test_TESTS WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - + set_tests_properties( ${aql-profile-v2-test_TESTS} PROPERTIES TIMEOUT 45 LABELS "unittests" FAIL_REGULAR_EXPRESSION "${AQLPROFILE_DEFAULT_FAIL_REGEX}") - diff --git a/projects/aqlprofile/src/core/tests/aql_profile_tests.cpp b/projects/aqlprofile/src/core/tests/aql_profile_tests.cpp index ba932e64c4..33fbe90985 100644 --- a/projects/aqlprofile/src/core/tests/aql_profile_tests.cpp +++ b/projects/aqlprofile/src/core/tests/aql_profile_tests.cpp @@ -25,6 +25,8 @@ #include "core/aql_profile.hpp" #include "core/pm4_factory.h" +#include "aqlprofile-sdk/version.h" +#include "aqlprofile-sdk/aql_profile_v2.h" // header for memcpy #include @@ -44,7 +46,7 @@ Pm4Factory::instances_t* Pm4Factory::instances_ = nullptr; // Mock classes to simulate Pm4Factory and related functionality class MockPm4Factory : public Pm4Factory { -public: + public: MockPm4Factory() : Pm4Factory(BlockInfoMap(nullptr, 0)) {} MOCK_METHOD(const GpuBlockInfo*, GetBlockInfo, (const hsa_ven_amd_aqlprofile_event_t*), (const)); MOCK_METHOD(bool, IsGFX9, (), (const)); @@ -103,7 +105,7 @@ hsa_status_t DefaultTracedataCallback(hsa_ven_amd_aqlprofile_info_type_t info_ty // Test fixture for CountersVec tests class CountersVecTest : public Test { -protected: + protected: void SetUp() override { pm4_factory = new NiceMock(); ON_CALL(*pm4_factory, IsGFX9()).WillByDefault(Return(true)); @@ -117,7 +119,7 @@ protected: }; pm4_builder::counters_vector CountersVecTest::CountersVec(const profile_t* profile, - const Pm4Factory* pm4_factory) { + const Pm4Factory* pm4_factory) { pm4_builder::counters_vector vec; std::map index_map; for (const hsa_ven_amd_aqlprofile_event_t* p = profile->events; @@ -171,12 +173,12 @@ TEST_F(CountersVecTest, RegularEvents) { pm4_factory->GetBlockInfo(profile->events); bool is_gfx9 = pm4_factory->IsGFX9(); EXPECT_TRUE(is_gfx9); - + } // Test fixture for the DefaultTracedataCallback function class DefaultTracedataCallbackTest : public Test { -protected: + protected: hsa_ven_amd_aqlprofile_info_data_t CreateInfoData(uint32_t sample_id) { hsa_ven_amd_aqlprofile_info_data_t data{}; data.sample_id = sample_id; @@ -243,3 +245,20 @@ TEST_F(DefaultTracedataCallbackTest, NonTraceInfoType) { EXPECT_EQ(callback_data.trace_data.ptr, original_ptr); EXPECT_EQ(callback_data.trace_data.size, original_size); } + +TEST(aqlprofile, version) { + auto correct_version = aqlprofile_version_t{.major = AQLPROFILE_VERSION_MAJOR, + .minor = AQLPROFILE_VERSION_MINOR, + .patch = AQLPROFILE_VERSION_PATCH}; + + auto query_version = aqlprofile_version_t{}; + + auto ret = aqlprofile_get_version(&query_version); + + EXPECT_EQ(ret, HSA_STATUS_SUCCESS); + EXPECT_EQ(query_version.major, correct_version.major); + EXPECT_EQ(query_version.minor, correct_version.minor); + EXPECT_EQ(query_version.patch, correct_version.patch); + + EXPECT_EQ(aqlprofile_get_version(nullptr), HSA_STATUS_ERROR_INVALID_ARGUMENT); +} diff --git a/projects/aqlprofile/src/core/tests/aql_profile_v2_tests.cpp b/projects/aqlprofile/src/core/tests/aql_profile_v2_tests.cpp index 72e92a5fdb..38aa068da5 100644 --- a/projects/aqlprofile/src/core/tests/aql_profile_v2_tests.cpp +++ b/projects/aqlprofile/src/core/tests/aql_profile_v2_tests.cpp @@ -4,7 +4,7 @@ #include #include -#include "../include/aqlprofile-sdk/aql_profile_v2.h" +#include "aqlprofile-sdk/aql_profile_v2.h" #include "../logger.h" #include "../pm4_factory.h" // Define static members @@ -27,14 +27,14 @@ protected: memset(&test_agent_info_v1_, 0, sizeof(test_agent_info_v1_)); memset(&test_handle_, 0, sizeof(test_handle_)); memset(&test_agent_handle_, 0, sizeof(test_agent_handle_)); - + // Set up default agent info test_agent_info_.agent_gfxip = "gfx90a"; test_agent_info_.xcc_num = 1; test_agent_info_.se_num = 8; test_agent_info_.cu_num = 104; test_agent_info_.shader_arrays_per_se = 2; - + // Set up default agent info v1 test_agent_info_v1_.agent_gfxip = "gfx90a"; test_agent_info_v1_.xcc_num = 1; @@ -43,7 +43,7 @@ protected: test_agent_info_v1_.shader_arrays_per_se = 2; test_agent_info_v1_.domain = 0; test_agent_info_v1_.location_id = 0x12345678; - + test_handle_.handle = 0x1234567890ABCDEF; test_agent_handle_.handle = 0xFEDCBA0987654321; } @@ -63,13 +63,13 @@ TEST_F(AqlProfileV2Test, EnumValues) { EXPECT_EQ(AQLPROFILE_MEMORY_HINT_DEVICE_COHERENT, 3); EXPECT_EQ(AQLPROFILE_MEMORY_HINT_DEVICE_NONCOHERENT, 4); EXPECT_GT(AQLPROFILE_MEMORY_HINT_LAST, AQLPROFILE_MEMORY_HINT_DEVICE_NONCOHERENT); - + // Test agent version enum EXPECT_EQ(AQLPROFILE_AGENT_VERSION_NONE, 0); EXPECT_EQ(AQLPROFILE_AGENT_VERSION_V0, 1); EXPECT_EQ(AQLPROFILE_AGENT_VERSION_V1, 2); EXPECT_GT(AQLPROFILE_AGENT_VERSION_LAST, AQLPROFILE_AGENT_VERSION_V1); - + // Test accumulation type enum EXPECT_EQ(AQLPROFILE_ACCUMULATION_NONE, 0); EXPECT_EQ(AQLPROFILE_ACCUMULATION_LO_RES, 1); @@ -82,12 +82,12 @@ TEST_F(AqlProfileV2Test, BlockNameEnum) { // Test that reserved blocks are in the expected range EXPECT_EQ(AQLPROFILE_BLOCK_NAME_RESERVED_0, HSA_VEN_AMD_AQLPROFILE_BLOCKS_NUMBER); EXPECT_EQ(AQLPROFILE_BLOCK_NAME_RESERVED_1, HSA_VEN_AMD_AQLPROFILE_BLOCKS_NUMBER + 1); - + // Test that new block names are defined EXPECT_GT(AQLPROFILE_BLOCK_NAME_CHA, AQLPROFILE_BLOCK_NAME_RESERVED_5); EXPECT_GT(AQLPROFILE_BLOCK_NAME_CHC, AQLPROFILE_BLOCK_NAME_CHA); EXPECT_GT(AQLPROFILE_BLOCK_NAME_SQG, AQLPROFILE_BLOCK_NAME_GRBMH); - + // Test final block count EXPECT_GT(AQLPROFILE_BLOCKS_NUMBER, HSA_VEN_AMD_AQLPROFILE_BLOCKS_NUMBER); } @@ -95,26 +95,26 @@ TEST_F(AqlProfileV2Test, BlockNameEnum) { // Test buffer descriptor flags structure TEST_F(AqlProfileV2Test, BufferDescFlags) { aqlprofile_buffer_desc_flags_t flags; - + // Test raw access flags.raw = 0; EXPECT_EQ(flags.device_access, 0); EXPECT_EQ(flags.host_access, 0); EXPECT_EQ(flags.memory_hint, 0); - + // Test individual field access flags.device_access = 1; flags.host_access = 1; flags.memory_hint = AQLPROFILE_MEMORY_HINT_HOST; - + EXPECT_EQ(flags.device_access, 1); EXPECT_EQ(flags.host_access, 1); EXPECT_EQ(flags.memory_hint, AQLPROFILE_MEMORY_HINT_HOST); - + // Test field width constraints flags.memory_hint = 0x3F; // 6 bits max EXPECT_EQ(flags.memory_hint, 0x3F); - + // Test bit manipulation uint32_t expected = (1 << 0) | (1 << 1) | (0x3F << 2); EXPECT_EQ(flags.raw, expected); @@ -123,18 +123,18 @@ TEST_F(AqlProfileV2Test, BufferDescFlags) { // Test PMC event flags structure TEST_F(AqlProfileV2Test, PmcEventFlags) { aqlprofile_pmc_event_flags_t flags; - + // Test raw access flags.raw = 0; EXPECT_EQ(flags.sq_flags.accum, 0); - + // Test accumulation field flags.sq_flags.accum = AQLPROFILE_ACCUMULATION_LO_RES; EXPECT_EQ(flags.sq_flags.accum, AQLPROFILE_ACCUMULATION_LO_RES); - + flags.sq_flags.accum = AQLPROFILE_ACCUMULATION_HI_RES; EXPECT_EQ(flags.sq_flags.accum, AQLPROFILE_ACCUMULATION_HI_RES); - + // Test field width (3 bits for accumulation) flags.sq_flags.accum = 0x7; // 3 bits max EXPECT_EQ(flags.sq_flags.accum, 0x7); @@ -143,13 +143,13 @@ TEST_F(AqlProfileV2Test, PmcEventFlags) { // Test PMC event structure TEST_F(AqlProfileV2Test, PmcEvent) { aqlprofile_pmc_event_t event; - + event.block_index = 42; event.event_id = 123; event.flags.raw = 0; event.flags.sq_flags.accum = AQLPROFILE_ACCUMULATION_HI_RES; event.block_name = HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_SQ; - + EXPECT_EQ(event.block_index, 42); EXPECT_EQ(event.event_id, 123); EXPECT_EQ(event.flags.sq_flags.accum, AQLPROFILE_ACCUMULATION_HI_RES); @@ -163,7 +163,7 @@ TEST_F(AqlProfileV2Test, AgentInfo) { EXPECT_EQ(test_agent_info_.se_num, 8); EXPECT_EQ(test_agent_info_.cu_num, 104); EXPECT_EQ(test_agent_info_.shader_arrays_per_se, 2); - + // Test with different GPU configurations aqlprofile_agent_info_t gfx11_info; gfx11_info.agent_gfxip = "gfx1100"; @@ -171,7 +171,7 @@ TEST_F(AqlProfileV2Test, AgentInfo) { gfx11_info.se_num = 6; gfx11_info.cu_num = 96; gfx11_info.shader_arrays_per_se = 4; - + EXPECT_STREQ(gfx11_info.agent_gfxip, "gfx1100"); EXPECT_EQ(gfx11_info.xcc_num, 2); EXPECT_EQ(gfx11_info.se_num, 6); @@ -188,13 +188,13 @@ TEST_F(AqlProfileV2Test, AgentInfoV1) { EXPECT_EQ(test_agent_info_v1_.shader_arrays_per_se, 2); EXPECT_EQ(test_agent_info_v1_.domain, 0); EXPECT_EQ(test_agent_info_v1_.location_id, 0x12345678); - + // Test with different PCI information aqlprofile_agent_info_v1_t pci_info; pci_info.agent_gfxip = "gfx942"; pci_info.domain = 0x0001; pci_info.location_id = 0x00010203; // Bus=1, Device=2, Function=3 - + EXPECT_EQ(pci_info.domain, 0x0001); EXPECT_EQ(pci_info.location_id, 0x00010203); } @@ -203,12 +203,12 @@ TEST_F(AqlProfileV2Test, AgentInfoV1) { TEST_F(AqlProfileV2Test, HandleStructures) { EXPECT_EQ(test_handle_.handle, 0x1234567890ABCDEF); EXPECT_EQ(test_agent_handle_.handle, 0xFEDCBA0987654321); - + // Test handle comparison aqlprofile_handle_t handle1 = {0x123}; aqlprofile_handle_t handle2 = {0x123}; aqlprofile_handle_t handle3 = {0x456}; - + EXPECT_EQ(handle1.handle, handle2.handle); EXPECT_NE(handle1.handle, handle3.handle); } @@ -216,17 +216,17 @@ TEST_F(AqlProfileV2Test, HandleStructures) { // Test PMC profile structure TEST_F(AqlProfileV2Test, PmcProfile) { std::vector events(3); - + // Setup events events[0] = {0, 100, {0}, HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_SQ}; events[1] = {1, 200, {0}, HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_TA}; events[2] = {2, 300, {0}, HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_TCA}; - + aqlprofile_pmc_profile_t profile; profile.agent = test_agent_handle_; profile.events = events.data(); profile.event_count = events.size(); - + EXPECT_EQ(profile.agent.handle, test_agent_handle_.handle); EXPECT_EQ(profile.event_count, 3); EXPECT_EQ(profile.events[0].block_index, 0); @@ -240,39 +240,39 @@ TEST_F(AqlProfileV2Test, PmcProfile) { // Test ATT parameter structure TEST_F(AqlProfileV2Test, AttParameter) { aqlprofile_att_parameter_t param; - + // Test basic parameter param.parameter_name = HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_OCCUPANCY_MODE; param.value = 1; - + EXPECT_EQ(param.parameter_name, HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_OCCUPANCY_MODE); EXPECT_EQ(param.value, 1); - + // Test counter ID and SIMD mask fields param.parameter_name = HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_SE_MASK; param.counter_id = 0x1234567; // 28 bits max param.simd_mask = 0xF; // 4 bits max - + EXPECT_EQ(param.counter_id, 0x1234567); EXPECT_EQ(param.simd_mask, 0xF); - + } // Test ATT profile structure TEST_F(AqlProfileV2Test, AttProfile) { hsa_agent_t agent; agent.handle = 0xABCDEF1234567890; - + std::vector params(1); params[0].parameter_name = HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_OCCUPANCY_MODE; params[0].value = 1; - + aqlprofile_att_profile_t profile; profile.agent = agent; profile.parameters = params.data(); profile.parameter_count = params.size(); - + EXPECT_EQ(profile.agent.handle, agent.handle); EXPECT_EQ(profile.parameter_count, 1); EXPECT_EQ(profile.parameters[0].parameter_name, HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_OCCUPANCY_MODE); @@ -284,47 +284,47 @@ TEST_F(AqlProfileV2Test, AttProfile) { // Test PMC AQL packets structure TEST_F(AqlProfileV2Test, PmcAqlPackets) { aqlprofile_pmc_aql_packets_t packets; - + // Initialize packet headers packets.start_packet.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE; packets.stop_packet.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE; packets.read_packet.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE; - + // Test packet initialization - EXPECT_EQ(packets.start_packet.header & HSA_PACKET_HEADER_TYPE, + EXPECT_EQ(packets.start_packet.header & HSA_PACKET_HEADER_TYPE, HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE); - EXPECT_EQ(packets.stop_packet.header & HSA_PACKET_HEADER_TYPE, + EXPECT_EQ(packets.stop_packet.header & HSA_PACKET_HEADER_TYPE, HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE); - EXPECT_EQ(packets.read_packet.header & HSA_PACKET_HEADER_TYPE, + EXPECT_EQ(packets.read_packet.header & HSA_PACKET_HEADER_TYPE, HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE); } // Test ATT control AQL packets structure TEST_F(AqlProfileV2Test, AttControlAqlPackets) { aqlprofile_att_control_aql_packets_t packets; - + // Initialize packet headers packets.start_packet.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE; packets.stop_packet.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE; - + // Test packet initialization - EXPECT_EQ(packets.start_packet.header & HSA_PACKET_HEADER_TYPE, + EXPECT_EQ(packets.start_packet.header & HSA_PACKET_HEADER_TYPE, HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE); - EXPECT_EQ(packets.stop_packet.header & HSA_PACKET_HEADER_TYPE, + EXPECT_EQ(packets.stop_packet.header & HSA_PACKET_HEADER_TYPE, HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE); } // Test ATT code object data structure TEST_F(AqlProfileV2Test, AttCodeobjData) { aqlprofile_att_codeobj_data_t data; - + data.id = 0x123456789ABCDEF0; data.addr = 0xDEADBEEFCAFEBABE; data.size = 0x10000; data.agent.handle = 0x1122334455667788; data.isUnload = 1; data.fromStart = 0; - + EXPECT_EQ(data.id, 0x123456789ABCDEF0); EXPECT_EQ(data.addr, 0xDEADBEEFCAFEBABE); EXPECT_EQ(data.size, 0x10000); @@ -373,10 +373,10 @@ TEST_F(AqlProfileV2Test, StructureSizes) { EXPECT_GT(sizeof(aqlprofile_pmc_aql_packets_t), 0); EXPECT_GT(sizeof(aqlprofile_att_control_aql_packets_t), 0); EXPECT_GT(sizeof(aqlprofile_att_codeobj_data_t), 0); - + // Verify v1 structure is larger than base version EXPECT_GT(sizeof(aqlprofile_agent_info_v1_t), sizeof(aqlprofile_agent_info_t)); - + // Verify handle structures are 8 bytes (uint64_t) EXPECT_EQ(sizeof(aqlprofile_handle_t), 8); EXPECT_EQ(sizeof(aqlprofile_agent_handle_t), 8); @@ -387,22 +387,22 @@ TEST_F(AqlProfileV2Test, UnionBitfieldFunctionality) { // Test buffer descriptor flags union aqlprofile_buffer_desc_flags_t flags; flags.raw = 0xFFFFFFFF; - + // Check that bitfields are properly masked EXPECT_EQ(flags.device_access, 1); // 1 bit - EXPECT_EQ(flags.host_access, 1); // 1 bit + EXPECT_EQ(flags.host_access, 1); // 1 bit EXPECT_EQ(flags.memory_hint, 0x3F); // 6 bits - + // Test PMC event flags union aqlprofile_pmc_event_flags_t pmc_flags; pmc_flags.raw = 0xFFFFFFFF; - + EXPECT_EQ(pmc_flags.sq_flags.accum, 0x7); // 3 bits - + // Test ATT parameter union aqlprofile_att_parameter_t param; param.value = 0xFFFFFFFF; - + EXPECT_EQ(param.counter_id, 0x0FFFFFFF); // 28 bits EXPECT_EQ(param.simd_mask, 0xF); // 4 bits } @@ -412,20 +412,20 @@ TEST_F(AqlProfileV2Test, DefaultInvalidValues) { // Test zero-initialized structures aqlprofile_handle_t zero_handle = {0}; EXPECT_EQ(zero_handle.handle, 0); - + aqlprofile_agent_info_t zero_info = {}; EXPECT_EQ(zero_info.agent_gfxip, nullptr); EXPECT_EQ(zero_info.xcc_num, 0); EXPECT_EQ(zero_info.se_num, 0); EXPECT_EQ(zero_info.cu_num, 0); EXPECT_EQ(zero_info.shader_arrays_per_se, 0); - + // Test with maximum values aqlprofile_pmc_event_t max_event = {}; max_event.block_index = UINT32_MAX; max_event.event_id = UINT32_MAX; max_event.flags.raw = UINT32_MAX; - + EXPECT_EQ(max_event.block_index, UINT32_MAX); EXPECT_EQ(max_event.event_id, UINT32_MAX); EXPECT_EQ(max_event.flags.raw, UINT32_MAX); @@ -446,41 +446,41 @@ public: // Test callback function signatures TEST_F(AqlProfileV2Test, CallbackSignatures) { CallbackMock mock; - + // Test that callback function pointers can be assigned - aqlprofile_memory_alloc_callback_t alloc_cb = + aqlprofile_memory_alloc_callback_t alloc_cb = [](void** ptr, uint64_t size, aqlprofile_buffer_desc_flags_t flags, void* userdata) -> hsa_status_t { return HSA_STATUS_SUCCESS; }; - - aqlprofile_memory_dealloc_callback_t dealloc_cb = + + aqlprofile_memory_dealloc_callback_t dealloc_cb = [](void* ptr, void* userdata) -> void {}; - - aqlprofile_memory_copy_t copy_cb = + + aqlprofile_memory_copy_t copy_cb = [](void* dst, const void* src, size_t size, void* userdata) -> hsa_status_t { return HSA_STATUS_SUCCESS; }; - - aqlprofile_pmc_data_callback_t pmc_cb = + + aqlprofile_pmc_data_callback_t pmc_cb = [](aqlprofile_pmc_event_t event, uint64_t counter_id, uint64_t counter_value, void* userdata) -> hsa_status_t { return HSA_STATUS_SUCCESS; }; - - aqlprofile_att_data_callback_t att_cb = + + aqlprofile_att_data_callback_t att_cb = [](uint32_t shader, void* buffer, uint64_t size, void* callback_data) -> hsa_status_t { return HSA_STATUS_SUCCESS; }; - - aqlprofile_eventname_callback_t event_cb = + + aqlprofile_eventname_callback_t event_cb = [](int id, const char* name, void* data) -> hsa_status_t { return HSA_STATUS_SUCCESS; }; - - aqlprofile_coordinate_callback_t coord_cb = + + aqlprofile_coordinate_callback_t coord_cb = [](int position, int id, int extent, int coordinate, const char* name, void* userdata) -> hsa_status_t { return HSA_STATUS_SUCCESS; }; - + // Verify callbacks are assigned EXPECT_NE(alloc_cb, nullptr); EXPECT_NE(dealloc_cb, nullptr); @@ -501,11 +501,11 @@ protected: last_callback_id_ = -1; last_callback_name_ = ""; } - + static int callback_call_count_; static int last_callback_id_; static std::string last_callback_name_; - + // Mock callback functions for testing static hsa_status_t eventname_callback_mock(int id, const char* name, void* data) { callback_call_count_++; @@ -513,26 +513,26 @@ protected: if (name) last_callback_name_ = name; return HSA_STATUS_SUCCESS; } - - static hsa_status_t coordinate_callback_mock(int position, int id, int extent, + + static hsa_status_t coordinate_callback_mock(int position, int id, int extent, int coordinate, const char* name, void* userdata) { callback_call_count_++; return HSA_STATUS_SUCCESS; } - - static hsa_status_t pmc_data_callback_mock(aqlprofile_pmc_event_t event, uint64_t counter_id, + + static hsa_status_t pmc_data_callback_mock(aqlprofile_pmc_event_t event, uint64_t counter_id, uint64_t counter_value, void* userdata) { callback_call_count_++; return HSA_STATUS_SUCCESS; } - - static hsa_status_t att_data_callback_mock(uint32_t shader, void* buffer, + + static hsa_status_t att_data_callback_mock(uint32_t shader, void* buffer, uint64_t size, void* callback_data) { callback_call_count_++; return HSA_STATUS_SUCCESS; } - - static hsa_status_t memory_alloc_mock(void** ptr, uint64_t size, + + static hsa_status_t memory_alloc_mock(void** ptr, uint64_t size, aqlprofile_buffer_desc_flags_t flags, void* userdata) { if (ptr && size > 0) { *ptr = malloc(size); @@ -540,11 +540,11 @@ protected: } return HSA_STATUS_ERROR_INVALID_ARGUMENT; } - + static void memory_dealloc_mock(void* ptr, void* userdata) { if (ptr) free(ptr); } - + static hsa_status_t memory_copy_mock(void* dst, const void* src, size_t size, void* userdata) { if (dst && src && size > 0) { memcpy(dst, src, size); diff --git a/projects/aqlprofile/src/core/tests/memorymanager_tests.cpp b/projects/aqlprofile/src/core/tests/memorymanager_tests.cpp index c6fb97ec97..bf4c0752ed 100644 --- a/projects/aqlprofile/src/core/tests/memorymanager_tests.cpp +++ b/projects/aqlprofile/src/core/tests/memorymanager_tests.cpp @@ -121,4 +121,4 @@ TEST(CodeobjMemoryManagerTest, CmdBufferAlloc) { hsa_agent_t agent = {.handle = 1}; CodeobjMemoryManager mgr(agent, dummy_alloc, dummy_dealloc, 128, nullptr); ASSERT_NE(mgr.cmd_buffer.get(), nullptr); -} \ No newline at end of file +} diff --git a/projects/aqlprofile/test/CMakeLists.txt b/projects/aqlprofile/test/CMakeLists.txt index 331051bb50..58c414eaf7 100644 --- a/projects/aqlprofile/test/CMakeLists.txt +++ b/projects/aqlprofile/test/CMakeLists.txt @@ -34,8 +34,20 @@ find_package(Clang REQUIRED CONFIG ## Building test executable add_executable ( ${EXE_NAME} ${KERN_SRC} ${CTRL_SRC} ${UTIL_SRC} ) -target_include_directories ( ${EXE_NAME} PRIVATE ${TEST_DIR} ${API_PATH} ${ROCM_ROOT_DIR}/include ${TEST_DIR}/parser/ ${TEST_DIR}/../src/core/include) -target_link_libraries( ${EXE_NAME} PRIVATE pthread hsa-runtime64::hsa-runtime64 dl ) +target_include_directories ( ${EXE_NAME} + PRIVATE + ${TEST_DIR} + ${API_PATH} + ${ROCM_ROOT_DIR}/include + ${TEST_DIR}/parser/ + ${TEST_DIR}/../src/core/include +) +target_link_libraries( ${EXE_NAME} + PRIVATE + pthread + aqlprofile::headers + hsa-runtime64::hsa-runtime64 + dl ) install(TARGETS ${EXE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME} COMPONENT tests) ## Build the hsa (standalone) simple_convolution test