Skip to content

Commit 5e112cb

Browse files
committed
Minor changes in project settings.
1 parent bc32fd7 commit 5e112cb

4 files changed

Lines changed: 65 additions & 69 deletions

File tree

‎LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Pythoniasm
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md‎

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Built for the modern sovereign miner, optimized for freedom.
99

1010
## 🛠 What Is This?
1111

12-
A CLI-based Python tuner that runs multi-objective optimization on your ESPminer.
12+
A CLI-based tuner that runs multi-objective optimization on your ESPminer.
1313
It finds the best balance of:
1414
- 🧠 **Hashrate** (TH/s)
1515
- 🔌 **Efficiency** (J/TH)
@@ -46,15 +46,7 @@ To enhance your ESPminer optimization workflow, consider integrating the Optuna
4646

4747
Install dependencies:
4848
```bash
49-
pip install -r requirements.txt
50-
```
51-
52-
Required Python packages:
53-
```
54-
optuna
55-
requests
56-
pandas
57-
rich
49+
pip install .
5850
```
5951

6052
---
@@ -98,7 +90,7 @@ Each trial logs:
9890
In a separate terminal, start the dashboard:
9991

10092
```bash
101-
optuna-dashboard sqlite:///db.sqlite3
93+
optuna-dashboard sqlite:///espminer-optim-db.sqlite3
10294
```
10395

10496
This will start a local server, typically accessible at `http://localhost:8080/`.

‎optimize.py‎

Lines changed: 28 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
import optuna
2-
import requests
3-
import time
4-
import pandas as pd
5-
import os
61
import json
2+
import os
3+
import time
4+
75
import numpy as np
6+
import optuna
7+
import pandas as pd
8+
import requests
89
from rich.console import Console
9-
from rich.prompt import Prompt, IntPrompt, Confirm
10-
from rich.table import Table
1110
from rich.progress import (
11+
BarColumn,
1212
Progress,
1313
SpinnerColumn,
14-
TimeElapsedColumn,
15-
BarColumn,
1614
TextColumn,
15+
TimeElapsedColumn,
1716
)
17+
from rich.prompt import Confirm, IntPrompt, Prompt
18+
from rich.table import Table
19+
1820

1921
# Initialize rich console
2022
console = Console()
@@ -25,30 +27,18 @@
2527
device_ip = Prompt.ask("Enter Bitaxe device URI", default="192.168.1.4")
2628
study_name = Prompt.ask("Enter trial name", default="espmineroptim")
2729
n_trials = IntPrompt.ask("Enter number of trials", default=10, show_default=True)
28-
trial_length_s = (
29-
IntPrompt.ask("Enter trial duration (min.)", default=1, show_default=True) * 60
30-
)
30+
trial_length_s = IntPrompt.ask("Enter trial duration (min.)", default=1, show_default=True) * 60
3131

3232
# Frequency bounds
33-
min_frequency_MHz = IntPrompt.ask(
34-
"Enter minimum frequency (MHz)", default=400, show_default=True
35-
)
36-
max_frequency_MHz = IntPrompt.ask(
37-
"Enter maximum frequency (MHz)", default=625, show_default=True
38-
)
33+
min_frequency_MHz = IntPrompt.ask("Enter minimum frequency (MHz)", default=400, show_default=True)
34+
max_frequency_MHz = IntPrompt.ask("Enter maximum frequency (MHz)", default=625, show_default=True)
3935

4036
# Voltage bounds
41-
min_coreVoltage_mV = IntPrompt.ask(
42-
"Enter minimum coreVoltage (mV)", default=1000, show_default=True
43-
)
44-
max_coreVoltage_mV = IntPrompt.ask(
45-
"Enter maximum coreVoltage (mV)", default=1250, show_default=True
46-
)
37+
min_coreVoltage_mV = IntPrompt.ask("Enter minimum coreVoltage (mV)", default=1000, show_default=True)
38+
max_coreVoltage_mV = IntPrompt.ask("Enter maximum coreVoltage (mV)", default=1250, show_default=True)
4739

4840
limit_temp_degC = IntPrompt.ask("Enter temp limit (°C)", default=68, show_default=True)
49-
limit_vrTemp_degC = IntPrompt.ask(
50-
"Enter voltage regulator temp limit coreVoltage (°C)", default=78, show_default=True
51-
)
41+
limit_vrTemp_degC = IntPrompt.ask("Enter voltage regulator temp limit coreVoltage (°C)", default=78, show_default=True)
5242
confirmed = Confirm.ask("Check your inputs above. Start optimizing?")
5343
if not confirmed:
5444
exit(0)
@@ -98,19 +88,15 @@ def run_trial(frequency_MHz, coreVoltage_mV, trial_number):
9888
headers = {"Content-Type": "application/json"}
9989
payload = {"frequency": int(frequency_MHz), "coreVoltage": int(coreVoltage_mV)}
10090

101-
response = requests.patch(
102-
SETTINGS_URL, headers=headers, data=json.dumps(payload), timeout=10
103-
)
91+
response = requests.patch(SETTINGS_URL, headers=headers, data=json.dumps(payload), timeout=10)
10492
response.raise_for_status()
10593
time.sleep(1)
10694

