diff --git a/projects/rocprofiler-sdk/samples/counter_collection/client.cpp b/projects/rocprofiler-sdk/samples/counter_collection/client.cpp index 053396244f..e1b516a4ed 100644 --- a/projects/rocprofiler-sdk/samples/counter_collection/client.cpp +++ b/projects/rocprofiler-sdk/samples/counter_collection/client.cpp @@ -23,6 +23,7 @@ #include "client.hpp" #include +#include #include #include #include @@ -72,32 +73,6 @@ get_buffer() return buf; } -std::ostream* -get_output_stream() -{ - static std::ostream* isTerm = []() -> std::ostream* { - if(auto* outfile = getenv("ROCPROFILER_SAMPLE_OUTPUT_FILE")) - { - if(std::string_view{outfile} == "stdout") - return static_cast(&std::cout); - else if(std::string_view{outfile} == "stderr") - return &std::cerr; - } - return nullptr; - }(); - static std::unique_ptr stream; - - if(isTerm) return isTerm; - if(stream) return stream.get(); - std::string filename = "counter_collection.log"; - if(auto* outfile = getenv("ROCPROFILER_SAMPLE_OUTPUT_FILE")) - { - filename = outfile; - } - stream = std::make_unique(filename); - return stream.get(); -} - /** * Buffer callback called when the buffer is full. rocprofiler_record_header_t * can contain counter records as well as other records (such as tracing). These @@ -108,7 +83,7 @@ buffered_callback(rocprofiler_context_id_t, rocprofiler_buffer_id_t, rocprofiler_record_header_t** headers, size_t num_headers, - void*, + void* user_data, uint64_t) { static int enter_count = 0; @@ -128,7 +103,10 @@ buffered_callback(rocprofiler_context_id_t, } } - *get_output_stream() << "[" << __FUNCTION__ << "] " << ss.str() << "\n"; + auto* output_stream = static_cast(user_data); + if(!output_stream) throw std::runtime_error{"nullptr to output stream"}; + + *output_stream << "[" << __FUNCTION__ << "] " << ss.str() << "\n"; } /** @@ -221,7 +199,7 @@ dispatch_callback(rocprofiler_queue_id_t /*queue_id*/, } int -tool_init(rocprofiler_client_finalize_t, void*) +tool_init(rocprofiler_client_finalize_t, void* user_data) { ROCPROFILER_CALL(rocprofiler_create_context(&get_client_ctx()), "context creation failed"); @@ -230,32 +208,35 @@ tool_init(rocprofiler_client_finalize_t, void*) 2048, ROCPROFILER_BUFFER_POLICY_LOSSLESS, buffered_callback, - nullptr, + user_data, &get_buffer()), "buffer creation failed"); auto client_thread = rocprofiler_callback_thread_t{}; ROCPROFILER_CALL(rocprofiler_create_callback_thread(&client_thread), "failure creating callback thread"); - get_output_stream(); ROCPROFILER_CALL(rocprofiler_assign_callback_thread(get_buffer(), client_thread), "failed to assign thread for buffer"); ROCPROFILER_CALL(rocprofiler_configure_buffered_dispatch_profile_counting_service( get_client_ctx(), get_buffer(), dispatch_callback, nullptr), "Could not setup buffered service"); - rocprofiler_start_context(get_client_ctx()); + ROCPROFILER_CALL(rocprofiler_start_context(get_client_ctx()), "start context"); // no errors return 0; } void -tool_fini(void*) +tool_fini(void* user_data) { - rocprofiler_stop_context(get_client_ctx()); std::clog << "In tool fini\n"; -} + ROCPROFILER_CALL(rocprofiler_flush_buffer(get_buffer()), "buffer flush"); + rocprofiler_stop_context(get_client_ctx()); + auto* output_stream = static_cast(user_data); + *output_stream << std::flush; + if(output_stream != &std::cout && output_stream != &std::cerr) delete output_stream; +} } // namespace extern "C" rocprofiler_tool_configure_result_t* @@ -279,12 +260,22 @@ rocprofiler_configure(uint32_t version, std::clog << info.str() << std::endl; + std::ostream* output_stream = nullptr; + std::string filename = "counter_collection.log"; + if(auto* outfile = getenv("ROCPROFILER_SAMPLE_OUTPUT_FILE"); outfile) filename = outfile; + if(filename == "stdout") + output_stream = &std::cout; + else if(filename == "stderr") + output_stream = &std::cerr; + else + output_stream = new std::ofstream{filename}; + // create configure data static auto cfg = rocprofiler_tool_configure_result_t{sizeof(rocprofiler_tool_configure_result_t), &tool_init, &tool_fini, - static_cast(nullptr)}; + static_cast(output_stream)}; // return pointer to configure data return &cfg; diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/agent.hpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/agent.hpp index a40ab11c82..2c17ea6b0c 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/agent.hpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/agent.hpp @@ -62,5 +62,8 @@ get_agent_cache(hsa_agent_t agent); */ std::unordered_set& get_agent_available_properties(); + +void +construct_agent_cache(::HsaApiTable* table); } // namespace agent } // namespace rocprofiler diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/helpers.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/helpers.cpp index 5d4312397c..f5ddbe8d72 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/helpers.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/helpers.cpp @@ -32,8 +32,6 @@ namespace aql hsa_ven_amd_aqlprofile_id_query_t get_query_info(hsa_agent_t agent, const counters::Metric& metric) { - DLOG(WARNING) << fmt::format("Querying HSA for Counter: {}", metric); - hsa_ven_amd_aqlprofile_profile_t profile{.agent = agent}; hsa_ven_amd_aqlprofile_id_query_t query = {metric.block().c_str(), 0, 0}; if(hsa_ven_amd_aqlprofile_get_info(&profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_ID, &query) != diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/tests/CMakeLists.txt b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/tests/CMakeLists.txt index 4f5b424143..317a9cb316 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/tests/CMakeLists.txt +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/tests/CMakeLists.txt @@ -11,8 +11,8 @@ target_sources(aql-test PRIVATE ${ROCPROFILER_LIB_AQL_TEST_SOURCES}) target_link_libraries( aql-test PRIVATE rocprofiler::rocprofiler-static-library rocprofiler::rocprofiler-glog - rocprofiler::rocprofiler-hip rocprofiler::rocprofiler-common-library - GTest::gtest GTest::gtest_main) + rocprofiler::rocprofiler-hsa-runtime rocprofiler::rocprofiler-hip + rocprofiler::rocprofiler-common-library GTest::gtest GTest::gtest_main) gtest_add_tests( TARGET aql-test diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/tests/aql_test.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/tests/aql_test.cpp index 4af35ec695..40af5da201 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/tests/aql_test.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/aql/tests/aql_test.cpp @@ -31,6 +31,7 @@ #include #include +#include "lib/rocprofiler-sdk/agent.hpp" #include "lib/rocprofiler-sdk/aql/helpers.hpp" #include "lib/rocprofiler-sdk/aql/packet_construct.hpp" #include "lib/rocprofiler-sdk/counters/metrics.hpp" @@ -40,7 +41,7 @@ namespace rocprofiler { -AmdExtTable +AmdExtTable& get_ext_table() { static auto _v = []() { @@ -56,18 +57,37 @@ get_ext_table() return _v; } +CoreApiTable& +get_api_table() +{ + static auto _v = []() { + auto val = CoreApiTable{}; + val.hsa_iterate_agents_fn = hsa_iterate_agents; + val.hsa_agent_get_info_fn = hsa_agent_get_info; + val.hsa_queue_create_fn = hsa_queue_create; + val.hsa_queue_destroy_fn = hsa_queue_destroy; + return val; + }(); + return _v; +} + auto findDeviceMetrics(const hsa::AgentCache& agent, const std::unordered_set& metrics) { std::vector ret; auto all_counters = counters::getBaseHardwareMetrics(); + LOG(ERROR) << "Looking up counters for " << std::string(agent.name()); auto gfx_metrics = common::get_val(all_counters, std::string(agent.name())); - if(!gfx_metrics) return ret; + if(!gfx_metrics) + { + LOG(ERROR) << "No counters found for " << std::string(agent.name()); + return ret; + } for(auto& counter : *gfx_metrics) { - if(metrics.count(counter.name()) > 0 || metrics.empty()) + if((metrics.count(counter.name()) > 0 || metrics.empty()) && !counter.block().empty()) { ret.push_back(counter); } @@ -75,81 +95,76 @@ findDeviceMetrics(const hsa::AgentCache& agent, const std::unordered_set hsa_status_t { + ::free(x); + return HSA_STATUS_SUCCESS; + }); + EXPECT_TRUE(check_null(test_pkt.start)) << "Start packet not null"; + EXPECT_TRUE(check_null(test_pkt.stop)) << "Stop packet not null"; + EXPECT_TRUE(check_null(test_pkt.read)) << "Read packet not null"; + + // If this leaks, then AQLPacket is not freeing data correctly. + test_pkt.profile.output_buffer.ptr = malloc(sizeof(double)); + test_pkt.profile.command_buffer.ptr = malloc(sizeof(double)); + test_pkt.command_buf_mallocd = true; + test_pkt.output_buffer_malloced = true; + + // test custom destructor as well + rocprofiler::hsa::AQLPacket test_pkt2([](void* x) -> hsa_status_t { + ::free(x); + return HSA_STATUS_SUCCESS; + }); + test_pkt2.profile.output_buffer.ptr = malloc(sizeof(double)); + test_pkt2.profile.command_buffer.ptr = malloc(sizeof(double)); +} diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/counters/xml/basic_counters.xml b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/counters/xml/basic_counters.xml index 6fb67319ce..c75e39462b 100755 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/counters/xml/basic_counters.xml +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/counters/xml/basic_counters.xml @@ -76,6 +76,9 @@ + + + # EA1