afaa412d9d
`tests/rocprofiler/rocprofiler.cpp` uses `std::string` without including `<string>` directly. This works with libstdc++ due to transitive includes, but fails with libc++. Closes #1240
252 linhas
8.3 KiB
C++
252 linhas
8.3 KiB
C++
// MIT License
|
|
//
|
|
// Copyright (c) 2024-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.
|
|
|
|
|
|
#include <rocprofiler-register/rocprofiler-register.h>
|
|
#include <amdhip/amdhip.hpp>
|
|
#include <hsa-runtime/hsa-runtime.hpp>
|
|
#include <rccl/rccl.hpp>
|
|
#include <rocdecode/rocdecode.hpp>
|
|
#include <rocjpeg/rocjpeg.hpp>
|
|
#include <roctx/roctx.hpp>
|
|
|
|
#include <dlfcn.h>
|
|
#include <pthread.h>
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <tuple>
|
|
#include <vector>
|
|
|
|
#ifndef ROCP_REG_FILE_NAME
|
|
# define ROCP_REG_FILE_NAME \
|
|
::std::string{ __FILE__ } \
|
|
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
|
|
.c_str()
|
|
#endif
|
|
|
|
namespace rocprofiler
|
|
{
|
|
void
|
|
hip_init()
|
|
{
|
|
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
|
|
}
|
|
|
|
void
|
|
hsa_init()
|
|
{
|
|
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
|
|
}
|
|
|
|
ncclResult_t
|
|
ncclGetVersion(int*)
|
|
{
|
|
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
|
|
return {};
|
|
}
|
|
|
|
rocDecStatus
|
|
rocDecCreateDecoder(rocDecDecoderHandle*, RocDecoderCreateInfo*)
|
|
{
|
|
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
|
|
return {};
|
|
}
|
|
|
|
RocJpegStatus
|
|
rocJpegStreamCreate(RocJpegStreamHandle* jpeg_stream_handle)
|
|
{
|
|
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
|
|
return {};
|
|
}
|
|
|
|
void
|
|
roctx_range_push(const char* name)
|
|
{
|
|
printf("[%s][push] %s\n", ROCP_REG_FILE_NAME, name);
|
|
}
|
|
|
|
void
|
|
roctx_range_pop(const char* name)
|
|
{
|
|
printf("[%s][pop] %s\n", ROCP_REG_FILE_NAME, name);
|
|
}
|
|
|
|
using reginfo_vec_t = std::vector<rocprofiler_register_registration_info_t>;
|
|
|
|
bool
|
|
check_registration_info(const char* name,
|
|
uint64_t lib_version,
|
|
uint64_t num_tables,
|
|
const reginfo_vec_t& infovec)
|
|
{
|
|
for(const auto& itr : infovec)
|
|
{
|
|
if(std::string_view{ name } == std::string_view{ itr.common_name })
|
|
{
|
|
return std::tie(lib_version, num_tables) ==
|
|
std::tie(itr.lib_version, itr.api_table_length);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
} // namespace rocprofiler
|
|
|
|
extern "C" {
|
|
int
|
|
rocprofiler_set_api_table(const char*, uint64_t, uint64_t, void**, uint64_t)
|
|
__attribute__((visibility("default")));
|
|
|
|
int
|
|
rocprofiler_set_api_table(const char* name,
|
|
uint64_t lib_version,
|
|
uint64_t lib_instance,
|
|
void** tables,
|
|
uint64_t num_tables)
|
|
{
|
|
printf("[%s] %s :: %lu :: %lu :: %lu\n",
|
|
ROCP_REG_FILE_NAME,
|
|
name,
|
|
lib_version,
|
|
lib_instance,
|
|
num_tables);
|
|
|
|
auto* _tool_libs = std::getenv("ROCP_TOOL_LIBRARIES");
|
|
if(_tool_libs)
|
|
{
|
|
auto* _handle = dlopen(_tool_libs, RTLD_GLOBAL | RTLD_LAZY);
|
|
if(!_handle)
|
|
throw std::runtime_error{ std::string{ "error opening tool library " } +
|
|
_tool_libs };
|
|
auto* _sym = dlsym(_handle, "rocprofiler_configure");
|
|
if(!_sym)
|
|
throw std::runtime_error{ std::string{ "tool library " } +
|
|
std::string{ _tool_libs } +
|
|
" did not contain rocprofiler_configure symbol" };
|
|
}
|
|
|
|
auto registration_info = ::rocprofiler::reginfo_vec_t{};
|
|
{
|
|
auto* _handle =
|
|
dlopen("librocprofiler-register.so", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
|
|
if(!_handle)
|
|
throw std::runtime_error{
|
|
"error opening librocprofiler-register.so library "
|
|
};
|
|
auto* _sym = dlsym(_handle, "rocprofiler_register_iterate_registration_info");
|
|
if(!_sym)
|
|
throw std::runtime_error{
|
|
"librocprofiler-register.so did not contain "
|
|
"rocprofiler_register_iterate_registration_info symbol"
|
|
};
|
|
|
|
auto _func = [](rocprofiler_register_registration_info_t* _info,
|
|
void* _vdata) -> int {
|
|
auto* _vec = static_cast<::rocprofiler::reginfo_vec_t*>(_vdata);
|
|
_vec->emplace_back(*_info);
|
|
return 0;
|
|
};
|
|
|
|
auto iterate_registration_info =
|
|
reinterpret_cast<decltype(&rocprofiler_register_iterate_registration_info)>(
|
|
_sym);
|
|
iterate_registration_info(_func, ®istration_info);
|
|
}
|
|
|
|
using hip_table_t = hip::HipApiTable;
|
|
using hsa_table_t = hsa::HsaApiTable;
|
|
using roctx_table_t = roctx::ROCTxApiTable;
|
|
using rccl_table_t = rccl::rcclApiFuncTable;
|
|
using rocdecode_table_t = rocdecode::rocdecodeApiFuncTable;
|
|
using rocjpeg_table_t = rocjpeg::rocjpegApiFuncTable;
|
|
|
|
auto* _wrap_v = std::getenv("ROCP_REG_TEST_WRAP");
|
|
bool _wrap = (_wrap_v != nullptr && std::stoi(_wrap_v) != 0);
|
|
|
|
if(_wrap)
|
|
{
|
|
if(num_tables != 1)
|
|
throw std::runtime_error{ std::string{ "unexpected number of tables: " } +
|
|
std::to_string(num_tables) };
|
|
|
|
if(tables == nullptr) throw std::runtime_error{ "nullptr to tables" };
|
|
if(tables[0] == nullptr) throw std::runtime_error{ "nullptr to tables[0]" };
|
|
|
|
if(std::string_view{ name } == "hip")
|
|
{
|
|
hip_table_t* _table = static_cast<hip_table_t*>(tables[0]);
|
|
_table->hip_init_fn = &::rocprofiler::hip_init;
|
|
}
|
|
else if(std::string_view{ name } == "hsa")
|
|
{
|
|
hsa_table_t* _table = static_cast<hsa_table_t*>(tables[0]);
|
|
_table->hsa_init_fn = &::rocprofiler::hsa_init;
|
|
}
|
|
else if(std::string_view{ name } == "roctx")
|
|
{
|
|
roctx_table_t* _table = static_cast<roctx_table_t*>(tables[0]);
|
|
_table->roctxRangePush_fn = &::rocprofiler::roctx_range_push;
|
|
_table->roctxRangePop_fn = &::rocprofiler::roctx_range_pop;
|
|
}
|
|
else if(std::string_view{ name } == "rccl")
|
|
{
|
|
rccl_table_t* _table = static_cast<rccl_table_t*>(tables[0]);
|
|
_table->ncclGetVersion_fn = &::rocprofiler::ncclGetVersion;
|
|
}
|
|
else if(std::string_view{ name } == "rocdecode")
|
|
{
|
|
rocdecode_table_t* _table = static_cast<rocdecode_table_t*>(tables[0]);
|
|
_table->rocDecCreateDecoder_fn = &rocprofiler::rocDecCreateDecoder;
|
|
}
|
|
else if(std::string_view{ name } == "rocjpeg")
|
|
{
|
|
rocjpeg_table_t* _table = static_cast<rocjpeg_table_t*>(tables[0]);
|
|
_table->rocJpegStreamCreate_fn = &rocprofiler::rocJpegStreamCreate;
|
|
}
|
|
}
|
|
|
|
if(!::rocprofiler::check_registration_info(
|
|
name, lib_version, num_tables, registration_info))
|
|
{
|
|
auto ss = std::stringstream{};
|
|
ss << "no matching registration info for " << name << " "
|
|
<< " version " << lib_version << " (# tables = " << num_tables << ")";
|
|
throw std::runtime_error{ ss.str() };
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void
|
|
rocp_ctor(void) __attribute__((constructor));
|
|
bool rocprofiler_test_lib_link = false;
|
|
|
|
void
|
|
rocp_ctor()
|
|
{
|
|
rocprofiler_test_lib_link = true;
|
|
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
|
|
}
|