Logging updates (#7)
* General logging updates
* ROCm 6.1.x fatal defect: unconditional abort if tool found but rocprofiler-sdk missing
- Adding rocprofiler-sdk support breaks backwards compatibility in ROCm 6.1.x because `rocprofiler_configure` symbol triggers looking for rocprofiler-sdk library (which was not released until ROCm 6.2)
- Bump version to 0.5.0
* revert to using fatal error
* Include header updates
* Fix CodeQL suggestions
* CMake and CI updates
- minimum cmake version is 3.22.0
- added requirements.txt
- improved rocprofiler_register_{formatting,linting}.cmake
* Disable deprecated declarations warnings
* Use "overwrite" instead of "override"
- override is a keyword in C++
* Disable REQUIRED for formatting and linting when BUILD_DEVELOPER=ON
---------
Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>
[ROCm/rocprofiler-register commit: cb1b430251]
Este cometimento está contido em:
cometido por
GitHub
ascendente
e6f9ba2e77
cometimento
e820b8862a
+2
-1
@@ -81,7 +81,8 @@ jobs:
|
||||
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/${CC} 100 &&
|
||||
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/${CXX} 100 &&
|
||||
python3 -m pip install --upgrade pip &&
|
||||
python3 -m pip install 'cmake==3.21.4'
|
||||
python3 -m pip install 'cmake==3.22.0' &&
|
||||
python3 -m pip install -r requirements.txt
|
||||
|
||||
- name: Setup GCov
|
||||
timeout-minutes: 25
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.22.0 FATAL_ERROR)
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND CMAKE_CURRENT_SOURCE_DIR STREQUAL
|
||||
CMAKE_SOURCE_DIR)
|
||||
|
||||
@@ -2,18 +2,27 @@
|
||||
|
||||
## Overview
|
||||
|
||||
The rocprofiler-register library is a helper library that coordinates the modification of the intercept API table(s) of the HSA/HIP/ROCTx
|
||||
runtime libraries by the ROCprofiler (v2) library. The purpose of this library is to provide a consistent and automated mechanism
|
||||
The rocprofiler-register library is a helper library that coordinates the modification of the intercept API table(s) of the HSA/HIP/ROCTx
|
||||
runtime libraries by the ROCprofiler (v2) library. The purpose of this library is to provide a consistent and automated mechanism
|
||||
of enabling performance analysis in the ROCm runtimes which does not rely on environment variables or unique methods for each runtime
|
||||
library.
|
||||
library.
|
||||
|
||||
When a runtime is initialized (either explicitly and lazily) and the intercept API table is constructed, it passes this API table to
|
||||
rocprofiler-register. Rocprofiler-register scans the symbols in the address space and if it detects there is at least one visible symbol named
|
||||
`rocprofiler_configure` (which is a function provided by tools), it passes the intercept API table to the rocprofiler library (dlopening
|
||||
rocprofiler-register. Rocprofiler-register scans the symbols in the address space and if it detects there is at least one visible symbol named
|
||||
`rocprofiler_configure` (which is a function provided by tools), it passes the intercept API table to the rocprofiler library (dlopening
|
||||
the rocprofiler library if it is not already loaded). The rocprofiler library then does an extensive scan for _all_ the instances of
|
||||
the `rocprofiler_configure` symbols and invokes each of them. The `rocprofiler_configure` function (again, provided by a tool) returns
|
||||
effectively tells rocprofiler which behaviors it wants to be notified about, features it wants to use (e.g. API tracing, kernel dispatch timing),
|
||||
etc.
|
||||
etc.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Environment Variable | Description | Default Value |
|
||||
|-----------------------------------|---------------------------------------------------------------------------|----------------|
|
||||
| `ROCP_TOOL_LIBRARIES` | List of rocprofiler-sdk tool libraries (space, comma, or colon separated) | Empty (string) |
|
||||
| `ROCPROFILER_REGISTER_ENABLED` | Set to 0/false/no to disable rocprofiler-register | true (bool) |
|
||||
| `ROCPROFILER_REGISTER_SECURE` | Additional checks to ensure authenticity of runtime libraries | false (bool) |
|
||||
| `ROCPROFILER_REGISTER_FORCE_LOAD` | Load rocprofiler-sdk library regardless of whether there is a tool or not | false (bool) |
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -24,7 +33,7 @@ The default branch is `amd-mainline` but the only branch that should target that
|
||||
### Creating a feature branch
|
||||
|
||||
```console
|
||||
# fetch any updates
|
||||
# fetch any updates
|
||||
git fetch origin
|
||||
|
||||
# switch to staging branch
|
||||
@@ -44,18 +53,18 @@ branch as well.
|
||||
|
||||
### Pulling in updates to `amd-staging` to your feature branch
|
||||
|
||||
Linear histories are preferred so if another PR is merged into `amd-staging` while your PR is still open, please
|
||||
Linear histories are preferred so if another PR is merged into `amd-staging` while your PR is still open, please
|
||||
select the "Update with rebase" option (i.e. try to avoid a merge commit). From the command line, the git command
|
||||
would be `git pull --rebase origin amd-staging`.
|
||||
|
||||
## Build and Installation
|
||||
|
||||
rocprofiler-register has a standard CMake build and install process. E.g. the following configure
|
||||
rocprofiler-register to build with optimizations and without debug info in a `build-rocp-reg` subdirectory,
|
||||
rocprofiler-register to build with optimizations and without debug info in a `build-rocp-reg` subdirectory,
|
||||
build using 4 jobs, and install to `/opt/rocprofiler-register`:
|
||||
|
||||
```console
|
||||
cmake -B build-rocp-reg . -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-register
|
||||
cmake -B build-rocp-reg . -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-register
|
||||
cmake --build build-rocp-reg --target all --parallel 4
|
||||
cmake --build build-rocp-reg --target install
|
||||
```
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.4.0
|
||||
0.5.0
|
||||
|
||||
@@ -88,7 +88,8 @@ rocprofiler_register_target_compile_options(
|
||||
rocprofiler_register_target_compile_options(
|
||||
rocprofiler-register-developer-flags
|
||||
LANGUAGES C CXX
|
||||
INTERFACE "-Werror" "-Wdouble-promotion" "-Wshadow" "-Wextra")
|
||||
INTERFACE "-Werror" "-Wdouble-promotion" "-Wshadow" "-Wextra"
|
||||
"-Wno-deprecated-declarations")
|
||||
|
||||
if(ROCPROFILER_REGISTER_BUILD_DEVELOPER)
|
||||
target_link_libraries(rocprofiler-register-build-flags
|
||||
|
||||
@@ -13,10 +13,41 @@
|
||||
|
||||
include_guard(DIRECTORY)
|
||||
|
||||
find_program(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE NAMES clang-format-11
|
||||
clang-format-mp-11)
|
||||
find_program(ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE NAMES cmake-format)
|
||||
find_program(ROCPROFILER_REGISTER_BLACK_FORMAT_EXE NAMES black)
|
||||
if(NOT ROCPROFILER_REGISTER_CLANG_FORMAT_EXE AND EXISTS
|
||||
$ENV{HOME}/.local/bin/clang-format)
|
||||
execute_process(
|
||||
COMMAND $ENV{HOME}/.local/bin/clang-format --version
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
OUTPUT_VARIABLE _CLANG_FMT_OUT
|
||||
RESULT_VARIABLE _CLANG_FMT_RET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
||||
if(_CLANG_FMT_RET EQUAL 0)
|
||||
if("${_CLANG_FMT_OUT}" MATCHES "version 11\\.([0-9]+)\\.([0-9]+)")
|
||||
set(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE
|
||||
"$ENV{HOME}/.local/bin/clang-format"
|
||||
CACHE FILEPATH "clang-format exe")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(
|
||||
ROCPROFILER_REGISTER_CLANG_FORMAT_EXE
|
||||
NAMES clang-format-11 clang-format-mp-11 clang-format
|
||||
PATHS $ENV{HOME}/.local
|
||||
HINTS $ENV{HOME}/.local
|
||||
PATH_SUFFIXES bin)
|
||||
find_program(
|
||||
ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE
|
||||
NAMES cmake-format
|
||||
PATHS $ENV{HOME}/.local
|
||||
HINTS $ENV{HOME}/.local
|
||||
PATH_SUFFIXES bin)
|
||||
find_program(
|
||||
ROCPROFILER_REGISTER_BLACK_FORMAT_EXE
|
||||
NAMES black
|
||||
PATHS $ENV{HOME}/.local
|
||||
HINTS $ENV{HOME}/.local
|
||||
PATH_SUFFIXES bin)
|
||||
|
||||
add_custom_target(format-rocprofiler-register)
|
||||
if(NOT TARGET format)
|
||||
@@ -43,12 +74,14 @@ if(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE
|
||||
set(${_TYPE})
|
||||
endforeach()
|
||||
file(GLOB_RECURSE header_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.h
|
||||
${PROJECT_SOURCE_DIR}/${_DIR}/*.hpp)
|
||||
${PROJECT_SOURCE_DIR}/${_DIR}/*.hpp ${PROJECT_SOURCE_DIR}/${_DIR}/*.h.in
|
||||
${PROJECT_SOURCE_DIR}/${_DIR}/*.hpp.in)
|
||||
file(GLOB_RECURSE source_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.c
|
||||
${PROJECT_SOURCE_DIR}/${_DIR}/*.cpp)
|
||||
file(GLOB_RECURSE cmake_files ${PROJECT_SOURCE_DIR}/${_DIR}/*CMakeLists.txt
|
||||
${PROJECT_SOURCE_DIR}/${_DIR}/*.cmake)
|
||||
file(GLOB_RECURSE python_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.py)
|
||||
file(GLOB_RECURSE python_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.py
|
||||
${PROJECT_SOURCE_DIR}/${_DIR}/*.py.in)
|
||||
foreach(_TYPE header_files source_files cmake_files python_files)
|
||||
list(APPEND rocp_${_TYPE} ${${_TYPE}})
|
||||
endforeach()
|
||||
@@ -76,7 +109,7 @@ if(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE
|
||||
format-rocprofiler-register-python
|
||||
${ROCPROFILER_REGISTER_BLACK_FORMAT_EXE} -q ${rocp_python_files}
|
||||
COMMENT
|
||||
"[rocprofiler-register] Running Python formatter ${ROCPROFILER_REGISTER_BLACK_FORMAT_EXE}..."
|
||||
"[rocprofiler-register] Running python formatter ${ROCPROFILER_REGISTER_BLACK_FORMAT_EXE}..."
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -85,7 +118,7 @@ if(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE
|
||||
format-rocprofiler-register-cmake
|
||||
${ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE} -i ${rocp_cmake_files}
|
||||
COMMENT
|
||||
"[rocprofiler-register] Running CMake formatter ${ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE}..."
|
||||
"[rocprofiler-register] Running cmake formatter ${ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE}..."
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,13 +1,30 @@
|
||||
include_guard(GLOBAL)
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
#
|
||||
# Clang Tidy
|
||||
#
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
|
||||
include_guard(DIRECTORY)
|
||||
|
||||
if(NOT ROCPROFILER_REGISTER_CLANG_TIDY_EXE AND EXISTS $ENV{HOME}/.local/bin/clang-tidy)
|
||||
execute_process(
|
||||
COMMAND $ENV{HOME}/.local/bin/clang-tidy --version
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
OUTPUT_VARIABLE _CLANG_TIDY_OUT
|
||||
RESULT_VARIABLE _CLANG_TIDY_RET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
||||
|
||||
if(_CLANG_TIDY_RET EQUAL 0)
|
||||
if("${_CLANG_TIDY_OUT}" MATCHES "version 1[5-9]\\.([0-9]+)\\.([0-9]+)")
|
||||
set(ROCPROFILER_REGISTER_CLANG_TIDY_EXE
|
||||
"$ENV{HOME}/.local/bin/clang-tidy"
|
||||
CACHE FILEPATH "clang-tidy exe")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(
|
||||
ROCPROFILER_REGISTER_CLANG_TIDY_COMMAND
|
||||
ROCPROFILER_REGISTER_CLANG_TIDY_EXE
|
||||
NAMES clang-tidy-18
|
||||
clang-tidy-17
|
||||
clang-tidy-16
|
||||
@@ -16,19 +33,25 @@ find_program(
|
||||
clang-tidy-13
|
||||
clang-tidy-12
|
||||
clang-tidy-11
|
||||
clang-tidy)
|
||||
clang-tidy
|
||||
PATHS $ENV{HOME}/.local
|
||||
HINTS $ENV{HOME}/.local
|
||||
PATH_SUFFIXES bin)
|
||||
|
||||
macro(ROCPROFILER_REGISTER_ACTIVATE_CLANG_TIDY)
|
||||
if(ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
|
||||
if(NOT ROCPROFILER_REGISTER_CLANG_TIDY_COMMAND)
|
||||
if(NOT ROCPROFILER_REGISTER_CLANG_TIDY_EXE)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY is ON but clang-tidy is not found!"
|
||||
)
|
||||
endif()
|
||||
|
||||
rocprofiler_register_add_feature(ROCPROFILER_REGISTER_CLANG_TIDY_EXE
|
||||
"path to clang-tidy executable")
|
||||
|
||||
set(CMAKE_CXX_CLANG_TIDY
|
||||
${ROCPROFILER_REGISTER_CLANG_TIDY_COMMAND}
|
||||
${ROCPROFILER_REGISTER_CLANG_TIDY_EXE}
|
||||
-header-filter=${PROJECT_SOURCE_DIR}/source/.*
|
||||
--warnings-as-errors=*,-misc-header-include-cycle)
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ rocprofiler_register_add_option(
|
||||
${ROCM_DEP_ROCMCORE})
|
||||
|
||||
# In the future, we will do this even with clang-tidy enabled
|
||||
if(ROCPROFILER_REGISTER_BUILD_CI AND NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
|
||||
if(ROCPROFILER_REGISTER_BUILD_CI
|
||||
AND NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY
|
||||
AND NOT ROCPROFILER_REGISTER_BUILD_DEVELOPER)
|
||||
message(
|
||||
STATUS
|
||||
"Forcing ROCPROFILER_REGISTER_BUILD_DEVELOPER=ON because ROCPROFILER_REGISTER_BUILD_CI=ON"
|
||||
|
||||
@@ -15,7 +15,7 @@ if(ROCPROFILER_REGISTER_BUILD_GLOG)
|
||||
# May want to use GFLAGS in the future
|
||||
set(WITH_GFLAGS OFF)
|
||||
set(WITH_GTEST OFF)
|
||||
set(WITH_UNWIND OFF)
|
||||
set(WITH_UNWIND "none")
|
||||
add_subdirectory(glog EXCLUDE_FROM_ALL)
|
||||
else()
|
||||
find_package(glog REQUIRED)
|
||||
|
||||
+1
-1
Submódulo projects/rocprofiler-register/external/glog modificado: 3a0d4d22c5...7b134a5c82
@@ -0,0 +1,5 @@
|
||||
black
|
||||
clang-format>=11.0.0,<12.0.0
|
||||
clang-tidy>=15.0.0,<19.0.0
|
||||
cmake>=3.22.0
|
||||
cmake-format
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
#
|
||||
# builds the rocprofiler-register library
|
||||
#
|
||||
set(rocprofiler_register_details_sources dl.cpp utility.cpp)
|
||||
set(rocprofiler_register_details_sources dl.cpp logging.cpp utility.cpp)
|
||||
|
||||
set(rocprofiler_register_details_headers environment.hpp dl.hpp filesystem.hpp
|
||||
utility.hpp)
|
||||
logging.hpp utility.hpp)
|
||||
|
||||
target_sources(rocprofiler-register PRIVATE ${rocprofiler_register_details_sources}
|
||||
${rocprofiler_register_details_headers})
|
||||
|
||||
+27
-5
@@ -20,8 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fmt/core.h"
|
||||
#include "glog/logging.h"
|
||||
#include <fmt/core.h>
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
@@ -106,6 +106,21 @@ get_env_impl(std::string_view env_id, bool _default)
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
inline int
|
||||
set_env_impl(std::string_view env_id, bool value, int overwrite)
|
||||
{
|
||||
return ::setenv(env_id.data(), (value) ? "1" : "0", overwrite);
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
int
|
||||
set_env_impl(std::string_view env_id, Tp value, int overwrite)
|
||||
{
|
||||
auto str_value = std::stringstream{};
|
||||
str_value << value;
|
||||
return ::setenv(env_id.data(), str_value.str().c_str(), overwrite);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template <typename Tp>
|
||||
@@ -124,18 +139,25 @@ get_env(std::string_view env_id, Tp&& _default)
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
inline auto
|
||||
set_env(std::string_view env_id, Tp&& value, int overwrite = 0)
|
||||
{
|
||||
return set_env_impl(env_id, std::forward<Tp>(value), overwrite);
|
||||
}
|
||||
|
||||
struct env_config
|
||||
{
|
||||
std::string env_name = {};
|
||||
std::string env_value = {};
|
||||
int override = 0;
|
||||
int overwrite = 0;
|
||||
|
||||
auto operator()() const
|
||||
{
|
||||
if(env_name.empty()) return -1;
|
||||
LOG(INFO) << fmt::format(
|
||||
"setenv({}, {}, {})", env_name.c_str(), env_value.c_str(), override);
|
||||
return setenv(env_name.c_str(), env_value.c_str(), override);
|
||||
"setenv({}, {}, {})", env_name.c_str(), env_value.c_str(), overwrite);
|
||||
return setenv(env_name.c_str(), env_value.c_str(), overwrite);
|
||||
}
|
||||
};
|
||||
} // namespace common
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 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 "logging.hpp"
|
||||
#include "environment.hpp"
|
||||
#include "filesystem.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ranges.h>
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace logging
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct logging_config
|
||||
{
|
||||
bool logtostderr = true;
|
||||
bool alsologtostderr = false;
|
||||
bool logdir_gitignore = false; // add .gitignore to logdir
|
||||
int32_t loglevel = google::WARNING;
|
||||
std::string vlog_modules = {};
|
||||
std::string name = {};
|
||||
std::string logdir = {};
|
||||
};
|
||||
|
||||
struct log_level_info
|
||||
{
|
||||
int32_t google_level = 0;
|
||||
int32_t verbose_level = 0;
|
||||
};
|
||||
|
||||
void
|
||||
update_logging(const logging_config& cfg, bool setup_env = false, int env_override = 0)
|
||||
{
|
||||
static auto _mtx = std::mutex{};
|
||||
auto _lk = std::unique_lock<std::mutex>{ _mtx };
|
||||
|
||||
FLAGS_timestamp_in_logfile_name = false;
|
||||
FLAGS_logtostderr = cfg.logtostderr;
|
||||
FLAGS_minloglevel = cfg.loglevel;
|
||||
FLAGS_stderrthreshold = cfg.loglevel;
|
||||
FLAGS_alsologtostderr = cfg.alsologtostderr;
|
||||
|
||||
// if(!cfg.logdir.empty()) FLAGS_log_dir = cfg.logdir.c_str();
|
||||
|
||||
if(!cfg.logdir.empty() && !fs::exists(cfg.logdir))
|
||||
{
|
||||
fs::create_directories(cfg.logdir);
|
||||
|
||||
if(cfg.logdir_gitignore)
|
||||
{
|
||||
auto ignore = fs::path{ cfg.logdir } / ".gitignore";
|
||||
if(!fs::exists(ignore))
|
||||
{
|
||||
std::ofstream ofs{ ignore.string() };
|
||||
ofs << "/**" << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(setup_env)
|
||||
{
|
||||
common::set_env("GLOG_minloglevel", cfg.loglevel, env_override);
|
||||
common::set_env("GLOG_logtostderr", cfg.logtostderr ? 1 : 0, env_override);
|
||||
common::set_env(
|
||||
"GLOG_alsologtostderr", cfg.alsologtostderr ? 1 : 0, env_override);
|
||||
common::set_env("GLOG_stderrthreshold", cfg.loglevel, env_override);
|
||||
if(!cfg.logdir.empty())
|
||||
{
|
||||
common::set_env("GOOGLE_LOG_DIR", cfg.logdir, env_override);
|
||||
common::set_env("GLOG_log_dir", cfg.logdir, env_override);
|
||||
}
|
||||
if(!cfg.vlog_modules.empty())
|
||||
common::set_env("GLOG_vmodule", cfg.vlog_modules, env_override);
|
||||
}
|
||||
}
|
||||
|
||||
#define ROCP_REG_LOG_LEVEL_TRACE 4
|
||||
#define ROCP_REG_LOG_LEVEL_INFO 3
|
||||
#define ROCP_REG_LOG_LEVEL_WARNING 2
|
||||
#define ROCP_REG_LOG_LEVEL_ERROR 1
|
||||
#define ROCP_REG_LOG_LEVEL_NONE 0
|
||||
|
||||
void
|
||||
init_logging(std::string_view env_prefix, logging_config cfg = logging_config{})
|
||||
{
|
||||
static auto _once = std::once_flag{};
|
||||
std::call_once(_once, [env_prefix, &cfg]() {
|
||||
auto get_argv0 = []() {
|
||||
auto ifs = std::ifstream{ "/proc/self/cmdline" };
|
||||
auto sarg = std::string{};
|
||||
while(ifs && !ifs.eof())
|
||||
{
|
||||
ifs >> sarg;
|
||||
if(!sarg.empty()) break;
|
||||
}
|
||||
return sarg;
|
||||
};
|
||||
|
||||
auto to_lower = [](std::string val) {
|
||||
for(auto& itr : val)
|
||||
itr = tolower(itr);
|
||||
return val;
|
||||
};
|
||||
|
||||
const auto env_opts = std::unordered_map<std::string_view, log_level_info>{
|
||||
{ "trace", { google::INFO, ROCP_REG_LOG_LEVEL_TRACE } },
|
||||
{ "info", { google::INFO, ROCP_REG_LOG_LEVEL_INFO } },
|
||||
{ "warning", { google::WARNING, ROCP_REG_LOG_LEVEL_WARNING } },
|
||||
{ "error", { google::ERROR, ROCP_REG_LOG_LEVEL_ERROR } },
|
||||
{ "fatal", { google::FATAL, ROCP_REG_LOG_LEVEL_NONE } }
|
||||
};
|
||||
|
||||
auto supported = std::vector<std::string>{};
|
||||
supported.reserve(env_opts.size());
|
||||
for(auto itr : env_opts)
|
||||
supported.emplace_back(itr.first);
|
||||
|
||||
if(cfg.name.empty()) cfg.name = to_lower(std::string{ env_prefix });
|
||||
|
||||
cfg.logdir = common::get_env(fmt::format("{}_LOG_DIR", env_prefix), cfg.logdir);
|
||||
cfg.vlog_modules =
|
||||
common::get_env(fmt::format("{}_vmodule", env_prefix), cfg.vlog_modules);
|
||||
cfg.logtostderr = cfg.logdir.empty(); // log to stderr if no log dir set
|
||||
// cfg.alsologtostderr = !cfg.logdir.empty(); // log to file if log dir set
|
||||
|
||||
auto loglvl =
|
||||
to_lower(common::get_env(fmt::format("{}_LOG_LEVEL", env_prefix), ""));
|
||||
// default to warning
|
||||
auto& loglvl_v = cfg.loglevel;
|
||||
if(!loglvl.empty() &&
|
||||
loglvl.find_first_not_of("-0123456789") == std::string::npos)
|
||||
{
|
||||
auto val = std::stol(loglvl);
|
||||
if(val < 0)
|
||||
{
|
||||
loglvl_v = google::FATAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// default to trace in case val > ROCP_REG_LOG_LEVEL_TRACE
|
||||
auto itr = env_opts.at("trace");
|
||||
for(auto oitr : env_opts)
|
||||
{
|
||||
if(oitr.second.verbose_level == val)
|
||||
{
|
||||
itr = oitr.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
loglvl_v = itr.google_level;
|
||||
}
|
||||
}
|
||||
else if(!loglvl.empty())
|
||||
{
|
||||
if(env_opts.find(loglvl) == env_opts.end())
|
||||
throw std::runtime_error{ fmt::format(
|
||||
"invalid specifier for {}_LOG_LEVEL: {}. Supported: {}",
|
||||
env_prefix,
|
||||
loglvl,
|
||||
fmt::format("{}",
|
||||
fmt::join(supported.begin(), supported.end(), ", "))) };
|
||||
else
|
||||
{
|
||||
loglvl_v = env_opts.at(loglvl).google_level;
|
||||
}
|
||||
}
|
||||
|
||||
update_logging(cfg, !google::IsGoogleLoggingInitialized());
|
||||
|
||||
if(!google::IsGoogleLoggingInitialized())
|
||||
{
|
||||
static auto argv0 = get_argv0();
|
||||
// Prevent glog from crashing if vmodule is empty
|
||||
if(FLAGS_vmodule.empty()) FLAGS_vmodule = " ";
|
||||
|
||||
google::InitGoogleLogging(argv0.c_str());
|
||||
|
||||
// Swap out memory to avoid leaking the string
|
||||
if(!FLAGS_vmodule.empty()) std::string{}.swap(FLAGS_vmodule);
|
||||
if(!FLAGS_log_dir.empty()) std::string{}.swap(FLAGS_log_dir);
|
||||
}
|
||||
|
||||
update_logging(cfg);
|
||||
|
||||
LOG(INFO) << "logging initialized via " << fmt::format("{}_LOG_LEVEL", env_prefix)
|
||||
<< ". Log Level: " << loglvl;
|
||||
});
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void
|
||||
initialize()
|
||||
{
|
||||
init_logging("ROCPROFILER_REGISTER");
|
||||
}
|
||||
} // namespace logging
|
||||
} // namespace rocprofiler_register
|
||||
@@ -0,0 +1,37 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 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
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace logging
|
||||
{
|
||||
void
|
||||
initialize();
|
||||
} // namespace logging
|
||||
} // namespace rocprofiler_register
|
||||
+33
-11
@@ -25,7 +25,10 @@
|
||||
#include "details/dl.hpp"
|
||||
#include "details/environment.hpp"
|
||||
#include "details/filesystem.hpp"
|
||||
#include "glog/logging.h"
|
||||
#include "details/logging.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
@@ -92,8 +95,6 @@ static_assert(sizeof(bitset_t) ==
|
||||
sizeof(rocprofiler_register_library_indentifier_t::handle),
|
||||
"bitset should be same at uint64_t");
|
||||
|
||||
int rocprofiler_register_verbose = common::get_env("ROCPROFILER_REGISTER_VERBOSE", 0);
|
||||
constexpr int rocprofiler_register_info_level = 2;
|
||||
constexpr auto rocprofiler_lib_name = "librocprofiler-sdk.so";
|
||||
constexpr auto rocprofiler_lib_register_entrypoint = "rocprofiler_set_api_table";
|
||||
constexpr auto rocprofiler_register_lib_name =
|
||||
@@ -338,9 +339,8 @@ rocp_load_rocprofiler_lib(std::string _rocp_reg_lib)
|
||||
dlopen(_rocp_reg_lib_path.c_str(), RTLD_GLOBAL | RTLD_LAZY);
|
||||
}
|
||||
|
||||
if(rocprofiler_register_verbose >= rocprofiler_register_info_level)
|
||||
LOG(INFO) << "loaded " << _rocp_reg_lib_path_fname.string() << " library at "
|
||||
<< _rocp_reg_lib_path.string();
|
||||
LOG(INFO) << "loaded " << _rocp_reg_lib_path_fname.string() << " library at "
|
||||
<< _rocp_reg_lib_path.string();
|
||||
|
||||
LOG_IF(WARNING, rocprofiler_lib_handle == nullptr)
|
||||
<< _rocp_reg_lib << " failed to load\n";
|
||||
@@ -356,7 +356,7 @@ rocp_load_rocprofiler_lib(std::string _rocp_reg_lib)
|
||||
}
|
||||
|
||||
constexpr auto library_seq = std::make_index_sequence<ROCP_REG_LAST>{};
|
||||
auto global_mutex = std::recursive_mutex{};
|
||||
auto global_count = std::atomic<uint32_t>{ 0 };
|
||||
auto import_info = rocp_reg_get_imports(library_seq);
|
||||
auto instance_counters = std::array<std::atomic_uint64_t, ROCP_REG_LAST>{};
|
||||
} // namespace
|
||||
@@ -373,11 +373,33 @@ rocprofiler_register_library_api_table(
|
||||
{
|
||||
if(api_table_length < 1) return ROCP_REG_BAD_API_TABLE_LENGTH;
|
||||
|
||||
(void) lib_version;
|
||||
(void) api_tables;
|
||||
rocprofiler_register::logging::initialize();
|
||||
|
||||
auto _lk = std::unique_lock<std::recursive_mutex>{ global_mutex, std::defer_lock };
|
||||
if(_lk.owns_lock()) return ROCP_REG_DEADLOCK;
|
||||
// rocprofiler-register is disabled via environment
|
||||
if(!common::get_env("ROCPROFILER_REGISTER_ENABLED", true))
|
||||
{
|
||||
LOG(INFO) << "rocprofiler-register disabled via ROCPROFILER_REGISTER_ENABLED=0";
|
||||
return ROCP_REG_NO_TOOLS;
|
||||
}
|
||||
|
||||
struct scoped_count
|
||||
{
|
||||
scoped_count()
|
||||
: value{ ++global_count }
|
||||
{ }
|
||||
|
||||
~scoped_count() { --global_count; }
|
||||
|
||||
scoped_count(const scoped_count&) = delete;
|
||||
scoped_count(scoped_count&&) noexcept = delete;
|
||||
scoped_count& operator=(const scoped_count&) = delete;
|
||||
scoped_count& operator=(scoped_count&&) noexcept = delete;
|
||||
|
||||
uint32_t value = 0;
|
||||
};
|
||||
|
||||
auto _count = scoped_count{};
|
||||
if(_count.value > 1) return ROCP_REG_DEADLOCK;
|
||||
|
||||
auto _scan_result = rocp_reg_scan_for_tools();
|
||||
|
||||
|
||||
@@ -81,6 +81,11 @@ add_subdirectory(rocprofiler)
|
||||
#
|
||||
add_subdirectory(generic-tool)
|
||||
|
||||
#
|
||||
# test app
|
||||
#
|
||||
add_subdirectory(bin)
|
||||
|
||||
#
|
||||
# common to multiple tests
|
||||
#
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(
|
||||
hip
|
||||
HINTS
|
||||
${ROCM_PATH}
|
||||
ENV
|
||||
ROCM_PATH
|
||||
/opt/rocm
|
||||
PATHS
|
||||
${ROCM_PATH}
|
||||
ENV
|
||||
ROCM_PATH
|
||||
/opt/rocm)
|
||||
|
||||
if(hip_FOUND)
|
||||
add_executable(simple-hip)
|
||||
target_sources(simple-hip PRIVATE simple-hip.cpp)
|
||||
target_compile_options(simple-hip PRIVATE -W -Wall -Wextra -Werror)
|
||||
target_link_libraries(simple-hip PRIVATE Threads::Threads hip::host)
|
||||
set(PRELOAD_TESTS_DISABLED OFF)
|
||||
else()
|
||||
add_executable(simple-hip EXCLUDE_FROM_ALL)
|
||||
target_sources(simple-hip PRIVATE simple-hip.cpp)
|
||||
target_link_libraries(simple-hip PRIVATE Threads::Threads)
|
||||
set(PRELOAD_TESTS_DISABLED ON)
|
||||
endif()
|
||||
|
||||
#
|
||||
# INSTALL
|
||||
#
|
||||
set(TEST_DESTDIR "${CMAKE_BINARY_DIR}/tests/install")
|
||||
set(simple-hip-install-env "DESTDIR=${TEST_DESTDIR}")
|
||||
|
||||
add_test(
|
||||
NAME test-simple-hip-install
|
||||
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target install --parallel 4
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
set_tests_properties(
|
||||
test-simple-hip-install
|
||||
PROPERTIES TIMEOUT
|
||||
120
|
||||
LABELS
|
||||
"integration-test"
|
||||
ENVIRONMENT
|
||||
"${simple-hip-install-env}"
|
||||
DISABLED
|
||||
${PRELOAD_TESTS_DISABLED}
|
||||
FIXTURES_SETUP
|
||||
"simple-hip-install")
|
||||
|
||||
#
|
||||
# NORMAL (no profiling library)
|
||||
#
|
||||
string(REPLACE "//" "/" TEST_INSTALL_PREFIX "${TEST_DESTDIR}/${CMAKE_INSTALL_PREFIX}")
|
||||
set(simple-hip-normal-env
|
||||
"LD_LIBRARY_PATH=${TEST_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}:${ROCM_PATH}/${CMAKE_INSTALL_LIBDIR}"
|
||||
)
|
||||
|
||||
add_test(NAME test-simple-hip-normal COMMAND $<TARGET_FILE:simple-hip>)
|
||||
|
||||
set_tests_properties(
|
||||
test-simple-hip-normal
|
||||
PROPERTIES TIMEOUT
|
||||
120
|
||||
LABELS
|
||||
"integration-test"
|
||||
ENVIRONMENT
|
||||
"${simple-hip-normal-env}"
|
||||
DEPENDS
|
||||
test-simple-hip-install
|
||||
DISABLED
|
||||
${PRELOAD_TESTS_DISABLED}
|
||||
FIXTURES_SETUP
|
||||
"simple-hip-works"
|
||||
FIXTURES_REQUIRED
|
||||
"simple-hip-install")
|
||||
|
||||
#
|
||||
# PRELOAD
|
||||
#
|
||||
set(simple-hip-preload-env ${simple-hip-normal-env}
|
||||
"LD_PRELOAD=$<TARGET_FILE:generic-tool::generic-tool>")
|
||||
|
||||
add_test(NAME test-simple-hip-preload COMMAND $<TARGET_FILE:simple-hip>)
|
||||
|
||||
set_tests_properties(
|
||||
test-simple-hip-preload
|
||||
PROPERTIES TIMEOUT
|
||||
120
|
||||
LABELS
|
||||
"integration-test"
|
||||
ENVIRONMENT
|
||||
"${simple-hip-preload-env}"
|
||||
DEPENDS
|
||||
test-simple-hip-install
|
||||
DISABLED
|
||||
${PRELOAD_TESTS_DISABLED}
|
||||
FIXTURES_REQUIRED
|
||||
"simple-hip-install;simple-hip-works")
|
||||
@@ -0,0 +1,174 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2023 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 <hip/hip_runtime_api.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <random>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#define HIP_API_CALL(CALL) \
|
||||
if(hipError_t error_ = (CALL); error_ != hipSuccess) \
|
||||
{ \
|
||||
auto _hip_api_print_lk = auto_lock_t{ print_lock }; \
|
||||
fprintf(stderr, \
|
||||
"%s:%d :: HIP error : %s\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
hipGetErrorString(error_)); \
|
||||
fflush(stderr); \
|
||||
std::exit(EXIT_FAILURE); \
|
||||
}
|
||||
|
||||
static constexpr int64_t Bi = 1;
|
||||
static constexpr int64_t KiB = 1024 * Bi;
|
||||
static constexpr int64_t MiB = 1024 * KiB;
|
||||
|
||||
void
|
||||
run(size_t rank, size_t tid, const char* prefix);
|
||||
|
||||
namespace
|
||||
{
|
||||
using auto_lock_t = std::unique_lock<std::mutex>;
|
||||
auto print_lock = std::mutex{};
|
||||
size_t xdim = 4960 * 2;
|
||||
size_t ydim = 4960 * 2;
|
||||
size_t nthreads = 2;
|
||||
size_t nitr = 1;
|
||||
} // namespace
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
for(int i = 1; i < argc; ++i)
|
||||
{
|
||||
auto _arg = std::string{ argv[i] };
|
||||
if(_arg == "?" || _arg == "-h" || _arg == "--help")
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [M (%zu)] [N (%zu)] [NUM_THREADS (%zu)] [NUM_ITERATION "
|
||||
"(%zu)]\n",
|
||||
::basename(argv[0]),
|
||||
xdim,
|
||||
ydim,
|
||||
nthreads,
|
||||
nitr);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
if(argc > 1) xdim = atoll(argv[1]);
|
||||
if(argc > 2) ydim = atoll(argv[2]);
|
||||
if(argc > 3) nthreads = atoll(argv[3]);
|
||||
if(argc > 4) nitr = atoll(argv[4]);
|
||||
|
||||
int ndevice = 0;
|
||||
HIP_API_CALL(hipGetDeviceCount(&ndevice));
|
||||
|
||||
printf("[%s] Number of devices found: %i\n", ::basename(argv[0]), ndevice);
|
||||
printf("[%s] Number of matrix: %zu x %zu\n", ::basename(argv[0]), xdim, ydim);
|
||||
printf("[%s] Number of threads: %zu\n", ::basename(argv[0]), nthreads);
|
||||
printf("[%s] Number of iterations: %zu\n", ::basename(argv[0]), nitr);
|
||||
|
||||
for(size_t j = 0; j < nitr; ++j)
|
||||
{
|
||||
printf("\n[%s] Iteration #%zu\n\n", ::basename(argv[0]), j);
|
||||
|
||||
auto threads = std::vector<std::thread>{};
|
||||
threads.reserve(nthreads);
|
||||
|
||||
for(size_t i = 0; i < nthreads; ++i)
|
||||
threads.emplace_back(run, getpid(), i, ::basename(argv[0]));
|
||||
|
||||
for(auto& itr : threads)
|
||||
itr.join();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
auto
|
||||
allocate_memory(size_t M, size_t N, Tp val)
|
||||
{
|
||||
const auto sz = M * N;
|
||||
const auto nb = sz * sizeof(Tp);
|
||||
|
||||
Tp* ptr = new Tp[M * N];
|
||||
::memset(ptr, val, nb);
|
||||
|
||||
HIP_API_CALL(hipHostRegister(ptr, nb, hipHostRegisterDefault))
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
auto
|
||||
deallocate_memory(Tp* ptr)
|
||||
{
|
||||
HIP_API_CALL(hipHostUnregister(ptr))
|
||||
delete[] ptr;
|
||||
}
|
||||
|
||||
void
|
||||
run(size_t rank, size_t tid, const char* label)
|
||||
{
|
||||
const auto M = xdim;
|
||||
const auto N = ydim;
|
||||
|
||||
auto* inp = allocate_memory<int>(M, N, 0);
|
||||
auto* out = allocate_memory<int>(M, N, 1);
|
||||
|
||||
auto _engine =
|
||||
std::default_random_engine{ std::random_device{}() * (rank + 1) * (tid + 1) };
|
||||
std::uniform_int_distribution<int> _dist{ 0, 1000 };
|
||||
|
||||
for(size_t i = 0; i < (M * N); i++)
|
||||
inp[i] = _dist(_engine);
|
||||
|
||||
// lock during malloc to get more accurate memory info
|
||||
{
|
||||
auto_lock_t _lk{ print_lock };
|
||||
size_t free_gpu_mem = 0;
|
||||
size_t total_gpu_mem = 0;
|
||||
|
||||
HIP_API_CALL(hipMemGetInfo(&free_gpu_mem, &total_gpu_mem));
|
||||
free_gpu_mem /= MiB;
|
||||
total_gpu_mem /= MiB;
|
||||
|
||||
std::cout << "[" << label << "][" << rank << "][" << tid
|
||||
<< "] Available GPU memory (MiB): " << std::setw(6) << free_gpu_mem
|
||||
<< " / " << std::setw(6) << total_gpu_mem << std::endl;
|
||||
}
|
||||
|
||||
deallocate_memory(inp);
|
||||
deallocate_memory(out);
|
||||
}
|
||||
Criar uma nova questão referindo esta
Bloquear um utilizador