mirror of
https://github.com/Lurkki14/tuxclocker.git
synced 2024-11-21 15:57:25 -06:00
add test for RX 7000 fan curve temperature parsing
This commit is contained in:
parent
4d18b0cdfb
commit
31230172d7
@ -427,11 +427,16 @@ std::vector<TreeNode<DeviceNode>> getFanSpeedWriteRX7000(AMDGPUData data) {
|
||||
if (!contents.has_value())
|
||||
return {};
|
||||
|
||||
// We don't care acout the temps, since we set all points to desired speed
|
||||
// We don't care acout the temp range, since we set all points to desired speed
|
||||
auto speedRange = fromFanCurveContents(*contents);
|
||||
if (!speedRange.has_value())
|
||||
return {};
|
||||
|
||||
// Only fetch temperatures once
|
||||
auto temps = fanCurveTempsFromContents(*contents);
|
||||
if (temps.empty())
|
||||
return {};
|
||||
|
||||
// Doesn't make sense with what we do
|
||||
auto getFunc = [] { return std::nullopt; };
|
||||
|
||||
@ -443,27 +448,16 @@ std::vector<TreeNode<DeviceNode>> getFanSpeedWriteRX7000(AMDGPUData data) {
|
||||
if (speedRange->min > target || speedRange->max < target)
|
||||
return AssignmentError::OutOfRange;
|
||||
|
||||
// TODO: do we even need to care about setting same temperature?
|
||||
// Might be slow to do this every assignment
|
||||
auto lines = pstateSectionLines("OD_FAN_CURVE", *contents);
|
||||
// Write all curve points to same value
|
||||
std::ofstream file{fanCurvePath};
|
||||
if (lines.empty() || !file.good())
|
||||
return AssignmentError::UnknownError;
|
||||
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
// Write all curve points to same value
|
||||
auto words = fplus::split_one_of(std::string{" "}, false, lines[i]);
|
||||
if (words.size() < 3)
|
||||
return AssignmentError::UnknownError;
|
||||
|
||||
// Essentially cut off the 'C' in '65C'
|
||||
auto temp = std::atoi(words[1].c_str());
|
||||
for (int i = 0; i < temps.size(); i++) {
|
||||
char cmdString[32];
|
||||
// TODO: docs say PWM but internet says percentage
|
||||
snprintf(cmdString, 32, "%i %i %i", i, temp, target);
|
||||
snprintf(cmdString, 32, "%i %i %i", i, temps[i], target);
|
||||
if (!(file << cmdString))
|
||||
return AssignmentError::UnknownError;
|
||||
}
|
||||
|
||||
if (file << "c")
|
||||
return std::nullopt;
|
||||
return AssignmentError::UnknownError;
|
||||
|
@ -83,6 +83,19 @@ std::optional<Range<int>> fromFanCurveContents(const std::string &contentsRaw) {
|
||||
return parsePstateRangeLine("FAN_CURVE(fan_speed)", contents);
|
||||
}
|
||||
|
||||
std::vector<int> fanCurveTempsFromContents(const std::string &contents) {
|
||||
auto lines = pstateSectionLines("OD_FAN_CURVE", contents);
|
||||
|
||||
std::vector<int> retval;
|
||||
for (auto &line : lines) {
|
||||
auto value = parseLineValue(line);
|
||||
if (!value.has_value())
|
||||
return {};
|
||||
retval.push_back(*value);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::optional<std::pair<int, int>> parseLineValuePair(const std::string &line) {
|
||||
auto words = fplus::split_one_of(std::string{" "}, false, line);
|
||||
|
||||
|
@ -48,6 +48,7 @@ std::optional<TuxClocker::Device::Range<int>> parsePstateRangeLineWithRead(
|
||||
std::string title, AMDGPUData data);
|
||||
|
||||
std::optional<TuxClocker::Device::Range<int>> fromFanCurveContents(const std::string &contents);
|
||||
std::vector<int> fanCurveTempsFromContents(const std::string &contents);
|
||||
|
||||
std::optional<std::pair<int, int>> parseLineValuePair(const std::string &line);
|
||||
|
||||
|
49
src/test/Tests.cpp
Normal file
49
src/test/Tests.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include <AMDUtils.hpp>
|
||||
#include <fplus/fplus.hpp>
|
||||
#include <iostream>
|
||||
#include <Utils.hpp>
|
||||
|
||||
using namespace TuxClocker::Device;
|
||||
|
||||
const char *fanCurvePath = PROJECT_ROOT "/doc/amd-pptables/rx7000-fancurve";
|
||||
const char *fileErrorMessage = "Couldn't read sample file";
|
||||
|
||||
int test(std::vector<std::function<int()>> funcs) {
|
||||
for (int i = 0; i < funcs.size() - 1; i++) {
|
||||
auto ret = funcs[i]();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
return funcs.back()();
|
||||
}
|
||||
|
||||
int failWith(const char *message) {
|
||||
std::cerr << message << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fanCurveParse() {
|
||||
auto contents = fileContents(fanCurvePath);
|
||||
if (!contents.has_value())
|
||||
return failWith(fileErrorMessage);
|
||||
|
||||
auto range = fromFanCurveContents(*contents);
|
||||
if (!range.has_value())
|
||||
return failWith("Couldn't parse fan speed range");
|
||||
|
||||
return !(range->min == 15 && range->max == 100);
|
||||
}
|
||||
|
||||
int fanCurvePointParse() {
|
||||
auto contents = fileContents(fanCurvePath);
|
||||
if (!contents.has_value())
|
||||
return failWith(fileErrorMessage);
|
||||
|
||||
std::vector<int> expectedTemps = {0, 45, 50, 55, 65};
|
||||
auto temps = fanCurveTempsFromContents(*contents);
|
||||
return !(expectedTemps == temps);
|
||||
}
|
||||
|
||||
int main() {
|
||||
return test({fanCurveParse, fanCurvePointParse});
|
||||
}
|
15
src/test/meson.build
Normal file
15
src/test/meson.build
Normal file
@ -0,0 +1,15 @@
|
||||
incdir_tests = [ incdir, '../plugins/' ]
|
||||
|
||||
# https://github.com/mesonbuild/meson/issues/2518
|
||||
# TODO: remove the if when this issue is fixed
|
||||
if get_option('test')
|
||||
amdtests = executable('amdtest',
|
||||
'Tests.cpp', '../plugins/AMDUtils.cpp', '../plugins/Utils.cpp',
|
||||
# Find sample AMD files
|
||||
cpp_args : '-DPROJECT_ROOT="@0@"'.format(meson.source_root()),
|
||||
include_directories : [ incdir_tests, fplus_inc ],
|
||||
dependencies : [ libdrm_amdgpu, libdrm_dep, boost_dep ])
|
||||
|
||||
test('AMD parsing', amdtests,
|
||||
protocol : 'exitcode')
|
||||
endif
|
Loading…
Reference in New Issue
Block a user