This shows you the differences between two versions of the page.
— |
gnucap:manual:tech:plugins:solver [2024/11/26 08:08] (current) felixs created |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Matrix Solver Plugins ====== | ||
+ | ===== Framework ===== | ||
+ | |||
+ | Like other plugins, solvers are loaded using the load command or -a cmdline argument. The SIM_DATA class has two matrices, _aa and _lu. | ||
+ | The former for dc/tran/op (real valued) and the latter for small signal analysis like ac, pz, noise etc. (complex). SIM_DATA is currently statically instanciated in CKT_BASE::_sim. | ||
+ | |||
+ | A matrix is a BSMATRIX<numerical_type>, a "bump and spike" structure for storage. It has a pointer to a solver of type BSMATRIX_SOLVER<numerical_type>, which has a reference to the matrix to solve and a virtual interface. A solver plugin essentially attaches a solver to a matrix, replacing the current solver. | ||
+ | |||
+ | <code> | ||
+ | struct set{ | ||
+ | set(){ | ||
+ | auto x = new MY_SOLVER<double>(CKT_BASE::_sim->_aa); | ||
+ | CKT_BASE::_sim->_aa.set_solver(x); | ||
+ | } | ||
+ | ~set(){ | ||
+ | CKT_BASE::_sim->_aa.set_solver(nullptr); | ||
+ | } | ||
+ | } s; | ||
+ | </code> | ||
+ | |||
+ | The simulator will call virtual functions in the solver that MY_SOLVER is expected to implement. These are | ||
+ | (see m_matrix.h for the definite interface) as follows. | ||
+ | |||
+ | <code> | ||
+ | virtual void init(int ss) = 0; | ||
+ | virtual void uninit() = 0; | ||
+ | virtual void iwant(int, int); | ||
+ | virtual void allocate() = 0; | ||
+ | virtual void unallocate() = 0; | ||
+ | virtual void set_min_pivot(double x) = 0; | ||
+ | |||
+ | virtual void lu_decomp(bool do_partial) = 0; | ||
+ | virtual void fbsub(T*) const; | ||
+ | virtual void fbsub(T* x, const T* b, T* c = nullptr)const; | ||
+ | virtual void fbsubt(T*) const; | ||
+ | |||
+ | virtual void zero(); | ||
+ | |||
+ | virtual void load_diagonal_point(int i, T value); | ||
+ | virtual void load_point(int i, int j, T value); | ||
+ | virtual void load_couple(int i, int j, T value); | ||
+ | virtual void load_symmetric(int i, int j, T value); | ||
+ | virtual void load_asymmetric(int r1, int r2, int c1, int c2, T value); | ||
+ | </code> | ||
+ | |||
+ | Once a matrix is initialised (ss=number of rows/columns), it accepts "iwant" calls passing the coordinates that devices will load into later on. The allocate function is meant to arrange memory for both the load_* and lu_decomp calls. Forward/backward substitution is provided as usual, with variants for "separate output memory" and "transposed". | ||
+ | |||
+ | ===== Examples ===== | ||
+ | |||
+ | Gnucap has two solvers built in and set by default, see m_matrix_solver.h. | ||
+ | An in-place solver, LU_INPLACE, for use in small signal analysis. Another, LU_COPY, solves a copy of the matrix, allowing for partial updates, in cases where repeated solutions of very similar matrices are required. | ||
+ | |||
+ | A compressed sparse version of LU_COPY is (currently) available in tests/cbs.cc. It reduces both the memory use, by computing the exact footprint prior to allocation, and saves time by avoiding operations involving the known zeroes. It also tweaks propagation rules a bit, still numerical results are identical to LU_COPY, by construction. | ||
+ | |||
+ | Using alternative general purpose solvers like KLU or UMFPACK is relatively easy, and wrapper plugins are circulating. Now here's the platform to develop and benchmark the next generation (free/libre) matrix solvers ready for VLSI. |