10795
console.print("[cyan]→ Restarting device...[/cyan]")
10896
restart_response = requests.post(RESET_URL, timeout=10)
10997
restart_response.raise_for_status()
11098

111-
console.print(
112-
"[yellow]⏳ Waiting 30 seconds for system stabilization...[/yellow]"
113-
)
99+
console.print("[yellow]⏳ Waiting 30 seconds for system stabilization...[/yellow]")
114100
time.sleep(30)
115101

116102
hashRates_THps = []
@@ -123,9 +109,7 @@ def run_trial(frequency_MHz, coreVoltage_mV, trial_number):
123109
TimeElapsedColumn(),
124110
transient=True,
125111
) as progress:
126-
task = progress.add_task(
127-
"[green]Collecting system stats...", total=trial_length_s // 10
128-
)
112+
task = progress.add_task("[green]Collecting system stats...", total=trial_length_s // 10)
129113

130114
for _ in range(trial_length_s // 10):
131115
stats_response = requests.get(STATS_URL, timeout=10)
@@ -139,17 +123,11 @@ def run_trial(frequency_MHz, coreVoltage_mV, trial_number):
139123
actual_coreVoltage_mV = stats.get("coreVoltage", 0)
140124

141125
try:
142-
np.testing.assert_allclose(
143-
actual_frequency_MHz, frequency_MHz, rtol=1e-3
144-
)
145-
np.testing.assert_allclose(
146-
actual_coreVoltage_mV, coreVoltage_mV, rtol=1e-3
147-
)
126+
np.testing.assert_allclose(actual_frequency_MHz, frequency_MHz, rtol=1e-3)
127+
np.testing.assert_allclose(actual_coreVoltage_mV, coreVoltage_mV, rtol=1e-3)
148128
except AssertionError:
149129
console.print_exception()
150-
console.print(
151-
"[bold red]Real parameter not set within tolerance of 1%[/bold red]"
152-
)
130+
console.print("[bold red]Real parameter not set within tolerance of 1%[/bold red]")
153131
console.print()
154132
return
155133

@@ -159,9 +137,7 @@ def run_trial(frequency_MHz, coreVoltage_mV, trial_number):
159137
)
160138

161139
if temp_degC > limit_temp_degC or vrTemp_degC > limit_vrTemp_degC:
162-
console.print(
163-
"[bold red]❌ Temperature too high! Aborting.[/bold red]"
164-
)
140+
console.print("[bold red]❌ Temperature too high! Aborting.[/bold red]")
165141
return
166142

167143
hashRates_THps.append(hashRate_THps)
@@ -175,9 +151,7 @@ def run_trial(frequency_MHz, coreVoltage_mV, trial_number):
175151

176152
avg_hashRate_THps = sum(hashRates_THps) / len(hashRates_THps)
177153
avg_power_W = sum(powers_W) / len(powers_W)
178-
avg_efficiency_JpTH = (
179-
avg_power_W / avg_hashRate_THps if avg_hashRate_THps != 0 else 0
180-
)
154+
avg_efficiency_JpTH = avg_power_W / avg_hashRate_THps if avg_hashRate_THps != 0 else 0
181155
# scoring = (
182156
# hashRate_factor * avg_hashRate_THps
183157
# - efficiency_factor * avg_efficiency_JpTH
@@ -220,20 +194,16 @@ def run_trial(frequency_MHz, coreVoltage_mV, trial_number):
220194

221195

222196
def run_study(trial):
223-
frequency_MHz = trial.suggest_float(
224-
"frequency", float(min_frequency_MHz), float(max_frequency_MHz)
225-
)
226-
coreVoltage_mV = trial.suggest_float(
227-
"coreVoltage", float(min_coreVoltage_mV), float(max_coreVoltage_mV)
228-
)
197+
frequency_MHz = trial.suggest_float("frequency", float(min_frequency_MHz), float(max_frequency_MHz))
198+
coreVoltage_mV = trial.suggest_float("coreVoltage", float(min_coreVoltage_mV), float(max_coreVoltage_mV))
229199
return run_trial(frequency_MHz, coreVoltage_mV, trial.number)
230200

231201

232202
if __name__ == "__main__":
233203
console.print("[bold green]Starting Bitaxe Optimization...[/bold green]")
234204
study = optuna.create_study(
235205
directions=["maximize", "minimize"],
236-
storage="sqlite:///db.sqlite3", # Specify the storage URL here.
206+
storage="sqlite:///espminer-optim-db.sqlite3", # Specify the storage URL here.
237207
study_name=study_name,
238208
load_if_exists=True,
239209
)

‎pyproject.toml‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,16 @@ dependencies = [
1212
"rich>=14.0.0",
1313
"ruff>=0.11.5",
1414
]
15+
16+
[tool.ruff]
17+
line-length = 120
18+
19+
[tool.ruff.format]
20+
quote-style = "double"
21+
22+
[tool.ruff.lint]
23+
extend-select = ["I"]
24+
extend-ignore = ["E402","E722","E731"]
25+
26+
[tool.ruff.lint.isort]
27+
lines-after-imports = 2

0 commit comments

Comments
 (0)