From c66aacd53705292102101d162a6c8597cedbe053 Mon Sep 17 00:00:00 2001 From: Vladimir Indic <139573562+vlaindic@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:26:05 +0200 Subject: [PATCH] Disable counter collection if PC sampling is enabled (#924) --- .../rocprofiler-sdk/counters/controller.cpp | 9 ++ .../pc_sampling_vs_counter_collection.cpp | 140 ++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/source/lib/rocprofiler-sdk/counters/controller.cpp b/source/lib/rocprofiler-sdk/counters/controller.cpp index 3511483def..9045339292 100644 --- a/source/lib/rocprofiler-sdk/counters/controller.cpp +++ b/source/lib/rocprofiler-sdk/counters/controller.cpp @@ -76,6 +76,11 @@ CounterController::configure_agent_collection(rocprofiler_context_id_t auto& ctx = *ctx_p; if(ctx.counter_collection) return ROCPROFILER_STATUS_ERROR_AGENT_DISPATCH_CONFLICT; + + // FIXME: Due to the clock gating issue, counter collection and PC sampling service + // cannot coexist in the same context for now. + if(ctx.pc_sampler) return ROCPROFILER_STATUS_ERROR_CONTEXT_CONFLICT; + if(!rocprofiler::buffer::get_buffer(buffer_id.handle)) { return ROCPROFILER_STATUS_ERROR_BUFFER_NOT_FOUND; @@ -115,6 +120,10 @@ CounterController::configure_dispatch( if(ctx.agent_counter_collection) return ROCPROFILER_STATUS_ERROR_AGENT_DISPATCH_CONFLICT; + // FIXME: Due to the clock gating issue, counter collection and PC sampling service + // cannot coexist in the same context for now. + if(ctx.pc_sampler) return ROCPROFILER_STATUS_ERROR_CONTEXT_CONFLICT; + if(!ctx.counter_collection) { ctx.counter_collection = diff --git a/source/lib/rocprofiler-sdk/pc_sampling/tests/pc_sampling_vs_counter_collection.cpp b/source/lib/rocprofiler-sdk/pc_sampling/tests/pc_sampling_vs_counter_collection.cpp index c854c29641..79b8610de3 100644 --- a/source/lib/rocprofiler-sdk/pc_sampling/tests/pc_sampling_vs_counter_collection.cpp +++ b/source/lib/rocprofiler-sdk/pc_sampling/tests/pc_sampling_vs_counter_collection.cpp @@ -335,6 +335,110 @@ pc_sampling_vs_counter_collection(cc_setup_fn_t cc_setup_fn) EXPECT_EQ(rocprofiler_force_configure(rocp_init), ROCPROFILER_STATUS_SUCCESS); } +void +counter_collection_vs_pc_sampling(cc_setup_fn_t cc_setup_fn) +{ + using init_func_t = int (*)(rocprofiler_client_finalize_t, void*); + using fini_func_t = void (*)(void*); + + // using hsa_iterate_agents_cb_t = hsa_status_t (*)(hsa_agent_t, void*); + + auto cmd_line = rocprofiler::common::read_command_line(getpid()); + ASSERT_FALSE(cmd_line.empty()); + + static init_func_t tool_init = [](rocprofiler_client_finalize_t fini_func, + void* client_data) -> int { + auto* cb_data = static_cast(client_data); + + cb_data->client_workflow_count++; + cb_data->client_fini_func = fini_func; + + // This function returns the all gpu agents supporting some kind of PC sampling + EXPECT_EQ( + rocprofiler_query_available_agents(ROCPROFILER_AGENT_INFO_VERSION_0, + &find_all_gpu_agents_supporting_pc_sampling_impl, + sizeof(rocprofiler_agent_t), + static_cast(&cb_data->gpu_pcs_agents)), + ROCPROFILER_STATUS_SUCCESS); + + if(cb_data->gpu_pcs_agents.size() == 0) + { + ROCP_ERROR << "PC sampling unavailable\n"; + exit(0); + } + + EXPECT_EQ(rocprofiler_create_context(&cb_data->client_ctx), ROCPROFILER_STATUS_SUCCESS); + + // Create PC sampling buffer + EXPECT_EQ(rocprofiler_create_buffer(cb_data->client_ctx, + BUFFER_SIZE_BYTES, + WATERMARK, + ROCPROFILER_BUFFER_POLICY_LOSSLESS, + rocprofiler_pc_sampling_callback, + client_data, + &cb_data->client_buffer), + ROCPROFILER_STATUS_SUCCESS); + + // Configuring PC sampling service first + for(const auto* agent : cb_data->gpu_pcs_agents) + { + const auto agent_id = agent->id; + const auto pcs_config = extract_pc_sampling_config_prefer_stochastic(agent_id); + + size_t interval = pcs_config.max_interval; + + // This calls succeeds + EXPECT_EQ(rocprofiler_configure_pc_sampling_service(cb_data->client_ctx, + agent_id, + pcs_config.method, + pcs_config.unit, + interval, + cb_data->client_buffer), + ROCPROFILER_STATUS_SUCCESS); + } + + // Configuring counter collection service on the first listed GPU agent should fail + cb_data->cc_setup_fn(cb_data->client_ctx, cb_data->gpu_pcs_agents.at(0)->id); + + // no errors + return 0; + }; + + static fini_func_t tool_fini = [](void* client_data) -> void { + auto* cb_data = static_cast(client_data); + EXPECT_EQ(rocprofiler_stop_context(cb_data->client_ctx), ROCPROFILER_STATUS_SUCCESS); + + static_cast(client_data)->client_workflow_count++; + }; + + static auto cb_data = callback_data{}; + cb_data.cc_setup_fn = cc_setup_fn; + + static auto cfg_result = + rocprofiler_tool_configure_result_t{sizeof(rocprofiler_tool_configure_result_t), + tool_init, + tool_fini, + static_cast(&cb_data)}; + + static rocprofiler_configure_func_t rocp_init = + [](uint32_t version, + const char* runtime_version, + uint32_t prio, + rocprofiler_client_id_t* client_id) -> rocprofiler_tool_configure_result_t* { + auto expected_version = ROCPROFILER_VERSION; + EXPECT_EQ(expected_version, version); + EXPECT_EQ(std::string_view{runtime_version}, std::string_view{ROCPROFILER_VERSION_STRING}); + EXPECT_EQ(prio, 0); + EXPECT_EQ(client_id->name, nullptr); + cb_data.client_id = client_id; + cb_data.client_id->name = ::testing::UnitTest::GetInstance()->current_test_info()->name(); + + return &cfg_result; + }; + + EXPECT_EQ(rocprofiler_force_configure(rocp_init), ROCPROFILER_STATUS_SUCCESS); +} + } // namespace TEST(pc_sampling, pc_sampling_vs_dispatch_counter_collection) @@ -372,3 +476,39 @@ TEST(pc_sampling, pc_sampling_vs_agent_counter_collection) pc_sampling_vs_counter_collection(agent_counter_collection_setup_fn); } + +TEST(pc_sampling, dispatch_counter_collection_vs_pc_sampling) +{ + auto dispatch_counter_collection_setup_fn = [](rocprofiler_context_id_t context_id, + rocprofiler_agent_id_t /*agent_id*/) { + // Configure dispatch counter collection service on all agents + EXPECT_EQ(rocprofiler_configure_callback_dispatch_profile_counting_service( + context_id, dispatch_callback, nullptr, record_callback, nullptr), + ROCPROFILER_STATUS_ERROR_CONTEXT_CONFLICT); + }; + + counter_collection_vs_pc_sampling(dispatch_counter_collection_setup_fn); +} + +TEST(pc_sampling, agent_counter_collection_vs_pc_sampling) +{ + auto agent_counter_collection_setup_fn = [](rocprofiler_context_id_t context_id, + rocprofiler_agent_id_t agent_id) { + rocprofiler_buffer_id_t cc_buf_id; + // Create PC sampling buffer + EXPECT_EQ(rocprofiler_create_buffer(context_id, + BUFFER_SIZE_BYTES, + WATERMARK, + ROCPROFILER_BUFFER_POLICY_LOSSLESS, + rocprofiler_counter_collection_callback, + nullptr, + &cc_buf_id), + ROCPROFILER_STATUS_SUCCESS); + + EXPECT_EQ(rocprofiler_configure_agent_profile_counting_service( + context_id, cc_buf_id, agent_id, set_profile, nullptr), + ROCPROFILER_STATUS_ERROR_CONTEXT_CONFLICT); + }; + + counter_collection_vs_pc_sampling(agent_counter_collection_setup_fn); +}