diff --git a/client/include/rdc/rdc_client.h b/client/include/rdc/rdc_client.h index 512a5b83bf..0b4c0bc40a 100755 --- a/client/include/rdc/rdc_client.h +++ b/client/include/rdc/rdc_client.h @@ -344,6 +344,30 @@ rdc_status_t rdc_dev_temp_metric_get(rdc_channel_t channel, uint32_t dv_ind, uint32_t sensor_type, rsmi_temperature_metric_t metric, int64_t *temperature); + +/** + * @brief Remote call to rsmi_dev_fan_rpms_get() + * + */ +rdc_status_t +rdc_dev_fan_rpms_get(rdc_channel_t channel, uint32_t dv_ind, + uint32_t sensor_ind, int64_t *rpms); + +/** + * @brief Remote call to rsmi_dev_fan_speed_get() + * + */ +rdc_status_t +rdc_dev_fan_speed_get(rdc_channel_t channel, uint32_t dv_ind, + uint32_t sensor_ind, int64_t *speed); + +/** + * @brief Remote call to rsmi_dev_fan_speed_max_get() + * + */ +rdc_status_t +rdc_dev_fan_speed_max_get(rdc_channel_t channel, uint32_t dv_ind, + uint32_t sensor_ind, uint64_t *max_speed); /** @} */ // end of PhysQuer /** diff --git a/client/src/rdc_client.cc b/client/src/rdc_client.cc index b3ab41efd2..026a23c18f 100755 --- a/client/src/rdc_client.cc +++ b/client/src/rdc_client.cc @@ -225,6 +225,86 @@ rdc_dev_temp_metric_get(rdc_channel_t channel, uint32_t dv_ind, CATCH } +rdc_status_t +rdc_dev_fan_rpms_get(rdc_channel_t channel, uint32_t dv_ind, + uint32_t sensor_ind, int64_t *rpms) { + TRY + CHK_PTR_ARG(rpms) + UINTPTR_TO_RDC_CHAN(channel) + + ::rdc::GetFanRpmsResponse resp; + ::rdc::GetFanRpmsRequest in_args; + ::grpc::ClientContext context; + + in_args.set_dv_ind(dv_ind); + in_args.set_sensor_ind(sensor_ind); + + ::grpc::Status status = + ch->rsmi_stub()->GetFanRpms(&context, in_args, &resp); + + if (!status.ok()) { + return ::amd::rdc::GrpcErrorToRdcError(status.error_code()); + } + + *rpms = resp.rpms(); + + return static_cast(resp.ret_val()); + CATCH +} + +rdc_status_t +rdc_dev_fan_speed_get(rdc_channel_t channel, uint32_t dv_ind, + uint32_t sensor_ind, int64_t *speed) { + TRY + CHK_PTR_ARG(speed) + UINTPTR_TO_RDC_CHAN(channel) + + ::rdc::GetFanSpeedResponse resp; + ::rdc::GetFanSpeedRequest in_args; + ::grpc::ClientContext context; + + in_args.set_dv_ind(dv_ind); + in_args.set_sensor_ind(sensor_ind); + + ::grpc::Status status = + ch->rsmi_stub()->GetFanSpeed(&context, in_args, &resp); + + if (!status.ok()) { + return ::amd::rdc::GrpcErrorToRdcError(status.error_code()); + } + + *speed = resp.speed(); + + return static_cast(resp.ret_val()); + CATCH +} + +rdc_status_t +rdc_dev_fan_speed_max_get(rdc_channel_t channel, uint32_t dv_ind, + uint32_t sensor_ind, uint64_t *max_speed) { + TRY + CHK_PTR_ARG(max_speed) + UINTPTR_TO_RDC_CHAN(channel) + + ::rdc::GetFanSpeedMaxResponse resp; + ::rdc::GetFanSpeedMaxRequest in_args; + ::grpc::ClientContext context; + + in_args.set_dv_ind(dv_ind); + in_args.set_sensor_ind(sensor_ind); + + ::grpc::Status status = + ch->rsmi_stub()->GetFanSpeedMax(&context, in_args, &resp); + + if (!status.ok()) { + return ::amd::rdc::GrpcErrorToRdcError(status.error_code()); + } + + *max_speed = resp.max_speed(); + + return static_cast(resp.ret_val()); + CATCH +} rdc_status_t rdc_status_string(rdc_status_t status, const char **status_string) { diff --git a/docs/RDC_Manual.pdf b/docs/RDC_Manual.pdf index e6471f7c5c..9a6b1b3022 100644 Binary files a/docs/RDC_Manual.pdf and b/docs/RDC_Manual.pdf differ diff --git a/protos/rdc.proto b/protos/rdc.proto index ca9a2ea70d..08bfd09fbd 100755 --- a/protos/rdc.proto +++ b/protos/rdc.proto @@ -37,9 +37,12 @@ service Rsmi { // RSMI Physical Queries rpc GetTemperature(GetTemperatureRequest) returns(GetTemperatureResponse){} + rpc GetFanRpms(GetFanRpmsRequest) returns(GetFanRpmsResponse){} + rpc GetFanSpeed(GetFanSpeedRequest) returns(GetFanSpeedResponse){} + rpc GetFanSpeedMax(GetFanSpeedMaxRequest) returns(GetFanSpeedMaxResponse){} } -// rsmi_num_monitor_devices() +/* rsmi_num_monitor_devices() */ message GetNumDevicesRequest { } message GetNumDevicesResponse { @@ -48,6 +51,7 @@ message GetNumDevicesResponse { } /* GetTemperature */ +/* rsmi_dev_temp_metric_get() */ message GetTemperatureRequest { uint32 dv_ind = 1; uint32 sensor_type = 2; @@ -74,6 +78,38 @@ message GetTemperatureResponse { uint64 ret_val = 2; } +/* GetFanRpms */ +/* rsmi_dev_fan_rpms_get() */ +message GetFanRpmsRequest { + uint32 dv_ind = 1; + uint32 sensor_ind = 2; +} +message GetFanRpmsResponse { + int64 rpms = 1; + uint64 ret_val = 2; +} +/* GetFanSpeed */ +/* rsmi_dev_fan_speed_get() */ +message GetFanSpeedRequest { + uint32 dv_ind = 1; + uint32 sensor_ind = 2; +} +message GetFanSpeedResponse { + int64 speed = 1; + uint64 ret_val = 2; +} + +/* GetFanSpeedMax */ +/* rsmi_dev_fan_speed_max_get() */ +message GetFanSpeedMaxRequest { + uint32 dv_ind = 1; + uint32 sensor_ind = 2; +} +message GetFanSpeedMaxResponse { + uint64 max_speed = 1; + uint64 ret_val = 2; +} + /****************************************************************************/ /********************************** RdcAdmin Service ************************/ /****************************************************************************/ diff --git a/server/include/rdc/rdc_rsmi_service.h b/server/include/rdc/rdc_rsmi_service.h index 4ef2778701..40bc7907d7 100755 --- a/server/include/rdc/rdc_rsmi_service.h +++ b/server/include/rdc/rdc_rsmi_service.h @@ -46,11 +46,26 @@ class RsmiServiceImpl final : public ::rdc::Rsmi::Service { const ::rdc::GetTemperatureRequest* request, ::rdc::GetTemperatureResponse* response) override; + ::grpc::Status + GetFanRpms(::grpc::ServerContext* context, + const ::rdc::GetFanRpmsRequest* request, + ::rdc::GetFanRpmsResponse* response) override; + + ::grpc::Status + GetFanSpeed(::grpc::ServerContext* context, + const ::rdc::GetFanSpeedRequest* request, + ::rdc::GetFanSpeedResponse* response) override; + + ::grpc::Status + GetFanSpeedMax(::grpc::ServerContext* context, + const ::rdc::GetFanSpeedMaxRequest* request, + ::rdc::GetFanSpeedMaxResponse* response) override; + private: bool rsmi_initialized_; }; -} // rdc -} // amd +} // namespace rdc +} // namespace amd #endif // SERVER_INCLUDE_RDC_RDC_RSMI_SERVICE_H_ diff --git a/server/src/rdc_rsmi_service.cc b/server/src/rdc_rsmi_service.cc index f588b1f8c2..face11402c 100755 --- a/server/src/rdc_rsmi_service.cc +++ b/server/src/rdc_rsmi_service.cc @@ -74,6 +74,7 @@ RsmiServiceImpl::GetNumDevices(::grpc::ServerContext* context, (void)context; // Quiet warning for now; (void)request; + assert(reply != nullptr); rsmi_status_t ret = rsmi_num_monitor_devices(&num_devices); @@ -92,6 +93,7 @@ RsmiServiceImpl::GetTemperature(::grpc::ServerContext* context, const ::rdc::GetTemperatureRequest* request, ::rdc::GetTemperatureResponse* response) { (void)context; // Quiet warning for now; + assert(response != nullptr); int64_t temperature; rsmi_status_t ret = rsmi_dev_temp_metric_get(request->dv_ind(), @@ -103,6 +105,54 @@ RsmiServiceImpl::GetTemperature(::grpc::ServerContext* context, return ::grpc::Status::OK; } +::grpc::Status +RsmiServiceImpl::GetFanRpms(::grpc::ServerContext* context, + const ::rdc::GetFanRpmsRequest* request, + ::rdc::GetFanRpmsResponse* response) { + (void)context; // Quiet warning for now; + assert(response != nullptr); + + int64_t rpms; + rsmi_status_t ret = rsmi_dev_fan_rpms_get(request->dv_ind(), + request->sensor_ind(), &rpms); + + response->set_rpms(rpms); + response->set_ret_val(ret); + return ::grpc::Status::OK; +} + +::grpc::Status +RsmiServiceImpl::GetFanSpeed(::grpc::ServerContext* context, + const ::rdc::GetFanSpeedRequest* request, + ::rdc::GetFanSpeedResponse* response) { + (void)context; // Quiet warning for now; + assert(response != nullptr); + + int64_t speed; + rsmi_status_t ret = rsmi_dev_fan_speed_get(request->dv_ind(), + request->sensor_ind(), &speed); + + response->set_speed(speed); + response->set_ret_val(ret); + return ::grpc::Status::OK; +} + +::grpc::Status +RsmiServiceImpl::GetFanSpeedMax(::grpc::ServerContext* context, + const ::rdc::GetFanSpeedMaxRequest* request, + ::rdc::GetFanSpeedMaxResponse* response) { + (void)context; // Quiet warning for now; + assert(response != nullptr); + + uint64_t max_speed; + rsmi_status_t ret = rsmi_dev_fan_speed_max_get(request->dv_ind(), + request->sensor_ind(), &max_speed); + + response->set_max_speed(max_speed); + 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() { diff --git a/tests/rdc_tests/CMakeLists.txt b/tests/rdc_tests/CMakeLists.txt index ee19e8bd4e..7601156cd0 100755 --- a/tests/rdc_tests/CMakeLists.txt +++ b/tests/rdc_tests/CMakeLists.txt @@ -44,10 +44,11 @@ endif() # Required Defines first: -set(RDC_INC_DIR ${ROCM_DIR}/rdc/include) -set(RDC_LIB_DIR ${ROCM_DIR}/rdc/lib) +set(RDC_INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../client/include) +set(RDC_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../rdc/lib) set(RSMI_INC_DIR ${ROCM_DIR}/rocm_smi/include) + # # Determine RDC Header files are present # (no external source dependencies) diff --git a/tests/rdc_tests/functional/fan_read.cc b/tests/rdc_tests/functional/fan_read.cc new file mode 100755 index 0000000000..a82f7ff8a3 --- /dev/null +++ b/tests/rdc_tests/functional/fan_read.cc @@ -0,0 +1,108 @@ +/* +Copyright (c) 2020 - 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 + +#include "gtest/gtest.h" +#include "rdc/rdc_client.h" +#include "rdc_tests/functional/fan_read.h" +#include "rdc_tests/test_common.h" + +TestFanRead::TestFanRead() : TestBase() { + set_title("RDC Fan Read Test"); + set_description("The Fan Read tests verifies that the fan monitors can be " + "read properly."); +} + +TestFanRead::~TestFanRead(void) { +} + +void TestFanRead::SetUp(void) { + TestBase::SetUp(); + + return; +} + +void TestFanRead::DisplayTestInfo(void) { + TestBase::DisplayTestInfo(); +} + +void TestFanRead::DisplayResults(void) const { + TestBase::DisplayResults(); + return; +} + +void TestFanRead::Close() { + TestBase::Close(); +} + + +void TestFanRead::Run(void) { + uint64_t val_ui64; + rdc_status_t err; + int64_t val_i64; + + TestBase::Run(); + + err = AllocateRDCChannel(); + ASSERT_EQ(err, RDC_STATUS_SUCCESS); + + for (uint32_t i = 0; i < num_monitor_devs(); ++i) { + PrintDeviceHeader(i); + + IF_VERB(STANDARD) { + std::cout << "\t**Current Fan Speed: "; + } + err = rdc_dev_fan_speed_get(rdc_channel(), i, 0, &val_i64); + CHK_ERR_ASRT(err) + + // Verify api support checking functionality is working + err = rdc_dev_fan_speed_get(rdc_channel(), i, 0, nullptr); + ASSERT_EQ(err, RDC_RSMI_STATUS_INVALID_ARGS); + + err = rdc_dev_fan_speed_max_get(rdc_channel(), i, 0, &val_ui64); + CHK_ERR_ASRT(err) + IF_VERB(STANDARD) { + std::cout << val_i64/static_cast(val_ui64)*100; + std::cout << "% ("<< val_i64 << "/" << val_ui64 << ")" << std::endl; + } + // Verify api support checking functionality is working + err = rdc_dev_fan_speed_max_get(rdc_channel(), i, 0, nullptr); + ASSERT_EQ(err, RDC_RSMI_STATUS_INVALID_ARGS); + + IF_VERB(STANDARD) { + std::cout << "\t**Current fan RPMs: "; + } + err = rdc_dev_fan_rpms_get(rdc_channel(), i, 0, &val_i64); + CHK_ERR_ASRT(err) + IF_VERB(STANDARD) { + std::cout << val_i64 << std::endl; + } + + // Verify api support checking functionality is working + err = rdc_dev_fan_rpms_get(rdc_channel(), i, 0, nullptr); + ASSERT_EQ(err, RDC_RSMI_STATUS_INVALID_ARGS); + } +} diff --git a/tests/rdc_tests/functional/fan_read.h b/tests/rdc_tests/functional/fan_read.h new file mode 100755 index 0000000000..b9214bb470 --- /dev/null +++ b/tests/rdc_tests/functional/fan_read.h @@ -0,0 +1,50 @@ +/* +Copyright (c) 2020 - 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 TESTS_RDC_TESTS_FUNCTIONAL_FAN_READ_H_ +#define TESTS_RDC_TESTS_FUNCTIONAL_FAN_READ_H_ + +#include "rdc_tests/test_base.h" + +class TestFanRead : public TestBase { + public: + TestFanRead(); + + // @Brief: Destructor for test case of TestFanRead + virtual ~TestFanRead(); + + // @Brief: Setup the environment for measurement + virtual void SetUp(); + + // @Brief: Core measurement execution + virtual void Run(); + + // @Brief: Clean up and retrive the resource + virtual void Close(); + + // @Brief: Display results + virtual void DisplayResults() const; + + // @Brief: Display information about what this test does + virtual void DisplayTestInfo(void); +}; + +#endif // TESTS_RDC_TESTS_FUNCTIONAL_FAN_READ_H_ diff --git a/tests/rdc_tests/functional/temp_read.cc b/tests/rdc_tests/functional/temp_read.cc index 4f12f80d9e..447eec5b32 100755 --- a/tests/rdc_tests/functional/temp_read.cc +++ b/tests/rdc_tests/functional/temp_read.cc @@ -37,7 +37,7 @@ static const std::map kTempSensorNameMap = { {RSMI_TEMP_TYPE_EDGE, "Edge"}, }; TestTempRead::TestTempRead() : TestBase() { - set_title("RSMI Temp Read Test"); + set_title("RDC Temp Read Test"); set_description("The Temperature Read tests verifies that the temperature " "monitors can be read properly."); } @@ -61,8 +61,6 @@ void TestTempRead::DisplayResults(void) const { } void TestTempRead::Close() { - // This will close handles opened within rsmitst utility calls and call - // rsmi_shut_down(), so it should be done after other hsa cleanup TestBase::Close(); } diff --git a/tests/rdc_tests/functional/temp_read.h b/tests/rdc_tests/functional/temp_read.h index 4672498000..cfadcaf847 100755 --- a/tests/rdc_tests/functional/temp_read.h +++ b/tests/rdc_tests/functional/temp_read.h @@ -19,8 +19,8 @@ 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 TESTS_ROCM_SMI_TEST_FUNCTIONAL_TEMP_READ_H_ -#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_TEMP_READ_H_ +#ifndef TESTS_RDC_TESTS_FUNCTIONAL_TEMP_READ_H_ +#define TESTS_RDC_TESTS_FUNCTIONAL_TEMP_READ_H_ #include "rdc_tests/test_base.h" @@ -47,4 +47,4 @@ class TestTempRead : public TestBase { virtual void DisplayTestInfo(void); }; -#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_TEMP_READ_H_ +#endif // TESTS_RDC_TESTS_FUNCTIONAL_TEMP_READ_H_ diff --git a/tests/rdc_tests/main.cc b/tests/rdc_tests/main.cc index c97d26341e..ead448be0f 100755 --- a/tests/rdc_tests/main.cc +++ b/tests/rdc_tests/main.cc @@ -36,6 +36,7 @@ THE SOFTWARE. #include "functional/id_info_read.h" #include "functional/temp_read.h" +#include "functional/fan_read.h" static RDCTstGlobals *sRDCGlvalues = nullptr; @@ -91,6 +92,11 @@ TEST(rdctstReadOnly, TestTempRead) { TestTempRead tst; RunGenericTest(&tst); } +TEST(rdctstReadOnly, FanRead) { + TestFanRead tst; + RunGenericTest(&tst); +} + static int getPIDFromName(std::string name) { int pid = -1;