Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
- name: Install ngspice
shell: powershell
run: |
curl.exe -L -o ngspice.7z "https://downloads.sourceforge.net/project/ngspice/ng-spice-rework/45.2/ngspice-45.2_64.7z"
curl.exe -L -o ngspice.7z "https://sourceforge.net/projects/ngspice/files/ng-spice-rework/old-releases/45.2/ngspice-45.2_64.7z"

7z x ngspice.7z -o"C:\Program Files"

Expand Down Expand Up @@ -79,9 +79,17 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install ngspice
run: |
brew install ngspice # for power electronics problems
# - name: Install ngspice
# run: |
# # for power electronics problems
# VERSION=45.2
# brew tap-new local/oldies
# brew extract --version=$VERSION ngspice local/oldies
# # Fix outdated URL:
# sed -i -e "s|ng-spice-rework/|ng-spice-rework/old-releases/|" /opt/homebrew/Library/Taps/local/homebrew-oldies/Formula/ngspice@${VERSION}.rb
# brew install local/oldies/ngspice@$VERSION
# brew pin ngspice@$VERSION
# ngspice --version
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
40 changes: 21 additions & 19 deletions engibench/problems/power_electronics/utils/ngspice.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import platform
import re
import shutil
import subprocess

MIN_SUPPORTED_VERSION: int = 42 # Major version number of ngspice
Expand All @@ -28,27 +29,25 @@ def _get_ngspice_path(self) -> str:
"""Get the path to the ngspice executable based on the operating system.

Returns:
The path to ngspice executable or None if not found
The path to the ngspice executable
"""
if self.system == "windows":
# For Windows, use the bundled ngspice.exe
# Look for ngspice in Spice64 folder and common install locations
# Look for ngspice in PATH (e.g. Chocolatey), Spice64 folder and common install locations
possible_paths = [
self.ngspice_windows_path,
"ngspice.exe",
shutil.which("ngspice"),
os.path.normpath(os.path.join("C:/Program Files/Spice64/bin/ngspice.exe")),
os.path.normpath(os.path.join("C:/Program Files (x86)/ngspice/bin/ngspice.exe")),
]

for path in possible_paths:
if path and os.path.exists(path):
ngspice_path: str | None = path
break
else:
ngspice_path = possible_paths[0] # Default to first path if none found
if ngspice_path is None or not os.path.exists(ngspice_path):
ngspice_path: str | None = next((p for p in possible_paths if p and os.path.exists(p)), None)
if ngspice_path is None:
raise FileNotFoundError(
f"ngspice.exe not found at {ngspice_path}. You can download it from https://sourceforge.net/projects/ngspice/files/ng-spice-rework/45.2/. You can also see our GitHub Actions workflow (test.yml) for how to automatically install it."
"ngspice.exe not found. You can install it via Chocolatey "
"(`choco install ngspice`) or download it from "
"https://sourceforge.net/projects/ngspice/files/ng-spice-rework/. "
"You can also see our GitHub Actions workflow (test.yml) for how to automatically install it."
)
return ngspice_path
if self.system in ["darwin", "linux"]:
Expand Down Expand Up @@ -108,18 +107,21 @@ def version(self) -> int:
subprocess.CalledProcessError: If ngspice fails to run
"""
if self.system == "windows":
# Try finding the version from the docs folder (for SourceForge binary package)
pattern_int = re.compile(r"ngspice-(\d+)-manual\.pdf")
pattern_dec = re.compile(r"ngspice-(\d+\.\d+)-manual\.pdf")

docs_path = os.path.normpath(os.path.join(os.path.dirname(self._ngspice_path), "../docs/"))
for filename in os.listdir(docs_path):
match_int = pattern_int.match(filename)
match_dec = pattern_dec.match(filename)
if match_int:
return int(match_int.group(1)) # Already returns just the major version
if match_dec:
return int(match_dec.group(1).split(".")[0]) # Return only the major version
raise NgSpiceManualNotFoundError
try:
for filename in os.listdir(docs_path):
match_int = pattern_int.match(filename)
match_dec = pattern_dec.match(filename)
if match_int:
return int(match_int.group(1)) # Already returns just the major version
if match_dec:
return int(match_dec.group(1).split(".")[0]) # Return only the major version
except OSError:
print(f"Could not read ngspice docs folder at {docs_path!r}, falling back to --version flag.")

cmd = [self._ngspice_path, "--version"]
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
Expand Down
2 changes: 2 additions & 0 deletions tests/test_problem_implementations.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ def test_python_problem_impl(problem_class: type[Problem]) -> None:
"""
if problem_class.container_id is not None and not sys.platform.startswith("linux"):
pytest.skip(f"Skipping containerized problem {problem_class.__name__} on non-linux platform")
if problem_class.__module__.startswith("engibench.problems.power_electronics") and sys.platform == "darwin":
pytest.skip(f"Skipping {problem_class.__name__} on MacOs")
print(f"Testing optimization and simulation for {problem_class.__name__}...")
# Initialize problem and get a random design
problem = problem_class(seed=1)
Expand Down
Loading