-
-
Notifications
You must be signed in to change notification settings - Fork 137
Add ngspice shared library support #1497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: current
Are you sure you want to change the base?
Add ngspice shared library support #1497
Conversation
CLAUDE.md
Outdated
|
|
||
| ### Simulation Flow | ||
| 1. User creates schematic in GUI | ||
| 2. Schematic converted to SPICE netlist (via `qucs2spice`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This statement is totally wrong. qucs2spice serves only for conversion of some library models that don't provide SPICE netlist. See the qucs2spice.cpp and look for its usage in the code.
CLAUDE.md
Outdated
| 4. Results parsed and visualized in diagrams | ||
|
|
||
| ### Submodules | ||
| - `qucsator_rf/` is a git submodule (currently empty placeholder) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also wrong. It is not an empty placeholder.
CLAUDE.md
Outdated
| ### Debugging Build Issues | ||
| - Check component library files in `library/` are installed | ||
| - Verify Qt6 development packages present | ||
| - Ensure flex/bison/gperf available for parser generation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flex/bison is required only for QucsatorRF
CLAUDE.md
Outdated
| - Review CMake output for missing dependencies | ||
|
|
||
| ### Working with Schematic Editor | ||
| Key interaction code in `mouseactions.cpp` and `schematic.cpp`. Canvas uses custom Qt3-compatibility scroll view (`Q3ScrollView`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q3ScrollView view is not is use anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noting that currently Schematic still derives from Q3ScrollView. Should I update the CLAUDE.md to note that it is deprecated?
|
Wow, thank you for the early review! I just treated a draft PR for the CI 😅 You're a great maintainer! |
Address maintainer review comments on PR ra3xdh#1497: 1. Correct qucs2spice description - it's for library model format conversion, not general schematic-to-netlist conversion 2. Fix qucsator_rf description - it's a real RF simulator submodule, not an empty placeholder 3. Move flex/bison from required to optional dependencies (only needed for QucsatorRF) 4. Remove Q3ScrollView statement as it's deprecated 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Could you approve CI runs for me? |
Address maintainer review comments on PR ra3xdh#1497: 1. Correct qucs2spice description - it's for library model format conversion, not general schematic-to-netlist conversion 2. Fix qucsator_rf description - it's a real RF simulator submodule, not an empty placeholder 3. Move flex/bison from required to optional dependencies (only needed for QucsatorRF) 4. Remove Q3ScrollView statement as it's deprecated 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
672a604 to
9f84c23
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some notes. Also I feel like there's a clash gonna happen with your approach and AbstractSpiceKernel, but not sure...
| #if EXTERNAL_SIMULATORS | ||
| return a_simProcess->waitForFinished(10000); | ||
| #else | ||
| return true; // For shared library mode, blocking isn't needed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, as the caller fetches results immediately after calling this, we should block for now.
Worth doing another PR to make simulation runs non-blocking.
| #if EXTERNAL_SIMULATORS | ||
| ProcessFailedToStart = static_cast<int>(QProcess::FailedToStart), // 0 | ||
| ProcessCrashed = static_cast<int>(QProcess::Crashed), // 1 | ||
| ProcessTimedOut = static_cast<int>(QProcess::Timedout), // 2 | ||
| ProcessWriteError = static_cast<int>(QProcess::WriteError), // 3 | ||
| ProcessReadError = static_cast<int>(QProcess::ReadError), // 4 | ||
| ProcessUnknownError = static_cast<int>(QProcess::UnknownError) // 5 | ||
| #else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we switch on the process codes to output the right SimulatorError, it seems this isn't needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we error out at the top level if WITH_NGSPICE_SHARED is set and NGSPICE_INCLUDE_DIR/NGSPICE_LIBRARY is not found, then these if statement can just use WITH_NGSPICE_SHARED
It might also be neater to collect these all together in one place.
qucs/extsimkernels/CMakeLists.txt
Outdated
| # Add test for ngspice shared library if enabled | ||
| if(WITH_NGSPICE_SHARED AND NGSPICE_LIBRARY) | ||
| add_executable(test_ngspice_shared test_ngspice_shared.cpp) | ||
| target_link_libraries(test_ngspice_shared PRIVATE extsimkernels Qt6::Core) | ||
| add_test(NAME NgspiceSharedTest COMMAND test_ngspice_shared) | ||
| message(STATUS "NgspiceShared test enabled") | ||
| endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a top level TESTS_ENABLED flag would be useful here.
| void Ngspice::onSharedOutputReceived(const QString &text) | ||
| { | ||
| a_output += text; | ||
| if (a_console != nullptr) { | ||
| a_console->insertPlainText(text); | ||
| a_console->moveCursor(QTextCursor::End); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears this is not called from anywhere!
Document Qucs-S architecture, build system, code organization, and development workflows to help contributors understand the codebase. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Implements support for running simulations using the ngspice shared library
interface alongside the existing external process (QProcess) execution mode.
Key features:
- CMake options: WITH_NGSPICE_SHARED and WITH_EXTERNAL_SIMULATORS
- NgspiceShared wrapper class for libngspice API integration
- Unified SimulatorError enum for type-safe error handling across backends
- Conditional compilation supporting three build configurations:
1. Both modes enabled (shared library priority, external fallback)
2. Shared library only (WebAssembly/Emscripten compatible)
3. External process only (traditional QProcess-based)
- No breaking changes to existing API
Implementation details:
- Created qucs/extsimkernels/ngspice_shared.{h,cpp} wrapper
- Modified AbstractSpiceKernel to conditionally compile QProcess code
- Updated Ngspice class to dispatch to appropriate backend
- SimulatorError enum uses sequential auto-assignment (NoError=0, then 1,2,3...)
- Background commands (bg_*) rejected in shared library mode
- Thread-safe signal emission using Qt::QueuedConnection
- Updated Xyce simulator for conditional QProcess support
Error handling:
- Fixed ExternSimDialog to use SimulatorError instead of QProcess::ProcessError
- All signal connections updated to use unified error enum
- Comprehensive error messages for both backends
- Test suite validates enum uniqueness and error handling
All three build configurations tested and working on macOS.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Create automated test to verify ngspice shared library integration: - Tests basic initialization of NgspiceShared class - Runs simple voltage divider circuit simulation - Verifies Qt signals/callbacks work correctly - Tests error handling for invalid commands/netlists - Validates vector data retrieval from simulation results Test runs via ctest when WITH_NGSPICE_SHARED=ON is enabled. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Create Qt Test-based UI regression test framework: - Add tests/test_ngspice_integration.cpp with Qt Test framework - Tests NgspiceShared initialization, simulation, signals, and data retrieval - Tests run automatically in CI via ctest Add CI support for running tests: - Install xvfb for headless Qt testing on Linux - Run ctest after build step with verbose output - Tests validate NgspiceShared integration works correctly The test suite provides: - Automated validation of ngspice shared library integration - Signal/slot mechanism testing - Simulation result verification - Foundation for future UI regression tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Expanded NgspiceSharedTest to verify behavioral parity between shared library mode and traditional external process execution. This helps detect any behavioral differences introduced by the shared library implementation. Changes: - Added NgspiceExternalProcess helper class to run ngspice as external process (QProcess-based) for comparison - Added test_shared_vs_external() that runs the same circuit through both execution modes - Verifies both modes produce expected outputs (analysis completion, output vectors, node voltages) - Uses single global NgspiceShared instance to avoid multiple initialization issues (ngspice shared library doesn't handle repeated init/cleanup well in same process) - Added proper cleanup to prevent abort signals during test teardown Test results: - Both modes successfully complete circuit simulation - Both modes produce comparable outputs with expected vectors - Shared library: Returns structured vector data via API - External process: Produces text output with analysis results - All 3 test suites pass (GeometryTest, NgspiceSharedTest, NgspiceIntegration) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
ac8bf91 to
53147e8
Compare
This commit adds test_simulation_types.cpp which validates different SPICE simulation types supported by NgspiceShared: Test cases added: - DC operating point analysis with voltage divider - AC frequency sweep analysis with RC filter - Transient time-domain analysis with RC step response - Complex RC filter frequency response validation - RC step response with time constant verification All tests use raw SPICE netlists and verify: - Simulation execution completes successfully - Output vectors are generated correctly - Expected nodes/data are present in results Updated CLAUDE.md with comprehensive documentation on: - New test executable and what it covers - Guidelines for writing simulation type tests - Example SPICE netlist structure for tests All 5 tests pass (including new simulation types test). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Changes: - Add libngspice0-dev to Ubuntu dependencies - Enable WITH_NGSPICE_SHARED=ON in CMake configuration This allows simulation type tests (DC, AC, Transient) to run in CI instead of being skipped. The tests validate NgspiceShared integration with actual circuit simulations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Critical fixes: - Fix memory leak in test cleanup by explicitly deleting NgspiceShared - Remove duplicate test file from qucs/extsimkernels/ directory - Remove duplicate test build configuration from CMakeLists.txt Major improvements: - Add libngspice to macOS CI dependencies (brew install libngspice) - Enable WITH_NGSPICE_SHARED=ON in macOS CI build configuration - Clarify background command rejection comments in ngspice_shared.cpp (ngspice shared library has built-in threading via cbBGThreadRunning) These changes address the critical and major issues identified in code review while maintaining backward compatibility and test coverage. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Summary
WITH_NGSPICE_SHARED(default OFF) andWITH_EXTERNAL_SIMULATORS(default ON)NgspiceSharedwrapper class for the shared library APISimulatorErrorenum for type-safe error handling across both backendsTest plan
WITH_NGSPICE_SHARED=ON WITH_EXTERNAL_SIMULATORS=OFF🤖 Generated with Claude Code