Initial RDC commit
Includes server, client and example targets.
Change-Id: I30596fb0453af71d49b8390a8468a6d073200836
[ROCm/rdc commit: 5898345d17]
This commit is contained in:
Executable
@@ -0,0 +1,97 @@
|
||||
# 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
|
||||
# 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 Server ")
|
||||
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 client 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 "src")
|
||||
set(INC_DIR "include/${RDC}")
|
||||
|
||||
# TODO delete these if not used
|
||||
file(GLOB PROTOBUF_GENERATED_INCLUDES "${PROTOB_OUT_DIR}/*.h")
|
||||
file(GLOB PROTOBUF_GENERATED_SRCS "${PROTOB_OUT_DIR}/*.cc")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
"${PROTOB_OUT_DIR}" "${RSMI_INC_DIR}")
|
||||
|
||||
set(SERVER_SRC_LIST "${SRC_DIR}/rdc_rsmi_service.cc")
|
||||
set(SERVER_SRC_LIST ${SERVER_SRC_LIST} "${SRC_DIR}/rdc_main.cc")
|
||||
set(SERVER_SRC_LIST ${SERVER_SRC_LIST} "${PROTOBUF_GENERATED_SRCS}")
|
||||
message("SERVER_SRC_LIST=${SERVER_SRC_LIST}")
|
||||
|
||||
set(SERVER_DAEMON_EXE "rdcd")
|
||||
set(SERVICE_FILE_NAME "rdc.service")
|
||||
|
||||
link_directories(${RSMI_LIB_DIR})
|
||||
|
||||
add_executable(${SERVER_DAEMON_EXE} "${SERVER_SRC_LIST}")
|
||||
# target_include_directories(${SERVER_DAEMON_EXE} PUBLIC ${RSMI_INC_DIR})
|
||||
|
||||
target_link_libraries(${SERVER_DAEMON_EXE} pthread rt grpc grpc++
|
||||
grpc++_reflection dl protobuf rocm_smi64)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SERVER_DAEMON_EXE}
|
||||
PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
DESTINATION usr/sbin)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SERVICE_FILE_NAME}
|
||||
DESTINATION lib/systemd/system)
|
||||
|
||||
message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
|
||||
message(" Finished Cmake Server ")
|
||||
message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
|
||||
Executable
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
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
|
||||
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 SERVER_INCLUDE_RDC_RDC_MAIN_H_
|
||||
#define SERVER_INCLUDE_RDC_RDC_MAIN_H_
|
||||
|
||||
#include <grpcpp/grpcpp.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "rdc/rdc_rsmi_service.h"
|
||||
|
||||
class RDCServer {
|
||||
public:
|
||||
RDCServer();
|
||||
~RDCServer();
|
||||
|
||||
void Initialize();
|
||||
|
||||
void Run(void);
|
||||
|
||||
bool start_rsmi_service(void) const {return start_rsmi_service_;}
|
||||
void set_start_rsmi_service(bool s) {start_rsmi_service_ = s;}
|
||||
|
||||
void ShutDown(void);
|
||||
|
||||
private:
|
||||
void HandleSignal(int sig);
|
||||
std::string server_address_;
|
||||
bool start_rsmi_service_;
|
||||
std::unique_ptr<::grpc::Server> server_;
|
||||
|
||||
RsmiServiceImpl *rsmi_service_;
|
||||
};
|
||||
|
||||
#endif // SERVER_INCLUDE_RDC_RDC_MAIN_H_
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
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
|
||||
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 SERVER_INCLUDE_RDC_RDC_RSMI_SERVICE_H_
|
||||
#define SERVER_INCLUDE_RDC_RDC_RSMI_SERVICE_H_
|
||||
|
||||
#include "rdc.grpc.pb.h" // NOLINT
|
||||
#include "rocm_smi/rocm_smi.h"
|
||||
#include "rdc/rdc_rsmi_service.h"
|
||||
|
||||
class RsmiServiceImpl final : public ::rdc::Rsmi::Service {
|
||||
public:
|
||||
RsmiServiceImpl();
|
||||
~RsmiServiceImpl();
|
||||
|
||||
rsmi_status_t Initialize(uint64_t rsmi_init_flags = 0);
|
||||
|
||||
::grpc::Status VerifyConnection(::grpc::ServerContext* context,
|
||||
const rdc::VerifyConnectionRequest* request,
|
||||
rdc::VerifyConnectionResponse* reply) override;
|
||||
|
||||
::grpc::Status
|
||||
GetNumDevices(::grpc::ServerContext* context,
|
||||
const ::rdc::GetNumDevicesRequest* request,
|
||||
::rdc::GetNumDevicesResponse* reply) override;
|
||||
|
||||
::grpc::Status
|
||||
GetTemperature(::grpc::ServerContext* context,
|
||||
const ::rdc::GetTemperatureRequest* request,
|
||||
::rdc::GetTemperatureResponse* response) override;
|
||||
|
||||
private:
|
||||
bool rsmi_initialized_;
|
||||
};
|
||||
|
||||
#endif // SERVER_INCLUDE_RDC_RDC_RSMI_SERVICE_H_
|
||||
Executable
@@ -0,0 +1,37 @@
|
||||
|
||||
# References:
|
||||
# https://linuxconfig.org/how-to-create-systemd-service-unit-in-linux
|
||||
# https://www.linux.com/tutorials/systemd-services-beyond-starting-and-stopping/
|
||||
[Unit]
|
||||
Description=Radeon Data Center Daemon (rdcd)
|
||||
After=network.target
|
||||
|
||||
# Add any services that must be started before rdcd here
|
||||
#After=
|
||||
|
||||
# Add any non-service units required by rdcd here
|
||||
#Requires=
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
# If we need to start anything before rdcd, use this
|
||||
# ExecStartPre=
|
||||
|
||||
ExecStart=/usr/sbin/rdcd
|
||||
|
||||
# If we need to start anything after rdcd use this
|
||||
# ExecStartPost=
|
||||
|
||||
# If we want to change the default time out for the ExecStop (90 sec),
|
||||
# we can modify that time limit with TimeoutStopSec
|
||||
# TimeoutStopSec=
|
||||
|
||||
# Note, we can have multiple ExecStop commands if necessary
|
||||
ExecStop=/bin/kill -15 $MAINPID
|
||||
#ExecReload=
|
||||
#ExecStartPost=
|
||||
#ExecStopPost=
|
||||
|
||||
[Install]
|
||||
WantedBy= multi-user.target
|
||||
Executable
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DROCM_DIR=/opt/rocm ..
|
||||
make
|
||||
cd ..
|
||||
|
||||
Executable
+283
@@ -0,0 +1,283 @@
|
||||
|
||||
/*
|
||||
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
|
||||
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 <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <grpcpp/grpcpp.h>
|
||||
#include <sys/resource.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <csignal>
|
||||
|
||||
#include "rdc.grpc.pb.h" // NOLINT
|
||||
#include "rocm_smi/rocm_smi.h"
|
||||
#include "rdc/rdc_main.h"
|
||||
#include "rdc/rdc_rsmi_service.h"
|
||||
|
||||
static bool sShutDownServer = false;
|
||||
static bool sRestartServer = false;
|
||||
static const char *kDaemonName = "rdcd";
|
||||
static const char *kRDCDHomeDir = "/";
|
||||
static const char *kDaemonLockFile = "/var/run/rdcd.lock";
|
||||
|
||||
RDCServer::RDCServer() : server_address_("0.0.0.0:50051"),
|
||||
rsmi_service_(nullptr) {
|
||||
}
|
||||
|
||||
RDCServer::~RDCServer() {
|
||||
}
|
||||
|
||||
void
|
||||
RDCServer::Initialize() {
|
||||
}
|
||||
|
||||
// TODO(cfreehil): read server config from YAML file. Config can include things
|
||||
// like server address, Secure/Insecure creds, rsmi_init flags, etc.
|
||||
void
|
||||
RDCServer::Run() {
|
||||
::grpc::ServerBuilder builder;
|
||||
// Listen on the given address without any authentication mechanism.
|
||||
builder.AddListeningPort(server_address_, grpc::InsecureServerCredentials());
|
||||
|
||||
// Register services as the instances through which we'll communicate with
|
||||
// clients. These are synchronous services.
|
||||
|
||||
if (start_rsmi_service()) {
|
||||
rsmi_service_ = new RsmiServiceImpl();
|
||||
builder.RegisterService(rsmi_service_);
|
||||
|
||||
// TODO(cfreehil): pass flags from cnfg file
|
||||
rsmi_status_t ret = rsmi_service_->Initialize(0);
|
||||
|
||||
if (ret != RSMI_STATUS_SUCCESS) {
|
||||
std::cerr << "Failed to start RSMI service" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally assemble the server.
|
||||
// std::unique_ptr<::grpc::Server> server(builder.BuildAndStart());
|
||||
server_ = builder.BuildAndStart();
|
||||
|
||||
std::cerr << "Server listening on " << server_address_.c_str() << std::endl;
|
||||
|
||||
server_->Wait();
|
||||
}
|
||||
|
||||
static void HandleSignal(int sig) {
|
||||
std::cerr << "Caught signal " << sig << std::endl;
|
||||
|
||||
// For most signals, we will want to exit, so make that the default case
|
||||
// Handle the other signals specifically.
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
sShutDownServer = true;
|
||||
break;
|
||||
|
||||
// Grpc doesn't seem to handle stopping and restarting well, so
|
||||
// user must manually do these steps
|
||||
// case SIGHUP:
|
||||
// sRestartServer = true;
|
||||
// break;
|
||||
|
||||
default:
|
||||
std::cerr << "Unexpected signal caught" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void InitializeSignalHandling(void) {
|
||||
// signal(SIGHUP, HandleSignal);
|
||||
signal(SIGINT, HandleSignal);
|
||||
signal(SIGTERM, HandleSignal);
|
||||
}
|
||||
|
||||
void
|
||||
RDCServer::ShutDown(void) {
|
||||
server_->Shutdown();
|
||||
|
||||
if (rsmi_service_) {
|
||||
delete rsmi_service_;
|
||||
rsmi_service_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void * ProcessSignalLoop(void *server_ptr) {
|
||||
assert(server_ptr != nullptr);
|
||||
RDCServer *server = reinterpret_cast<RDCServer *>(server_ptr);
|
||||
|
||||
while (1) {
|
||||
if (sShutDownServer) {
|
||||
std::cerr << "Shutting down RDC Server." << std::endl;
|
||||
server->ShutDown();
|
||||
// We will need to add shutdown of any completion queues
|
||||
// here, when/if we add them
|
||||
break;
|
||||
} else if (sRestartServer) {
|
||||
std::cerr << "Re-starting RDC Server." << std::endl;
|
||||
// We will need to add shutdown of any completion queues
|
||||
// here, when/if we add them
|
||||
server->ShutDown();
|
||||
server->Run();
|
||||
|
||||
sRestartServer = false;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
pthread_exit(0);
|
||||
}
|
||||
|
||||
static void ExitIfAlreadyRunning(void) {
|
||||
int single_proc_fh;
|
||||
ssize_t fsz;
|
||||
|
||||
single_proc_fh = open(kDaemonLockFile, O_RDWR|O_CREAT, 0640);
|
||||
if (single_proc_fh < 0) {
|
||||
std::cerr << "Failed to open file lock:" << kDaemonLockFile << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (lockf(single_proc_fh, F_TLOCK, 0) < 0) {
|
||||
std::cerr << "Daemon already running. Exiting this instance." << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
std::string pid_str = std::to_string(getpid());
|
||||
fsz = write(single_proc_fh, pid_str.c_str(), pid_str.size());
|
||||
assert(static_cast<unsigned int>(fsz) == pid_str.size());
|
||||
}
|
||||
|
||||
static void
|
||||
MakeDaemon() {
|
||||
int fd0, fd1, fd2;
|
||||
struct rlimit max_files;
|
||||
|
||||
// RSMI, for one thing, will need to be able to read/write files
|
||||
// Note that umask turns *off* permission for a given bit, so you we want
|
||||
// the complement of the permissions we want files to have.
|
||||
umask(027);
|
||||
|
||||
// To Do; Make this optional based on CL option.
|
||||
#if 0
|
||||
pid_t pid;
|
||||
// We want to dissassociate with calling process, so fork, and let
|
||||
// daemon live in child process. Parent will exit.
|
||||
if ((pid = fork()) < 0) {
|
||||
std::cerr << "Failed to fork rdcd daemon." << std::endl;
|
||||
} else if (pid != 0) { // parent
|
||||
exit(0);
|
||||
}
|
||||
|
||||
setsid();
|
||||
|
||||
// Insulate from pgrp leader death
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
if ((pid = fork()) < 0) {
|
||||
std::cerr << "Failed to fork after signal(SIGHUP, SIG_IGN)" << std::endl;
|
||||
} else if (pid != 0) { // parent
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// chdir to dir that will always be available
|
||||
if (chdir(kRDCDHomeDir) < 0) {
|
||||
std::cerr << "Failed to change directory to " <<kRDCDHomeDir << std::endl;
|
||||
}
|
||||
|
||||
// Determine max. number of open files possible. We need to close all
|
||||
// open descriptors.
|
||||
if (getrlimit(RLIMIT_NOFILE, &max_files) < 0) {
|
||||
std::cerr << kDaemonName << ": can't get file limit" << std::endl;
|
||||
}
|
||||
|
||||
// Close files
|
||||
if (max_files.rlim_max > 1024) {
|
||||
max_files.rlim_max = 1024;
|
||||
}
|
||||
for (uint32_t i = 0; i < max_files.rlim_max; i++) {
|
||||
close(i);
|
||||
}
|
||||
|
||||
// Direct stdin, stdout, stdout to /dev/null.
|
||||
|
||||
fd0 = open("/dev/null", O_RDWR);
|
||||
fd1 = dup(0);
|
||||
fd2 = dup(0);
|
||||
|
||||
// Set up log file
|
||||
// openlog(kDaemonName, LOG_CONS|LOG_PID, LOG_DAEMON);
|
||||
if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
|
||||
std::cerr << "unexpected fildes: " << fd0 << " " << fd1 <<
|
||||
" " << fd2 << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ExitIfAlreadyRunning();
|
||||
|
||||
InitializeSignalHandling();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
RDCServer rdc_server;
|
||||
|
||||
(void)argc; // Ignore for now
|
||||
(void)argv;
|
||||
|
||||
MakeDaemon();
|
||||
|
||||
rdc_server.Initialize();
|
||||
|
||||
// Create a thread to handle signals to shutdown gracefully
|
||||
pthread_t sig_listen_thread;
|
||||
int thr_ret = pthread_create(&sig_listen_thread, NULL,
|
||||
ProcessSignalLoop, &rdc_server);
|
||||
|
||||
if (thr_ret) {
|
||||
std::cerr <<
|
||||
"Failed to create ProcessSignalLoop. pthread_create() returned " <<
|
||||
thr_ret;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO(cfreehil): Eventually, set these by reading a config file
|
||||
rdc_server.set_start_rsmi_service(true);
|
||||
// rdc_server.set_secure_communications(false);
|
||||
// rdc_server.set_address("0.0.0.0:50051")
|
||||
|
||||
rdc_server.Run();
|
||||
|
||||
if (sShutDownServer) {
|
||||
std::cerr << "RDC server successfully shut down." << std::endl;
|
||||
return 0;
|
||||
} else {
|
||||
std::cerr << "RDC server failed to start." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Executable
+138
@@ -0,0 +1,138 @@
|
||||
|
||||
/*
|
||||
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
|
||||
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 <assert.h>
|
||||
#include <grpcpp/grpcpp.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <csignal>
|
||||
|
||||
#include "rdc.grpc.pb.h" // NOLINT
|
||||
#include "rocm_smi/rocm_smi.h"
|
||||
#include "rdc/rdc_rsmi_service.h"
|
||||
|
||||
RsmiServiceImpl::RsmiServiceImpl():rsmi_initialized_(false) {
|
||||
}
|
||||
|
||||
RsmiServiceImpl::~RsmiServiceImpl() {
|
||||
if (rsmi_initialized_) {
|
||||
rsmi_status_t rsmi_ret = rsmi_shut_down();
|
||||
rsmi_initialized_ = false;
|
||||
assert(rsmi_ret == RSMI_STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
// rsmi and rdc currently happen to have a 1-to-1 mapping, but
|
||||
// have this function in case that changes
|
||||
static rsmi_temperature_metric_t
|
||||
rdc_temp2rsmi_temp(::rdc::GetTemperatureRequest_TemperatureMetric
|
||||
rdc_temp) {
|
||||
return static_cast<rsmi_temperature_metric_t>(rdc_temp);
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
RsmiServiceImpl::Initialize(uint64_t rsmi_init_flags) {
|
||||
rsmi_status_t rsmi_ret = rsmi_init(rsmi_init_flags);
|
||||
if (rsmi_ret != RSMI_STATUS_SUCCESS) {
|
||||
std::cout << "rsmi_init() returned error" << std::endl;
|
||||
} else {
|
||||
rsmi_initialized_ = true;
|
||||
}
|
||||
return rsmi_ret;
|
||||
}
|
||||
::grpc::Status
|
||||
RsmiServiceImpl::VerifyConnection(::grpc::ServerContext* context,
|
||||
const rdc::VerifyConnectionRequest* request,
|
||||
rdc::VerifyConnectionResponse* reply) {
|
||||
(void)context; // Quiet warning for now
|
||||
std::string prefix("Hello ");
|
||||
reply->set_message(prefix + request->name());
|
||||
return ::grpc::Status::OK;
|
||||
}
|
||||
|
||||
::grpc::Status
|
||||
RsmiServiceImpl::GetNumDevices(::grpc::ServerContext* context,
|
||||
const ::rdc::GetNumDevicesRequest* request,
|
||||
::rdc::GetNumDevicesResponse* reply) {
|
||||
assert(reply != nullptr);
|
||||
uint32_t num_devices;
|
||||
|
||||
(void)context; // Quiet warning for now;
|
||||
(void)request;
|
||||
|
||||
rsmi_status_t ret = rsmi_num_monitor_devices(&num_devices);
|
||||
|
||||
// TODO(cfreehil) replace below with macro
|
||||
if (ret != RSMI_STATUS_SUCCESS) {
|
||||
std::cout << "rsmi_num_monitor_devices() returned error" << std::endl;
|
||||
}
|
||||
reply->set_val(num_devices);
|
||||
reply->set_ret_val(ret);
|
||||
|
||||
return ::grpc::Status::OK;
|
||||
}
|
||||
|
||||
::grpc::Status
|
||||
RsmiServiceImpl::GetTemperature(::grpc::ServerContext* context,
|
||||
const ::rdc::GetTemperatureRequest* request,
|
||||
::rdc::GetTemperatureResponse* response) {
|
||||
(void)context; // Quiet warning for now;
|
||||
|
||||
int64_t temperature;
|
||||
rsmi_status_t ret = rsmi_dev_temp_metric_get(request->dv_ind(),
|
||||
request->sensor_type(), rdc_temp2rsmi_temp(request->metric()),
|
||||
&temperature);
|
||||
|
||||
response->set_temperature(temperature);
|
||||
response->set_ret_val(ret);
|
||||
return ::grpc::Status::OK;
|
||||
}
|
||||
|
||||
// TODO(cfreehil): read server config from YAML file. Config can include things
|
||||
// like server address, Secure/Insecure creds, rsmi_init flags, etc.
|
||||
void RunServer() {
|
||||
std::string server_address("0.0.0.0:50051");
|
||||
RsmiServiceImpl service;
|
||||
|
||||
::grpc::ServerBuilder builder;
|
||||
// Listen on the given address without any authentication mechanism.
|
||||
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
|
||||
// Register "service" as the instance through which we'll communicate with
|
||||
// clients. In this case it corresponds to an *synchronous* service.
|
||||
builder.RegisterService(&service);
|
||||
// Finally assemble the server.
|
||||
std::unique_ptr<::grpc::Server> server(builder.BuildAndStart());
|
||||
std::cout << "Server listening on " << server_address << std::endl;
|
||||
|
||||
uint64_t flags = 0; // TODO(cfreehil) Read this from config file
|
||||
rsmi_status_t rsmi_ret = rsmi_init(flags);
|
||||
// TODO(cfreehil): check rsmi return code
|
||||
// Wait for the server to shutdown. Note that some other thread must be
|
||||
// responsible for shutting down the server for this call to ever return.
|
||||
if (rsmi_ret != RSMI_STATUS_SUCCESS) {
|
||||
std::cout << "rsmi_init() returned error. Exiting" << std::endl;
|
||||
return;
|
||||
}
|
||||
server->Wait();
|
||||
}
|
||||
Verwijs in nieuw issue
Block a user