From 811890b029b7e4bfedb9eb8d1f7bf66a9e0b8077 Mon Sep 17 00:00:00 2001
From: salixor <salixor@pm.me>
Date: Wed, 31 Jul 2024 01:27:16 +0200
Subject: [PATCH] Have a very basic version of the script up and running

---
 Cargo.lock  | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 Cargo.toml  |   1 +
 src/main.rs |  74 ++++++++++++++++++++++++++++++-
 3 files changed, 197 insertions(+), 1 deletion(-)

diff --git a/Cargo.lock b/Cargo.lock
index d3bdb1e..b0ae3ab 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,55 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "anstream"
+version = "0.6.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
+dependencies = [
+ "anstyle",
+ "windows-sys",
+]
+
 [[package]]
 name = "bitflags"
 version = "2.6.0"
@@ -14,6 +63,52 @@ version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
+[[package]]
+name = "clap"
+version = "4.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
+
+[[package]]
+name = "colorchoice"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
+
 [[package]]
 name = "darling"
 version = "0.20.10"
@@ -55,12 +150,24 @@ version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
 [[package]]
 name = "ident_case"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
 [[package]]
 name = "libloading"
 version = "0.8.5"
@@ -75,6 +182,7 @@ dependencies = [
 name = "nvidia-performance-adjust"
 version = "0.1.0"
 dependencies = [
+ "clap",
  "nvml-wrapper",
 ]
 
@@ -166,6 +274,21 @@ version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
 
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets",
+]
+
 [[package]]
 name = "windows-targets"
 version = "0.52.6"
diff --git a/Cargo.toml b/Cargo.toml
index fdbd910..0404571 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,4 +4,5 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
+clap = { version = "4.5.11", features = ["derive"] }
 nvml-wrapper = { git = "https://github.com/mmstick/nvml-wrapper", branch = "offset" }
diff --git a/src/main.rs b/src/main.rs
index e7a11a9..c75e13e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,75 @@
+use std::process::exit;
+
+use clap::Parser;
+use nvml_wrapper::Nvml;
+
+#[derive(Parser, Debug)]
+struct TargetValues {
+    /// The power limit the GPU should target (in Watts)
+    #[arg(short, long)]
+    power: Option<i32>,
+    /// The clock offset the GPU should apply (in Hz)
+    #[arg(short, long)]
+    clock_offset: Option<i32>,
+    /// The memory clock offset the GPU should apply (in Hz)
+    #[arg(short, long)]
+    mem_clock_offset: Option<i32>,
+}
+
+impl TargetValues {
+    fn all_match_condition<F>(&self, condition: F) -> bool
+    where
+        F: Fn(Option<i32>) -> bool,
+    {
+        condition(self.power) && condition(self.mem_clock_offset) && condition(self.clock_offset)
+    }
+
+    fn all_empty(&self) -> bool {
+        self.all_match_condition(|x: Option<i32>| x.is_none())
+    }
+}
+
+fn to_milliwatts(watts: i32) -> i32 {
+    watts * 1000
+}
+
 fn main() {
-    println!("Hello, world!");
+    let args = TargetValues::parse();
+    let nvml = Nvml::init().unwrap();
+    let mut device = nvml.device_by_index(0).unwrap();
+
+    println!("GPU name: {:?}", device.name().unwrap());
+
+    if args.all_empty() {
+        println!("There is nothing to do!");
+        exit(1);
+    }
+
+    if let Some(power) = args.power {
+        println!("Target {}W power limit.", power);
+        let _power_result =
+            device.set_power_management_limit(to_milliwatts(power).try_into().unwrap());
+        println!(
+            "Effective target power limit: {:?}",
+            device.power_management_limit().unwrap()
+        );
+    }
+
+    if let Some(clock_offset) = args.clock_offset {
+        println!("Target {}Hz GPU clock offset.", clock_offset);
+        let _clock_result = device.set_gpc_clock_vf_offset(clock_offset);
+        println!(
+            "Effective target clock offset: {:?}",
+            device.gpc_clock_vf_offset().unwrap()
+        );
+    }
+
+    if let Some(mem_clock_offset) = args.mem_clock_offset {
+        println!("Target {}Hz GPU memclock offset.", mem_clock_offset);
+        let _mem_clock_result = device.set_mem_clock_vf_offset(mem_clock_offset);
+        println!(
+            "Effective target memory clock offset: {:?}",
+            device.mem_clock_vf_offset().unwrap()
+        );
+    }
 }
-- 
GitLab