diff --git a/projects/rdc/CMakeLists.txt b/projects/rdc/CMakeLists.txt index 93a8b9a294..e11f7f1337 100755 --- a/projects/rdc/CMakeLists.txt +++ b/projects/rdc/CMakeLists.txt @@ -1,15 +1,15 @@ # Copyright (c) 2019 - present 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 @@ -107,7 +107,7 @@ set(PROTOB_CMD "protoc") foreach(file ${PROTOB_DEF_SRC_FILES}) execute_process(COMMAND - protoc --proto_path=${PROTOB_SRC_DIR} --cpp_out=${PROTOB_OUT_DIR} ${file} + protoc --proto_path=${PROTOB_SRC_DIR} --cpp_out=${PROTOB_OUT_DIR} ${file} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE PROTOB_RESULT OUTPUT_VARIABLE PROTOB_OUT_VAR) @@ -135,16 +135,20 @@ set(SERVER_CTRL_COMPONENT "server_ctrl") set(SERVER_BIN_COMPONENT "server_bin") set(CLIENT_LIB_COMPONENT "client_lib") set(CLIENT_HEADER_COMPONENT "client_header") +set(RDC_LIB_COMPONENT "rdc_lib") set(GTEST_COMPONENT "rdc_gtest") set(EXAMPLE_COMPONENT "rdc_example") add_subdirectory("server") add_subdirectory("client") +add_subdirectory("rdc_libs") +add_subdirectory("example") # Turn on cmake "component install" set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) set(CPACK_COMPONENTS_ALL ${SERVER_CTRL_COMPONENT} - ${SERVER_BIN_COMPONENT} ${CLIENT_LIB_COMPONENT} ${CLIENT_HEADER_COMPONENT}) + ${SERVER_BIN_COMPONENT} ${CLIENT_LIB_COMPONENT} ${CLIENT_HEADER_COMPONENT} + ${RDC_LIB_COMPONENT}) configure_file( diff --git a/projects/rdc/example/CMakeLists.txt b/projects/rdc/example/CMakeLists.txt new file mode 100755 index 0000000000..0f2445aa20 --- /dev/null +++ b/projects/rdc/example/CMakeLists.txt @@ -0,0 +1,82 @@ +# Copyright (c) 2020 - present 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. + +# +# Minimum version of cmake required +# +cmake_minimum_required(VERSION 3.5.0) + +message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") +message(" Cmake Example ") +message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") + +message("") +message("Build Configuration:") +message("-----------BuildType: " ${CMAKE_BUILD_TYPE}) +message("------------Compiler: " ${CMAKE_CXX_COMPILER}) +message("-------------Version: " ${CMAKE_CXX_COMPILER_VERSION}) +message("--------Proj Src Dir: " ${PROJECT_SOURCE_DIR}) +message("--------Proj Bld Dir: " ${PROJECT_BINARY_DIR}) +message("--------Proj Lib Dir: " ${PROJECT_BINARY_DIR}/lib) +message("--------Proj Exe Dir: " ${PROJECT_BINARY_DIR}/bin) +message("--------RSMI Lib Dir: " ${RSMI_LIB_DIR}) +message("--------RSMI Inc Dir: " ${RSMI_INC_DIR}) +message("") + +set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} + CACHE STRING "Location of RDC example library source code.") +# set(CMAKE_INSTALL_PREFIX "/" +# CACHE STRING "Default installation directory.") +# set(CPACK_PACKAGING_INSTALL_PREFIX "/" +# CACHE STRING "Default packaging prefix.") +# + +## Compiler flags +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -m64") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse -msse2 -std=c++11 ") +# Use this instead of above for 32 bit +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") + +if ("${CMAKE_BUILD_TYPE}" STREQUAL Release) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") +else () + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -O0 -DDEBUG") +endif () + +set(SRC_DIR "${PROJECT_SOURCE_DIR}/example") +set(INC_DIR "${PROJECT_SOURCE_DIR}/include") +set(LIB_BOOSTRAP_DIR "${PROJECT_BINARY_DIR}/rdc_libs") + +include_directories(${INC_DIR}) + +set(JOBSTATS_EXAMPLE_SRC_LIST "${SRC_DIR}/job_stats_example.cc") +message("JOBSTATS_EXAMPLE_SRC_LIST=${JOBSTATS_EXAMPLE_SRC_LIST}") +set(JOBSTATS_EXAMPLE_EXE "jobstats") + +link_directories(${LIB_BOOSTRAP_DIR}) + +add_executable(${JOBSTATS_EXAMPLE_EXE} "${JOBSTATS_EXAMPLE_SRC_LIST}") + +target_link_libraries(${JOBSTATS_EXAMPLE_EXE} pthread dl rdc_bootstrap) + + +message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") +message(" Finished Cmake Example ") +message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") diff --git a/projects/rdc/example/job_stats_example.cc b/projects/rdc/example/job_stats_example.cc new file mode 100644 index 0000000000..8aab3f039f --- /dev/null +++ b/projects/rdc/example/job_stats_example.cc @@ -0,0 +1,190 @@ +/* +Copyright (c) 2020 - present 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 +#include +#include "rdc/rdc.h" + +int main(int, char **) { + rdc_status_t result; + rdc_handle_t rdc_handle; + bool standalone = false; + char hostIpAddress[] = {"127.0.0.1:50051"}; + char group_name[] = {"group1"}; + char job_id[] = {"123"}; + + + // Select the embedded mode and standalone mode dynamically. + std::cout << "Start rdci in: \n"; + std::cout << "0 - Embedded mode \n"; + std::cout << "1 - Standalone mode \n"; + while (!(std::cin >> standalone)) { + std::cout << "Invalid input.\n"; + std::cin.clear(); + std::cin.ignore(); + } + std::cout << std::endl; + std::cout << (standalone? + "Standalone mode selected.\n":"Embedded mode selected.\n"); + + // Init the rdc + result = rdc_init(0); + + if (result != RDC_ST_OK) { + std::cout << "Error initializing RDC. Return: " << + rdc_status_string(result) << std::endl; + goto cleanup; + } else { + std::cout << "RDC Initialized.\n"; + } + + if (standalone) { // standalone + result = rdc_connect(hostIpAddress, &rdc_handle); + if ( result != RDC_ST_OK ) { + std::cout << "Error connecting to remote rdcd. Return: " + << rdc_status_string(result) << std::endl; + goto cleanup; + } + } else { // embedded + result = rdc_start_embedded(RDC_OPERATION_MODE_AUTO, &rdc_handle); + if (result != RDC_ST_OK) { + std::cout << "Error starting embedded RDC engine. Return: " + << rdc_status_string(result) << std::endl; + goto cleanup; + } + } + + // Now we can use the same API for both standalone and embedded + // (1) create group and add GPUs + rdc_gpu_group_t group_id; + result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_EMPTY, + group_name, &group_id); + if (result != RDC_ST_OK) { + std::cout << "Error creating group. Return: " + << rdc_status_string(result); + goto cleanup; + } + + result = rdc_group_gpu_add(rdc_handle, group_id, 0); // Add GPU 0 + if (result != RDC_ST_OK) { + std::cout << "Error adding group. Return: " + << rdc_status_string(result); + goto cleanup; + } + + // (2) start the recording. Set the sample frequency to once per second, the + // max keep age to one hour and the maximum number of samples to + // keep to unlimited. + result = rdc_watch_job_fields(rdc_handle, group_id, 1000000, 3600, 0); + if (result != RDC_ST_OK) { + std::cout << "Error watch job fileds. Return: " + << rdc_status_string(result); + goto cleanup; + } + + // (3) Start a Slurm job on this group + result = rdc_job_start_stats(rdc_handle, group_id, job_id); + if (result != RDC_ST_OK) { + std::cout << "Error start job stats. Return: " + << rdc_status_string(result); + goto cleanup; + } + + // For standalone mode, the daemon will update and cache the samples + // In manual mode, we must call rdc_update_all_fields periodically to + // take samples. + if (!standalone) { // embedded manual mode + for (int i=5; i > 0 ; i--) { // As an example, we will take 5 samples + result = rdc_update_all_fields(rdc_handle, 0); + if (result != RDC_ST_OK) { + std::cout << "Error update all fields. Return: " + << rdc_status_string(result); + goto cleanup; + } + usleep(1000000); + } + } else { // standalone mode, do nothing + usleep(5000000); // sleep 5 seconds before fetch the stats + } + + // (4) stop the Slurm job, which will stop the watch + // We do not have to stop the job to get stats. The rdc_job_get_stats can be + // called at any time before stop + result = rdc_job_stop_stats(rdc_handle, job_id); + if (result != RDC_ST_OK) { + std::cout << "Error stop job stats. Return: " + << rdc_status_string(result); + goto cleanup; + } + + // (5) Get the stats + rdc_job_info_t job_info; + result = rdc_job_get_stats(rdc_handle, job_id, &job_info); + + if (result == RDC_ST_OK) { + std::cout << "|------- Execution Stats ----------+" + <<"------------------------------------\n"; + std::cout << "| Start Time * | " + << job_info.summary.start_time<< "\n"; + std::cout << "| End Time * | " + << job_info.summary.end_time <<"\n"; + std::cout << "| Total Execution Time (sec) * | " + << (job_info.summary.end_time-job_info.summary.start_time) + << "\n"; + std::cout << "+------- Performance Stats --------+" + << "------------------------------------\n"; + std::cout << "| Energy Consumed (Joules) | " + << job_info.summary.energy_consumed << "\n"; + std::cout << "| Power Usage (Watts) | " + << "Max: " << job_info.summary.power_usage.max_value + << " Min: "<< job_info.summary.power_usage.min_value + << " Avg: "<< job_info.summary.power_usage.average << "\n"; + std::cout << "| SM Clock (MHz) | " + << "Max: " < + +/** \file rdc_lib.h + * Main header file for the ROCm RDC library. + * All required function, structure, enum, etc. definitions should be defined + * in this file. + * + * @brief The rocm_rdc library api is new, and therefore subject to change + * either at the ABI or API level. Instead of marking every function prototype as "unstable", + * we areinstead saying the API is unstable (i.e., changes are possible) while the + * major version remains 0. This means that if the API/ABI changes, we will + * not increment the major version to 1. Once the ABI stabilizes, we will + * increment the major version to 1, and thereafter increment it on all ABI + * breaks. + */ + +/** + * @brief Error codes retured by rocm_rdc_lib functions + */ +typedef enum { + RDC_ST_OK = 0, + RDC_ST_NOT_SUPPORTED, //!< Not supported feature + RDC_ST_MSI_ERROR, //!< The MSI library error + RDC_ST_FAIL_LOAD_MODULE, //!< Fail to load the library + RDC_ST_INVALID_HANDLER //!< Fail to load the library +} rdc_status_t; + +/** + * @brief rdc operation mode + * rdc can run in auto mode where background threads will collect metrics. + * When run in manual mode, the user needs to periodically call rdc_update_all_fields + * for data collection. + */ +typedef enum { + RDC_OPERATION_MODE_AUTO = 0, + RDC_OPERATION_MODE_MANUAL +} rdc_operation_mode_t; + +/** + * @brief type of GPU group + */ +typedef enum { + RDC_GROUP_DEFAULT = 0, //!< All GPUs on the Node + RDC_GROUP_EMPTY //!< Empty group +} rdc_group_type_t; + +/** + * @brief the type stored in the filed value + */ +typedef enum { + INTEGER = 0, + DOUBLE, + STRING, + BLOB +} rdc_field_type_t; + + +#define GPU_ID_INVALID -1 +#define RDC_GROUP_ALL_GPUS -1000 +#define RDC_JOB_STATS_FIELDS -1000 + +/** + * @brief The max rdc field string length + */ +#define RDC_MAX_STR_LENGTH 256 + +/** + * @brief The max entities in a group + */ +#define RDC_GROUP_MAX_ENTITIES 64 + +/** + * @brief The max fields in a field group + */ +#define RDC_MAX_FIELD_IDS_PER_FIELD_GROUP 128 + + +/** + * @biref The fields + */ + +/** + * Memory usage of the GPU instance + */ +#define RDC_FI_GPU_MEMORY_USAGE 525 + +/** + * Total memory of the GPU instance + */ +#define RDC_FI_GPU_MEMORY_TOTAL 580 + +/** + * Power usage for the device + */ +#define RDC_FI_POWER_USAGE 155 + +/** + * SM clock for the GPU + */ +#define RDC_FI_GPU_SM_CLOCK 100 + +/** + * GPU Utilization + */ +#define RDC_FI_GPU_UTIL 203 + +/** + * Current temperature for the device + */ +#define RDC_FI_GPU_TEMP 150 + +/** + * @brief handlers used in various rdc calls + */ +typedef void *rdc_handle_t; +typedef uint32_t rdc_gpu_group_t; +typedef uint32_t rdc_field_grp_t; + +/** + * @brief The structure to store summary of data + */ +typedef struct { + uint64_t max_value; + uint64_t min_value; + uint64_t average; +} rdc_stats_summary_t; + +/** + * @brief The structure to hold the GPU usage information + */ +typedef struct { + uint32_t gpu_id; //!< GPU_ID_INVALID for summary information + uint64_t start_time; //!< The time to start the watching + uint64_t end_time; //!< The time to stop the watching + + uint64_t energy_consumed; + rdc_stats_summary_t power_usage; + rdc_stats_summary_t gpu_clock; + rdc_stats_summary_t gpu_utilization; + + uint64_t max_gpu_memory_used; + rdc_stats_summary_t memory_utilization; +} rdc_gpu_usage_info_t; + +/** + * @brief The structure to hold the job stats + */ +typedef struct { + uint32_t num_gpus; + rdc_gpu_usage_info_t summary; + rdc_gpu_usage_info_t gpus[16]; +} rdc_job_info_t; + +/** + * @brief The structure to store the field value + */ +typedef struct { + uint16_t field_id; //!< The field id of the value + int status; //!< RDC_ST_OK or error status + uint64_t ts; //!< Timestamp in usec since 1970 + rdc_field_type_t type; //!< The field type + union { + int64_t l_int; + double dbl; + char str[RDC_MAX_STR_LENGTH]; + } value; +} rdc_field_value; + +/** + * @brief The structure to store the field group info + */ +typedef struct { + uint32_t count; //!< count of fields in the group + char group_name[RDC_MAX_STR_LENGTH]; //!< field group name + /** + * The list of fields in the group + */ + uint32_t field_ids[RDC_MAX_FIELD_IDS_PER_FIELD_GROUP]; +} rdc_field_group_info_t; + +/** + * @brief The structure to store the job info + */ +typedef struct { + char job_id[RDC_MAX_STR_LENGTH]; //!< job id + rdc_gpu_group_t group_id; //!< group name + uint64_t start_time; //!< job start time + uint64_t stop_time; //!< job stop time +} rdc_job_group_info_t; + + +/** + * @brief Initialize ROCm RDC. + * + * @details When called, this initializes internal data structures, + * including those corresponding to sources of information that RDC provides. + * This must be called before rdc_start_embedded() or rdc_connect() + * + * @param[in] init_flags init_flags Bit flags that tell RDC how to initialize. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_init(uint64_t init_flags); + +/** + * @brief Shutdown ROCm RDC. + * + * @details Do any necessary clean up. + */ +rdc_status_t rdc_shutdown(); + +/** + * @brief Start embedded RDC agent within this process. + * + * @details The RDC is loaded as library so that it does not require rdcd + * daemon. In this mode, the user has to periodically call rdc_update_all_fields() + * when op_mode is RDC_OPERATION_MODE_MANUAL, which tells RDC to collect + * the stats. This function is not thread safe. + * + * @param[in] op_mode Operation modes. When RDC_OPERATION_MODE_AUTO, RDC schedules + * background task to collect the stats. When RDC_OPERATION_MODE_MANUAL, the user + * needs to call rdc_update_all_fields() periodically. + * + * @param[inout] p_rdc_handle Caller provided pointer to rdc_handle_t. Upon + * successful call, the value will contain the handler for following API calls. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_start_embedded(rdc_operation_mode_t op_mode, + rdc_handle_t* p_rdc_handle); + +/** + * @brief Stop embedded RDC agent. + * + * @details Stop the embedded RDC agent, and p_rdc_handle becomes invalid after + * this call. This function is not thread safe. + * + * @param[in] p_rdc_handle The RDC handler that come from rdc_start_embedded(). + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_stop_embedded(rdc_handle_t p_rdc_handle); + +/** + * @brief Connect to rdcd daemon + * + * @details This method is used to connect to a remote stand-alone rdcd daemon. + * This function is not thread safe. + * + * @param[in] ipAndPort The IP and port of the remote rdcd. The ipAndPort can be + * specified in this x.x.x.x:yyyy format, where x.x.x.x is the IP address and + * yyyy is the port. + * + * @param[inout] p_rdc_handle Caller provided pointer to rdc_handle_t. Upon + * successful call, the value will contain the handler for following API calls. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_connect(const char *ipAndPort, rdc_handle_t* p_rdc_handle); + +/** + * @brief Disconnect from rdcd daemon. + * + * @details Disconnect from rdcd daemon, and p_rdc_handle becomes invalid after + * this call. This function is not thread safe. + * + * @param[in] p_rdc_handle The RDC handler that come from rdc_connect(). + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_disconnect(rdc_handle_t p_rdc_handle); + +/** + * @brief Create a group contains multiple GPUs + * + * @details This method can create a group contains multiple GPUs. Instead of + * executing an operation separately for each GPU, the RDC group enables + * the user to execute same operation on all the GPUs present in the group as a + * single API call. + * + * @param[in] p_rdc_handle The RDC handler. + * + * @param[in] type The type of the group. RDC_GROUP_DEFAULT includes all the GPUs + * on the node, and RDC_GROUP_EMPTY creates an empty group. + * + * @param[in] group_name The group name specified as NULL terminated C String + * + * @param[inout] p_rdc_group_id Caller provided pointer to rdc_gpu_group_t. Upon + * successful call, the value will contain the group id for following group API calls. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_group_gpu_create(rdc_handle_t p_rdc_handle, + rdc_group_type_t type, const char* group_name, + rdc_gpu_group_t* p_rdc_group_id); + +/** + * @brief Add a GPU to the group + * + * @details This method can add a GPU to the group + * + * @param[in] p_rdc_handle The The RDC handler. + * + * @param[in] group_id The group id to which the GPU will be added. + * + * @param[in] gpu_index The GPU index to be added to the group. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_group_gpu_add(rdc_handle_t p_rdc_handle, + rdc_gpu_group_t group_id, uint32_t gpu_index); + +/** + * @brief Request the RDC to watch the job stats + * + * @details The summary job stats can be retrieved using rdc_job_get_stats() + * In RDC_OPERATION_MODE_MANUAL, user must call rdc_update_all_fields(1) + * at least once, before call rdc_job_get_stats() + * + * @param[in] p_rdc_handle The The RDC handler. + * + * @param[in] group_id The group of GPUs to be watched. + * + * @param[in] update_freq How often to update this field in usec. + * + * @param[in] max_keep_age How long to keep data for this field in seconds. + * + * @param[in] max_keep_samples Maximum number of samples to keep. 0=no limit. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_watch_job_fields(rdc_handle_t p_rdc_handle, + rdc_gpu_group_t group_id, uint64_t update_freq, + double max_keep_age, uint32_t max_keep_samples); + +/** + * @brief Request RDC a job to be started + * + * @details This should be execute as part of job prologue + * + * @param[in] p_rdc_handle The The RDC handler. + * + * @param[in] job_id The name of the job. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_job_start_stats(rdc_handle_t p_rdc_handle, + rdc_gpu_group_t group_id, char job_id[64]); + +/** + * @brief Get the stats of the job using the job id. + * + * @details The stats can be retrieved at any point when the job is in process. + * + * @param[in] p_rdc_handle The The RDC handler. + * + * @param[in] job_id The name of the job. + * + * @param[inout] p_job_info Caller provided pointer to rdc_job_info_t. Upon + * successful call, the value will contain the stats of the job. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_job_get_stats(rdc_handle_t p_rdc_handle, char job_id[64], + rdc_job_info_t* p_job_info); + +/** + * @brief Request RDC to stop watching the stats of the job + * + * @details This should be execute as part of job epilogue. The job Id remains + * available to view the stats at any point. You must call rdc_watch_job_fields() + * before this call. + * + * @param[in] p_rdc_handle The The RDC handler. + * + * @param[in] job_id The name of the job. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_job_stop_stats(rdc_handle_t p_rdc_handle, + char job_id[64]); + +/** + * @brief Request RDC to update all fields to be watched. + * + * @details In RDC_OPERATION_MODE_MANUAL, the user must call this method periodically. + * + * @param[in] p_rdc_handle The The RDC handler. + * + * @param[in] wait_for_update Whether or not to wait for the update loop to + * complete before returning to the caller 1=wait. 0=do not wait. + * + * @retval ::RDC_ST_OK is returned upon successful call. + */ +rdc_status_t rdc_update_all_fields(rdc_handle_t p_rdc_handle, + uint32_t wait_for_update); + +/** + * @brief Get a description of a provided RDC error status + * + * @details return the string in human readable format. + * + * @param[in] status The The RDC status. + * + * @retval The string to describe the RDC status. + */ +const char* rdc_status_string(rdc_status_t status); + +#endif // RDC_RDC_H_ diff --git a/projects/rdc/include/rdc_lib/RdcHandler.h b/projects/rdc/include/rdc_lib/RdcHandler.h new file mode 100644 index 0000000000..73a7d90d89 --- /dev/null +++ b/projects/rdc/include/rdc_lib/RdcHandler.h @@ -0,0 +1,55 @@ +/* +Copyright (c) 2020 - present 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. +*/ +#ifndef RDC_LIB_RDCHANDLER_H_ +#define RDC_LIB_RDCHANDLER_H_ + +#include "rdc_lib/rdc_common.h" +#include "rdc/rdc.h" + +namespace amd { +namespace rdc { + +// Interface class +class RdcHandler { + public: + virtual rdc_status_t rdc_group_gpu_create(rdc_group_type_t type, + const char* group_name, rdc_gpu_group_t* p_rdc_group_id) = 0; + virtual rdc_status_t rdc_group_gpu_add(rdc_gpu_group_t groupId, + uint32_t gpu_index) = 0; + + virtual rdc_status_t rdc_job_start_stats(rdc_gpu_group_t groupId, + char job_id[64]) = 0; + virtual rdc_status_t rdc_watch_job_fields(rdc_gpu_group_t groupId, + uint64_t update_freq, double max_keep_age, + uint32_t max_keep_samples) = 0; + virtual rdc_status_t rdc_job_get_stats(char jobId[64], + rdc_job_info_t* p_job_info)= 0; + virtual rdc_status_t rdc_job_stop_stats(char job_id[64]) = 0; + + virtual rdc_status_t rdc_update_all_fields(uint32_t wait_for_update) = 0; + virtual ~RdcHandler(){} +}; + +} // namespace rdc +} // namespace amd + +#endif // RDC_LIB_RDCHANDLER_H_ diff --git a/projects/rdc/include/rdc_lib/impl/RdcEmbeddedHandler.h b/projects/rdc/include/rdc_lib/impl/RdcEmbeddedHandler.h new file mode 100644 index 0000000000..9abf0f4106 --- /dev/null +++ b/projects/rdc/include/rdc_lib/impl/RdcEmbeddedHandler.h @@ -0,0 +1,62 @@ +/* +Copyright (c) 2020 - present 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. +*/ +#ifndef RDC_LIB_IMPL_RDCEMBEDDEDHANDLER_H_ +#define RDC_LIB_IMPL_RDCEMBEDDEDHANDLER_H_ + +#include "rdc_lib/RdcHandler.h" + + +namespace amd { +namespace rdc { + +class RdcEmbeddedHandler: public RdcHandler +{ + public: + rdc_status_t rdc_group_gpu_create(rdc_group_type_t type, + const char* group_name, + rdc_gpu_group_t* p_rdc_group_id) override; + rdc_status_t rdc_group_gpu_add(rdc_gpu_group_t groupId, + uint32_t gpu_index) override; + + rdc_status_t rdc_job_start_stats(rdc_gpu_group_t groupId, + char job_id[64]) override; + + rdc_status_t rdc_watch_job_fields(rdc_gpu_group_t groupId, + uint64_t update_freq, double max_keep_age, + uint32_t max_keep_samples) override; + rdc_status_t rdc_job_get_stats(char jobId[64], + rdc_job_info_t* p_job_info) override; + rdc_status_t rdc_job_stop_stats(char job_id[64]) override; + + rdc_status_t rdc_update_all_fields(uint32_t wait_for_update) override; + + explicit RdcEmbeddedHandler(rdc_operation_mode_t op_mode); +}; + +} // namespace rdc +} // namespace amd + +extern "C" { + amd::rdc::RdcHandler *make_handler(rdc_operation_mode_t op_mode); +} + +#endif // RDC_LIB_IMPL_RDCEMBEDDEDHANDLER_H_ diff --git a/projects/rdc/include/rdc_lib/rdc_common.h b/projects/rdc/include/rdc_lib/rdc_common.h new file mode 100644 index 0000000000..9960e536da --- /dev/null +++ b/projects/rdc/include/rdc_lib/rdc_common.h @@ -0,0 +1,35 @@ +/* +Copyright (c) 2020 - present 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. +*/ + +#ifndef RDC_LIB_RDC_COMMON_H_ +#define RDC_LIB_RDC_COMMON_H_ +#include + + +#ifdef DEBUG +#define LOG_DEBUG(message) std::cout << message << std::endl +#else +#define LOG_DEBUG(message) +#endif + + +#endif // RDC_LIB_RDC_COMMON_H_ diff --git a/projects/rdc/rdc_libs/CMakeLists.txt b/projects/rdc/rdc_libs/CMakeLists.txt new file mode 100755 index 0000000000..cf23fb8068 --- /dev/null +++ b/projects/rdc/rdc_libs/CMakeLists.txt @@ -0,0 +1,183 @@ +# Copyright (c) 2020 - present 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. + +# +# Minimum version of cmake required +# +cmake_minimum_required(VERSION 3.5.0) + +message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") +message(" Cmake RDC Lib ") +message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") + +## Compiler flags +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -m64") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse -msse2 -std=c++11 ") +# Use this instead of above for 32 bit +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") + +if ("${CMAKE_BUILD_TYPE}" STREQUAL Release) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") +else () + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -O0 -DDEBUG") +endif () + + +# Required Defines first: + +message("") +message("Build Configuration:") +message("-----------BuildType: " ${CMAKE_BUILD_TYPE}) +message("------------Compiler: " ${CMAKE_CXX_COMPILER}) +message("-------------Version: " ${CMAKE_CXX_COMPILER_VERSION}) +message("--------Proj Src Dir: " ${PROJECT_SOURCE_DIR}) +message("--------Proj Bld Dir: " ${PROJECT_BINARY_DIR}) +message("--------Proj Lib Dir: " ${PROJECT_BINARY_DIR}/lib) +message("--------Proj Exe Dir: " ${PROJECT_BINARY_DIR}/bin) +message("--------RSMI Lib Dir: " ${RSMI_LIB_DIR}) +message("--------RSMI Inc Dir: " ${RSMI_INC_DIR}) +message("") + +## Set default module path if not already set +if(NOT DEFINED CMAKE_MODULE_PATH) + set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/") +endif() + + +set(SRC_DIR "${PROJECT_SOURCE_DIR}/rdc_libs") +set(RDC_LIB_INC_DIR "${PROJECT_SOURCE_DIR}/include") + + +################# Determine the library version ######################### +## Setup the SO version based on git tags. +set(SO_VERSION_GIT_TAG_PREFIX "rdc_so_ver") + +# provide git to utilities +find_program (GIT NAMES git) + +# Debian package specific variables +# Set a default value for the package version +get_version_from_tag("1.0.0.0" ${SO_VERSION_GIT_TAG_PREFIX} GIT) + +# VERSION_* variables should be set by get_version_from_tag +set(SO_VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}") +message("SOVERSION: ${SO_VERSION_STRING}") + +## Define default variable and variables for the optional build target +set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} + CACHE STRING "Location of RDC library source code.") +set(CMAKE_INSTALL_PREFIX ${RDC_LIB_ROOT_PATH} + CACHE STRING "Default installation directory.") +set(CPACK_PACKAGING_INSTALL_PREFIX ${RDC_LIB_ROOT_PATH} + CACHE STRING "Default packaging prefix.") +set(CPACK_GENERATOR "DEB;RPM" CACHE STRING "Default packaging generators.") + +if (NOT DEFINED CPACK_PACKAGE_VENDOR) + set(CPACK_PACKAGE_VENDOR "AMD") +endif() + +if (NOT DEFINED CPACK_PACKAGE_CONTACT) + set(CPACK_PACKAGE_CONTACT "Advanced Micro Devices Inc.") +endif() + +if (NOT DEFINED CPACK_PACKAGE_DESCRIPTION_SUMMARY) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "Radeon Data Center Tools") +endif() + +if (NOT RDC_PACKAGE) + set(RDC_PACKAGE RDC_lib64) +endif() + +set(CPACK_PACKAGE_FILE_NAME "${RDC_PACKAGE}-${PKG_VERSION_STR}") +## Verbose output. +set(CMAKE_VERBOSE_MAKEFILE on) + +# librdc_bootstrap.so set up +set(BOOTSTRAP_LIB "rdc_bootstrap") +set(BOOTSTRAP_LIB_COMPONENT "lib${BOOTSTRAP_LIB}") +set(BOOTSTRAP_LIB_SRC_LIST "${SRC_DIR}/bootstrap/src/RdcBootStrap.cc") +set(BOOTSTRAP_LIB_INC_LIST "${RDC_LIB_INC_DIR}/rdc/rdc.h") +set(BOOTSTRAP_LIB_INC_LIST ${BOOTSTRAP_LIB_INC_LIST} "${RDC_LIB_INC_DIR}/rdc_lib/rdc_common.h") +set(BOOTSTRAP_LIB_INC_LIST ${BOOTSTRAP_LIB_INC_LIST} "${RDC_LIB_INC_DIR}/rdc_lib/RdcHandler.h") + +message("BOOTSTRAP_LIB_INC_LIST=${BOOTSTRAP_LIB_INC_LIST}") + +add_library(${BOOTSTRAP_LIB} SHARED ${BOOTSTRAP_LIB_SRC_LIST} ${BOOTSTRAP_LIB_INC_LIST}) +target_link_libraries(${BOOTSTRAP_LIB} pthread dl) +target_include_directories(${BOOTSTRAP_LIB} PRIVATE + "${PROJECT_SOURCE_DIR}" + "${PROJECT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_SOURCE_DIR}/include") + +# TODO: set the properties for the library once we have one +## Set the VERSION and SOVERSION values +set_property(TARGET ${BOOTSTRAP_LIB} PROPERTY + SOVERSION "${VERSION_MAJOR}") +set_property(TARGET ${BOOTSTRAP_LIB} PROPERTY + VERSION "${SO_VERSION_STRING}") + +# librdc.so set up +set(RDC_LIB "rdc") +set(RDC_LIB_COMPONENT "lib${RDC_LIB}") +set(RDC_LIB_SRC_LIST "${SRC_DIR}/rdc/src/RdcEmbeddedHandler.cc") +set(RDC_LIB_INC_LIST "${RDC_LIB_INC_DIR}/rdc_lib/impl/RdcEmbeddedHandler.h") +message("RDC_LIB_INC_LIST=${RDC_LIB_INC_LIST}") + +link_directories(${RSMI_LIB_DIR}) +add_library(${RDC_LIB} SHARED ${RDC_LIB_SRC_LIST} ${RDC_LIB_INC_LIST}) +target_link_libraries(${RDC_LIB} pthread rocm_smi64) +target_include_directories(${RDC_LIB} PRIVATE + "${PROJECT_SOURCE_DIR}" + "${PROJECT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${RSMI_INC_DIR}") + +# TODO: set the properties for the library once we have one +## Set the VERSION and SOVERSION values +set_property(TARGET ${RDC_LIB} PROPERTY + SOVERSION "${VERSION_MAJOR}") +set_property(TARGET ${RDC_LIB} PROPERTY + VERSION "${SO_VERSION_STRING}") + + +## If the library is a release, strip the target library +if ("${CMAKE_BUILD_TYPE}" STREQUAL Release) + add_custom_command( + TARGET ${BOOTSTRAP_LIB} + POST_BUILD COMMAND ${CMAKE_STRIP} lib${BOOTSTRAP_LIB}.so) + add_custom_command( + TARGET ${RDC_LIB} + POST_BUILD COMMAND ${CMAKE_STRIP} lib${RDC_LIB}.so) +endif () + +## Add the install directives for the runtime library. +install(TARGETS ${BOOTSTRAP_LIB} ${RDC_LIB} + LIBRARY DESTINATION ${RDC_LIB_ROOT_PATH}${RDC}/lib + COMPONENT ${RDC_LIB_COMPONENT}) +install(FILES ${SOURCE_DIR}/include/rdc/rdc.h + DESTINATION ${RDC_LIB_ROOT_PATH}${RDC}/include/rdc + COMPONENT ${LIB_HEADER_COMPONENT}) + +message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") +message(" Finished Cmake RDC Lib ") +message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") + + diff --git a/projects/rdc/rdc_libs/bootstrap/src/RdcBootStrap.cc b/projects/rdc/rdc_libs/bootstrap/src/RdcBootStrap.cc new file mode 100644 index 0000000000..6f0afa3025 --- /dev/null +++ b/projects/rdc/rdc_libs/bootstrap/src/RdcBootStrap.cc @@ -0,0 +1,208 @@ +/* +Copyright (c) 2020 - present 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 +#include "rdc/rdc.h" +#include "rdc_lib/RdcHandler.h" +#include "rdc_lib/rdc_common.h" + +static void* libHandler = nullptr; + +rdc_status_t rdc_init(uint64_t) { + return RDC_ST_OK; +} + +rdc_status_t rdc_shutdown() { + if (libHandler) { + dlclose(libHandler); + libHandler = nullptr; + } + return RDC_ST_OK; +} + +rdc_status_t rdc_connect(const char* ipAddress, + rdc_handle_t* p_rdc_handle ) { + amd::rdc::RdcHandler* (*func_make_handler)(const char*); + + if (!ipAddress || !p_rdc_handle) { + return RDC_ST_FAIL_LOAD_MODULE; + } + + if (!libHandler) { + libHandler = dlopen("librdc_client.so", RTLD_LAZY); + } + + if (!libHandler) { + return RDC_ST_FAIL_LOAD_MODULE; + } + + *reinterpret_cast(&func_make_handler) = + dlsym(libHandler, "make_handler"); + if (!func_make_handler) { + return RDC_ST_FAIL_LOAD_MODULE; + } + + *p_rdc_handle = static_cast + (func_make_handler(ipAddress)); + return RDC_ST_OK; +} + +rdc_status_t rdc_disconnect(rdc_handle_t p_rdc_handle) { + if (!p_rdc_handle) { + return RDC_ST_INVALID_HANDLER; + } + delete static_cast(p_rdc_handle); + p_rdc_handle = nullptr; + return RDC_ST_OK; +} + +rdc_status_t rdc_start_embedded(rdc_operation_mode_t op_mode, + rdc_handle_t* p_rdc_handle ) { + amd::rdc::RdcHandler* (*func_make_handler)(rdc_operation_mode_t); + char *error; + if (!p_rdc_handle) { + return RDC_ST_FAIL_LOAD_MODULE; + } + + dlerror(); + + if (!libHandler) { + libHandler = dlopen("librdc.so", RTLD_LAZY); + } + + if (!libHandler) { + error = dlerror(); + LOG_DEBUG("Fail to open librdc.so: " << error); + return RDC_ST_FAIL_LOAD_MODULE; + } + + *reinterpret_cast(&func_make_handler) = + dlsym(libHandler, "make_handler"); + if (!func_make_handler) { + error = dlerror(); + LOG_DEBUG("Fail to find function make_handler:" << error); + return RDC_ST_FAIL_LOAD_MODULE; + } + + *p_rdc_handle = static_cast + (func_make_handler(op_mode)); + + return RDC_ST_OK; +} + +rdc_status_t rdc_stop_embedded(rdc_handle_t p_rdc_handle) { + if (!p_rdc_handle) { + return RDC_ST_INVALID_HANDLER; + } + delete static_cast(p_rdc_handle); + p_rdc_handle = nullptr; + return RDC_ST_OK; +} + + +rdc_status_t rdc_watch_job_fields(rdc_handle_t p_rdc_handle, + rdc_gpu_group_t group_id, uint64_t update_freq, double max_keep_age, + uint32_t max_keep_samples) { + if (!p_rdc_handle) { + return RDC_ST_INVALID_HANDLER; + } + + return static_cast(p_rdc_handle)-> + rdc_watch_job_fields(group_id, update_freq, + max_keep_age, max_keep_samples); +} + +rdc_status_t rdc_update_all_fields(rdc_handle_t p_rdc_handle, + uint32_t wait_for_update) { + if (!p_rdc_handle) { + return RDC_ST_INVALID_HANDLER; + } + + return static_cast(p_rdc_handle)-> + rdc_update_all_fields(wait_for_update); +} + +rdc_status_t rdc_job_get_stats(rdc_handle_t p_rdc_handle, char job_id[64] , + rdc_job_info_t* p_job_info) { + if (!p_rdc_handle) { + return RDC_ST_INVALID_HANDLER; + } + + return static_cast(p_rdc_handle)-> + rdc_job_get_stats(job_id, p_job_info); +} + +rdc_status_t rdc_job_start_stats(rdc_handle_t p_rdc_handle, + rdc_gpu_group_t groupId, char job_id[64] ) { + if (!p_rdc_handle) { + return RDC_ST_INVALID_HANDLER; + } + + return static_cast(p_rdc_handle)-> + rdc_job_start_stats(groupId, job_id); +} + + +rdc_status_t rdc_job_stop_stats(rdc_handle_t p_rdc_handle, char job_id[64] ) { + if (!p_rdc_handle) { + return RDC_ST_INVALID_HANDLER; + } + + return static_cast(p_rdc_handle)-> + rdc_job_stop_stats(job_id); +} + +rdc_status_t rdc_group_gpu_create(rdc_handle_t p_rdc_handle, + rdc_group_type_t type, const char* group_name, + rdc_gpu_group_t* p_rdc_group_id) { + if (!p_rdc_handle) { + return RDC_ST_INVALID_HANDLER; + } + + return static_cast(p_rdc_handle)-> + rdc_group_gpu_create(type, group_name, p_rdc_group_id); +} + +rdc_status_t rdc_group_gpu_add(rdc_handle_t p_rdc_handle, + rdc_gpu_group_t groupId, uint32_t gpuIndex ) { + if (!p_rdc_handle) { + return RDC_ST_INVALID_HANDLER; + } + + return static_cast(p_rdc_handle)-> + rdc_group_gpu_add(groupId, gpuIndex); +} + +const char* rdc_status_string(rdc_status_t result) { + switch (result) { + case RDC_ST_OK: + return "Success"; + case RDC_ST_NOT_SUPPORTED: + return "Not supported"; + case RDC_ST_FAIL_LOAD_MODULE: + return "Fail to load module"; + case RDC_ST_INVALID_HANDLER: + return "Invalid handler"; + default: + return "Unknown"; + } +} + diff --git a/projects/rdc/rdc_libs/rdc/src/RdcEmbeddedHandler.cc b/projects/rdc/rdc_libs/rdc/src/RdcEmbeddedHandler.cc new file mode 100644 index 0000000000..7850b35f00 --- /dev/null +++ b/projects/rdc/rdc_libs/rdc/src/RdcEmbeddedHandler.cc @@ -0,0 +1,99 @@ +/* +Copyright (c) 2020 - present 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 "rdc_lib/impl/RdcEmbeddedHandler.h" +#include "rdc_lib/rdc_common.h" +#include "rocm_smi/rocm_smi.h" + +namespace { +// call the rsmi_init when load library +// and rsmi_shutdown when unload the library. +class rsmi_initializer { + rsmi_initializer() { rsmi_init(0);} + ~rsmi_initializer() { rsmi_shut_down();} + public: + static rsmi_initializer& getInstance() { + static rsmi_initializer instance; + return instance; + } +}; + +static rsmi_initializer& in = rsmi_initializer::getInstance(); +} // namespace + +amd::rdc::RdcHandler *make_handler(rdc_operation_mode_t op_mode) { + return new amd::rdc::RdcEmbeddedHandler(op_mode); +} + +namespace amd { +namespace rdc { + + +RdcEmbeddedHandler::RdcEmbeddedHandler(rdc_operation_mode_t) { + // TODO(next_step): implement +} + +rdc_status_t RdcEmbeddedHandler::rdc_group_gpu_create(rdc_group_type_t type, + const char* group_name, rdc_gpu_group_t* p_rdc_group_id) { + // TODO(next_step): implement + return RDC_ST_OK; +} + +rdc_status_t RdcEmbeddedHandler::rdc_group_gpu_add(rdc_gpu_group_t group_id, + uint32_t gpu_index ) { + // TODO(next_step): implement + return RDC_ST_OK; +} + + +rdc_status_t RdcEmbeddedHandler::rdc_job_start_stats( + rdc_gpu_group_t groupId, char job_id[64]) { + // TODO(next_step): implement + return RDC_ST_OK; +} + +rdc_status_t RdcEmbeddedHandler::rdc_watch_job_fields(rdc_gpu_group_t groupId, + uint64_t update_freq, double max_keep_age, uint32_t max_keep_samples) { + // TODO(next_step): implement + return RDC_ST_OK; +} + +rdc_status_t RdcEmbeddedHandler::rdc_job_get_stats(char job_id[64], + rdc_job_info_t* p_job_info) { + // TODO(next_step): implement + LOG_DEBUG("RdcEmbeddedHandler::rdc_job_get_stats:" << job_id); + return RDC_ST_OK; +} + +rdc_status_t RdcEmbeddedHandler::rdc_job_stop_stats(char job_id[64] ) { + // TODO(next_step): implement + return RDC_ST_OK; +} + +rdc_status_t RdcEmbeddedHandler::rdc_update_all_fields( + uint32_t wait_for_update) { + // TODO(next_step): implement + LOG_DEBUG("RdcEmbeddedHandler::rdc_update_all_fields"); + return RDC_ST_OK; +} + +} // namespace rdc +} // namespace amd