From b91e3c3a6a861192a79cf5ea243fb0bd45b58006 Mon Sep 17 00:00:00 2001 From: couriersud Date: Sat, 12 Jan 2019 00:35:08 +0100 Subject: Removed most inlines not necessary ... (nw) On some I wasn't entirely sure :-( Thanks Vas: https://github.com/mamedev/mame/commit/0f0e8853f33bef49bc6f5bd8b53444d209699e44#r31909683 --- src/lib/netlist/plib/pstate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/netlist/plib/pstate.h') diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h index 9757d6408b7..91534a56663 100644 --- a/src/lib/netlist/plib/pstate.h +++ b/src/lib/netlist/plib/pstate.h @@ -40,7 +40,7 @@ public: template struct datatype_f { - static inline const datatype_t f() + static const datatype_t f() { return datatype_t(sizeof(T), plib::is_integral::value || std::is_enum::value, -- cgit v1.2.3-70-g09d2 From 32b0442c732dff5f062abf895db4d74b8feedcc7 Mon Sep 17 00:00:00 2001 From: couriersud Date: Mon, 21 Jan 2019 00:36:57 +0100 Subject: netlist: refactor code for better scalability and flexibility. (nw) These changes aim to remove some of the duplication of code in the various solvers. Tested with gcc-7 clang-8 and nvcc-9.2 --- src/lib/netlist/build/makefile | 3 +- src/lib/netlist/nl_base.h | 4 +- src/lib/netlist/plib/parray.h | 117 +++++++++ src/lib/netlist/plib/pstate.h | 2 +- src/lib/netlist/solver/mat_cr.h | 372 ++++++++++++++++++++++++----- src/lib/netlist/solver/nld_matrix_solver.h | 75 ++++-- src/lib/netlist/solver/nld_ms_direct.h | 153 +++++------- src/lib/netlist/solver/nld_ms_direct1.h | 50 ++-- src/lib/netlist/solver/nld_ms_direct2.h | 61 ++--- src/lib/netlist/solver/nld_ms_gcr.h | 314 ++++++------------------ src/lib/netlist/solver/nld_ms_gmres.h | 242 +++++++++---------- src/lib/netlist/solver/nld_ms_sm.h | 102 ++++---- src/lib/netlist/solver/nld_ms_sor.h | 66 ++--- src/lib/netlist/solver/nld_ms_sor_mat.h | 74 +++--- src/lib/netlist/solver/nld_ms_w.h | 109 +++++---- src/lib/netlist/solver/nld_solver.cpp | 69 +++--- src/lib/netlist/solver/nld_solver.h | 2 +- src/lib/netlist/solver/vector_base.h | 100 ++++---- src/mame/audio/nl_kidniki.cpp | 5 +- 19 files changed, 1053 insertions(+), 867 deletions(-) create mode 100644 src/lib/netlist/plib/parray.h (limited to 'src/lib/netlist/plib/pstate.h') diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 272f1718429..e291737dd71 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -207,7 +207,7 @@ native: $(MAKE) CEXTRAFLAGS="-march=native -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter" clang: - $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-march=native -Wno-unused-parameter -Weverything -Werror -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wweak-template-vtables -Wno-exit-time-destructors" + $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-march=native -Wno-c++11-narrowing -Wno-unused-parameter -Weverything -Werror -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wweak-template-vtables -Wno-exit-time-destructors" clang-5: $(MAKE) CC=clang++-5.0 LD=clang++-5.0 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-inconsistent-missing-destructor-override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors" @@ -217,6 +217,7 @@ nvcc: CEXTRAFLAGS="-x cu -DNVCCBUILD=1 --expt-extended-lambda --expt-relaxed-constexpr --default-stream per-thread --restrict" # +# -Wno-c++11-narrowing : seems a bit broken # Mostly done: -Wno-weak-vtables -Wno-cast-align # FIXME: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-exit-time-destructors # FIXME: -Winconsistent-missing-destructor-override : c++ community has diverging opinions on this https://github.com/isocpp/CppCoreGuidelines/issues/721 diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 97f83735028..f50f45b12de 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -322,11 +322,11 @@ namespace netlist const T &value //!< Initial value after construction ); //! Copy Constructor. - constexpr state_var(const state_var &rhs) noexcept = default; + constexpr state_var(const state_var &rhs) = default; //! Move Constructor. constexpr state_var(state_var &&rhs) noexcept = default; //! Assignment operator to assign value of a state var. - C14CONSTEXPR state_var &operator=(const state_var &rhs) noexcept = default; + C14CONSTEXPR state_var &operator=(const state_var &rhs) = default; //! Assignment move operator to assign value of a state var. C14CONSTEXPR state_var &operator=(state_var &&rhs) noexcept = default; //! Assignment operator to assign value of type T. diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h new file mode 100644 index 00000000000..b40fd7f712f --- /dev/null +++ b/src/lib/netlist/plib/parray.h @@ -0,0 +1,117 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * parray.h + * + */ + +#ifndef PARRAY_H_ +#define PARRAY_H_ + +#include "pconfig.h" +#include "pexception.h" + +#include +#include +#include +#include +#include + +namespace plib { + + template + struct sizeabs + { + static constexpr std::size_t ABS() { return (SIZE < 0) ? static_cast(0 - SIZE) : static_cast(SIZE); } + typedef typename std::array container; + }; + + template + struct sizeabs + { + static constexpr const std::size_t ABS = 0; + typedef typename std::vector container; + }; + + /** + * \brief Array with preallocated or dynamic allocation + * + * Passing SIZE > 0 has the same functionality as a std::array. + * SIZE = 0 is pure dynamic allocation, the actual array size is passed to the + * constructor. + * SIZE < 0 reserves std::abs(SIZE) elements statically in place allocated. The + * actual size is passed in by the constructor. + * This array is purely intended for HPC application where depending on the + * architecture a preference dynamic/static has to be made. + * + * This struct is not intended to be a full replacement to std::array. + * It is a subset to enable switching between dynamic and static allocation. + * I consider > 10% performance difference to be a use case. + */ + + template + struct parray + { + public: + static constexpr std::size_t SIZEABS() { return sizeabs::ABS(); } + + typedef typename sizeabs::container base_type; + typedef typename base_type::size_type size_type; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + + template + parray(size_type size, typename std::enable_if::type = 0) + : m_a(size), m_size(size) + { + } + +#if 0 + /* allow construction in fixed size arrays */ + template + parray(typename std::enable_if::type = 0) + : m_size(0) + { + } +#endif + template + parray(size_type size, typename std::enable_if::type = 0) + : m_size(size) + { + if (SIZE < 0 && size > SIZEABS()) + throw plib::pexception("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZEABS())); + else if (SIZE > 0 && size != SIZEABS()) + throw plib::pexception("parray: size error"); + } + + inline size_type size() const noexcept { return SIZE <= 0 ? m_size : SIZEABS(); } + + constexpr size_type max_size() const noexcept { return base_type::max_size(); } + + bool empty() const noexcept { return size() == 0; } + +#if 0 + reference operator[](size_type i) /*noexcept*/ + { + if (i >= m_size) throw plib::pexception("limits error " + to_string(i) + ">=" + to_string(m_size)); + return m_a[i]; + } + const_reference operator[](size_type i) const /*noexcept*/ + { + if (i >= m_size) throw plib::pexception("limits error " + to_string(i) + ">=" + to_string(m_size)); + return m_a[i]; + } +#else + reference operator[](size_type i) noexcept { return m_a[i]; } + constexpr const_reference operator[](size_type i) const noexcept { return m_a[i]; } +#endif + FT * data() noexcept { return m_a.data(); } + const FT * data() const noexcept { return m_a.data(); } + + private: + base_type m_a; + size_type m_size; + }; +} + +#endif /* PARRAY_H_ */ diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h index 91534a56663..5b8acc92221 100644 --- a/src/lib/netlist/plib/pstate.h +++ b/src/lib/netlist/plib/pstate.h @@ -103,7 +103,7 @@ public: template void save_item(const void *owner, std::vector &v, const pstring &stname) { - save_state(v.data(), owner, stname, v.size()); + save_state_ptr(owner, stname, datatype_f::f(), v.size(), v.data()); } void pre_save(); diff --git a/src/lib/netlist/solver/mat_cr.h b/src/lib/netlist/solver/mat_cr.h index 8693c49c3e1..57e7fafdac3 100644 --- a/src/lib/netlist/solver/mat_cr.h +++ b/src/lib/netlist/solver/mat_cr.h @@ -11,60 +11,232 @@ #define MAT_CR_H_ #include +#include +#include +#include +#include + #include "../plib/pconfig.h" #include "../plib/palloc.h" +#include "../plib/pstate.h" +#include "../plib/parray.h" + +namespace plib +{ -template +template struct mat_cr_t { typedef C index_type; typedef T value_type; - C diag[N]; // diagonal index pointer n - C ia[N+1]; // row index pointer n + 1 - C ja[N*N]; // column index array nz_num, initially (n * n) - T A[N*N]; // Matrix elements nz_num, initially (n * n) + parray diag; // diagonal index pointer n + parray row_idx; // row index pointer n + 1 + parray col_idx; // column index array nz_num, initially (n * n) + parray A; // Matrix elements nz_num, initially (n * n) + //parray nzbd; // Support for gaussian elimination + parray nzbd; // Support for gaussian elimination + // contains elimination rows below the diagonal - std::size_t size; + std::size_t m_size; std::size_t nz_num; explicit mat_cr_t(const std::size_t n) - : size(n) + : diag(n) + , row_idx(n+1) + , col_idx(n*n) + , A(n*n) + , nzbd(n * (n+1) / 2) + , m_size(n) , nz_num(0) { -#if 0 -#if 0 - ia = plib::palloc_array(n + 1); - ja = plib::palloc_array(n * n); - diag = plib::palloc_array(n); -#else - diag = plib::palloc_array(n + (n + 1) + n * n); - ia = diag + n; - ja = ia + (n+1); - A = plib::palloc_array(n * n); -#endif -#endif + for (std::size_t i=0; i 0 && col_idx[ri] == c) + A[ri] = val; + else + { + for (C i = nz_num; i>ri; i--) + { + A[i] = A[i-1]; + col_idx[i] = col_idx[i-1]; + } + A[ri] = val; + col_idx[ri] = c; + for (C i = row_idx[r]; i < size()+1;i++) + row_idx[i]++; + nz_num++; + if (c==r) + diag[r] = ri; + } + } + + enum constants_e + { + FILL_INFINITY = 9999999 + }; + + template + std::pair gaussian_extend_fill_mat(M &fill) + { + std::size_t ops = 0; + std::size_t fill_max = 0; + + for (std::size_t k = 0; k < fill.size(); k++) + { + ops++; // 1/A(k,k) + for (std::size_t row = k + 1; row < fill.size(); row++) + { + if (fill[row][k] < FILL_INFINITY) + { + ops++; + for (std::size_t col = k + 1; col < fill[row].size(); col++) + //if (fill[k][col] < FILL_INFINITY) + { + auto f = std::min(fill[row][col], 1 + fill[row][k] + fill[k][col]); + if (f < FILL_INFINITY) + { + if (f > fill_max) + fill_max = f; + ops += 2; + } + fill[row][col] = f; + } + } + } + } + return { fill_max, ops }; + } + + template + void build_from_fill_mat(const M &f, std::size_t max_fill = FILL_INFINITY - 1, + unsigned band_width = FILL_INFINITY) + { + C nz = 0; + if (nz_num != 0) + throw pexception("build_from_mat only allowed on empty CR matrix"); + for (std::size_t k=0; k < size(); k++) + { + row_idx[k] = nz; + + for (std::size_t j=0; j < size(); j++) + if (f[k][j] <= max_fill && std::abs(static_cast(k)-static_cast(j)) <= static_cast(band_width)) + { + col_idx[nz] = static_cast(j); + if (j == k) + diag[k] = nz; + nz++; + } + } + + row_idx[size()] = nz; + nz_num = nz; + /* build nzbd */ + + std::size_t p=0; + for (std::size_t k=0; k < size(); k++) + { + for (std::size_t j=k + 1; j < size(); j++) + if (f[j][k] < FILL_INFINITY) + nzbd[p++] = static_cast(j); + nzbd[p++] = 0; // end of sequence + } + } + + template + void gaussian_elimination(V & RHS) + { + std::size_t nzbdp = 0; + const std::size_t iN = size(); + + for (std::size_t i = 0; i < iN - 1; i++) + { + std::size_t pi = diag[i]; + const value_type f = 1.0 / A[pi++]; + const std::size_t piie = row_idx[i+1]; + + while (auto j = nzbd[nzbdp++]) + { + // proceed to column i + std::size_t pj = row_idx[j]; + + while (col_idx[pj] < i) + pj++; + + const value_type f1 = - A[pj++] * f; + + // subtract row i from j */ + for (std::size_t pii = pi; pii + void gaussian_back_substitution(V1 &V, const V2 &RHS) + { + const std::size_t iN = size(); + /* row n-1 */ + V[iN - 1] = RHS[iN - 1] / A[diag[iN - 1]]; + + for (std::size_t j = iN - 1; j-- > 0;) + { + value_type tmp = 0; + const auto jdiag = diag[j]; + const std::size_t e = row_idx[j+1]; + for (std::size_t pk = jdiag + 1; pk < e; pk++) + tmp += A[pk] * V[col_idx[pk]]; + V[j] = (RHS[j] - tmp) / A[jdiag]; + } + } + + template + void gaussian_back_substitution(V1 &V) + { + const std::size_t iN = size(); + /* row n-1 */ + V[iN - 1] = V[iN - 1] / A[diag[iN - 1]]; + + for (std::size_t j = iN - 1; j-- > 0;) + { + value_type tmp = 0; + const auto jdiag = diag[j]; + const std::size_t e = row_idx[j+1]; + for (std::size_t pk = jdiag + 1; pk < e; pk++) + tmp += A[pk] * V[col_idx[pk]]; + V[j] = (V[j] - tmp) / A[jdiag]; + } + } + + + template + void mult_vec(const VTV & RESTRICT x, VTR & RESTRICT res) { /* * res = A * x @@ -77,14 +249,68 @@ struct mat_cr_t while (k < oe) { T tmp = 0.0; - const std::size_t e = ia[i+1]; + const std::size_t e = row_idx[i+1]; for (; k < e; k++) - tmp += A[k] * x[ja[k]]; + tmp += A[k] * x[col_idx[k]]; res[i++] = tmp; } } - void incomplete_LU_factorization(T * RESTRICT LU) + /* throws error if P(source)>P(destination) */ + template + void slim_copy_from(LUMAT & src) + { + for (std::size_t r=0; r + void reduction_copy_from(LUMAT & src) + { + C sp = 0; + for (std::size_t r=0; r + void raw_copy_from(LUMAT & src) + { + for (std::size_t k = 0; k < nz_num; k++) + A[k] = src.A[k]; + } + + void incomplete_LU_factorization() { /* * incomplete LU Factorization according to http://de.wikipedia.org/wiki/ILU-Zerlegung @@ -93,38 +319,67 @@ struct mat_cr_t * */ +#if 0 const std::size_t lnz = nz_num; - for (std::size_t k = 0; k < lnz; k++) - LU[k] = A[k]; - - for (std::size_t i = 1; ia[i] < lnz; i++) // row i + for (std::size_t i = 1; row_idx[i] < lnz; i++) // row i { - const std::size_t iai1 = ia[i + 1]; - const std::size_t pke = diag[i]; - for (std::size_t pk = ia[i]; pk < pke; pk++) // all columns left of diag in row i + const std::size_t p_i_end = row_idx[i + 1]; + // loop over all columns left of diag in row i + for (std::size_t p_i_k = row_idx[i]; p_i_k < diag[i]; p_i_k++) { // pk == (i, k) - const std::size_t k = ja[pk]; - const std::size_t iak1 = ia[k + 1]; - const T LUpk = LU[pk] = LU[pk] / LU[diag[k]]; + const std::size_t k = col_idx[p_i_k]; + // get start of row k + const std::size_t p_k_end = row_idx[k + 1]; + + const T LUp_i_k = A[p_i_k] = A[p_i_k] / A[diag[k]]; - std::size_t pt = ia[k]; + std::size_t p_k_j = row_idx[k]; - for (std::size_t pj = pk + 1; pj < iai1; pj++) // pj = (i, j) + for (std::size_t p_i_j = p_i_k + 1; p_i_j < p_i_end; p_i_j++) // pj = (i, j) { // we can assume that within a row ja increases continuously */ - const std::size_t ej = ja[pj]; - while (ja[pt] < ej && pt < iak1) - pt++; - if (pt < iak1 && ja[pt] == ej) - LU[pj] = LU[pj] - LUpk * LU[pt]; + const std::size_t j = col_idx[p_i_j]; // row i, column j + while (col_idx[p_k_j] < j && p_k_j < p_k_end) + p_k_j++; + if (p_k_j < p_k_end && col_idx[p_k_j] == j) + A[p_i_j] = A[p_i_j] - LUp_i_k * A[p_k_j]; } } } - } +#else + for (std::size_t i = 1; i < m_size; i++) // row i + { + const std::size_t p_i_end = row_idx[i + 1]; + // loop over all columns k left of diag in row i + for (std::size_t i_k = row_idx[i]; i_k < diag[i]; i_k++) + { + const std::size_t k = col_idx[i_k]; + const std::size_t p_k_end = row_idx[k + 1]; + const T LUp_i_k = A[i_k] = A[i_k] / A[diag[k]]; + + // get start of row k + //std::size_t k_j = row_idx[k]; + std::size_t k_j = diag[k]; - void solveLUx (const T * RESTRICT LU, T * RESTRICT r) + for (std::size_t i_j = i_k + 1; i_j < p_i_end; i_j++) // pj = (i, j) + { + // we can assume that within a row ja increases continuously */ + const std::size_t j = col_idx[i_j]; // row i, column j + while (col_idx[k_j] < j && k_j < p_k_end) + k_j++; + if (k_j >= p_k_end) + break; + if (col_idx[k_j] == j) + A[i_j] = A[i_j] - LUp_i_k * A[k_j]; + } + } + } +#endif + } + template + void solveLUx (R &r) { /* * Solve a linear equation Ax = r @@ -147,29 +402,30 @@ struct mat_cr_t * This can be solved for x using backwards elimination in U. * */ - - for (std::size_t i = 1; ia[i] < nz_num; ++i ) + for (std::size_t i = 1; i < m_size; ++i ) { T tmp = 0.0; - const std::size_t j1 = ia[i]; + const std::size_t j1 = row_idx[i]; const std::size_t j2 = diag[i]; for (std::size_t j = j1; j < j2; ++j ) - tmp += LU[j] * r[ja[j]]; + tmp += A[j] * r[col_idx[j]]; r[i] -= tmp; } // i now is equal to n; - for (std::size_t i = size; i-- > 0; ) + for (std::size_t i = m_size; i-- > 0; ) { T tmp = 0.0; const std::size_t di = diag[i]; - const std::size_t j2 = ia[i+1]; + const std::size_t j2 = row_idx[i+1]; for (std::size_t j = di + 1; j < j2; j++ ) - tmp += LU[j] * r[ja[j]]; - r[i] = (r[i] - tmp) / LU[di]; + tmp += A[j] * r[col_idx[j]]; + r[i] = (r[i] - tmp) / A[di]; } } }; +} + #endif /* MAT_CR_H_ */ diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index f43f0e06f6f..cb2c1b86a47 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -54,12 +54,43 @@ public: void set_pointers(); + template + void fill_matrix(AP &tcr, FT &RHS) + { + FT gtot_t = 0.0; + FT RHS_t = 0.0; + + const std::size_t term_count = this->count(); + const std::size_t railstart = this->m_railstart; + const FT * const * RESTRICT other_cur_analog = this->connected_net_V(); + + for (std::size_t i = 0; i < railstart; i++) + { + *tcr[i] -= m_go[i]; + gtot_t += m_gt[i]; + RHS_t += m_Idr[i]; + } + + for (std::size_t i = railstart; i < term_count; i++) + { + RHS_t += (m_Idr[i] + m_go[i] * *other_cur_analog[i]); + gtot_t += m_gt[i]; + } + + RHS = RHS_t; + // update diagonal element ... + *tcr[railstart] += gtot_t; //mat.A[mat.diag[k]] += gtot_t; + } + std::size_t m_railstart; std::vector m_nz; /* all non zero for multiplication */ std::vector m_nzrd; /* non zero right of the diagonal for elimination, may include RHS element */ std::vector m_nzbd; /* non zero below of the diagonal for elimination */ + + + /* state */ nl_double m_last_V; nl_double m_DD_n_m_1; @@ -157,14 +188,15 @@ protected: /* virtual */ void add_term(std::size_t net_idx, terminal_t *term); template - void store(const T * RESTRICT V); + void store(const T & RESTRICT V); + template - T delta(const T * RESTRICT V); + auto delta(const T & RESTRICT V) -> typename std::decay::type; template - void build_LE_A(); + void build_LE_A(T &child); template - void build_LE_RHS(); + void build_LE_RHS(T &child); std::vector> m_terms; std::vector m_nets; @@ -199,7 +231,7 @@ private: }; template -T matrix_solver_t::delta(const T * RESTRICT V) +auto matrix_solver_t::delta(const T & RESTRICT V) -> typename std::decay::type { /* NOTE: Ideally we should also include currents (RHS) here. This would * need a reevaluation of the right hand side after voltages have been updated @@ -207,14 +239,14 @@ T matrix_solver_t::delta(const T * RESTRICT V) */ const std::size_t iN = this->m_terms.size(); - T cerr = 0; + typename std::decay::type cerr = 0; for (std::size_t i = 0; i < iN; i++) - cerr = std::max(cerr, std::abs(V[i] - static_cast(this->m_nets[i]->Q_Analog()))); + cerr = std::max(cerr, std::abs(V[i] - this->m_nets[i]->Q_Analog())); return cerr; } template -void matrix_solver_t::store(const T * RESTRICT V) +void matrix_solver_t::store(const T & RESTRICT V) { const std::size_t iN = this->m_terms.size(); for (std::size_t i = 0; i < iN; i++) @@ -222,34 +254,33 @@ void matrix_solver_t::store(const T * RESTRICT V) } template -void matrix_solver_t::build_LE_A() +void matrix_solver_t::build_LE_A(T &child) { + typedef typename T::float_type float_type; static_assert(std::is_base_of::value, "T must derive from matrix_solver_t"); - T &child = static_cast(*this); - const std::size_t iN = child.N(); for (std::size_t k = 0; k < iN; k++) { terms_for_net_t *terms = m_terms[k].get(); - nl_double * Ak = &child.A(k, 0ul); + float_type * Ak = &child.A(k, 0ul); for (std::size_t i=0; i < iN; i++) Ak[i] = 0.0; const std::size_t terms_count = terms->count(); const std::size_t railstart = terms->m_railstart; - const nl_double * const RESTRICT gt = terms->gt(); + const float_type * const RESTRICT gt = terms->gt(); { - nl_double akk = 0.0; + float_type akk = 0.0; for (std::size_t i = 0; i < terms_count; i++) akk += gt[i]; Ak[k] = akk; } - const nl_double * const RESTRICT go = terms->go(); + const float_type * const RESTRICT go = terms->go(); int * RESTRICT net_other = terms->connected_net_idx(); for (std::size_t i = 0; i < railstart; i++) @@ -258,21 +289,21 @@ void matrix_solver_t::build_LE_A() } template -void matrix_solver_t::build_LE_RHS() +void matrix_solver_t::build_LE_RHS(T &child) { static_assert(std::is_base_of::value, "T must derive from matrix_solver_t"); - T &child = static_cast(*this); + typedef typename T::float_type float_type; const std::size_t iN = child.N(); for (std::size_t k = 0; k < iN; k++) { - nl_double rhsk_a = 0.0; - nl_double rhsk_b = 0.0; + float_type rhsk_a = 0.0; + float_type rhsk_b = 0.0; const std::size_t terms_count = m_terms[k]->count(); - const nl_double * const RESTRICT go = m_terms[k]->go(); - const nl_double * const RESTRICT Idr = m_terms[k]->Idr(); - const nl_double * const * RESTRICT other_cur_analog = m_terms[k]->connected_net_V(); + const float_type * const RESTRICT go = m_terms[k]->go(); + const float_type * const RESTRICT Idr = m_terms[k]->Idr(); + const float_type * const * RESTRICT other_cur_analog = m_terms[k]->connected_net_V(); for (std::size_t i = 0; i < terms_count; i++) rhsk_a = rhsk_a + Idr[i]; diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index 398e20995f8..2c56e9fecb4 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -14,28 +14,21 @@ #include "nld_solver.h" #include "nld_matrix_solver.h" #include "vector_base.h" - -/* Disabling dynamic allocation gives a ~10% boost in performance - * This flag has been added to support continuous storage for arrays - * going forward in case we implement cuda solvers in the future. - */ -#define NL_USE_DYNAMIC_ALLOCATION (1) +#include "mat_cr.h" namespace netlist { - namespace devices - { -//#define nl_ext_double _float128 // slow, very slow -//#define nl_ext_double long double // slightly slower -#define nl_ext_double nl_double - +namespace devices +{ -template +template class matrix_solver_direct_t: public matrix_solver_t { friend class matrix_solver_t; public: + typedef FT float_type; + matrix_solver_direct_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size); matrix_solver_direct_t(netlist_base_t &anetlist, const pstring &name, const eSortType sort, const solver_parameters_t *params, const std::size_t size); @@ -48,36 +41,25 @@ protected: virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; unsigned solve_non_dynamic(const bool newton_raphson); - constexpr std::size_t N() const { return (m_N == 0) ? m_dim : m_N; } + constexpr std::size_t N() const { return (SIZE > 0) ? static_cast(SIZE) : m_dim; } void LE_solve(); template - void LE_back_subst(T * RESTRICT x); + void LE_back_subst(T & RESTRICT x); -#if (NL_USE_DYNAMIC_ALLOCATION) - nl_ext_double &A(const std::size_t r, const std::size_t c) { return m_A[r * m_pitch + c]; } - nl_ext_double &RHS(const std::size_t r) { return m_A[r * m_pitch + N()]; } -#else - nl_ext_double &A(const std::size_t r, const std::size_t c) { return m_A[r][c]; } - nl_ext_double &RHS(const std::size_t r) { return m_A[r][N()]; } -#endif - nl_double m_last_RHS[storage_N]; // right hand side - contains currents + FT &A(std::size_t r, std::size_t c) { return m_A[r * m_pitch + c]; } + FT &RHS(std::size_t r) { return m_A[r * m_pitch + N()]; } + plib::parray m_last_RHS; + plib::parray m_new_V; private: - //static const std::size_t m_pitch = (((storage_N + 1) + 0) / 1) * 1; - static constexpr std::size_t m_pitch = (((storage_N + 1) + 7) / 8) * 8; - //static const std::size_t m_pitch = (((storage_N + 1) + 15) / 16) * 16; - //static const std::size_t m_pitch = (((storage_N + 1) + 31) / 32) * 32; -#if (NL_USE_DYNAMIC_ALLOCATION) - //nl_ext_double * RESTRICT m_A; - std::vector m_A; -#else - nl_ext_double m_A[storage_N][m_pitch]; -#endif - //nl_ext_double m_RHSx[storage_N]; + static constexpr const std::size_t SIZEABS = plib::parray::SIZEABS(); + static constexpr const std::size_t m_pitch_ABS = (((SIZEABS + 1) + 7) / 8) * 8; const std::size_t m_dim; + const std::size_t m_pitch; + plib::parray m_A; }; @@ -85,16 +67,13 @@ private: // matrix_solver_direct // ---------------------------------------------------------------------------------------- -template -matrix_solver_direct_t::~matrix_solver_direct_t() +template +matrix_solver_direct_t::~matrix_solver_direct_t() { -#if (NL_USE_DYNAMIC_ALLOCATION) - //plib::pfree_array(m_A); -#endif } -template -void matrix_solver_direct_t::vsetup(analog_net_t::list_t &nets) +template +void matrix_solver_direct_t::vsetup(analog_net_t::list_t &nets) { matrix_solver_t::setup_base(nets); @@ -107,34 +86,31 @@ void matrix_solver_direct_t::vsetup(analog_net_t::list_t &nets) t->m_nzrd.push_back(static_cast(N())); } - state().save(*this, m_last_RHS, "m_last_RHS"); + state().save(*this, m_last_RHS.data(), "m_last_RHS", m_last_RHS.size()); for (std::size_t k = 0; k < N(); k++) state().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k)); } -template -void matrix_solver_direct_t::LE_solve() +template +void matrix_solver_direct_t::LE_solve() { const std::size_t kN = N(); if (!m_params.m_pivot) { for (std::size_t i = 0; i < kN; i++) { - /* FIXME: Singular matrix? */ - nl_double *Ai = &A(i, 0); - const nl_double f = 1.0 / A(i,i); + const FT f = 1.0 / A(i,i); const auto &nzrd = m_terms[i]->m_nzrd; const auto &nzbd = m_terms[i]->m_nzbd; for (std::size_t j : nzbd) { - nl_double *Aj = &A(j, 0); - const nl_double f1 = -f * Aj[i]; + const FT f1 = -f * A(j, i); for (std::size_t k : nzrd) - Aj[k] += Ai[k] * f1; + A(j, k) += A(i, k) * f1; //RHS(j) += RHS(i) * f1; } } @@ -161,17 +137,17 @@ void matrix_solver_direct_t::LE_solve() //std::swap(RHS(i), RHS(maxrow)); } /* FIXME: Singular matrix? */ - const nl_double f = 1.0 / A(i,i); + const FT f = 1.0 / A(i,i); /* Eliminate column i from row j */ for (std::size_t j = i + 1; j < kN; j++) { - const nl_double f1 = - A(j,i) * f; + const FT f1 = - A(j,i) * f; if (f1 != NL_FCONST(0.0)) { - const nl_double * RESTRICT pi = &A(i,i+1); - nl_double * RESTRICT pj = &A(j,i+1); + const FT * RESTRICT pi = &A(i,i+1); + FT * RESTRICT pj = &A(j,i+1); #if 1 vec_add_mult_scalar_p(kN-i,pi,f1,pj); #else @@ -188,10 +164,10 @@ void matrix_solver_direct_t::LE_solve() } } -template +template template -void matrix_solver_direct_t::LE_back_subst( - T * RESTRICT x) +void matrix_solver_direct_t::LE_back_subst( + T & RESTRICT x) { const std::size_t kN = N(); @@ -200,7 +176,7 @@ void matrix_solver_direct_t::LE_back_subst( { for (std::size_t j = kN; j-- > 0; ) { - T tmp = 0; + FT tmp = 0; for (std::size_t k = j+1; k < kN; k++) tmp += A(j,k) * x[k]; x[j] = (RHS(j) - tmp) / A(j,j); @@ -210,40 +186,33 @@ void matrix_solver_direct_t::LE_back_subst( { for (std::size_t j = kN; j-- > 0; ) { - T tmp = 0; - - const auto *p = m_terms[j]->m_nzrd.data(); - const auto e = m_terms[j]->m_nzrd.size() - 1; /* exclude RHS element */ - T * Aj = &A(j,0); - for (std::size_t k = 0; k < e; k++) - { - const auto pk = p[k]; - tmp += Aj[pk] * x[pk]; - } + FT tmp = 0; + const auto &nzrd = m_terms[j]->m_nzrd; + const auto e = nzrd.size() - 1; /* exclude RHS element */ + for ( std::size_t k = 0; k < e; k++) + tmp += A(j, nzrd[k]) * x[nzrd[k]]; x[j] = (RHS(j) - tmp) / A(j,j); } } } -template -unsigned matrix_solver_direct_t::solve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_direct_t::solve_non_dynamic(const bool newton_raphson) { - nl_double new_V[storage_N]; // = { 0.0 }; - this->LE_solve(); - this->LE_back_subst(new_V); + this->LE_back_subst(m_new_V); - const nl_double err = (newton_raphson ? delta(new_V) : 0.0); - store(new_V); + const FT err = (newton_raphson ? delta(m_new_V) : 0.0); + store(m_new_V); return (err > this->m_params.m_accuracy) ? 2 : 1; } -template -unsigned matrix_solver_direct_t::vsolve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_direct_t::vsolve_non_dynamic(const bool newton_raphson) { - build_LE_A(); - build_LE_RHS(); + this->build_LE_A(*this); + this->build_LE_RHS(*this); for (std::size_t i=0, iN=N(); i < iN; i++) m_last_RHS[i] = RHS(i); @@ -252,33 +221,33 @@ unsigned matrix_solver_direct_t::vsolve_non_dynamic(const bool n return this->solve_non_dynamic(newton_raphson); } -template -matrix_solver_direct_t::matrix_solver_direct_t(netlist_base_t &anetlist, const pstring &name, +template +matrix_solver_direct_t::matrix_solver_direct_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size) : matrix_solver_t(anetlist, name, ASCENDING, params) +, m_last_RHS(size) +, m_new_V(size) , m_dim(size) +, m_pitch(m_pitch_ABS ? m_pitch_ABS : (((m_dim + 1) + 7) / 8) * 8) +, m_A(size * m_pitch) { -#if (NL_USE_DYNAMIC_ALLOCATION) - m_A.resize(N() * m_pitch); - //m_A = plib::palloc_array(N() * m_pitch); -#endif for (unsigned k = 0; k < N(); k++) { m_last_RHS[k] = 0.0; } } -template -matrix_solver_direct_t::matrix_solver_direct_t(netlist_base_t &anetlist, const pstring &name, +template +matrix_solver_direct_t::matrix_solver_direct_t(netlist_base_t &anetlist, const pstring &name, const eSortType sort, const solver_parameters_t *params, const std::size_t size) : matrix_solver_t(anetlist, name, sort, params) +, m_last_RHS(size) +, m_new_V(size) , m_dim(size) +, m_pitch(m_pitch_ABS ? m_pitch_ABS : (((m_dim + 1) + 7) / 8) * 8) +, m_A(size * m_pitch) { -#if (NL_USE_DYNAMIC_ALLOCATION) - m_A.resize(N() * m_pitch); - //m_A = plib::palloc_array(N() * m_pitch); -#endif - for (unsigned k = 0; k < N(); k++) + for (std::size_t k = 0; k < N(); k++) { m_last_RHS[k] = 0.0; } diff --git a/src/lib/netlist/solver/nld_ms_direct1.h b/src/lib/netlist/solver/nld_ms_direct1.h index 4ffbb833bc3..4016b8826b0 100644 --- a/src/lib/netlist/solver/nld_ms_direct1.h +++ b/src/lib/netlist/solver/nld_ms_direct1.h @@ -13,37 +13,41 @@ namespace netlist { - namespace devices - { -class matrix_solver_direct1_t: public matrix_solver_direct_t<1,1> +namespace devices { -public: + template + class matrix_solver_direct1_t: public matrix_solver_direct_t + { + public: - matrix_solver_direct1_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params) - : matrix_solver_direct_t<1, 1>(anetlist, name, params, 1) - {} - virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; + typedef FT float_type; + typedef matrix_solver_direct_t base_type; -}; + matrix_solver_direct1_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params) + : matrix_solver_direct_t(anetlist, name, params, 1) + {} -// ---------------------------------------------------------------------------------------- -// matrix_solver - Direct1 -// ---------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------- + // matrix_solver - Direct1 + // ---------------------------------------------------------------------------------------- + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override + { + this->build_LE_A(*this); + this->build_LE_RHS(*this); + //NL_VERBOSE_OUT(("{1} {2}\n", new_val, m_RHS[0] / m_A[0][0]); -inline unsigned matrix_solver_direct1_t::vsolve_non_dynamic(const bool newton_raphson) -{ - build_LE_A(); - build_LE_RHS(); - //NL_VERBOSE_OUT(("{1} {2}\n", new_val, m_RHS[0] / m_A[0][0]); + FT new_V[1] = { this->RHS(0) / this->A(0,0) }; + + const FT err = (newton_raphson ? this->delta(new_V) : 0.0); + this->store(new_V); + return (err > this->m_params.m_accuracy) ? 2 : 1; + } + + }; - nl_double new_V[1] = { RHS(0) / A(0,0) }; - const nl_double err = (newton_raphson ? delta(new_V) : 0.0); - store(new_V); - return (err > this->m_params.m_accuracy) ? 2 : 1; -} - } //namespace devices +} //namespace devices } // namespace netlist diff --git a/src/lib/netlist/solver/nld_ms_direct2.h b/src/lib/netlist/solver/nld_ms_direct2.h index 75bfd6e0803..07ead72a353 100644 --- a/src/lib/netlist/solver/nld_ms_direct2.h +++ b/src/lib/netlist/solver/nld_ms_direct2.h @@ -13,43 +13,48 @@ namespace netlist { - namespace devices - { -class matrix_solver_direct2_t: public matrix_solver_direct_t<2,2> +namespace devices { -public: - matrix_solver_direct2_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params) - : matrix_solver_direct_t<2, 2>(anetlist, name, params, 2) - {} - virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; + template + class matrix_solver_direct2_t: public matrix_solver_direct_t + { + public: -}; + typedef FT float_type; -// ---------------------------------------------------------------------------------------- -// matrix_solver - Direct2 -// ---------------------------------------------------------------------------------------- + matrix_solver_direct2_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params) + : matrix_solver_direct_t(anetlist, name, params, 2) + {} + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; -inline unsigned matrix_solver_direct2_t::vsolve_non_dynamic(const bool newton_raphson) -{ - build_LE_A(); - build_LE_RHS(); + }; + + // ---------------------------------------------------------------------------------------- + // matrix_solver - Direct2 + // ---------------------------------------------------------------------------------------- + + template + inline unsigned matrix_solver_direct2_t::vsolve_non_dynamic(const bool newton_raphson) + { + this->build_LE_A(*this); + this->build_LE_RHS(*this); - const nl_double a = A(0,0); - const nl_double b = A(0,1); - const nl_double c = A(1,0); - const nl_double d = A(1,1); + const float_type a = this->A(0,0); + const float_type b = this->A(0,1); + const float_type c = this->A(1,0); + const float_type d = this->A(1,1); - nl_double new_V[2]; - new_V[1] = (a * RHS(1) - c * RHS(0)) / (a * d - b * c); - new_V[0] = (RHS(0) - b * new_V[1]) / a; + float_type new_V[2]; + new_V[1] = (a * this->RHS(1) - c * this->RHS(0)) / (a * d - b * c); + new_V[0] = (this->RHS(0) - b * new_V[1]) / a; - const nl_double err = (newton_raphson ? delta(new_V) : 0.0); - store(new_V); - return (err > this->m_params.m_accuracy) ? 2 : 1; -} + const float_type err = (newton_raphson ? this->delta(new_V) : 0.0); + this->store(new_V); + return (err > this->m_params.m_accuracy) ? 2 : 1; + } - } //namespace devices +} //namespace devices } // namespace netlist #endif /* NLD_MS_DIRECT2_H_ */ diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h index 0f5c041061f..e708cdfb281 100644 --- a/src/lib/netlist/solver/nld_ms_gcr.h +++ b/src/lib/netlist/solver/nld_ms_gcr.h @@ -21,17 +21,23 @@ namespace netlist { - namespace devices - { -template +namespace devices +{ + +template class matrix_solver_GCR_t: public matrix_solver_t { public: + // FIXME: dirty hack to make this compile + static constexpr const std::size_t storage_N = 100; + matrix_solver_GCR_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size) : matrix_solver_t(anetlist, name, matrix_solver_t::ASCENDING, params) , m_dim(size) + , RHS(size) + , new_V(size) , mat(size) , m_proc() { @@ -41,7 +47,7 @@ public: { } - constexpr std::size_t N() const { return (m_N == 0) ? m_dim : m_N; } + constexpr std::size_t N() const { return m_dim; } virtual void vsetup(analog_net_t::list_t &nets) override; virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; @@ -51,7 +57,7 @@ public: private: //typedef typename mat_cr_t::type mattype; - typedef typename mat_cr_t::index_type mattype; + typedef typename plib::mat_cr_t::index_type mat_index_type; void csc_private(plib::putf8_fmt_writer &strm); @@ -60,8 +66,12 @@ private: pstring static_compile_name(); const std::size_t m_dim; - std::vector m_term_cr[storage_N]; - mat_cr_t mat; + plib::parray RHS; + plib::parray new_V; + + std::vector m_term_cr[storage_N]; + + plib::mat_cr_t mat; //extsolver m_proc; plib::dynproc m_proc; @@ -72,166 +82,89 @@ private: // matrix_solver - GCR // ---------------------------------------------------------------------------------------- -template -void matrix_solver_GCR_t::vsetup(analog_net_t::list_t &nets) +template +void matrix_solver_GCR_t::vsetup(analog_net_t::list_t &nets) { setup_base(nets); - mattype nz = 0; const std::size_t iN = this->N(); /* build the final matrix */ - bool touched[storage_N][storage_N] = { { false } }; + std::vector> fill(iN); + + std::size_t raw_elements = 0; + for (std::size_t k = 0; k < iN; k++) { + fill[k].resize(iN, decltype(mat)::FILL_INFINITY); for (auto &j : this->m_terms[k]->m_nz) - touched[k][j] = true; - } + { + fill[k][j] = 0; + raw_elements++; + } - unsigned fc = 0; + } - unsigned ops = 0; + auto gr = mat.gaussian_extend_fill_mat(fill); for (std::size_t k = 0; k < iN; k++) { - ops++; // 1/A(k,k) - for (std::size_t row = k + 1; row < iN; row++) + unsigned fm = 0; + pstring ml = ""; + for (std::size_t j = 0; j < iN; j++) { - if (touched[row][k]) - { - ops++; - fc++; - for (std::size_t col = k + 1; col < iN; col++) - if (touched[k][col]) - { - touched[row][col] = true; - ops += 2; - } - } + ml += fill[k][j] < decltype(mat)::FILL_INFINITY ? "X" : "_"; + if (fill[k][j] < decltype(mat)::FILL_INFINITY) + if (fill[k][j] > fm) + fm = fill[k][j]; } + this->log().verbose("{1:4} {2} {3:4}", k, ml, fm); } - for (mattype k=0; km_terms[k]->m_railstart;j++) { int other = this->m_terms[k]->connected_net_idx()[j]; - for (auto i = mat.ia[k]; i < nz; i++) - if (other == static_cast(mat.ja[i])) + for (auto i = mat.row_idx[k]; i < mat.row_idx[k+1]; i++) + if (other == static_cast(mat.col_idx[i])) { - m_term_cr[k].push_back(i); + m_term_cr[k].push_back(&mat.A[i]); break; } } nl_assert(m_term_cr[k].size() == this->m_terms[k]->m_railstart); + m_term_cr[k].push_back(&mat.A[mat.diag[k]]); } - mat.ia[iN] = nz; - mat.nz_num = nz; - - this->log().verbose("Ops: {1} Occupancy ratio: {2}\n", ops, - static_cast(nz) / static_cast(iN * iN)); + this->log().verbose("maximum fill: {1}", gr.first); + this->log().verbose("Post elimination occupancy ratio: {2} Ops: {1}", gr.second, + static_cast(mat.nz_num) / static_cast(iN * iN)); + this->log().verbose(" Pre elimination occupancy ratio: {2}", + static_cast(raw_elements) / static_cast(iN * iN)); // FIXME: Move me if (state().lib().isLoaded()) { pstring symname = static_compile_name(); -#if 0 - m_proc = this->netlist().lib().template getsym(symname); - if (m_proc != nullptr) - this->log().verbose("External static solver {1} found ...", symname); - else - this->log().warning("External static solver {1} not found ...", symname); -#else m_proc.load(this->state().lib(), symname); if (m_proc.resolved()) this->log().warning("External static solver {1} found ...", symname); else this->log().warning("External static solver {1} not found ...", symname); -#endif } } -#if 0 -template -void matrix_solver_GCR_t::csc_private(plib::putf8_fmt_writer &strm) -{ - const std::size_t iN = N(); - for (std::size_t i = 0; i < iN - 1; i++) - { - const auto &nzbd = this->m_terms[i]->m_nzbd; - - if (nzbd.size() > 0) - { - std::size_t pi = mat.diag[i]; - //const nl_double f = 1.0 / m_A[pi++]; - strm("const double f{1} = 1.0 / m_A[{2}];\n", i, pi); - pi++; - const std::size_t piie = mat.ia[i+1]; - - //for (auto & j : nzbd) - for (std::size_t j : nzbd) - { - // proceed to column i - std::size_t pj = mat.ia[j]; - - while (mat.ja[pj] < i) - pj++; - - //const nl_double f1 = - m_A[pj++] * f; - strm("\tconst double f{1}_{2} = -f{3} * m_A[{4}];\n", i, j, i, pj); - pj++; - - // subtract row i from j */ - for (std::size_t pii = pi; pii 0;) - { - strm("\tdouble tmp{1} = 0.0;\n", j); - const std::size_t e = mat.ia[j+1]; - for (std::size_t pk = mat.diag[j] + 1; pk < e; pk++) - { - strm("\ttmp{1} += m_A[{2}] * V[{3}];\n", j, pk, mat.ja[pk]); - } - strm("\tV[{1}] = (RHS[{1}] - tmp{1}) / m_A[{4}];\n", j, j, j, mat.diag[j]); - } -} -#else -template -void matrix_solver_GCR_t::csc_private(plib::putf8_fmt_writer &strm) +template +void matrix_solver_GCR_t::csc_private(plib::putf8_fmt_writer &strm) { const std::size_t iN = N(); @@ -246,28 +179,28 @@ void matrix_solver_GCR_t::csc_private(plib::putf8_fmt_writer &st { std::size_t pi = mat.diag[i]; - //const nl_double f = 1.0 / m_A[pi++]; + //const FT f = 1.0 / m_A[pi++]; strm("const double f{1} = 1.0 / m_A{2};\n", i, pi); pi++; - const std::size_t piie = mat.ia[i+1]; + const std::size_t piie = mat.row_idx[i+1]; //for (auto & j : nzbd) for (std::size_t j : nzbd) { // proceed to column i - std::size_t pj = mat.ia[j]; + std::size_t pj = mat.row_idx[j]; - while (mat.ja[pj] < i) + while (mat.col_idx[pj] < i) pj++; - //const nl_double f1 = - m_A[pj++] * f; + //const FT f1 = - m_A[pj++] * f; strm("\tconst double f{1}_{2} = -f{3} * m_A{4};\n", i, j, i, pj); pj++; // subtract row i from j */ for (std::size_t pii = pi; pii::csc_private(plib::putf8_fmt_writer &st for (std::size_t j = iN - 1; j-- > 0;) { strm("\tdouble tmp{1} = 0.0;\n", j); - const std::size_t e = mat.ia[j+1]; + const std::size_t e = mat.row_idx[j+1]; for (std::size_t pk = mat.diag[j] + 1; pk < e; pk++) { - strm("\ttmp{1} += m_A{2} * V[{3}];\n", j, pk, mat.ja[pk]); + strm("\ttmp{1} += m_A{2} * V[{3}];\n", j, pk, mat.col_idx[pk]); } strm("\tV[{1}] = (RHS[{1}] - tmp{1}) / m_A{4};\n", j, j, j, mat.diag[j]); } } -#endif -template -pstring matrix_solver_GCR_t::static_compile_name() +template +pstring matrix_solver_GCR_t::static_compile_name() { plib::postringstream t; plib::putf8_fmt_writer w(&t); @@ -305,8 +237,8 @@ pstring matrix_solver_GCR_t::static_compile_name() return plib::pfmt("nl_gcr_{1:x}_{2}")(h( t.str() ))(mat.nz_num); } -template -std::pair matrix_solver_GCR_t::create_solver_code() +template +std::pair matrix_solver_GCR_t::create_solver_code() { plib::postringstream t; plib::putf8_fmt_writer strm(&t); @@ -320,69 +252,16 @@ std::pair matrix_solver_GCR_t::create_solver_c } -template -unsigned matrix_solver_GCR_t::vsolve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_GCR_t::vsolve_non_dynamic(const bool newton_raphson) { const std::size_t iN = this->N(); - nl_double RHS[storage_N]; - nl_double new_V[storage_N]; - mat.set_scalar(0.0); + /* populate matrix */ for (std::size_t k = 0; k < iN; k++) - { - terms_for_net_t *t = this->m_terms[k].get(); - nl_double gtot_t = 0.0; - nl_double RHS_t = 0.0; - - const std::size_t term_count = t->count(); - const std::size_t railstart = t->m_railstart; - const nl_double * const RESTRICT gt = t->gt(); - const nl_double * const RESTRICT go = t->go(); - const nl_double * const RESTRICT Idr = t->Idr(); - const nl_double * const * RESTRICT other_cur_analog = t->connected_net_V(); - const unsigned * const RESTRICT tcr = m_term_cr[k].data(); - -#if 0 - for (std::size_t i = 0; i < term_count; i++) - { - gtot_t += gt[i]; - RHS_t += Idr[i]; - } - - for (std::size_t i = railstart; i < term_count; i++) - RHS_t += go[i] * *other_cur_analog[i]; - - RHS[k] = RHS_t; - - // add diagonal element - mat.A[mat.diag[k]] = gtot_t; - - for (std::size_t i = 0; i < railstart; i++) - mat.A[tcr[i]] -= go[i]; - } -#else - for (std::size_t i = 0; i < railstart; i++) - mat.A[tcr[i]] -= go[i]; - - for (std::size_t i = 0; i < railstart; i++) - { - gtot_t += gt[i]; - RHS_t += Idr[i]; - } - - for (std::size_t i = railstart; i < term_count; i++) - { - RHS_t += (Idr[i] + go[i] * *other_cur_analog[i]); - gtot_t += gt[i]; - } - - RHS[k] = RHS_t; - mat.A[mat.diag[k]] += gtot_t; - } -#endif - mat.ia[iN] = static_cast(mat.nz_num); + this->m_terms[k]->fill_matrix(m_term_cr[k], RHS[k]); /* now solve it */ @@ -394,63 +273,14 @@ unsigned matrix_solver_GCR_t::vsolve_non_dynamic(const bool newt } else { - for (std::size_t i = 0; i < iN - 1; i++) - { - const auto &nzbd = this->m_terms[i]->m_nzbd; - - if (nzbd.size() > 0) - { - std::size_t pi = mat.diag[i]; - const nl_double f = 1.0 / mat.A[pi++]; - const std::size_t piie = mat.ia[i+1]; - - for (std::size_t j : nzbd) // for (std::size_t j = i + 1; j < iN; j++) - { - // proceed to column i - //__builtin_prefetch(&m_A[mat.diag[j+1]], 1); - std::size_t pj = mat.ia[j]; - - while (mat.ja[pj] < i) - pj++; - - const nl_double f1 = - mat.A[pj++] * f; - - // subtract row i from j */ - for (std::size_t pii = pi; pii 0;) - { - //__builtin_prefetch(&new_V[j-1], 1); - //if (j>0)__builtin_prefetch(&m_A[mat.diag[j-1]], 0); - double tmp = 0; - auto jdiag = mat.diag[j]; - const std::size_t e = mat.ia[j+1]; - for (std::size_t pk = jdiag + 1; pk < e; pk++) - { - tmp += mat.A[pk] * new_V[mat.ja[pk]]; - } - new_V[j] = (RHS[j] - tmp) / mat.A[jdiag]; - } + mat.gaussian_elimination(RHS); + /* backward substitution */ + mat.gaussian_back_substitution(new_V, RHS); } this->m_stat_calculations++; - const nl_double err = (newton_raphson ? delta(new_V) : 0.0); + const FT err = (newton_raphson ? delta(new_V) : 0.0); store(new_V); return (err > this->m_params.m_accuracy) ? 2 : 1; } diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index 81a7313c154..0b08d995fd3 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -15,6 +15,7 @@ #include #include +#include "../plib/parray.h" #include "mat_cr.h" #include "nld_ms_direct.h" #include "nld_solver.h" @@ -24,17 +25,34 @@ namespace netlist { namespace devices { -template -class matrix_solver_GMRES_t: public matrix_solver_direct_t + +template +class matrix_solver_GMRES_t: public matrix_solver_direct_t { public: + typedef FT float_type; + // FIXME: dirty hack to make this compile + static constexpr const std::size_t storage_N = plib::sizeabs::ABS(); + + // Maximum iterations before a restart ... + static constexpr const std::size_t restart_N = (storage_N > 0 ? 20 : 0); + + /* Sort rows in ascending order. This should minimize fill-in and thus + * maximize the efficiency of the incomplete LUT. + */ matrix_solver_GMRES_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size) - : matrix_solver_direct_t(anetlist, name, matrix_solver_t::ASCENDING, params, size) + : matrix_solver_direct_t(anetlist, name, matrix_solver_t::ASCENDING, params, size) , m_use_iLU_preconditioning(true) - , m_use_more_precise_stop_condition(false) + , m_use_more_precise_stop_condition(true) + , m_ILU_scale(0) , m_accuracy_mult(1.0) + , m_term_cr(size) , mat(size) + , residual(size) + , Ax(size) + , m_LU(size) + //, m_v(size) { } @@ -48,26 +66,32 @@ public: private: //typedef typename mat_cr_t::type mattype; - typedef typename mat_cr_t::index_type mattype; + typedef typename plib::mat_cr_t::index_type mattype; - unsigned solve_ilu_gmres(nl_double (& RESTRICT x)[storage_N], const nl_double (& RESTRICT rhs)[storage_N], const unsigned restart_max, std::size_t mr, nl_double accuracy); + template + std::size_t solve_ilu_gmres(VT &x, const VRHS & rhs, const std::size_t restart_max, std::size_t mr, float_type accuracy); - std::vector m_term_cr[storage_N]; bool m_use_iLU_preconditioning; bool m_use_more_precise_stop_condition; - nl_double m_accuracy_mult; // FXIME: Save state + std::size_t m_ILU_scale; + float_type m_accuracy_mult; // FXIME: Save state + + plib::parray, SIZE> m_term_cr; + plib::mat_cr_t mat; + plib::parray residual; + plib::parray Ax; - mat_cr_t mat; + plib::mat_cr_t m_LU; - nl_double m_LU[storage_N * storage_N]; + float_type m_c[restart_N + 1]; /* mr + 1 */ + float_type m_g[restart_N + 1]; /* mr + 1 */ + float_type m_ht[restart_N + 1][restart_N]; /* (mr + 1), mr */ + float_type m_s[restart_N + 1]; /* mr + 1 */ + float_type m_y[restart_N + 1]; /* mr + 1 */ - nl_double m_c[storage_N + 1]; /* mr + 1 */ - nl_double m_g[storage_N + 1]; /* mr + 1 */ - nl_double m_ht[storage_N + 1][storage_N]; /* (mr + 1), mr */ - nl_double m_s[storage_N + 1]; /* mr + 1 */ - nl_double m_v[storage_N + 1][storage_N]; /*(mr + 1), n */ - nl_double m_y[storage_N + 1]; /* mr + 1 */ + //plib::parray m_v[restart_N + 1]; /* mr + 1, n */ + float_type m_v[restart_N + 1][storage_N]; /* mr + 1, n */ }; @@ -75,106 +99,72 @@ private: // matrix_solver - GMRES // ---------------------------------------------------------------------------------------- -template -void matrix_solver_GMRES_t::vsetup(analog_net_t::list_t &nets) +template +void matrix_solver_GMRES_t::vsetup(analog_net_t::list_t &nets) { - matrix_solver_direct_t::vsetup(nets); + matrix_solver_direct_t::vsetup(nets); - mattype nz = 0; const std::size_t iN = this->N(); + std::vector> fill(iN); + for (std::size_t k=0; km_terms[k].get(); - mat.ia[k] = nz; - for (std::size_t j=0; jm_nz.size(); j++) { - mat.ja[nz] = static_cast(row->m_nz[j]); - if (row->m_nz[j] == k) - mat.diag[k] = nz; - nz++; + fill[k][static_cast(row->m_nz[j])] = 0; } + } + + mat.build_from_fill_mat(fill, 0); + m_LU.gaussian_extend_fill_mat(fill); + m_LU.build_from_fill_mat(fill, m_ILU_scale); // ILU(2) + //m_LU.build_from_fill_mat(fill, 9999, 20); // Band matrix width 20 - /* build pointers into the compressed row format matrix for each terminal */ + /* build pointers into the compressed row format matrix for each terminal */ - for (unsigned j=0; j< this->m_terms[k]->m_railstart;j++) + for (std::size_t k=0; km_terms[k]->m_railstart;j++) { - for (unsigned i = mat.ia[k]; im_terms[k]->connected_net_idx()[j] == static_cast(mat.ja[i])) + for (std::size_t i = mat.row_idx[k]; im_terms[k]->connected_net_idx()[j] == static_cast(mat.col_idx[i])) { - m_term_cr[k].push_back(i); + m_term_cr[k].push_back(&mat.A[i]); break; } } nl_assert(m_term_cr[k].size() == this->m_terms[k]->m_railstart); + m_term_cr[k].push_back(&mat.A[mat.diag[k]]); } - - mat.ia[iN] = nz; - mat.nz_num = nz; } -template -unsigned matrix_solver_GMRES_t::vsolve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_GMRES_t::vsolve_non_dynamic(const bool newton_raphson) { const std::size_t iN = this->N(); - /* ideally, we could get an estimate for the spectral radius of - * Inv(D - L) * U - * - * and estimate using - * - * omega = 2.0 / (1.0 + std::sqrt(1-rho)) - */ - - //nz_num = 0; - nl_double RHS[storage_N]; - nl_double new_V[storage_N]; + plib::parray RHS(iN); + //float_type new_V[storage_N]; mat.set_scalar(0.0); + /* populate matrix and V for first estimate */ for (std::size_t k = 0; k < iN; k++) { - nl_double gtot_t = 0.0; - nl_double RHS_t = 0.0; - - const std::size_t term_count = this->m_terms[k]->count(); - const std::size_t railstart = this->m_terms[k]->m_railstart; - const nl_double * const RESTRICT gt = this->m_terms[k]->gt(); - const nl_double * const RESTRICT go = this->m_terms[k]->go(); - const nl_double * const RESTRICT Idr = this->m_terms[k]->Idr(); - const nl_double * const * RESTRICT other_cur_analog = this->m_terms[k]->connected_net_V(); - - for (std::size_t i = 0; i < term_count; i++) - { - gtot_t = gtot_t + gt[i]; - RHS_t = RHS_t + Idr[i]; - } - - for (std::size_t i = railstart; i < term_count; i++) - RHS_t = RHS_t + go[i] * *other_cur_analog[i]; - - RHS[k] = RHS_t; - - // add diagonal element - mat.A[mat.diag[k]] = gtot_t; - - for (std::size_t i = 0; i < railstart; i++) - { - const std::size_t pi = m_term_cr[k][i]; - mat.A[pi] -= go[i]; - } - - new_V[k] = this->m_nets[k]->Q_Analog(); - + this->m_terms[k]->fill_matrix(m_term_cr[k], RHS[k]); + this->m_new_V[k] = this->m_nets[k]->Q_Analog(); } - mat.ia[iN] = static_cast(mat.nz_num); - const nl_double accuracy = this->m_params.m_accuracy; + + //mat.row_idx[iN] = static_cast(mat.nz_num); + const float_type accuracy = this->m_params.m_accuracy; const std::size_t mr = (iN > 3 ) ? static_cast(std::sqrt(iN) * 2.0) : iN; - unsigned iter = std::max(1u, this->m_params.m_gs_loops); - unsigned gsl = solve_ilu_gmres(new_V, RHS, iter, mr, accuracy); + std::size_t iter = std::max(1u, this->m_params.m_gs_loops); + std::size_t gsl = solve_ilu_gmres(this->m_new_V, RHS, iter, mr, accuracy); const std::size_t failed = mr * iter; this->m_iterative_total += gsl; @@ -183,26 +173,29 @@ unsigned matrix_solver_GMRES_t::vsolve_non_dynamic(const bool ne if (gsl >= failed) { this->m_iterative_fail++; - return matrix_solver_direct_t::vsolve_non_dynamic(newton_raphson); + return matrix_solver_direct_t::vsolve_non_dynamic(newton_raphson); } - const nl_double err = (newton_raphson ? this->delta(new_V) : 0.0); - this->store(new_V); + //if (newton_raphson) + // printf("%e %e\n", this->delta(this->m_new_V), this->m_params.m_accuracy); + + const float_type err = (newton_raphson ? this->delta(this->m_new_V) : 0.0); + this->store(this->m_new_V); return (err > this->m_params.m_accuracy) ? 2 : 1; } template inline void givens_mult( const T c, const T s, T & g0, T & g1 ) { - const T tg0 = c * g0 - s * g1; - const T tg1 = s * g0 + c * g1; + const T g0_last(g0); - g0 = tg0; - g1 = tg1; + g0 = c * g0 - s * g1; + g1 = s * g0_last + c * g1; } -template -unsigned matrix_solver_GMRES_t::solve_ilu_gmres (nl_double (& RESTRICT x)[storage_N], const nl_double (& RESTRICT rhs)[storage_N], const unsigned restart_max, std::size_t mr, nl_double accuracy) +template +template +std::size_t matrix_solver_GMRES_t::solve_ilu_gmres (VT &x, const VRHS &rhs, const std::size_t restart_max, std::size_t mr, float_type accuracy) { /*------------------------------------------------------------------------- * The code below was inspired by code published by John Burkardt under @@ -226,15 +219,22 @@ unsigned matrix_solver_GMRES_t::solve_ilu_gmres (nl_double (& RE * *------------------------------------------------------------------------*/ - unsigned itr_used = 0; + std::size_t itr_used = 0; double rho_delta = 0.0; const std::size_t n = this->N(); + if (mr > restart_N) mr = restart_N; if (mr > n) mr = n; if (m_use_iLU_preconditioning) - mat.incomplete_LU_factorization(m_LU); + { + if (m_ILU_scale < 1) + m_LU.raw_copy_from(mat); + else + m_LU.reduction_copy_from(mat); + m_LU.incomplete_LU_factorization(); + } if (m_use_more_precise_stop_condition) { @@ -249,27 +249,22 @@ unsigned matrix_solver_GMRES_t::solve_ilu_gmres (nl_double (& RE * differently: The invest doesn't pay off. * Therefore we use the approach in the else part. */ - nl_double t[storage_N]; - nl_double Ax[storage_N]; - vec_set(n, accuracy, t); - mat.mult_vec(t, Ax); + vec_set_scalar(n, residual, accuracy); + mat.mult_vec(residual, Ax); - mat.solveLUx(m_LU, Ax); + m_LU.solveLUx(Ax); - const nl_double rho_to_accuracy = std::sqrt(vec_mult2(n, Ax)) / accuracy; + const float_type rho_to_accuracy = std::sqrt(vec_mult2(n, Ax)) / accuracy; rho_delta = accuracy * rho_to_accuracy; } else - rho_delta = accuracy * std::sqrt(n) * m_accuracy_mult; + rho_delta = accuracy * std::sqrt(static_cast(n)) * m_accuracy_mult; - for (unsigned itr = 0; itr < restart_max; itr++) + for (std::size_t itr = 0; itr < restart_max; itr++) { std::size_t last_k = mr; - nl_double rho; - - nl_double Ax[storage_N]; - nl_double residual[storage_N]; + float_type rho; mat.mult_vec(x, Ax); @@ -277,19 +272,19 @@ unsigned matrix_solver_GMRES_t::solve_ilu_gmres (nl_double (& RE if (m_use_iLU_preconditioning) { - mat.solveLUx(m_LU, residual); + m_LU.solveLUx(residual); } - rho = std::sqrt(vec_mult2(n, residual)); + rho = std::sqrt(vec_mult2(n, residual)); if (rho < rho_delta) return itr_used + 1; - vec_set(mr+1, NL_FCONST(0.0), m_g); + vec_set_scalar(mr+1, m_g, NL_FCONST(0.0)); m_g[0] = rho; for (std::size_t i = 0; i < mr + 1; i++) - vec_set(mr, NL_FCONST(0.0), m_ht[i]); + vec_set_scalar(mr, m_ht[i], NL_FCONST(0.0)); vec_mult_scalar(n, residual, NL_FCONST(1.0) / rho, m_v[0]); @@ -300,14 +295,14 @@ unsigned matrix_solver_GMRES_t::solve_ilu_gmres (nl_double (& RE mat.mult_vec(m_v[k], m_v[k1]); if (m_use_iLU_preconditioning) - mat.solveLUx(m_LU, m_v[k1]); + m_LU.solveLUx(m_v[k1]); for (std::size_t j = 0; j <= k; j++) { - m_ht[j][k] = vec_mult(n, m_v[k1], m_v[j]); + m_ht[j][k] = vec_mult(n, m_v[k1], m_v[j]); vec_add_mult_scalar(n, m_v[j], -m_ht[j][k], m_v[k1]); } - m_ht[k1][k] = std::sqrt(vec_mult2(n, m_v[k1])); + m_ht[k1][k] = std::sqrt(vec_mult2(n, m_v[k1])); if (m_ht[k1][k] != 0.0) vec_scale(n, m_v[k1], NL_FCONST(1.0) / m_ht[k1][k]); @@ -315,7 +310,7 @@ unsigned matrix_solver_GMRES_t::solve_ilu_gmres (nl_double (& RE for (std::size_t j = 0; j < k; j++) givens_mult(m_c[j], m_s[j], m_ht[j][k], m_ht[j+1][k]); - const nl_double mu = 1.0 / std::hypot(m_ht[k][k], m_ht[k1][k]); + const float_type mu = 1.0 / std::hypot(m_ht[k][k], m_ht[k1][k]); m_c[k] = m_ht[k][k] * mu; m_s[k] = -m_ht[k1][k] * mu; @@ -345,36 +340,17 @@ unsigned matrix_solver_GMRES_t::solve_ilu_gmres (nl_double (& RE { double tmp = m_g[i]; for (std::size_t j = i + 1; j <= last_k; j++) - { tmp -= m_ht[i][j] * m_y[j]; - } m_y[i] = tmp / m_ht[i][i]; } for (std::size_t i = 0; i <= last_k; i++) vec_add_mult_scalar(n, m_v[i], m_y[i], x); -#if 1 if (rho <= rho_delta) - { break; - } -#else - /* we try to approximate the x difference between to steps using m_v[last_k] */ - double xdelta = m_y[last_k] * vec_maxabs(n, m_v[last_k]); - if (xdelta < accuracy) - { - if (m_accuracy_mult < 16384.0) - m_accuracy_mult = m_accuracy_mult * 2.0; - break; - } - else - m_accuracy_mult = m_accuracy_mult / 2.0; - -#endif } - return itr_used; } diff --git a/src/lib/netlist/solver/nld_ms_sm.h b/src/lib/netlist/solver/nld_ms_sm.h index 81517fcdc1e..02e83bd5bbd 100644 --- a/src/lib/netlist/solver/nld_ms_sm.h +++ b/src/lib/netlist/solver/nld_ms_sm.h @@ -41,19 +41,21 @@ namespace netlist { - namespace devices - { -//#define nl_ext_double _float128 // slow, very slow -//#define nl_ext_double long double // slightly slower -#define nl_ext_double nl_double +namespace devices +{ -template +template class matrix_solver_sm_t: public matrix_solver_t { friend class matrix_solver_t; public: + typedef FT float_ext_type; + typedef FT float_type; + // FIXME: dirty hack to make this compile + static constexpr const std::size_t storage_N = 100; + matrix_solver_sm_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size); @@ -66,7 +68,7 @@ protected: virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; unsigned solve_non_dynamic(const bool newton_raphson); - constexpr std::size_t N() const { return (m_N == 0) ? m_dim : m_N; } + constexpr std::size_t N() const { return m_dim; } void LE_invert(); @@ -75,33 +77,33 @@ protected: template - nl_ext_double &A(const T1 &r, const T2 &c) { return m_A[r][c]; } + float_ext_type &A(const T1 &r, const T2 &c) { return m_A[r][c]; } template - nl_ext_double &W(const T1 &r, const T2 &c) { return m_W[r][c]; } + float_ext_type &W(const T1 &r, const T2 &c) { return m_W[r][c]; } template - nl_ext_double &Ainv(const T1 &r, const T2 &c) { return m_Ainv[r][c]; } + float_ext_type &Ainv(const T1 &r, const T2 &c) { return m_Ainv[r][c]; } template - nl_ext_double &RHS(const T1 &r) { return m_RHS[r]; } + float_ext_type &RHS(const T1 &r) { return m_RHS[r]; } template - nl_ext_double &lA(const T1 &r, const T2 &c) { return m_lA[r][c]; } + float_ext_type &lA(const T1 &r, const T2 &c) { return m_lA[r][c]; } template - nl_ext_double &lAinv(const T1 &r, const T2 &c) { return m_lAinv[r][c]; } + float_ext_type &lAinv(const T1 &r, const T2 &c) { return m_lAinv[r][c]; } - nl_double m_last_RHS[storage_N]; // right hand side - contains currents + float_type m_last_RHS[storage_N]; // right hand side - contains currents private: static constexpr std::size_t m_pitch = ((( storage_N) + 7) / 8) * 8; - nl_ext_double m_A[storage_N][m_pitch]; - nl_ext_double m_Ainv[storage_N][m_pitch]; - nl_ext_double m_W[storage_N][m_pitch]; - nl_ext_double m_RHS[storage_N]; // right hand side - contains currents + float_ext_type m_A[storage_N][m_pitch]; + float_ext_type m_Ainv[storage_N][m_pitch]; + float_ext_type m_W[storage_N][m_pitch]; + float_ext_type m_RHS[storage_N]; // right hand side - contains currents - nl_ext_double m_lA[storage_N][m_pitch]; - nl_ext_double m_lAinv[storage_N][m_pitch]; + float_ext_type m_lA[storage_N][m_pitch]; + float_ext_type m_lAinv[storage_N][m_pitch]; - //nl_ext_double m_RHSx[storage_N]; + //float_ext_type m_RHSx[storage_N]; const std::size_t m_dim; std::size_t m_cnt; @@ -112,13 +114,13 @@ private: // matrix_solver_direct // ---------------------------------------------------------------------------------------- -template -matrix_solver_sm_t::~matrix_solver_sm_t() +template +matrix_solver_sm_t::~matrix_solver_sm_t() { } -template -void matrix_solver_sm_t::vsetup(analog_net_t::list_t &nets) +template +void matrix_solver_sm_t::vsetup(analog_net_t::list_t &nets) { matrix_solver_t::setup_base(nets); @@ -130,8 +132,8 @@ void matrix_solver_sm_t::vsetup(analog_net_t::list_t &nets) -template -void matrix_solver_sm_t::LE_invert() +template +void matrix_solver_sm_t::LE_invert() { const std::size_t kN = N(); @@ -148,7 +150,7 @@ void matrix_solver_sm_t::LE_invert() for (std::size_t i = 0; i < kN; i++) { /* FIXME: Singular matrix? */ - const nl_double f = 1.0 / W(i,i); + const float_type f = 1.0 / W(i,i); const auto * RESTRICT const p = m_terms[i]->m_nzrd.data(); const std::size_t e = m_terms[i]->m_nzrd.size(); @@ -159,7 +161,7 @@ void matrix_solver_sm_t::LE_invert() for (std::size_t jb = 0; jb < eb; jb++) { const unsigned j = pb[jb]; - const nl_double f1 = - W(j,i) * f; + const float_type f1 = - W(j,i) * f; if (f1 != 0.0) { for (std::size_t k = 0; k < e; k++) @@ -173,10 +175,10 @@ void matrix_solver_sm_t::LE_invert() for (std::size_t i = kN; i-- > 0; ) { /* FIXME: Singular matrix? */ - const nl_double f = 1.0 / W(i,i); + const float_type f = 1.0 / W(i,i); for (std::size_t j = i; j-- > 0; ) { - const nl_double f1 = - W(j,i) * f; + const float_type f1 = - W(j,i) * f; if (f1 != 0.0) { for (std::size_t k = i; k < kN; k++) @@ -193,9 +195,9 @@ void matrix_solver_sm_t::LE_invert() } } -template +template template -void matrix_solver_sm_t::LE_compute_x( +void matrix_solver_sm_t::LE_compute_x( T * RESTRICT x) { const std::size_t kN = N(); @@ -205,7 +207,7 @@ void matrix_solver_sm_t::LE_compute_x( for (std::size_t k=0; k::LE_compute_x( } -template -unsigned matrix_solver_sm_t::solve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_sm_t::solve_non_dynamic(const bool newton_raphson) { static constexpr const bool incremental = true; const std::size_t iN = N(); - nl_double new_V[storage_N]; // = { 0.0 }; + float_type new_V[storage_N]; // = { 0.0 }; if ((m_cnt % 50) == 0) { @@ -236,7 +238,7 @@ unsigned matrix_solver_sm_t::solve_non_dynamic(const bool newton } for (std::size_t row = 0; row < iN; row ++) { - nl_double v[m_pitch] = {0}; + float_type v[m_pitch] = {0}; std::size_t cols[m_pitch]; std::size_t colcount = 0; @@ -252,10 +254,10 @@ unsigned matrix_solver_sm_t::solve_non_dynamic(const bool newton if (colcount > 0) { - nl_double lamba = 0.0; - nl_double w[m_pitch] = {0}; + float_type lamba = 0.0; + float_type w[m_pitch] = {0}; - nl_double z[m_pitch]; + float_type z[m_pitch]; /* compute w and lamba */ for (std::size_t i = 0; i < iN; i++) z[i] = Ainv(i, row); /* u is row'th column */ @@ -266,7 +268,7 @@ unsigned matrix_solver_sm_t::solve_non_dynamic(const bool newton for (std::size_t j=0; j::solve_non_dynamic(const bool newton lamba = -1.0 / (1.0 + lamba); for (std::size_t i=0; i::solve_non_dynamic(const bool newton this->LE_compute_x(new_V); - const nl_double err = (newton_raphson ? delta(new_V) : 0.0); + const float_type err = (newton_raphson ? delta(new_V) : 0.0); store(new_V); return (err > this->m_params.m_accuracy) ? 2 : 1; } -template -unsigned matrix_solver_sm_t::vsolve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_sm_t::vsolve_non_dynamic(const bool newton_raphson) { - build_LE_A(); - build_LE_RHS(); + this->build_LE_A(*this); + this->build_LE_RHS(*this); for (std::size_t i=0, iN=N(); i < iN; i++) m_last_RHS[i] = RHS(i); @@ -306,8 +308,8 @@ unsigned matrix_solver_sm_t::vsolve_non_dynamic(const bool newto return this->solve_non_dynamic(newton_raphson); } -template -matrix_solver_sm_t::matrix_solver_sm_t(netlist_base_t &anetlist, const pstring &name, +template +matrix_solver_sm_t::matrix_solver_sm_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size) : matrix_solver_t(anetlist, name, NOSORT, params) , m_dim(size) diff --git a/src/lib/netlist/solver/nld_ms_sor.h b/src/lib/netlist/solver/nld_ms_sor.h index 1cc588a3e29..23944043d8b 100644 --- a/src/lib/netlist/solver/nld_ms_sor.h +++ b/src/lib/netlist/solver/nld_ms_sor.h @@ -20,15 +20,22 @@ namespace netlist { namespace devices - { -template -class matrix_solver_SOR_t: public matrix_solver_direct_t +{ + +template +class matrix_solver_SOR_t: public matrix_solver_direct_t { public: + typedef FT float_type; + matrix_solver_SOR_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size) - : matrix_solver_direct_t(anetlist, name, matrix_solver_t::ASCENDING, params, size) + : matrix_solver_direct_t(anetlist, name, matrix_solver_t::ASCENDING, params, size) , m_lp_fact(*this, "m_lp_fact", 0) + , w(size, 0.0) + , one_m_w(size, 0.0) + , RHS(size, 0.0) + , new_V(size, 0.0) { } @@ -38,7 +45,11 @@ public: virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; private: - state_var m_lp_fact; + state_var m_lp_fact; + std::vector w; + std::vector one_m_w; + std::vector RHS; + std::vector new_V; }; // ---------------------------------------------------------------------------------------- @@ -46,14 +57,14 @@ private: // ---------------------------------------------------------------------------------------- -template -void matrix_solver_SOR_t::vsetup(analog_net_t::list_t &nets) +template +void matrix_solver_SOR_t::vsetup(analog_net_t::list_t &nets) { - matrix_solver_direct_t::vsetup(nets); + matrix_solver_direct_t::vsetup(nets); } -template -unsigned matrix_solver_SOR_t::vsolve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_SOR_t::vsolve_non_dynamic(const bool newton_raphson) { const std::size_t iN = this->N(); bool resched = false; @@ -67,24 +78,19 @@ unsigned matrix_solver_SOR_t::vsolve_non_dynamic(const bool newt * omega = 2.0 / (1.0 + std::sqrt(1-rho)) */ - const nl_double ws = this->m_params.m_gs_sor; - - nl_double w[storage_N]; - nl_double one_m_w[storage_N]; - nl_double RHS[storage_N]; - nl_double new_V[storage_N]; + const float_type ws = this->m_params.m_gs_sor; for (std::size_t k = 0; k < iN; k++) { - nl_double gtot_t = 0.0; - nl_double gabs_t = 0.0; - nl_double RHS_t = 0.0; + float_type gtot_t = 0.0; + float_type gabs_t = 0.0; + float_type RHS_t = 0.0; const std::size_t term_count = this->m_terms[k]->count(); - const nl_double * const RESTRICT gt = this->m_terms[k]->gt(); - const nl_double * const RESTRICT go = this->m_terms[k]->go(); - const nl_double * const RESTRICT Idr = this->m_terms[k]->Idr(); - const nl_double * const *other_cur_analog = this->m_terms[k]->connected_net_V(); + const float_type * const RESTRICT gt = this->m_terms[k]->gt(); + const float_type * const RESTRICT go = this->m_terms[k]->go(); + const float_type * const RESTRICT Idr = this->m_terms[k]->Idr(); + const float_type * const *other_cur_analog = this->m_terms[k]->connected_net_V(); new_V[k] = this->m_nets[k]->Q_Analog(); @@ -123,22 +129,22 @@ unsigned matrix_solver_SOR_t::vsolve_non_dynamic(const bool newt } } - const nl_double accuracy = this->m_params.m_accuracy; + const float_type accuracy = this->m_params.m_accuracy; do { resched = false; - nl_double err = 0; + float_type err = 0; for (std::size_t k = 0; k < iN; k++) { const int * RESTRICT net_other = this->m_terms[k]->connected_net_idx(); const std::size_t railstart = this->m_terms[k]->m_railstart; - const nl_double * RESTRICT go = this->m_terms[k]->go(); + const float_type * RESTRICT go = this->m_terms[k]->go(); - nl_double Idrive = 0.0; + float_type Idrive = 0.0; for (std::size_t i = 0; i < railstart; i++) - Idrive = Idrive + go[i] * new_V[net_other[i]]; + Idrive = Idrive + go[i] * new_V[static_cast(net_other[i])]; - const nl_double new_val = new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k]; + const float_type new_val = new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k]; err = std::max(std::abs(new_val - new_V[k]), err); new_V[k] = new_val; @@ -158,7 +164,7 @@ unsigned matrix_solver_SOR_t::vsolve_non_dynamic(const bool newt { // Fallback to direct solver ... this->m_iterative_fail++; - return matrix_solver_direct_t::vsolve_non_dynamic(newton_raphson); + return matrix_solver_direct_t::vsolve_non_dynamic(newton_raphson); } for (std::size_t k = 0; k < iN; k++) diff --git a/src/lib/netlist/solver/nld_ms_sor_mat.h b/src/lib/netlist/solver/nld_ms_sor_mat.h index 7e80877d36e..5eb4405600e 100644 --- a/src/lib/netlist/solver/nld_ms_sor_mat.h +++ b/src/lib/netlist/solver/nld_ms_sor_mat.h @@ -22,20 +22,24 @@ namespace netlist { namespace devices { -template -class matrix_solver_SOR_mat_t: public matrix_solver_direct_t + +template +class matrix_solver_SOR_mat_t: public matrix_solver_direct_t { friend class matrix_solver_t; public: + typedef FT float_type; + matrix_solver_SOR_mat_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, std::size_t size) - : matrix_solver_direct_t(anetlist, name, matrix_solver_t::DESCENDING, params, size) - , m_Vdelta(*this, "m_Vdelta", 0.0) + : matrix_solver_direct_t(anetlist, name, matrix_solver_t::DESCENDING, params, size) + , m_Vdelta(*this, "m_Vdelta", std::vector(size)) , m_omega(*this, "m_omega", params->m_gs_sor) , m_lp_fact(*this, "m_lp_fact", 0) , m_gs_fail(*this, "m_gs_fail", 0) , m_gs_total(*this, "m_gs_total", 0) + , new_V(size, 0.0) { } @@ -46,28 +50,31 @@ public: virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; private: - state_var m_Vdelta; + //state_var m_Vdelta; + state_var> m_Vdelta; - state_var m_omega; - state_var m_lp_fact; + state_var m_omega; + state_var m_lp_fact; state_var m_gs_fail; state_var m_gs_total; + + std::vector new_V; }; // ---------------------------------------------------------------------------------------- // matrix_solver - Gauss - Seidel // ---------------------------------------------------------------------------------------- -template -void matrix_solver_SOR_mat_t::vsetup(analog_net_t::list_t &nets) +template +void matrix_solver_SOR_mat_t::vsetup(analog_net_t::list_t &nets) { - matrix_solver_direct_t::vsetup(nets); + matrix_solver_direct_t::vsetup(nets); } #if 0 //FIXME: move to solve_base template -nl_double matrix_solver_SOR_mat_t::vsolve() +float_type matrix_solver_SOR_mat_t::vsolve() { /* * enable linear prediction on first newton pass @@ -89,13 +96,13 @@ nl_double matrix_solver_SOR_mat_t::vsolve() if (USE_LINEAR_PREDICTION) { - nl_double sq = 0; - nl_double sqo = 0; - const nl_double rez_cts = 1.0 / this->current_timestep(); + float_type sq = 0; + float_type sqo = 0; + const float_type rez_cts = 1.0 / this->current_timestep(); for (unsigned k = 0; k < this->N(); k++) { const analog_net_t *n = this->m_nets[k]; - const nl_double nv = (n->Q_Analog() - this->m_last_V[k]) * rez_cts ; + const float_type nv = (n->Q_Analog() - this->m_last_V[k]) * rez_cts ; sq += nv * nv; sqo += this->m_Vdelta[k] * this->m_Vdelta[k]; this->m_Vdelta[k] = nv; @@ -103,7 +110,7 @@ nl_double matrix_solver_SOR_mat_t::vsolve() // FIXME: used to be 1e90, but this would not be compatible with float if (sqo > NL_FCONST(1e-20)) - m_lp_fact = std::min(std::sqrt(sq/sqo), (nl_double) 2.0); + m_lp_fact = std::min(std::sqrt(sq/sqo), (float_type) 2.0); else m_lp_fact = NL_FCONST(0.0); } @@ -113,8 +120,8 @@ nl_double matrix_solver_SOR_mat_t::vsolve() } #endif -template -unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool newton_raphson) { /* The matrix based code looks a lot nicer but actually is 30% slower than * the optimized code which works directly on the data structures. @@ -122,11 +129,10 @@ unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool */ - nl_double new_v[storage_N] = { 0.0 }; const std::size_t iN = this->N(); - matrix_solver_t::build_LE_A(); - matrix_solver_t::build_LE_RHS(); + this->build_LE_A(*this); + this->build_LE_RHS(*this); bool resched = false; @@ -139,19 +145,19 @@ unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool if (1 && ws_cnt % 200 == 0) { // update omega - nl_double lambdaN = 0; - nl_double lambda1 = 1e9; + float_type lambdaN = 0; + float_type lambda1 = 1e9; for (int k = 0; k < iN; k++) { #if 0 - nl_double akk = std::abs(this->m_A[k][k]); + float_type akk = std::abs(this->m_A[k][k]); if ( akk > lambdaN) lambdaN = akk; if (akk < lambda1) lambda1 = akk; #else - nl_double akk = std::abs(this->m_A[k][k]); - nl_double s = 0.0; + float_type akk = std::abs(this->m_A[k][k]); + float_type s = 0.0; for (int i=0; im_A[k][i]); akk = s / akk - 1.0; @@ -170,25 +176,25 @@ unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool #endif for (std::size_t k = 0; k < iN; k++) - new_v[k] = this->m_nets[k]->Q_Analog(); + new_V[k] = this->m_nets[k]->Q_Analog(); do { resched = false; - nl_double cerr = 0.0; + float_type cerr = 0.0; for (std::size_t k = 0; k < iN; k++) { - nl_double Idrive = 0; + float_type Idrive = 0; const auto *p = this->m_terms[k]->m_nz.data(); const std::size_t e = this->m_terms[k]->m_nz.size(); for (std::size_t i = 0; i < e; i++) - Idrive = Idrive + this->A(k,p[i]) * new_v[p[i]]; + Idrive = Idrive + this->A(k,p[i]) * new_V[p[i]]; - const nl_double delta = m_omega * (this->RHS(k) - Idrive) / this->A(k,k); + const float_type delta = m_omega * (this->RHS(k) - Idrive) / this->A(k,k); cerr = std::max(cerr, std::abs(delta)); - new_v[k] += delta; + new_V[k] += delta; } if (cerr > this->m_params.m_accuracy) @@ -208,10 +214,10 @@ unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool //this->netlist().warning("Falling back to direct solver .. Consider increasing RESCHED_LOOPS"); this->m_gs_fail++; - return matrix_solver_direct_t::solve_non_dynamic(newton_raphson); + return matrix_solver_direct_t::solve_non_dynamic(newton_raphson); } else { - this->store(new_v); + this->store(new_V.data()); return resched_cnt; } diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h index faaeb50b3d3..7ce2802336d 100644 --- a/src/lib/netlist/solver/nld_ms_w.h +++ b/src/lib/netlist/solver/nld_ms_w.h @@ -50,15 +50,18 @@ namespace netlist { namespace devices { -//#define nl_ext_double _float128 // slow, very slow -//#define nl_ext_double long double // slightly slower -#define nl_ext_double nl_double -template +template class matrix_solver_w_t: public matrix_solver_t { friend class matrix_solver_t; + public: + typedef FT float_ext_type; + typedef FT float_type; + + // FIXME: dirty hack to make this compile + static constexpr const std::size_t storage_N = 100; matrix_solver_w_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size); @@ -71,7 +74,7 @@ protected: virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; unsigned solve_non_dynamic(const bool newton_raphson); - constexpr std::size_t N() const { return (m_N == 0) ? m_dim : m_N; } + constexpr std::size_t N() const { return m_dim; } void LE_invert(); @@ -80,40 +83,40 @@ protected: template - nl_ext_double &A(const T1 &r, const T2 &c) { return m_A[r][c]; } + float_ext_type &A(const T1 &r, const T2 &c) { return m_A[r][c]; } template - nl_ext_double &W(const T1 &r, const T2 &c) { return m_W[r][c]; } + float_ext_type &W(const T1 &r, const T2 &c) { return m_W[r][c]; } /* access to Ainv for fixed columns over row, there store transposed */ template - nl_ext_double &Ainv(const T1 &r, const T2 &c) { return m_Ainv[c][r]; } + float_ext_type &Ainv(const T1 &r, const T2 &c) { return m_Ainv[c][r]; } template - nl_ext_double &RHS(const T1 &r) { return m_RHS[r]; } + float_ext_type &RHS(const T1 &r) { return m_RHS[r]; } template - nl_ext_double &lA(const T1 &r, const T2 &c) { return m_lA[r][c]; } + float_ext_type &lA(const T1 &r, const T2 &c) { return m_lA[r][c]; } - nl_double m_last_RHS[storage_N]; // right hand side - contains currents + float_type m_last_RHS[storage_N]; // right hand side - contains currents private: static constexpr std::size_t m_pitch = ((( storage_N) + 7) / 8) * 8; - nl_ext_double m_A[storage_N][m_pitch]; - nl_ext_double m_Ainv[storage_N][m_pitch]; - nl_ext_double m_W[storage_N][m_pitch]; - nl_ext_double m_RHS[storage_N]; // right hand side - contains currents + float_ext_type m_A[storage_N][m_pitch]; + float_ext_type m_Ainv[storage_N][m_pitch]; + float_ext_type m_W[storage_N][m_pitch]; + float_ext_type m_RHS[storage_N]; // right hand side - contains currents - nl_ext_double m_lA[storage_N][m_pitch]; + float_ext_type m_lA[storage_N][m_pitch]; /* temporary */ - nl_double H[storage_N][m_pitch] ; + float_type H[storage_N][m_pitch] ; unsigned rows[storage_N]; unsigned cols[storage_N][m_pitch]; unsigned colcount[storage_N]; unsigned m_cnt; - //nl_ext_double m_RHSx[storage_N]; + //float_ext_type m_RHSx[storage_N]; const std::size_t m_dim; @@ -123,13 +126,13 @@ private: // matrix_solver_direct // ---------------------------------------------------------------------------------------- -template -matrix_solver_w_t::~matrix_solver_w_t() +template +matrix_solver_w_t::~matrix_solver_w_t() { } -template -void matrix_solver_w_t::vsetup(analog_net_t::list_t &nets) +template +void matrix_solver_w_t::vsetup(analog_net_t::list_t &nets) { matrix_solver_t::setup_base(nets); @@ -141,8 +144,8 @@ void matrix_solver_w_t::vsetup(analog_net_t::list_t &nets) -template -void matrix_solver_w_t::LE_invert() +template +void matrix_solver_w_t::LE_invert() { const std::size_t kN = N(); @@ -159,7 +162,7 @@ void matrix_solver_w_t::LE_invert() for (std::size_t i = 0; i < kN; i++) { /* FIXME: Singular matrix? */ - const nl_double f = 1.0 / W(i,i); + const float_type f = 1.0 / W(i,i); const auto * RESTRICT const p = m_terms[i]->m_nzrd.data(); const size_t e = m_terms[i]->m_nzrd.size(); @@ -170,7 +173,7 @@ void matrix_solver_w_t::LE_invert() for (std::size_t jb = 0; jb < eb; jb++) { const auto j = pb[jb]; - const nl_double f1 = - W(j,i) * f; + const float_type f1 = - W(j,i) * f; if (f1 != 0.0) { for (std::size_t k = 0; k < e; k++) @@ -184,10 +187,10 @@ void matrix_solver_w_t::LE_invert() for (std::size_t i = kN; i-- > 0; ) { /* FIXME: Singular matrix? */ - const nl_double f = 1.0 / W(i,i); + const float_type f = 1.0 / W(i,i); for (std::size_t j = i; j-- > 0; ) { - const nl_double f1 = - W(j,i) * f; + const float_type f1 = - W(j,i) * f; if (f1 != 0.0) { for (std::size_t k = i; k < kN; k++) @@ -203,9 +206,9 @@ void matrix_solver_w_t::LE_invert() } } -template +template template -void matrix_solver_w_t::LE_compute_x( +void matrix_solver_w_t::LE_compute_x( T * RESTRICT x) { const std::size_t kN = N(); @@ -215,7 +218,7 @@ void matrix_solver_w_t::LE_compute_x( for (std::size_t k=0; k::LE_compute_x( } -template -unsigned matrix_solver_w_t::solve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_w_t::solve_non_dynamic(const bool newton_raphson) { const auto iN = N(); - nl_double new_V[storage_N]; // = { 0.0 }; + float_type new_V[storage_N]; // = { 0.0 }; if ((m_cnt % 100) == 0) { @@ -266,7 +269,7 @@ unsigned matrix_solver_w_t::solve_non_dynamic(const bool newton_ /* construct w = transform(V) * y * dim: rowcount x iN * */ - nl_double w[storage_N]; + float_type w[storage_N]; for (unsigned i = 0; i < rowcount; i++) { const unsigned r = rows[i]; @@ -287,7 +290,7 @@ unsigned matrix_solver_w_t::solve_non_dynamic(const bool newton_ for (unsigned k=0; k< colcount[i]; k++) { const unsigned col = cols[i][k]; - nl_double f = VT(rows[i],col); + float_type f = VT(rows[i],col); if (f!=0.0) for (unsigned j= 0; j < rowcount; j++) H[i][j] += f * Ainv(col,rows[j]); @@ -298,15 +301,15 @@ unsigned matrix_solver_w_t::solve_non_dynamic(const bool newton_ { if (H[i][i] == 0.0) printf("%s H singular\n", this->name().c_str()); - const nl_double f = 1.0 / H[i][i]; + const float_type f = 1.0 / H[i][i]; for (unsigned j = i+1; j < rowcount; j++) { - const nl_double f1 = - f * H[j][i]; + const float_type f1 = - f * H[j][i]; if (f1!=0.0) { - nl_double *pj = &H[j][i+1]; - const nl_double *pi = &H[i][i+1]; + float_type *pj = &H[j][i+1]; + const float_type *pi = &H[i][i+1]; for (unsigned k = 0; k < rowcount-i-1; k++) pj[k] += f1 * pi[k]; //H[j][k] += f1 * H[i][k]; @@ -316,12 +319,12 @@ unsigned matrix_solver_w_t::solve_non_dynamic(const bool newton_ } /* Back substitution */ //inv(H) w = t w = H t - nl_double t[storage_N]; // FIXME: convert to member + float_type t[storage_N]; // FIXME: convert to member for (unsigned j = rowcount; j-- > 0; ) { - nl_double tmp = 0; - const nl_double *pj = &H[j][j+1]; - const nl_double *tj = &t[j+1]; + float_type tmp = 0; + const float_type *pj = &H[j][j+1]; + const float_type *tj = &t[j+1]; for (unsigned k = 0; k < rowcount-j-1; k++) tmp += pj[k] * tj[k]; //tmp += H[j][k] * t[k]; @@ -331,7 +334,7 @@ unsigned matrix_solver_w_t::solve_non_dynamic(const bool newton_ /* x = y - Zt */ for (unsigned i=0; i::solve_non_dynamic(const bool newton_ if (0) for (unsigned i=0; i::solve_non_dynamic(const bool newton_ printf("%s failed on row %d: %f RHS: %f\n", this->name().c_str(), i, std::abs(tmp-RHS(i)), RHS(i)); } - const nl_double err = (newton_raphson ? delta(new_V) : 0.0); + const float_type err = (newton_raphson ? delta(new_V) : 0.0); store(new_V); return (err > this->m_params.m_accuracy) ? 2 : 1; } -template -unsigned matrix_solver_w_t::vsolve_non_dynamic(const bool newton_raphson) +template +unsigned matrix_solver_w_t::vsolve_non_dynamic(const bool newton_raphson) { - build_LE_A(); - build_LE_RHS(); + this->build_LE_A(*this); + this->build_LE_RHS(*this); for (std::size_t i=0, iN=N(); i < iN; i++) m_last_RHS[i] = RHS(i); @@ -373,8 +376,8 @@ unsigned matrix_solver_w_t::vsolve_non_dynamic(const bool newton return this->solve_non_dynamic(newton_raphson); } -template -matrix_solver_w_t::matrix_solver_w_t(netlist_base_t &anetlist, const pstring &name, +template +matrix_solver_w_t::matrix_solver_w_t(netlist_base_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size) : matrix_solver_t(anetlist, name, NOSORT, params) ,m_cnt(0) diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 3421081b7ec..2997f1c8e45 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -133,12 +133,12 @@ matrix_solver_t * create_it(netlist_base_t &nl, pstring name, solver_parameters_ return plib::palloc(nl, name, ¶ms, size); } -template +template matrix_solver_t * NETLIB_NAME(solver)::create_solver(std::size_t size, const pstring &solvername) { if (m_method() == "SOR_MAT") { - return create_it>(state(), solvername, m_params, size); + return create_it>(state(), solvername, m_params, size); //typedef matrix_solver_SOR_mat_t solver_sor_mat; //return plib::make_unique(state(), solvername, &m_params, size); } @@ -146,34 +146,34 @@ matrix_solver_t * NETLIB_NAME(solver)::create_solver(std::size_t size, const pst { if (size > 0) // GCR always outperforms MAT solver { - return create_it>(state(), solvername, m_params, size); + return create_it>(state(), solvername, m_params, size); } else { - return create_it>(state(), solvername, m_params, size); + return create_it>(state(), solvername, m_params, size); } } else if (m_method() == "MAT") { - return create_it>(state(), solvername, m_params, size); + return create_it>(state(), solvername, m_params, size); } else if (m_method() == "SM") { /* Sherman-Morrison Formula */ - return create_it>(state(), solvername, m_params, size); + return create_it>(state(), solvername, m_params, size); } else if (m_method() == "W") { /* Woodbury Formula */ - return create_it>(state(), solvername, m_params, size); + return create_it>(state(), solvername, m_params, size); } else if (m_method() == "SOR") { - return create_it>(state(), solvername, m_params, size); + return create_it>(state(), solvername, m_params, size); } else if (m_method() == "GMRES") { - return create_it>(state(), solvername, m_params, size); + return create_it>(state(), solvername, m_params, size); } else { @@ -288,64 +288,64 @@ void NETLIB_NAME(solver)::post_start() switch (net_count) { -#if 0 +#if 1 case 1: if (use_specific) - ms = plib::palloc(state(), sname, &m_params); + ms = plib::palloc>(state(), sname, &m_params); else - ms = create_solver<1,1>(1, sname); + ms = create_solver(1, sname); break; case 2: if (use_specific) - ms = plib::palloc(state(), sname, &m_params); + ms = plib::palloc>(state(), sname, &m_params); else - ms = create_solver<2,2>(2, sname); + ms = create_solver(2, sname); break; #if 1 case 3: - ms = create_solver<3,3>(3, sname); + ms = create_solver(3, sname); break; case 4: - ms = create_solver<4,4>(4, sname); + ms = create_solver(4, sname); break; case 5: - ms = create_solver<5,5>(5, sname); + ms = create_solver(5, sname); break; case 6: - ms = create_solver<6,6>(6, sname); + ms = create_solver(6, sname); break; case 7: - ms = create_solver<7,7>(7, sname); + ms = create_solver(7, sname); break; case 8: - ms = create_solver<8,8>(8, sname); + ms = create_solver(8, sname); break; case 9: - ms = create_solver<9,9>(9, sname); + ms = create_solver(9, sname); break; case 10: - ms = create_solver<10,10>(10, sname); + ms = create_solver(10, sname); break; case 11: - ms = create_solver<11,11>(11, sname); + ms = create_solver(11, sname); break; case 12: - ms = create_solver<12,12>(12, sname); + ms = create_solver(12, sname); break; case 15: - ms = create_solver<15,15>(15, sname); + ms = create_solver(15, sname); break; case 31: - ms = create_solver<31,31>(31, sname); + ms = create_solver(31, sname); break; case 35: - ms = create_solver<35,35>(35, sname); + ms = create_solver(35, sname); break; case 43: - ms = create_solver<43,43>(43, sname); + ms = create_solver(43, sname); break; case 49: - ms = create_solver<49,49>(49, sname); + ms = create_solver(49, sname); break; #endif #if 0 @@ -358,32 +358,31 @@ void NETLIB_NAME(solver)::post_start() log().warning(MW_1_NO_SPECIFIC_SOLVER, net_count); if (net_count <= 8) { - ms = create_solver<0, 8>(net_count, sname); + ms = create_solver(net_count, sname); } else if (net_count <= 16) { - ms = create_solver<0,16>(net_count, sname); + ms = create_solver(net_count, sname); } else if (net_count <= 32) { - ms = create_solver<0,32>(net_count, sname); + ms = create_solver(net_count, sname); } else if (net_count <= 64) { - ms = create_solver<0,64>(net_count, sname); + ms = create_solver(net_count, sname); } else if (net_count <= 128) { - ms = create_solver<0,128>(net_count, sname); + ms = create_solver(net_count, sname); } else { log().fatal(MF_1_NETGROUP_SIZE_EXCEEDED_1, 128); ms = nullptr; /* tease compilers */ } - break; } diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index a52730773a7..a07917b195d 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -102,7 +102,7 @@ private: solver_parameters_t m_params; - template + template matrix_solver_t * create_solver(std::size_t size, const pstring &solvername); }; diff --git a/src/lib/netlist/solver/vector_base.h b/src/lib/netlist/solver/vector_base.h index 0587269efdf..61ca2f3d9c0 100644 --- a/src/lib/netlist/solver/vector_base.h +++ b/src/lib/netlist/solver/vector_base.h @@ -12,6 +12,7 @@ #include #include +#include #include "../plib/pconfig.h" #if 0 @@ -36,63 +37,50 @@ private: #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif -template -void vec_set (const std::size_t n, const T scalar, T (& RESTRICT v)[N]) +template +void vec_set_scalar (const std::size_t n, VT &v, const T & scalar) { - if (n != N) - for ( std::size_t i = 0; i < n; i++ ) - v[i] = scalar; - else - for ( std::size_t i = 0; i < N; i++ ) - v[i] = scalar; + for ( std::size_t i = 0; i < n; i++ ) + v[i] = scalar; } -template -T vec_mult (const std::size_t n, const T (& RESTRICT v1)[N], const T (& RESTRICT v2)[N] ) +template +void vec_set (const std::size_t n, VT &v, const VS & source) +{ + for ( std::size_t i = 0; i < n; i++ ) + v[i] = source [i]; +} + +template +T vec_mult (const std::size_t n, const V1 & v1, const V2 & v2 ) { T value = 0.0; - if (n != N) - for ( std::size_t i = 0; i < n; i++ ) - value += v1[i] * v2[i]; - else - for ( std::size_t i = 0; i < N; i++ ) - value += v1[i] * v2[i]; + for ( std::size_t i = 0; i < n; i++ ) + value += v1[i] * v2[i]; return value; } -template -T vec_mult2 (const std::size_t n, const T (& RESTRICT v)[N]) +template +T vec_mult2 (const std::size_t n, const VT &v) { T value = 0.0; - if (n != N) - for ( std::size_t i = 0; i < n; i++ ) - value += v[i] * v[i]; - else - for ( std::size_t i = 0; i < N; i++ ) - value += v[i] * v[i]; + for ( std::size_t i = 0; i < n; i++ ) + value += v[i] * v[i]; return value; } -template -void vec_mult_scalar (const std::size_t n, const T (& RESTRICT v)[N], const T & scalar, T (& RESTRICT result)[N]) +template +void vec_mult_scalar (const std::size_t n, const VV & v, const T & scalar, VR & result) { - if (n != N) - for ( std::size_t i = 0; i < n; i++ ) - result[i] = scalar * v[i]; - else - for ( std::size_t i = 0; i < N; i++ ) - result[i] = scalar * v[i]; + for ( std::size_t i = 0; i < n; i++ ) + result[i] = scalar * v[i]; } -template -void vec_add_mult_scalar (const std::size_t n, const T (& RESTRICT v)[N], const T scalar, T (& RESTRICT result)[N]) +template +void vec_add_mult_scalar (const std::size_t n, const VV & v, const T scalar, VR & result) { - if (n != N) - for ( std::size_t i = 0; i < n; i++ ) - result[i] = result[i] + scalar * v[i]; - else - for ( std::size_t i = 0; i < N; i++ ) - result[i] = result[i] + scalar * v[i]; + for ( std::size_t i = 0; i < n; i++ ) + result[i] = result[i] + scalar * v[i]; } template @@ -102,37 +90,29 @@ void vec_add_mult_scalar_p(const std::size_t & n, const T * RESTRICT v, const T result[i] += scalar * v[i]; } -template -void vec_add_ip(const std::size_t n, const T * RESTRICT v, T * RESTRICT result) +template +void vec_add_ip(const std::size_t n, const V & v, R & result) { for ( std::size_t i = 0; i < n; i++ ) result[i] += v[i]; } -template -void vec_sub(const std::size_t n, const T (& RESTRICT v1)[N], const T (& RESTRICT v2)[N], T (& RESTRICT result)[N]) +template +void vec_sub(const std::size_t n, const V1 &v1, const V2 & v2, VR & result) { - if (n != N) - for ( std::size_t i = 0; i < n; i++ ) - result[i] = v1[i] - v2[i]; - else - for ( std::size_t i = 0; i < N; i++ ) - result[i] = v1[i] - v2[i]; + for ( std::size_t i = 0; i < n; i++ ) + result[i] = v1[i] - v2[i]; } -template -void vec_scale(const std::size_t n, T (& RESTRICT v)[N], const T scalar) +template +void vec_scale(const std::size_t n, V & v, const T scalar) { - if (n != N) - for ( std::size_t i = 0; i < n; i++ ) - v[i] = scalar * v[i]; - else - for ( std::size_t i = 0; i < N; i++ ) - v[i] = scalar * v[i]; + for ( std::size_t i = 0; i < n; i++ ) + v[i] = scalar * v[i]; } -template -T vec_maxabs(const std::size_t n, const T * RESTRICT v) +template +T vec_maxabs(const std::size_t n, const V & v) { T ret = 0.0; for ( std::size_t i = 0; i < n; i++ ) diff --git a/src/mame/audio/nl_kidniki.cpp b/src/mame/audio/nl_kidniki.cpp index f430637868f..7916f992dee 100644 --- a/src/mame/audio/nl_kidniki.cpp +++ b/src/mame/audio/nl_kidniki.cpp @@ -317,15 +317,16 @@ NETLIST_START(kidniki) PARAM(Solver.METHOD, "MAT_CR") //PARAM(Solver.METHOD, "MAT") //PARAM(Solver.METHOD, "GMRES") - PARAM(Solver.SOR_FACTOR, 1.00) + PARAM(Solver.SOR_FACTOR, 1.0) PARAM(Solver.DYNAMIC_TS, 0) PARAM(Solver.DYNAMIC_LTE, 5e-4) PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 20e-6) #else SOLVER(Solver, 18000) - PARAM(Solver.ACCURACY, 1e-6) + PARAM(Solver.ACCURACY, 1e-7) PARAM(Solver.NR_LOOPS, 100) PARAM(Solver.GS_LOOPS, 20) + //PARAM(Solver.METHOD, "MAT_CR") PARAM(Solver.METHOD, "GMRES") #endif -- cgit v1.2.3-70-g09d2 From c87a487d6de35479210d36dcf53d2c96a478601a Mon Sep 17 00:00:00 2001 From: couriersud Date: Mon, 4 Feb 2019 00:27:23 +0100 Subject: netlist: Refactoring and some functionality enhancements. (nw) - Removed dead code. - nltool now adds a define NLTOOL_VERSION. This can be tested in netlists. It is used in kidniki to ensure I stop committing debug parameters. - Optimized the proposal for no-deactivate hints. - Documented in breakout that hints were manually optimized. - Minor optimizations in the order of 2% enhancement. --- src/devices/machine/netlist.cpp | 6 +-- src/devices/machine/netlist.h | 1 - src/lib/netlist/devices/nld_9310.cpp | 31 +++++++------- src/lib/netlist/devices/nld_9316.cpp | 34 +++++----------- src/lib/netlist/devices/nld_system.cpp | 23 +++++++++++ src/lib/netlist/devices/nlid_system.h | 15 +++---- src/lib/netlist/devices/nlid_truthtable.h | 4 +- src/lib/netlist/nl_base.cpp | 68 ++++++++++--------------------- src/lib/netlist/nl_base.h | 59 +++++++++++++++++++++------ src/lib/netlist/nl_setup.cpp | 11 ++--- src/lib/netlist/nl_setup.h | 13 ++++-- src/lib/netlist/plib/plists.h | 3 +- src/lib/netlist/plib/poptions.cpp | 6 +-- src/lib/netlist/plib/poptions.h | 26 ++++++------ src/lib/netlist/plib/pparser.cpp | 14 +++---- src/lib/netlist/plib/pparser.h | 6 ++- src/lib/netlist/plib/pstate.cpp | 4 +- src/lib/netlist/plib/pstate.h | 4 +- src/lib/netlist/plib/putil.h | 4 ++ src/lib/netlist/prg/nltool.cpp | 21 ++++++---- src/lib/netlist/prg/nlwav.cpp | 10 ++--- src/mame/audio/nl_kidniki.cpp | 9 ++++ src/mame/machine/nl_breakout.cpp | 47 ++++++++++++++++++--- 23 files changed, 250 insertions(+), 169 deletions(-) (limited to 'src/lib/netlist/plib/pstate.h') diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 6795dcb9d6a..fc76132a731 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -301,7 +301,7 @@ public: { int pos = (upto - m_last_buffer_time) / m_sample_time; if (pos > m_bufsize) - state().log().fatal("sound {1}: pos {2} exceeded bufsize {3}\n", name().c_str(), pos, m_bufsize); + throw emu_fatalerror("sound %s: pos %d exceeded bufsize %d\n", name().c_str(), pos, m_bufsize); while (m_last_pos < pos ) { m_buffer[m_last_pos++] = (stream_sample_t) m_cur; @@ -1050,10 +1050,8 @@ ATTR_COLD uint64_t netlist_mame_cpu_device::execute_cycles_to_clocks(uint64_t cy ATTR_HOT void netlist_mame_cpu_device::execute_run() { - bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0); - // debugging //m_ppc = m_pc; // copy PC to previous PC - if (check_debugger) + if (debugger_enabled()) { while (m_icount > 0) { diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index d79e9e298c2..06edb4beaa4 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -109,7 +109,6 @@ public: ATTR_HOT inline netlist::setup_t &setup(); ATTR_HOT inline netlist_mame_t &netlist() { return *m_netlist; } - ATTR_HOT inline const netlist::netlist_time last_time_update() { return m_old; } ATTR_HOT void update_icount(netlist::netlist_time time); ATTR_HOT void check_mame_abort_slice(); diff --git a/src/lib/netlist/devices/nld_9310.cpp b/src/lib/netlist/devices/nld_9310.cpp index 4348de20417..cbc197a70d8 100644 --- a/src/lib/netlist/devices/nld_9310.cpp +++ b/src/lib/netlist/devices/nld_9310.cpp @@ -158,32 +158,35 @@ namespace netlist NETLIB_UPDATE(9310_sub) { + auto cnt(m_cnt); + if (m_loadq) { - if (m_cnt < MAXCNT - 1) + if (cnt < MAXCNT - 1) { - ++m_cnt; - update_outputs(m_cnt); + ++cnt; + update_outputs(cnt); } - else if (m_cnt == MAXCNT - 1) + else if (cnt == MAXCNT - 1) { - m_cnt = MAXCNT; + cnt = MAXCNT; m_RC.push(m_ent, NLTIME_FROM_NS(20)); m_QA.push(1, NLTIME_FROM_NS(20)); } else // MAXCNT { m_RC.push(0, NLTIME_FROM_NS(20)); - m_cnt = 0; - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); + cnt = 0; + update_outputs_all(cnt, NLTIME_FROM_NS(20)); } } else { - m_cnt = m_ABCD->read_ABCD(); - m_RC.push(m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); - update_outputs_all(m_cnt, NLTIME_FROM_NS(22)); + cnt = m_ABCD->read_ABCD(); + m_RC.push(m_ent & (cnt == MAXCNT), NLTIME_FROM_NS(27)); + update_outputs_all(cnt, NLTIME_FROM_NS(22)); } + m_cnt = cnt; } NETLIB_UPDATE(9310) @@ -224,10 +227,10 @@ namespace netlist #if 0 // for (int i=0; i<4; i++) // m_Q[i], (cnt >> i) & 1, delay[i]); - m_QA, (cnt >> 0) & 1, out_delay); - m_QB, (cnt >> 1) & 1, out_delay); - m_QC, (cnt >> 2) & 1, out_delay); - m_QD, (cnt >> 3) & 1, out_delay); + m_QA.push((cnt >> 0) & 1, out_delay); + m_QB.push((cnt >> 1) & 1, out_delay); + m_QC.push((cnt >> 2) & 1, out_delay); + m_QD.push((cnt >> 3) & 1, out_delay); #else if ((cnt & 1) == 1) m_QA.push(1, out_delay); diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp index 20858ebc74f..69dd1c1c6ca 100644 --- a/src/lib/netlist/devices/nld_9316.cpp +++ b/src/lib/netlist/devices/nld_9316.cpp @@ -105,27 +105,15 @@ namespace netlist NETLIB_HANDLER(9316, clk) { + auto cnt(m_cnt); if (m_LOADQ()) { - ++m_cnt &= MAXCNT; - //m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); -#if 0 - if (m_cnt == MAXCNT) - { - m_RC.push(m_ENT(), NLTIME_FROM_NS(27)); - update_outputs_all(MAXCNT, NLTIME_FROM_NS(20)); - } - else if (m_cnt == 0) - { - m_RC.push(0, NLTIME_FROM_NS(27)); - update_outputs_all(0, NLTIME_FROM_NS(20)); - } - else - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); -#else - if (m_cnt > 0 && m_cnt < MAXCNT) - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); - else if (m_cnt == 0) + ++cnt &= MAXCNT; + //m_RC.push(m_ENT() && (cnt == MAXCNT), NLTIME_FROM_NS(27)); + + if (cnt > 0 && cnt < MAXCNT) + update_outputs_all(cnt, NLTIME_FROM_NS(20)); + else if (cnt == 0) { m_RC.push(0, NLTIME_FROM_NS(27)); update_outputs_all(0, NLTIME_FROM_NS(20)); @@ -135,14 +123,14 @@ namespace netlist m_RC.push(m_ENT(), NLTIME_FROM_NS(27)); update_outputs_all(MAXCNT, NLTIME_FROM_NS(20)); } -#endif } else { - m_cnt = m_abcd; - m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); - update_outputs_all(m_cnt, NLTIME_FROM_NS(22)); + cnt = m_abcd; + m_RC.push(m_ENT() && (cnt == MAXCNT), NLTIME_FROM_NS(27)); + update_outputs_all(cnt, NLTIME_FROM_NS(22)); } + m_cnt = cnt; } NETLIB_UPDATE(9316) diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index 24af4527a70..134017d06b0 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -40,15 +40,38 @@ namespace netlist { m_cnt = 0; m_off = netlist_time::from_double(m_offset()); + m_feedback.m_delegate = NETLIB_DELEGATE(extclock, update); + + //m_feedback.m_delegate .set(&NETLIB_NAME(extclock)::update, this); //m_Q.initial(0); } + NETLIB_HANDLER(extclock, clk2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + if (++m_cnt >= m_size) + m_cnt = 0; + } + + NETLIB_HANDLER(extclock, clk2_pow2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + m_cnt = (++m_cnt) & (m_size-1); + } + NETLIB_UPDATE(extclock) { m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off); m_off = netlist_time::zero(); if (++m_cnt >= m_size) m_cnt = 0; + + // continue with optimized clock handlers .... + + if ((m_size & (m_size-1)) == 0) // power of 2? + m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2_pow2, this); + else + m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2, this); } // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 3d878646549..7271084bbc1 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -52,7 +52,7 @@ namespace netlist NETLIB_RESETI() { - m_Q.net().set_time(netlist_time::zero()); + m_Q.net().set_next_scheduled_time(netlist_time::zero()); } NETLIB_UPDATE_PARAMI() @@ -65,7 +65,7 @@ namespace netlist logic_net_t &net = m_Q.net(); // this is only called during setup ... net.toggle_new_Q(); - net.set_time(exec().time() + m_inc); + net.set_next_scheduled_time(exec().time() + m_inc); } public: @@ -73,13 +73,6 @@ namespace netlist param_double_t m_freq; netlist_time m_inc; - - static void mc_update(logic_net_t &net) - { - net.toggle_new_Q(); - net.update_devs(); - } - }; // ----------------------------------------------------------------------------- @@ -158,6 +151,10 @@ namespace netlist NETLIB_UPDATEI(); NETLIB_RESETI(); //NETLIB_UPDATE_PARAMI(); + + NETLIB_HANDLERI(clk2); + NETLIB_HANDLERI(clk2_pow2); + protected: param_double_t m_freq; diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h index f0f85e037de..c633a6991a1 100644 --- a/src/lib/netlist/devices/nlid_truthtable.h +++ b/src/lib/netlist/devices/nlid_truthtable.h @@ -179,7 +179,7 @@ namespace devices m_I[i].activate(); //nstate |= (m_I[i]() ? (1 << i) : 0); nstate |= (m_I[i]() << i); - mt = std::max(this->m_I[i].net().time(), mt); + mt = std::max(this->m_I[i].net().next_scheduled_time(), mt); } else for (std::size_t i = 0; i < m_NI; i++) @@ -208,7 +208,7 @@ namespace devices { //nstate |= (m_I[i]() ? (1 << i) : 0); nstate |= (m_I[i]() << i); - mt = std::max(this->m_I[i].net().time(), mt); + mt = std::max(this->m_I[i].net().next_scheduled_time(), mt); } else for (std::size_t i = 0; i < m_NI; i++) diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 14807111ff2..4ce980dbba8 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -164,11 +164,9 @@ void detail::queue_t::register_state(plib::state_manager_t &manager, const pstri manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size()); } -void detail::queue_t::on_pre_save() +void detail::queue_t::on_pre_save(plib::state_manager_t &manager) { - state().log().debug("on_pre_save\n"); m_qsize = this->size(); - state().log().debug("qsize {1}\n", m_qsize); for (std::size_t i = 0; i < m_qsize; i++ ) { m_times[i] = this->listptr()[i].m_exec_time.as_raw(); @@ -177,10 +175,9 @@ void detail::queue_t::on_pre_save() } -void detail::queue_t::on_post_load() +void detail::queue_t::on_post_load(plib::state_manager_t &manager) { this->clear(); - state().log().debug("qsize {1}\n", m_qsize); for (std::size_t i = 0; i < m_qsize; i++ ) { detail::net_t *n = state().nets()[m_net_ids[i]].get(); @@ -247,11 +244,11 @@ detail::terminal_type detail::core_terminal_t::type() const // ---------------------------------------------------------------------------------------- netlist_t::netlist_t(const pstring &aname, std::unique_ptr callbacks) - : m_state(plib::make_unique(aname, + : m_time(netlist_time::zero()) + , m_mainclock(nullptr) + , m_state(plib::make_unique(aname, std::move(callbacks), plib::make_unique(*this))) // FIXME, ugly but needed to have netlist_state_t constructed first - , m_time(netlist_time::zero()) - , m_mainclock(nullptr) , m_queue(*m_state) , m_solver(nullptr) { @@ -272,8 +269,7 @@ netlist_t::~netlist_t() netlist_state_t::netlist_state_t(const pstring &aname, std::unique_ptr &&callbacks, std::unique_ptr &&setup) -: m_params(nullptr) -, m_name(aname) +: m_name(aname) , m_state() , m_callbacks(std::move(callbacks)) // Order is important here , m_log(*m_callbacks) @@ -339,7 +335,7 @@ void netlist_t::reset() m_time = netlist_time::zero(); m_queue.clear(); if (m_mainclock != nullptr) - m_mainclock->m_Q.net().set_time(netlist_time::zero()); + m_mainclock->m_Q.net().set_next_scheduled_time(netlist_time::zero()); //if (m_solver != nullptr) // m_solver->reset(); @@ -452,7 +448,7 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT { logic_net_t &mc_net(m_mainclock->m_Q.net()); const netlist_time inc(m_mainclock->m_inc); - netlist_time mc_time(mc_net.time()); + netlist_time mc_time(mc_net.next_scheduled_time()); do { @@ -474,7 +470,7 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT else break; } while (true); //while (e.m_object != nullptr); - mc_net.set_time(mc_time); + mc_net.set_next_scheduled_time(mc_time); } m_stat_mainloop.stop(); } @@ -503,6 +499,9 @@ void netlist_t::print_stats() const total_count += entry->m_stat_total_time.count(); } + log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count, + total_time, total_time / total_count); + nperftime_t overhead; nperftime_t test; overhead.start(); @@ -531,10 +530,16 @@ void netlist_t::print_stats() const / static_cast::type>(m_queue.m_prof_call()); log().verbose("Overhead per pop {1:11}", overhead_per_pop ); log().verbose(""); + + auto trigger = total_count * 200 / 1000000; // 200 ppm for (auto &entry : m_state->m_devices) { - if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count()) - log().verbose("HINT({}, NO_DEACTIVATE)", entry->name()); + // Factor of 3 offers best performace increase + if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count() + && entry->m_stat_inc_active() > trigger) + log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", entry->name(), + static_cast(entry->m_stat_inc_active()) / static_cast(entry->m_stat_total_time.count()), + entry->m_stat_inc_active(), entry->m_stat_total_time.count()); } } } @@ -687,7 +692,7 @@ detail::net_t::net_t(netlist_base_t &nl, const pstring &aname, core_terminal_t * , m_new_Q(*this, "m_new_Q", 0) , m_cur_Q (*this, "m_cur_Q", 0) , m_in_queue(*this, "m_in_queue", QS_DELIVERED) - , m_time(*this, "m_time", netlist_time::zero()) + , m_next_scheduled_time(*this, "m_time", netlist_time::zero()) , m_railterminal(mr) { } @@ -697,35 +702,6 @@ detail::net_t::~net_t() state().run_state_manager().remove_save_items(this); } -void detail::net_t::add_to_active_list(core_terminal_t &term) NL_NOEXCEPT -{ - const bool was_empty = m_list_active.empty(); - m_list_active.push_front(&term); - if (was_empty) - { - railterminal().device().do_inc_active(); - if (m_in_queue == QS_DELAYED_DUE_TO_INACTIVE) - { - if (m_time > exec().time()) - { - m_in_queue = QS_QUEUED; /* pending */ - exec().queue().push({m_time, this}); - } - else - { - m_in_queue = QS_DELIVERED; - m_cur_Q = m_new_Q; - } - } - } -} - -void detail::net_t::remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT -{ - m_list_active.remove(&term); - if (m_list_active.empty()) - railterminal().device().do_dec_active(); -} void detail::net_t::rebuild_list() { @@ -779,7 +755,7 @@ void detail::net_t::update_devs() NL_NOEXCEPT void detail::net_t::reset() { - m_time = netlist_time::zero(); + m_next_scheduled_time = netlist_time::zero(); m_in_queue = QS_DELIVERED; m_new_Q = 0; diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index ca75046b3e5..35ecc694cfd 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -732,8 +732,8 @@ namespace netlist void update_devs() NL_NOEXCEPT; - const netlist_time time() const noexcept { return m_time; } - void set_time(netlist_time ntime) noexcept { m_time = ntime; } + const netlist_time next_scheduled_time() const noexcept { return m_next_scheduled_time; } + void set_next_scheduled_time(netlist_time ntime) noexcept { m_next_scheduled_time = ntime; } bool isRailNet() const noexcept { return !(m_railterminal == nullptr); } core_terminal_t & railterminal() const noexcept { return *m_railterminal; } @@ -761,7 +761,7 @@ namespace netlist state_var m_cur_Q; state_var m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */ - state_var m_time; + state_var m_next_scheduled_time; private: plib::linkedlist_t m_list_active; @@ -803,7 +803,7 @@ namespace netlist if (newQ != m_new_Q) { m_in_queue = QS_DELAYED_DUE_TO_INACTIVE; - m_time = at; + m_next_scheduled_time = at; } m_cur_Q = m_new_Q = newQ; } @@ -1204,8 +1204,8 @@ namespace netlist protected: void register_state(plib::state_manager_t &manager, const pstring &module) override; - void on_pre_save() override; - void on_post_load() override; + void on_pre_save(plib::state_manager_t &manager) override; + void on_post_load(plib::state_manager_t &manager) override; private: std::size_t m_qsize; @@ -1272,8 +1272,6 @@ namespace netlist template void register_net(plib::owned_ptr &&net) { m_nets.push_back(std::move(net)); } - devices::NETLIB_NAME(netlistparams) *m_params; - template inline std::vector get_device_list() { @@ -1387,11 +1385,10 @@ namespace netlist void print_stats() const; private: - std::unique_ptr m_state; - /* mostly rw */ netlist_time m_time; devices::NETLIB_NAME(mainclock) * m_mainclock; + std::unique_ptr m_state; detail::queue_t m_queue; devices::NETLIB_NAME(solver) * m_solver; @@ -1517,15 +1514,50 @@ namespace netlist { if ((num_cons() != 0)) { + auto &lexec(exec()); + auto &q(lexec.queue()); + auto nst(lexec.time() + delay); + if (is_queued()) - exec().queue().remove(this); - m_time = exec().time() + delay; + q.remove(this); m_in_queue = (!m_list_active.empty()) ? QS_QUEUED : QS_DELAYED_DUE_TO_INACTIVE; /* queued ? */ if (m_in_queue == QS_QUEUED) - exec().queue().push(queue_t::entry_t(m_time, this)); + q.push(queue_t::entry_t(nst, this)); + m_next_scheduled_time = nst; } } + inline void detail::net_t::add_to_active_list(core_terminal_t &term) NL_NOEXCEPT + { + if (m_list_active.empty()) + { + m_list_active.push_front(&term); + railterminal().device().do_inc_active(); + if (m_in_queue == QS_DELAYED_DUE_TO_INACTIVE) + { + if (m_next_scheduled_time > exec().time()) + { + m_in_queue = QS_QUEUED; /* pending */ + exec().queue().push({m_next_scheduled_time, this}); + } + else + { + m_in_queue = QS_DELIVERED; + m_cur_Q = m_new_Q; + } + } + } + else + m_list_active.push_front(&term); + } + + inline void detail::net_t::remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT + { + m_list_active.remove(&term); + if (m_list_active.empty()) + railterminal().device().do_dec_active(); + } + inline const analog_net_t & analog_t::net() const NL_NOEXCEPT { return static_cast(core_terminal_t::net()); @@ -1583,6 +1615,7 @@ namespace netlist return m_device.exec(); } + inline const netlist_t &detail::device_object_t::exec() const NL_NOEXCEPT { return m_device.exec(); diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 291e95add83..cef51f481db 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -27,6 +27,7 @@ namespace netlist { setup_t::setup_t(netlist_t &netlist) : m_netlist(netlist) + , m_netlist_params(nullptr) , m_factory(*this) , m_proxy_cnt(0) , m_frontier_cnt(0) @@ -970,13 +971,13 @@ std::unique_ptr setup_t::get_data_stream(const pstring &name) return std::unique_ptr(nullptr); } -void setup_t::register_define(const pstring &defstr) +void setup_t::add_define(const pstring &defstr) { auto p = defstr.find("="); if (p != pstring::npos) - register_define(plib::left(defstr, p), defstr.substr(p+1)); + add_define(plib::left(defstr, p), defstr.substr(p+1)); else - register_define(defstr, "1"); + add_define(defstr, "1"); } // ---------------------------------------------------------------------------------------- @@ -1024,7 +1025,7 @@ void setup_t::prepare_to_run() log().debug("Searching for solver and parameters ...\n"); auto solver = netlist().get_single_device("solver"); - netlist().m_params = netlist().get_single_device("parameter"); + m_netlist_params = netlist().get_single_device("parameter"); /* create devices */ @@ -1039,7 +1040,7 @@ void setup_t::prepare_to_run() } } - bool use_deactivate = (netlist().m_params->m_use_deactivate() ? true : false); + bool use_deactivate = m_netlist_params->m_use_deactivate() ? true : false; for (auto &d : netlist().devices()) { diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 4becfe1ee0c..25201bee1b5 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -123,6 +123,7 @@ namespace netlist namespace devices { class nld_base_proxy; + class nld_netlistparams; } class core_device_t; @@ -274,8 +275,12 @@ namespace netlist m_sources.push_back(std::move(src)); } - void register_define(pstring def, pstring val) { m_defines.push_back(plib::ppreprocessor::define_t(def, val)); } - void register_define(const pstring &defstr); + void add_define(pstring def, pstring val) + { + m_defines.insert({ def, plib::ppreprocessor::define_t(def, val)}); + } + + void add_define(const pstring &defstr); factory::list_t &factory() { return m_factory; } const factory::list_t &factory() const { return m_factory; } @@ -337,14 +342,16 @@ namespace netlist std::unordered_map m_terminals; netlist_t &m_netlist; + devices::nld_netlistparams *m_netlist_params; std::unordered_map m_params; + std::vector m_links; factory::list_t m_factory; std::unordered_map m_models; std::stack m_namespace_stack; source_t::list_t m_sources; - std::vector m_defines; + plib::ppreprocessor::defines_map_type m_defines; unsigned m_proxy_cnt; unsigned m_frontier_cnt; diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h index 5574f095484..d440d76de2a 100644 --- a/src/lib/netlist/plib/plists.h +++ b/src/lib/netlist/plib/plists.h @@ -152,9 +152,10 @@ public: void remove(const LC *elem) noexcept { auto p = &m_head; - for ( ; *p != elem; p = &((*p)->m_next)) + while(*p != elem) { //nl_assert(*p != nullptr); + p = &((*p)->m_next); } (*p) = elem->m_next; } diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index 43e992f9225..dcb8e3931f3 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -219,7 +219,7 @@ namespace plib { } pstring options::help(pstring description, pstring usage, - unsigned width, unsigned indent) + unsigned width, unsigned indent) const { pstring ret; @@ -293,7 +293,7 @@ namespace plib { return ret; } - option *options::getopt_short(pstring arg) + option *options::getopt_short(pstring arg) const { for (auto & optbase : m_opts) { @@ -303,7 +303,7 @@ namespace plib { } return nullptr; } - option *options::getopt_long(pstring arg) + option *options::getopt_long(pstring arg) const { for (auto & optbase : m_opts) { diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index 4a8e6d788d7..925329e80d4 100644 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -27,7 +27,7 @@ public: option_base(options &parent, pstring help); virtual ~option_base(); - pstring help() { return m_help; } + pstring help() const { return m_help; } private: pstring m_help; }; @@ -39,7 +39,7 @@ public: : option_base(parent, help), m_group(group) { } ~option_group(); - pstring group() { return m_group; } + pstring group() const { return m_group; } private: pstring m_group; }; @@ -51,7 +51,7 @@ public: : option_base(parent, help), m_example(group) { } ~option_example(); - pstring example() { return m_example; } + pstring example() const { return m_example; } private: pstring m_example; }; @@ -93,7 +93,7 @@ public: : option(parent, ashort, along, help, true), m_val(defval) {} - pstring operator ()() { return m_val; } + pstring operator ()() const { return m_val; } protected: virtual int parse(const pstring &argument) override; @@ -128,7 +128,7 @@ public: { } - T operator ()() { return m_val; } + T operator ()() const { return m_val; } pstring as_string() const { return limit()[m_val]; } @@ -157,7 +157,7 @@ public: : option(parent, ashort, along, help, false), m_val(false) {} - bool operator ()() { return m_val; } + bool operator ()() const { return m_val; } protected: virtual int parse(const pstring &argument) override; @@ -180,7 +180,7 @@ public: , m_max(maxval) {} - T operator ()() { return m_val; } + T operator ()() const { return m_val; } protected: virtual int parse(const pstring &argument) override @@ -203,7 +203,7 @@ public: : option(parent, ashort, along, help, true) {} - std::vector operator ()() { return m_val; } + const std::vector &operator ()() const { return m_val; } protected: virtual int parse(const pstring &argument) override; @@ -233,9 +233,9 @@ public: int parse(int argc, char *argv[]); pstring help(pstring description, pstring usage, - unsigned width = 72, unsigned indent = 20); + unsigned width = 72, unsigned indent = 20) const; - pstring app() { return m_app; } + pstring app() const { return m_app; } private: static pstring split_paragraphs(pstring text, unsigned width, unsigned indent, @@ -244,7 +244,7 @@ private: void check_consistency(); template - T *getopt_type() + T *getopt_type() const { for (auto & optbase : m_opts ) { @@ -254,8 +254,8 @@ private: return nullptr; } - option *getopt_short(pstring arg); - option *getopt_long(pstring arg); + option *getopt_short(pstring arg) const; + option *getopt_long(pstring arg) const; std::vector m_opts; pstring m_app; diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp index 48e29570b4c..d666ad11054 100644 --- a/src/lib/netlist/plib/pparser.cpp +++ b/src/lib/netlist/plib/pparser.cpp @@ -268,7 +268,7 @@ void ptokenizer::error(const pstring &errs) // A simple preprocessor // ---------------------------------------------------------------------------------------- -ppreprocessor::ppreprocessor(std::vector *defines) +ppreprocessor::ppreprocessor(defines_map_type *defines) : pistream() , m_ifflag(0) , m_level(0) @@ -292,12 +292,7 @@ ppreprocessor::ppreprocessor(std::vector *defines) m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")}); if (defines != nullptr) - { - for (auto & p : *defines) - { - m_defines.insert({p.m_name, p}); - } - } + m_defines = *defines; } void ppreprocessor::error(const pstring &err) @@ -524,7 +519,10 @@ pstring ppreprocessor::process_line(pstring line) } } else - error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(line)); + { + if (m_ifflag == 0) + error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line))); + } } else { diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h index 1eeb92d797b..3829e8cdcc8 100644 --- a/src/lib/netlist/plib/pparser.h +++ b/src/lib/netlist/plib/pparser.h @@ -163,7 +163,9 @@ public: pstring m_replace; }; - explicit ppreprocessor(std::vector *defines = nullptr); + using defines_map_type = std::unordered_map; + + explicit ppreprocessor(defines_map_type *defines = nullptr); virtual ~ppreprocessor() override {} template @@ -214,7 +216,7 @@ private: pstring process_line(pstring line); pstring process_comments(pstring line); - std::unordered_map m_defines; + defines_map_type m_defines; std::vector m_expr_sep; std::uint_least64_t m_ifflag; // 31 if levels diff --git a/src/lib/netlist/plib/pstate.cpp b/src/lib/netlist/plib/pstate.cpp index 3cab5dec127..a5465bfed46 100644 --- a/src/lib/netlist/plib/pstate.cpp +++ b/src/lib/netlist/plib/pstate.cpp @@ -48,13 +48,13 @@ void state_manager_t::remove_save_items(const void *owner) void state_manager_t::pre_save() { for (auto & s : m_custom) - s->m_callback->on_pre_save(); + s->m_callback->on_pre_save(*this); } void state_manager_t::post_load() { for (auto & s : m_custom) - s->m_callback->on_post_load(); + s->m_callback->on_post_load(*this); } template<> void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname) diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h index 5b8acc92221..3a908cba2d2 100644 --- a/src/lib/netlist/plib/pstate.h +++ b/src/lib/netlist/plib/pstate.h @@ -56,8 +56,8 @@ public: virtual ~callback_t(); virtual void register_state(state_manager_t &manager, const pstring &module) = 0; - virtual void on_pre_save() = 0; - virtual void on_post_load() = 0; + virtual void on_pre_save(state_manager_t &manager) = 0; + virtual void on_post_load(state_manager_t &manager) = 0; protected: }; diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h index 4212677c81c..023a0271ce2 100644 --- a/src/lib/netlist/plib/putil.h +++ b/src/lib/netlist/plib/putil.h @@ -14,6 +14,10 @@ #include #include // <<= needed by windows build +#define PSTRINGIFY_HELP(y) # y +#define PSTRINGIFY(x) PSTRINGIFY_HELP(x) + + namespace plib { diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 3c9839a7845..984f8703079 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -17,6 +17,8 @@ #include +#define NLTOOL_VERSION 20190202 + class tool_app_t : public plib::app { public: @@ -36,7 +38,7 @@ public: opt_name(*this, "n", "name", "", "the netlist in file specified by ""-f"" option to run; default is first one"), opt_grp3(*this, "Options for run command", "These options are only used by the run command."), - opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"), + opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)\n\n abc def\n\n xyz"), opt_logs(*this, "l", "log" , "define terminal to log. This option may be specified repeatedly."), opt_inp(*this, "i", "input", "", "input file to process (default is none)"), opt_loadstate(*this,"", "loadstate", "", "load state from file and continue from there"), @@ -99,6 +101,8 @@ private: void listdevices(); + std::vector m_options; + }; static NETLIST_START(dummy) @@ -186,7 +190,7 @@ public: // read the netlist ... for (auto & d : defines) - setup().register_define(d); + setup().add_define(d); for (auto & r : roms) setup().register_source(plib::make_unique_base(setup(), r)); @@ -347,7 +351,7 @@ void tool_app_t::run() nt.read_netlist(opt_file(), opt_name(), opt_logs(), - opt_defines(), opt_rfolders()); + m_options, opt_rfolders()); std::vector inps = read_input(nt.setup(), opt_inp()); @@ -423,7 +427,7 @@ void tool_app_t::static_compile() nt.read_netlist(opt_file(), opt_name(), opt_logs(), - opt_defines(), opt_rfolders()); + m_options, opt_rfolders()); plib::putf8_writer w(&pout_strm); std::map mp; @@ -543,9 +547,9 @@ void tool_app_t::create_header() if (last_source != e->sourcefile()) { last_source = e->sourcefile(); - pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), 72)); + pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), opt_linewidth())); pout("{1}{2}\n", pstring("// Source: "), plib::replace_all(e->sourcefile(), "../", "")); - pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), 72)); + pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), opt_linewidth())); } cmac(e.get()); } @@ -697,7 +701,7 @@ int tool_app_t::execute() if (opt_version()) { pout( - "nltool (netlist) 0.1\n" + "nltool (netlist) " PSTRINGIFY(NLTOOL_VERSION) "\n" "Copyright (C) 2019 Couriersud\n" "License GPLv2+: GNU GPL version 2 or later .\n" "This is free software: you are free to change and redistribute it.\n" @@ -706,6 +710,9 @@ int tool_app_t::execute() return 0; } + m_options = opt_defines(); + m_options.push_back("NLTOOL_VERSION=" PSTRINGIFY(NLTOOL_VERSION)); + try { pstring cmd = opt_cmd.as_string(); diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 8116e48111a..c25330627b6 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -381,11 +381,11 @@ public: nlwav_app() : plib::app(), opt_fmt(*this, "f", "format", 0, std::vector({"wav","vcda","vcdd"}), - "output format. Available options are wav|vcda|vcdd.\n" - "wav : multichannel wav output\n" - "vcda : analog VCD output\n" - "vcdd : digital VCD output\n" - "Digital signals are created using the high and low options" + "output format. Available options are wav|vcda|vcdd." + " wav : multichannel wav output" + " vcda : analog VCD output" + " vcdd : digital VCD output" + " Digital signals are created using the --high and --low options" ), opt_out(*this, "o", "output", "-", "output file"), opt_rate(*this, "r", "rate", 48000, "sample rate of output file"), diff --git a/src/mame/audio/nl_kidniki.cpp b/src/mame/audio/nl_kidniki.cpp index 7865ea40750..9e8c47247af 100644 --- a/src/mame/audio/nl_kidniki.cpp +++ b/src/mame/audio/nl_kidniki.cpp @@ -2,8 +2,17 @@ // copyright-holders:Andrew Gardner, Couriersud #include "netlist/devices/net_lib.h" +#ifdef NLBASE_H_ +#error Somehow nl_base.h made it into the include chain. +#endif + +#ifndef NLTOOL_VERSION #define USE_FRONTIERS 1 #define USE_FIXED_STV 1 +#else +#define USE_FRONTIERS 0 +#define USE_FIXED_STV 1 +#endif /* ---------------------------------------------------------------------------- * Library section header START diff --git a/src/mame/machine/nl_breakout.cpp b/src/mame/machine/nl_breakout.cpp index 87426734036..0823df42350 100644 --- a/src/mame/machine/nl_breakout.cpp +++ b/src/mame/machine/nl_breakout.cpp @@ -1702,22 +1702,19 @@ CIRCUIT_LAYOUT( breakout ) NET_C(GND, D9.1, D9.2, D9.13, D9.3, D9.4, D9.5) - HINT(A3.1.sub, NO_DEACTIVATE) +#if 1 + // 158% -- manually optimized HINT(B6.s3, NO_DEACTIVATE) HINT(C4.s3, NO_DEACTIVATE) HINT(C4.s4, NO_DEACTIVATE) HINT(C5.s3, NO_DEACTIVATE) HINT(C5.s4, NO_DEACTIVATE) - HINT(D3.2.sub, NO_DEACTIVATE) HINT(E2.s2, NO_DEACTIVATE) HINT(E3.s2, NO_DEACTIVATE) HINT(E5.s4, NO_DEACTIVATE) - HINT(E8.2.sub, NO_DEACTIVATE) HINT(E9.s6, NO_DEACTIVATE) - HINT(F5.2.sub, NO_DEACTIVATE) HINT(H2.s1, NO_DEACTIVATE) HINT(H3.s1, NO_DEACTIVATE) - HINT(H6.sub, NO_DEACTIVATE) HINT(J3.s4, NO_DEACTIVATE) HINT(J5, NO_DEACTIVATE) HINT(J6.sub, NO_DEACTIVATE) @@ -1729,9 +1726,47 @@ CIRCUIT_LAYOUT( breakout ) HINT(M4.s2, NO_DEACTIVATE) HINT(M6.sub, NO_DEACTIVATE) HINT(M8.s1, NO_DEACTIVATE) - HINT(N6.sub, NO_DEACTIVATE) HINT(N7.s3, NO_DEACTIVATE) +#else + // 152% hints provided by log output + HINT(M4.s2, NO_DEACTIVATE) // 29.001761 197676 6816 + HINT(M3.s3, NO_DEACTIVATE) // inf 129571 0 + HINT(N7.s3, NO_DEACTIVATE) // inf 7850387 0 + HINT(M3.s2, NO_DEACTIVATE) // 23.234535 395870 17038 + HINT(M3.s1, NO_DEACTIVATE) // 14.500880 197676 13632 + HINT(L7.s3, NO_DEACTIVATE) // 122672.000000 122672 1 + HINT(L7.s2, NO_DEACTIVATE) // 122672.000000 122672 1 + HINT(K7.s4, NO_DEACTIVATE) // 122673.000000 122673 1 + HINT(K7.s3, NO_DEACTIVATE) // 122672.000000 122672 1 + HINT(K7.s2, NO_DEACTIVATE) // 122673.000000 122673 1 + HINT(K7.s1, NO_DEACTIVATE) // 122673.000000 122673 1 + HINT(K4.s4, NO_DEACTIVATE) // 1438.774735 4202661 2921 + HINT(K4.s2, NO_DEACTIVATE) // 3.939380 847790 215209 + HINT(E2.s2, NO_DEACTIVATE) // 108.050000 315506 2920 + HINT(L7.s4, NO_DEACTIVATE) // 122672.000000 122672 1 + HINT(E9.s6, NO_DEACTIVATE) // inf 129571 0 + HINT(J2.s6, NO_DEACTIVATE) // 493.408951 959187 1944 + HINT(C5.s3, NO_DEACTIVATE) // inf 195514 0 + HINT(M3.s4, NO_DEACTIVATE) // 27.744898 418726 15092 + HINT(J8.s1, NO_DEACTIVATE) // 40890.000000 122670 3 + HINT(E3.s2, NO_DEACTIVATE) // 203581.000000 203581 1 + HINT(M9.s4, NO_DEACTIVATE) // inf 323268 0 + HINT(L4.s2, NO_DEACTIVATE) // 7.290053 1192536 163584 + HINT(J3.s4, NO_DEACTIVATE) // 393.639951 957726 2433 + HINT(L7.s1, NO_DEACTIVATE) // inf 122672 0 + HINT(F2.s1, NO_DEACTIVATE) // 286289.000000 286289 1 + HINT(M8.s1, NO_DEACTIVATE) // 129571.000000 129571 1 + HINT(J7.s2, NO_DEACTIVATE) // inf 122672 0 + HINT(H2.s1, NO_DEACTIVATE) // 393.839704 958212 2433 + HINT(H3.s1, NO_DEACTIVATE) // 3.932473 850122 216180 + HINT(J2.s5, NO_DEACTIVATE) // 26.140344 203581 7788 + HINT(J7.s1, NO_DEACTIVATE) // inf 122672 0 + HINT(J8.s3, NO_DEACTIVATE) // 40890.000000 122670 3 + + +#endif + CIRCUIT_LAYOUT_END /* -- cgit v1.2.3-70-g09d2 From 3b899b86e67e3a5cc093d2dd9c0dcaeed197c806 Mon Sep 17 00:00:00 2001 From: couriersud Date: Wed, 6 Feb 2019 10:24:34 +0100 Subject: netlist: Refactoring after adding clang-tidy support to netlist makefile - convert macros to c++ code. - order of device creation should not depend on std lib. - some state saving cleanup. - added support for clang-tidy to makefile. - modifications triggered by clang-tidy-9. --- src/devices/machine/netlist.cpp | 17 ++- src/lib/netlist/analog/nld_bjt.cpp | 8 +- src/lib/netlist/analog/nld_opamps.cpp | 4 +- src/lib/netlist/analog/nld_switches.cpp | 6 +- src/lib/netlist/analog/nlid_fourterm.cpp | 26 ++-- src/lib/netlist/analog/nlid_fourterm.h | 37 ++---- src/lib/netlist/analog/nlid_twoterm.cpp | 10 +- src/lib/netlist/analog/nlid_twoterm.h | 21 ++- src/lib/netlist/build/makefile | 53 +++++++- src/lib/netlist/devices/net_lib.h | 30 ++--- src/lib/netlist/devices/nld_4066.cpp | 14 +- src/lib/netlist/devices/nld_4316.cpp | 9 +- src/lib/netlist/devices/nld_74165.cpp | 1 + src/lib/netlist/devices/nld_7448.cpp | 2 +- src/lib/netlist/devices/nld_7483.cpp | 2 +- src/lib/netlist/devices/nld_74ls629.cpp | 2 +- src/lib/netlist/devices/nld_log.cpp | 2 +- src/lib/netlist/devices/nld_mm5837.cpp | 6 +- src/lib/netlist/devices/nld_r2r_dac.cpp | 4 +- src/lib/netlist/devices/nld_schmitt.cpp | 10 +- src/lib/netlist/devices/nlid_cmos.h | 2 +- src/lib/netlist/devices/nlid_proxy.cpp | 20 +-- src/lib/netlist/devices/nlid_proxy.h | 12 +- src/lib/netlist/devices/nlid_system.h | 17 +-- src/lib/netlist/devices/nlid_truthtable.cpp | 9 +- src/lib/netlist/devices/nlid_truthtable.h | 8 +- src/lib/netlist/macro/nlm_cd4xxx.cpp | 2 +- src/lib/netlist/netlist_types.h | 13 +- src/lib/netlist/nl_base.cpp | 153 +++++++--------------- src/lib/netlist/nl_base.h | 187 ++++++++++++++------------- src/lib/netlist/nl_config.h | 13 +- src/lib/netlist/nl_factory.cpp | 11 +- src/lib/netlist/nl_factory.h | 20 ++- src/lib/netlist/nl_lists.h | 12 +- src/lib/netlist/nl_parser.cpp | 8 +- src/lib/netlist/nl_parser.h | 8 +- src/lib/netlist/nl_setup.cpp | 91 ++++++++----- src/lib/netlist/nl_setup.h | 39 +++--- src/lib/netlist/nl_time.h | 48 ++++--- src/lib/netlist/plib/gmres.h | 8 +- src/lib/netlist/plib/mat_cr.h | 18 +-- src/lib/netlist/plib/palloc.cpp | 8 +- src/lib/netlist/plib/palloc.h | 4 +- src/lib/netlist/plib/parray.h | 6 +- src/lib/netlist/plib/pchrono.cpp | 4 +- src/lib/netlist/plib/pchrono.h | 17 ++- src/lib/netlist/plib/pconfig.h | 9 -- src/lib/netlist/plib/pdynlib.cpp | 4 +- src/lib/netlist/plib/pdynlib.h | 2 +- src/lib/netlist/plib/pexception.cpp | 28 +--- src/lib/netlist/plib/pexception.h | 26 +--- src/lib/netlist/plib/pfmtlog.cpp | 11 +- src/lib/netlist/plib/pfmtlog.h | 34 +++-- src/lib/netlist/plib/pfunction.cpp | 13 +- src/lib/netlist/plib/pfunction.h | 4 +- src/lib/netlist/plib/plists.h | 10 +- src/lib/netlist/plib/pmain.cpp | 5 - src/lib/netlist/plib/pmain.h | 8 +- src/lib/netlist/plib/pomp.h | 6 +- src/lib/netlist/plib/poptions.cpp | 24 +--- src/lib/netlist/plib/poptions.h | 19 ++- src/lib/netlist/plib/pparser.cpp | 45 +++---- src/lib/netlist/plib/pparser.h | 39 +++--- src/lib/netlist/plib/ppmf.h | 14 +- src/lib/netlist/plib/pstate.cpp | 18 +-- src/lib/netlist/plib/pstate.h | 43 +++--- src/lib/netlist/plib/pstream.cpp | 37 +----- src/lib/netlist/plib/pstream.h | 119 ++++++++--------- src/lib/netlist/plib/pstring.cpp | 2 +- src/lib/netlist/plib/pstring.h | 81 ++++++------ src/lib/netlist/plib/ptypes.h | 30 ++--- src/lib/netlist/plib/putil.cpp | 16 +-- src/lib/netlist/plib/putil.h | 28 +++- src/lib/netlist/plib/vector_ops.h | 4 +- src/lib/netlist/prg/nltool.cpp | 32 ++--- src/lib/netlist/prg/nlwav.cpp | 24 ++-- src/lib/netlist/solver/nld_matrix_solver.cpp | 59 ++++----- src/lib/netlist/solver/nld_matrix_solver.h | 28 ++-- src/lib/netlist/solver/nld_ms_direct.h | 32 ++--- src/lib/netlist/solver/nld_ms_direct1.h | 2 +- src/lib/netlist/solver/nld_ms_direct2.h | 2 +- src/lib/netlist/solver/nld_ms_gcr.h | 20 ++- src/lib/netlist/solver/nld_ms_gmres.h | 14 +- src/lib/netlist/solver/nld_ms_sm.h | 30 ++--- src/lib/netlist/solver/nld_ms_sor.h | 26 ++-- src/lib/netlist/solver/nld_ms_sor_mat.h | 12 +- src/lib/netlist/solver/nld_ms_w.h | 32 ++--- src/lib/netlist/solver/nld_solver.cpp | 26 ++-- src/lib/netlist/solver/nld_solver.h | 10 +- src/lib/netlist/tools/nl_convert.cpp | 8 +- src/lib/netlist/tools/nl_convert.h | 20 +-- 91 files changed, 966 insertions(+), 1092 deletions(-) (limited to 'src/lib/netlist/plib/pstate.h') diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index fc76132a731..957d4575672 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -581,11 +581,12 @@ void netlist_mame_analog_output_device::custom_netlist_additions(netlist::setup_ { const pstring pin(m_in); pstring dname = pstring("OUT_") + pin; + pstring dfqn = setup.build_fqn(dname); m_delegate.bind_relative_to(owner()->machine().root_device()); - plib::owned_ptr dev = plib::owned_ptr::Create(setup.netlist(), setup.build_fqn(dname)); + plib::owned_ptr dev = plib::owned_ptr::Create(setup.netlist(), dfqn); static_cast(dev.get())->register_callback(std::move(m_delegate)); - setup.netlist().add_dev(std::move(dev)); + setup.netlist().add_dev(dfqn, std::move(dev)); setup.register_link(dname + ".IN", pin); } @@ -616,11 +617,13 @@ void netlist_mame_logic_output_device::custom_netlist_additions(netlist::setup_t { pstring pin(m_in); pstring dname = "OUT_" + pin; + pstring dfqn = setup.build_fqn(dname); + m_delegate.bind_relative_to(owner()->machine().root_device()); - plib::owned_ptr dev = plib::owned_ptr::Create(setup.netlist(), setup.build_fqn(dname)); + plib::owned_ptr dev = plib::owned_ptr::Create(setup.netlist(), dfqn); static_cast(dev.get())->register_callback(std::move(m_delegate)); - setup.netlist().add_dev(std::move(dev)); + setup.netlist().add_dev(dfqn, std::move(dev)); setup.register_link(dname + ".IN", pin); } @@ -882,9 +885,9 @@ void netlist_mame_device::device_start() setup().prepare_to_run(); - netlist().nlstate().save(*this, m_rem, "m_rem"); - netlist().nlstate().save(*this, m_div, "m_div"); - netlist().nlstate().save(*this, m_old, "m_old"); + netlist().nlstate().save(*this, m_rem, this->name(), "m_rem"); + netlist().nlstate().save(*this, m_div, this->name(), "m_div"); + netlist().nlstate().save(*this, m_old, this->name(), "m_old"); save_state(); diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp index bd2e55e145f..7f8e57a8511 100644 --- a/src/lib/netlist/analog/nld_bjt.cpp +++ b/src/lib/netlist/analog/nld_bjt.cpp @@ -6,8 +6,8 @@ */ #include "../solver/nld_solver.h" -#include "nlid_twoterm.h" #include "../nl_setup.h" +#include "nlid_twoterm.h" #include @@ -248,10 +248,6 @@ public: register_subalias("B", m_D_EB.m_N); // Anode register_subalias("C", m_D_CB.m_P); // Cathode - //register_term("_B1", m_D_CB.m_N); // Anode - - //register_term("_E1", m_D_EC.m_P); - //register_term("_C1", m_D_EC.m_N); connect(m_D_EB.m_P, m_D_EC.m_P); connect(m_D_EB.m_N, m_D_CB.m_N); @@ -432,6 +428,6 @@ NETLIB_UPDATE_PARAM(QBJT_EB) namespace devices { NETLIB_DEVICE_IMPL_NS(analog, QBJT_EB, "QBJT_EB", "MODEL") NETLIB_DEVICE_IMPL_NS(analog, QBJT_switch, "QBJT_SW", "MODEL") - } + } // namespace devices } // namespace netlist diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index b65ff0a9edd..53ba7b3897d 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -8,8 +8,8 @@ #include "nld_opamps.h" #include "../nl_base.h" #include "../nl_errstr.h" -#include "nlid_twoterm.h" #include "nlid_fourterm.h" +#include "nlid_twoterm.h" #include @@ -240,5 +240,5 @@ namespace netlist namespace devices { NETLIB_DEVICE_IMPL_NS(analog, opamp, "OPAMP", "MODEL") - } + } // namespace devices } // namespace netlist diff --git a/src/lib/netlist/analog/nld_switches.cpp b/src/lib/netlist/analog/nld_switches.cpp index 7f650737de8..0e62fe13952 100644 --- a/src/lib/netlist/analog/nld_switches.cpp +++ b/src/lib/netlist/analog/nld_switches.cpp @@ -27,7 +27,7 @@ namespace netlist { NETLIB_CONSTRUCTOR(switch1) , m_R(*this, "R") - , m_POS(*this, "POS", 0) + , m_POS(*this, "POS", false) { register_subalias("1", m_R.m_P); register_subalias("2", m_R.m_N); @@ -75,7 +75,7 @@ namespace netlist NETLIB_CONSTRUCTOR(switch2) , m_R1(*this, "R1") , m_R2(*this, "R2") - , m_POS(*this, "POS", 0) + , m_POS(*this, "POS", false) { connect(m_R1.m_N, m_R2.m_N); @@ -139,5 +139,5 @@ namespace netlist namespace devices { NETLIB_DEVICE_IMPL_NS(analog, switch1, "SWITCH", "") NETLIB_DEVICE_IMPL_NS(analog, switch2, "SWITCH2", "") - } + } // namespace devices } // namespace netlist diff --git a/src/lib/netlist/analog/nlid_fourterm.cpp b/src/lib/netlist/analog/nlid_fourterm.cpp index 7cd9bd83561..f4451c55023 100644 --- a/src/lib/netlist/analog/nlid_fourterm.cpp +++ b/src/lib/netlist/analog/nlid_fourterm.cpp @@ -24,16 +24,16 @@ namespace netlist NETLIB_RESET(VCCS) { const nl_double m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A - const nl_double GI = NL_FCONST(1.0) / m_RI(); + const nl_double GI = plib::constants::one / m_RI(); m_IP.set(GI); m_IN.set(GI); - m_OP.set(m_mult, NL_FCONST(0.0)); - m_OP1.set(-m_mult, NL_FCONST(0.0)); + m_OP.set(m_mult, plib::constants::zero); + m_OP1.set(-m_mult, plib::constants::zero); - m_ON.set(-m_mult, NL_FCONST(0.0)); - m_ON1.set(m_mult, NL_FCONST(0.0)); + m_ON.set(-m_mult, plib::constants::zero); + m_ON1.set(m_mult, plib::constants::zero); } NETLIB_UPDATE(VCCS) @@ -79,11 +79,11 @@ NETLIB_UPDATE_TERMINALS(LVCCS) const nl_double beta = m_mult * (1.0 - X*X); const nl_double I = m_cur_limit() * X - beta * m_vi; - m_OP.set(beta, NL_FCONST(0.0), I); - m_OP1.set(-beta, NL_FCONST(0.0)); + m_OP.set(beta, plib::constants::zero, I); + m_OP1.set(-beta, plib::constants::zero); - m_ON.set(-beta, NL_FCONST(0.0), -I); - m_ON1.set(beta, NL_FCONST(0.0)); + m_ON.set(-beta, plib::constants::zero, -I); + m_ON1.set(beta, plib::constants::zero); } // ---------------------------------------------------------------------------------------- @@ -106,11 +106,11 @@ NETLIB_UPDATE_PARAM(CCCS) NETLIB_RESET(VCVS) { - m_gfac = NL_FCONST(1.0) / m_RO(); + m_gfac = plib::constants::one / m_RO(); NETLIB_NAME(VCCS)::reset(); - m_OP2.set(NL_FCONST(1.0) / m_RO()); - m_ON2.set(NL_FCONST(1.0) / m_RO()); + m_OP2.set(plib::constants::one / m_RO()); + m_ON2.set(plib::constants::one / m_RO()); } } //namespace analog @@ -120,5 +120,5 @@ NETLIB_RESET(VCVS) NETLIB_DEVICE_IMPL_NS(analog, VCCS, "VCCS", "") NETLIB_DEVICE_IMPL_NS(analog, CCCS, "CCCS", "") NETLIB_DEVICE_IMPL_NS(analog, LVCCS, "LVCCS", "") - } + } // namespace devices } // namespace netlist diff --git a/src/lib/netlist/analog/nlid_fourterm.h b/src/lib/netlist/analog/nlid_fourterm.h index a0984221cae..800a9d1cfb8 100644 --- a/src/lib/netlist/analog/nlid_fourterm.h +++ b/src/lib/netlist/analog/nlid_fourterm.h @@ -9,6 +9,7 @@ #define NLID_FOURTERM_H_ #include "../nl_base.h" +#include "../plib/putil.h" namespace netlist { namespace analog { @@ -40,26 +41,17 @@ namespace netlist { NETLIB_CONSTRUCTOR(VCCS) , m_G(*this, "G", 1.0) , m_RI(*this, "RI", 1e9) - , m_OP(*this, "OP") - , m_ON(*this, "ON") - , m_IP(*this, "IP") - , m_IN(*this, "IN") - , m_OP1(*this, "_OP1") - , m_ON1(*this, "_ON1") + , m_OP(*this, "OP", &m_IP) + , m_ON(*this, "ON", &m_IP) + , m_IP(*this, "IP", &m_IN) // <= this should be NULL and terminal be filtered out prior to solving... + , m_IN(*this, "IN", &m_IP) // <= this should be NULL and terminal be filtered out prior to solving... + , m_OP1(*this, "_OP1", &m_IN) + , m_ON1(*this, "_ON1", &m_IN) , m_gfac(1.0) { - m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving... - m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving... - - m_OP.m_otherterm = &m_IP; - m_OP1.m_otherterm = &m_IN; - - m_ON.m_otherterm = &m_IP; - m_ON1.m_otherterm = &m_IN; - connect(m_OP, m_OP1); connect(m_ON, m_ON1); - m_gfac = NL_FCONST(1.0); + m_gfac = plib::constants::one; } param_double_t m_G; @@ -137,7 +129,7 @@ namespace netlist { public: NETLIB_CONSTRUCTOR_DERIVED(CCCS, VCCS) { - m_gfac = NL_FCONST(1.0) / m_RI(); + m_gfac = plib::constants::one / m_RI(); } protected: @@ -180,12 +172,9 @@ namespace netlist { public: NETLIB_CONSTRUCTOR_DERIVED(VCVS, VCCS) , m_RO(*this, "RO", 1.0) - , m_OP2(*this, "_OP2") - , m_ON2(*this, "_ON2") + , m_OP2(*this, "_OP2", &m_ON2) + , m_ON2(*this, "_ON2", &m_OP2) { - m_OP2.m_otherterm = &m_ON2; - m_ON2.m_otherterm = &m_OP2; - connect(m_OP2, m_OP1); connect(m_ON2, m_ON1); } @@ -202,7 +191,7 @@ namespace netlist { }; - } -} + } // namespace analog +} // namespace netlist #endif /* NLD_FOURTERM_H_ */ diff --git a/src/lib/netlist/analog/nlid_twoterm.cpp b/src/lib/netlist/analog/nlid_twoterm.cpp index 51c17b92267..5b4bf064093 100644 --- a/src/lib/netlist/analog/nlid_twoterm.cpp +++ b/src/lib/netlist/analog/nlid_twoterm.cpp @@ -7,8 +7,8 @@ #include "../solver/nld_solver.h" -#include "nlid_twoterm.h" #include "../nl_factory.h" +#include "nlid_twoterm.h" #include @@ -70,7 +70,7 @@ void generic_diode::update_diode(const nl_double nVd) } else { - const double a = std::max((nVd - m_Vd) * m_VtInv, NL_FCONST(-0.99)); + const double a = std::max((nVd - m_Vd) * m_VtInv, plib::constants()(-0.99)); m_Vd = m_Vd + std::log1p(a) * m_Vt; //const double IseVDVt = m_Is * std::exp(m_Vd * m_VtInv); const double IseVDVt = std::exp(m_logIs + m_Vd * m_VtInv); @@ -145,7 +145,7 @@ NETLIB_RESET(POT) v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); m_R1.set_R(std::max(m_R() * v, exec().gmin())); - m_R2.set_R(std::max(m_R() * (NL_FCONST(1.0) - v), exec().gmin())); + m_R2.set_R(std::max(m_R() * (plib::constants::one - v), exec().gmin())); } NETLIB_UPDATE_PARAM(POT) @@ -158,7 +158,7 @@ NETLIB_UPDATE_PARAM(POT) v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); m_R1.set_R(std::max(m_R() * v, exec().gmin())); - m_R2.set_R(std::max(m_R() * (NL_FCONST(1.0) - v), exec().gmin())); + m_R2.set_R(std::max(m_R() * (plib::constants::one - v), exec().gmin())); } @@ -288,6 +288,6 @@ NETLIB_UPDATE_TERMINALS(D) NETLIB_DEVICE_IMPL_NS(analog, D, "DIODE", "MODEL") NETLIB_DEVICE_IMPL_NS(analog, VS, "VS", "V") NETLIB_DEVICE_IMPL_NS(analog, CS, "CS", "I") - } + } // namespace devices } // namespace netlist diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h index 5571e17867d..aa165d58a4e 100644 --- a/src/lib/netlist/analog/nlid_twoterm.h +++ b/src/lib/netlist/analog/nlid_twoterm.h @@ -33,9 +33,9 @@ #ifndef NLID_TWOTERM_H_ #define NLID_TWOTERM_H_ +#include "../plib/pfunction.h" #include "netlist/nl_base.h" #include "netlist/nl_setup.h" -#include "../plib/pfunction.h" // ----------------------------------------------------------------------------- // Implementation @@ -52,12 +52,13 @@ namespace netlist template inline core_device_t &bselect(bool b, C &d1, core_device_t &d2) { - core_device_t *h = dynamic_cast(&d1); + auto *h = dynamic_cast(&d1); return b ? *h : d2; } template<> inline core_device_t &bselect(bool b, netlist_base_t &d1, core_device_t &d2) { + plib::unused_var(d1); if (b) throw nl_exception("bselect with netlist and b==true"); return d2; @@ -66,11 +67,9 @@ namespace netlist NETLIB_OBJECT(twoterm) { NETLIB_CONSTRUCTOR_EX(twoterm, bool terminals_owned = false) - , m_P(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "1") - , m_N(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "2") + , m_P(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "1", &m_N) + , m_N(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "2", &m_P) { - m_P.m_otherterm = &m_N; - m_N.m_otherterm = &m_P; } terminal_t m_P; @@ -124,7 +123,7 @@ NETLIB_OBJECT_DERIVED(R_base, twoterm) public: void set_R(const nl_double R) { - const nl_double G = NL_FCONST(1.0) / R; + const nl_double G = plib::constants::one / R; set_mat( G, -G, 0.0, -G, G, 0.0); } @@ -166,7 +165,7 @@ NETLIB_OBJECT(POT) , m_R2(*this, "_R2") , m_R(*this, "R", 10000) , m_Dial(*this, "DIAL", 0.5) - , m_DialIsLog(*this, "DIALLOG", 0) + , m_DialIsLog(*this, "DIALLOG", false) { register_subalias("1", m_R1.m_P); register_subalias("2", m_R1.m_N); @@ -195,8 +194,8 @@ NETLIB_OBJECT(POT2) , m_R1(*this, "_R1") , m_R(*this, "R", 10000) , m_Dial(*this, "DIAL", 0.5) - , m_DialIsLog(*this, "DIALLOG", 0) - , m_Reverse(*this, "REVERSE", 0) + , m_DialIsLog(*this, "DIALLOG", false) + , m_Reverse(*this, "REVERSE", false) { register_subalias("1", m_R1.m_P); register_subalias("2", m_R1.m_N); @@ -489,7 +488,7 @@ private: }; - } //namespace devices + } // namespace analog } // namespace netlist #endif /* NLD_TWOTERM_H_ */ diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 33618e346b5..8996ba242ec 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -12,6 +12,28 @@ SRC = .. VSBUILD = $(SRC)/buildVS DOC = $(SRC)/documentation +TIDY_DB = ../compile_commands.json + +TIDY_FLAGSX = -checks=*,-google*,-hicpp*,-readability*,-fuchsia*,-llvm-header-guard, +TIDY_FLAGSX += -modernize-use-using,-cppcoreguidelines-pro-type-reinterpret-cast, +TIDY_FLAGSX += -cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-owning-memory, +TIDY_FLAGSX += -modernize-use-default-member-init,-cert-*,-cppcoreguidelines-pro-bounds-constant-array-index, +TIDY_FLAGSX += -modernize-pass-by-value,-misc-macro-parentheses,-cppcoreguidelines-pro-type-static-cast-downcast, +TIDY_FLAGSX += -cppcoreguidelines-special-member-functions,-cppcoreguidelines-pro-bounds-array-to-pointer-decay, +TIDY_FLAGSX += -performance-unnecessary-value-param,-android-*,-cppcoreguidelines-avoid-magic-numbers, +TIDY_FLAGSX += -cppcoreguidelines-macro-usage,-misc-non-private-member-variables-in-classes, +TIDY_FLAGSX += -cppcoreguidelines-non-private-member-variables-in-classes, +TIDY_FLAGSX += -cppcoreguidelines-avoid-c-arrays,-modernize-avoid-c-arrays, +TIDY_FLAGSX += -performance-unnecessary-copy-initialization, +TIDY_FLAGSX += -bugprone-macro-parentheses + +space := +space += +TIDY_FLAGS = $(subst $(space),,$(TIDY_FLAGSX)) + +#TIDY_FLAGS = -checks=llvm-include-order -fix +#TIDY_FLAGS = -checks=llvm-namespace-comment -fix +#TIDY_FLAGS = -checks=modernize-use-override -fix ifeq ($(subst Windows_NT,windows,$(OS)),windows) OBJ = obj/mingw @@ -32,6 +54,7 @@ LD = @g++ MD = @mkdir RM = @rm DOXYGEN = @doxygen +CLANG_TIDY = clang-tidy-9 TARGETS = nltool nlwav @@ -154,6 +177,8 @@ DOCS = \ $(DOC)/test1-50r.svg \ ALL_OBJS = $(OBJS) $(PMAIN) $(NLOBJ)/prg/nltool.o $(NLOBJ)/prg/nlwav.o + +ALL_TIDY_FILES = $(ALL_OBJS:.o=.json) SOURCES = $(patsubst $(OBJ)%, $(SRC)%, $(ALL_OBJS:.o=.cpp)) ALLFILES = $(SOURCES) $(VSBUILDS) $(DOCS) @@ -207,7 +232,7 @@ native: $(MAKE) CEXTRAFLAGS="-march=native -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter" clang: - $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-march=native -Wno-unused-parameter -Weverything -Werror -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wweak-template-vtables -Wno-exit-time-destructors" + $(MAKE) CC=clang++-9 LD=clang++-9 CEXTRAFLAGS="-march=native -Wno-unused-parameter -Weverything -Werror -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wweak-template-vtables -Wno-exit-time-destructors" clang-5: $(MAKE) CC=clang++-5.0 LD=clang++-5.0 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-inconsistent-missing-destructor-override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors" @@ -216,6 +241,8 @@ nvcc: $(MAKE) CC=/usr/local/cuda-9.0/bin/nvcc LD=/usr/local/cuda-9.2/bin/nvcc \ CEXTRAFLAGS="-x cu -DNVCCBUILD=1 --expt-extended-lambda --expt-relaxed-constexpr --default-stream per-thread --restrict" +tidy_db: compile_commands_prefix $(ALL_TIDY_FILES) compile_commands_postfix + # # -Wno-c++11-narrowing : seems a bit broken # Mostly done: -Wno-weak-vtables -Wno-cast-align @@ -256,6 +283,18 @@ ifeq ($(filter $(MAKECMDGOALS),$(MAKEFILE_TARGETS_WITHOUT_INCLUDE)),) -include .depend endif +#------------------------------------------------- +# clang tidy +#------------------------------------------------- +tidy: tidy_db + @echo running tidy + @for i in $(SOURCES); do \ + $(CLANG_TIDY) $$i $(TIDY_FLAGS) -header-filter=.*; \ + done + +tidy_db: compile_commands_prefix $(ALL_TIDY_FILES) compile_commands_postfix + + #------------------------------------------------- # generic rules #------------------------------------------------- @@ -277,3 +316,15 @@ $(OBJ)/%.a: $(RM) $@ $(AR) $(ARFLAGS) $@ $^ +$(OBJ)/%.json: $(SRC)/%.cpp + @echo Building compile database entry for $< ... + @echo { \"directory\": \".\", >> $(TIDY_DB) + @echo \"command\": \"$(CC) $(CDEFS) $(CFLAGS) -c $< -o dummy.o\", >> $(TIDY_DB) + @echo \"file\": \"$(CURDIR)/$<\" } >> $(TIDY_DB) + @echo "," >> $(TIDY_DB) + +compile_commands_prefix: + @echo "[" > $(TIDY_DB) + +compile_commands_postfix: + @echo "]" >> $(TIDY_DB) diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h index 4809f330c6b..6cd2b6349f1 100644 --- a/src/lib/netlist/devices/net_lib.h +++ b/src/lib/netlist/devices/net_lib.h @@ -35,19 +35,8 @@ #include "nld_2102A.h" #include "nld_2716.h" -#include "nld_tms4800.h" #include "nld_4020.h" #include "nld_4066.h" -#include "nld_7448.h" -#include "nld_7450.h" -#include "nld_7473.h" -#include "nld_7474.h" -#include "nld_7475.h" -#include "nld_7483.h" -#include "nld_7485.h" -#include "nld_7490.h" -#include "nld_7493.h" -#include "nld_7497.h" #include "nld_74107.h" #include "nld_74123.h" #include "nld_74153.h" @@ -61,21 +50,32 @@ #include "nld_74193.h" #include "nld_74194.h" #include "nld_74365.h" +#include "nld_7448.h" +#include "nld_7450.h" +#include "nld_7473.h" +#include "nld_7474.h" +#include "nld_7475.h" +#include "nld_7483.h" +#include "nld_7485.h" +#include "nld_7490.h" +#include "nld_7493.h" +#include "nld_7497.h" #include "nld_74ls629.h" -#include "nld_82S16.h" #include "nld_82S115.h" #include "nld_82S123.h" #include "nld_82S126.h" +#include "nld_82S16.h" #include "nld_9310.h" #include "nld_9316.h" #include "nld_9322.h" +#include "nld_tms4800.h" #include "nld_am2847.h" #include "nld_dm9314.h" #include "nld_dm9334.h" -#include "nld_ne555.h" #include "nld_mm5837.h" +#include "nld_ne555.h" #include "nld_r2r_dac.h" @@ -86,15 +86,15 @@ #include "nld_log.h" #include "../macro/nlm_cd4xxx.h" -#include "../macro/nlm_ttl74xx.h" #include "../macro/nlm_opamp.h" #include "../macro/nlm_other.h" +#include "../macro/nlm_ttl74xx.h" #include "../analog/nld_bjt.h" #include "../analog/nld_fourterm.h" +#include "../analog/nld_opamps.h" #include "../analog/nld_switches.h" #include "../analog/nld_twoterm.h" -#include "../analog/nld_opamps.h" #include "nld_legacy.h" #endif diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp index c4598f4fd1a..81a9a07ef0b 100644 --- a/src/lib/netlist/devices/nld_4066.cpp +++ b/src/lib/netlist/devices/nld_4066.cpp @@ -7,9 +7,9 @@ #include "nld_4066.h" -#include "nlid_cmos.h" #include "netlist/analog/nlid_twoterm.h" #include "netlist/solver/nld_solver.h" +#include "nlid_cmos.h" namespace netlist { @@ -41,28 +41,28 @@ namespace netlist { // Start in off condition // FIXME: is ROFF correct? - m_R.set_R(NL_FCONST(1.0) / exec().gmin()); + m_R.set_R(plib::constants::one / exec().gmin()); } NETLIB_UPDATE(CD4066_GATE) { nl_double sup = (m_supply.vdd() - m_supply.vss()); - nl_double low = NL_FCONST(0.45) * sup; - nl_double high = NL_FCONST(0.55) * sup; + nl_double low = plib::constants()(0.45) * sup; + nl_double high = plib::constants()(0.55) * sup; nl_double in = m_control() - m_supply.vss(); - nl_double rON = m_base_r() * NL_FCONST(5.0) / sup; + nl_double rON = m_base_r() * plib::constants()(5.0) / sup; nl_double R = -1.0; if (in < low) { - R = NL_FCONST(1.0) / exec().gmin(); + R = plib::constants::one / exec().gmin(); } else if (in > high) { R = rON; } - if (R > NL_FCONST(0.0)) + if (R > plib::constants::zero) { m_R.update(); m_R.set_R(R); diff --git a/src/lib/netlist/devices/nld_4316.cpp b/src/lib/netlist/devices/nld_4316.cpp index 6774e1e1408..c34a0602147 100644 --- a/src/lib/netlist/devices/nld_4316.cpp +++ b/src/lib/netlist/devices/nld_4316.cpp @@ -6,9 +6,9 @@ */ #include "nld_4316.h" -#include "nlid_cmos.h" #include "netlist/analog/nlid_twoterm.h" #include "netlist/solver/nld_solver.h" +#include "nlid_cmos.h" namespace netlist { namespace devices { @@ -38,7 +38,7 @@ namespace netlist { namespace devices { NETLIB_RESET(CD4316_GATE) { - m_R.set_R(NL_FCONST(1.0) / exec().gmin()); + m_R.set_R(plib::constants::one / exec().gmin()); } NETLIB_UPDATE(CD4316_GATE) @@ -47,10 +47,11 @@ namespace netlist { namespace devices { if (m_S() && !m_E()) m_R.set_R(m_base_r()); else - m_R.set_R(NL_FCONST(1.0) / exec().gmin()); + m_R.set_R(plib::constants::one / exec().gmin()); m_R.solve_later(NLTIME_FROM_NS(1)); } NETLIB_DEVICE_IMPL(CD4316_GATE, "CD4316_GATE", "") -} } // namesapce netlist::devices +} // namespace devices + } // namespace netlist diff --git a/src/lib/netlist/devices/nld_74165.cpp b/src/lib/netlist/devices/nld_74165.cpp index 6ad95da091f..a8aef44b623 100644 --- a/src/lib/netlist/devices/nld_74165.cpp +++ b/src/lib/netlist/devices/nld_74165.cpp @@ -86,6 +86,7 @@ namespace netlist } else if (!m_CLK() || m_CLKINH()) { + // FIXME: qh is overwritten below? qh = old_qh; } else if (!m_last_CLK) diff --git a/src/lib/netlist/devices/nld_7448.cpp b/src/lib/netlist/devices/nld_7448.cpp index 239d6b50921..f14714de17c 100644 --- a/src/lib/netlist/devices/nld_7448.cpp +++ b/src/lib/netlist/devices/nld_7448.cpp @@ -133,7 +133,7 @@ namespace netlist #else -#define BITS7(b6,b5,b4,b3,b2,b1,b0) (b6<<6) | (b5<<5) | (b4<<4) | (b3<<3) | (b2<<2) | (b1<<1) | (b0<<0) +#define BITS7(b6,b5,b4,b3,b2,b1,b0) ((b6)<<6) | ((b5)<<5) | ((b4)<<4) | ((b3)<<3) | ((b2)<<2) | ((b1)<<1) | ((b0)<<0) static constexpr uint8_t tab7448[16] = { diff --git a/src/lib/netlist/devices/nld_7483.cpp b/src/lib/netlist/devices/nld_7483.cpp index 2fbdeb7e52b..285fbeee19e 100644 --- a/src/lib/netlist/devices/nld_7483.cpp +++ b/src/lib/netlist/devices/nld_7483.cpp @@ -107,7 +107,7 @@ namespace netlist NETLIB_UPDATE(7483) { - uint8_t r = static_cast(m_a + m_b + m_C0()); + auto r = static_cast(m_a + m_b + m_C0()); if (r != m_lastr) { diff --git a/src/lib/netlist/devices/nld_74ls629.cpp b/src/lib/netlist/devices/nld_74ls629.cpp index bdebea3a45e..5383501043c 100644 --- a/src/lib/netlist/devices/nld_74ls629.cpp +++ b/src/lib/netlist/devices/nld_74ls629.cpp @@ -210,7 +210,7 @@ namespace netlist freq += k9 * v_rng * v_freq_3; freq += k10 * v_rng * v_freq_4; - freq *= NL_FCONST(0.1e-6) / m_CAP(); + freq *= plib::constants()(0.1e-6) / m_CAP(); // FIXME: we need a possibility to remove entries from queue ... // or an exact model ... diff --git a/src/lib/netlist/devices/nld_log.cpp b/src/lib/netlist/devices/nld_log.cpp index 107cd3863c0..c99fcb5a9bc 100644 --- a/src/lib/netlist/devices/nld_log.cpp +++ b/src/lib/netlist/devices/nld_log.cpp @@ -6,8 +6,8 @@ */ #include "../nl_base.h" -#include "../plib/pstream.h" #include "../plib/pfmtlog.h" +#include "../plib/pstream.h" #include "nld_log.h" //#include "sound/wavwrite.h" diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp index eb2840d31fa..93ba4683a0a 100644 --- a/src/lib/netlist/devices/nld_mm5837.cpp +++ b/src/lib/netlist/devices/nld_mm5837.cpp @@ -6,8 +6,8 @@ */ #include "nld_mm5837.h" -#include "../solver/nld_matrix_solver.h" #include "../analog/nlid_twoterm.h" +#include "../solver/nld_matrix_solver.h" #define R_LOW (1000.0) #define R_HIGH (1000.0) @@ -69,7 +69,7 @@ namespace netlist { //m_V0.initial(0.0); //m_RV.do_reset(); - m_RV.set(NL_FCONST(1.0) / R_LOW, 0.0, 0.0); + m_RV.set(plib::constants::one / R_LOW, 0.0, 0.0); m_inc = netlist_time::from_double(1.0 / m_FREQ()); if (m_FREQ() < 24000 || m_FREQ() > 56000) log().warning(MW_1_FREQUENCY_OUTSIDE_OF_SPECS_1, m_FREQ()); @@ -108,7 +108,7 @@ namespace netlist // We only need to update the net first if this is a time stepping net if (m_is_timestep) m_RV.update(); - m_RV.set(NL_FCONST(1.0) / R, V, 0.0); + m_RV.set(plib::constants::one / R, V, plib::constants::zero); m_RV.solve_later(NLTIME_FROM_NS(1)); } diff --git a/src/lib/netlist/devices/nld_r2r_dac.cpp b/src/lib/netlist/devices/nld_r2r_dac.cpp index a622ebe52ab..594ee185600 100644 --- a/src/lib/netlist/devices/nld_r2r_dac.cpp +++ b/src/lib/netlist/devices/nld_r2r_dac.cpp @@ -6,8 +6,8 @@ */ #include "../nl_base.h" -#include "../nl_factory.h" #include "../analog/nlid_twoterm.h" +#include "../nl_factory.h" namespace netlist { @@ -50,6 +50,6 @@ namespace netlist namespace devices { NETLIB_DEVICE_IMPL_NS(analog, r2r_dac, "R2R_DAC", "VIN,R,N") - } + } // namespace devices } // namespace netlist diff --git a/src/lib/netlist/devices/nld_schmitt.cpp b/src/lib/netlist/devices/nld_schmitt.cpp index a21f50c0681..ed3783535a0 100644 --- a/src/lib/netlist/devices/nld_schmitt.cpp +++ b/src/lib/netlist/devices/nld_schmitt.cpp @@ -7,9 +7,9 @@ #include "nld_schmitt.h" +#include "../analog/nlid_twoterm.h" #include "../nl_base.h" #include "../nl_errstr.h" -#include "../analog/nlid_twoterm.h" #include "../solver/nld_solver.h" #include @@ -85,8 +85,8 @@ namespace netlist m_RVI.reset(); m_RVO.reset(); m_is_timestep = m_RVO.m_P.net().solver()->has_timestep_devices(); - m_RVI.set(NL_FCONST(1.0) / m_model.m_RI, m_model.m_VI, 0.0); - m_RVO.set(NL_FCONST(1.0) / m_model.m_ROL, m_model.m_VOL, 0.0); + m_RVI.set(plib::constants::one / m_model.m_RI, m_model.m_VI, 0.0); + m_RVO.set(plib::constants::one / m_model.m_ROL, m_model.m_VOL, 0.0); } NETLIB_UPDATEI() @@ -98,7 +98,7 @@ namespace netlist m_last_state = 0; if (m_is_timestep) m_RVO.update(); - m_RVO.set(NL_FCONST(1.0) / m_model.m_ROH, m_model.m_VOH, 0.0); + m_RVO.set(plib::constants::one / m_model.m_ROH, m_model.m_VOH, 0.0); m_RVO.solve_later(); } } @@ -109,7 +109,7 @@ namespace netlist m_last_state = 1; if (m_is_timestep) m_RVO.update(); - m_RVO.set(NL_FCONST(1.0) / m_model.m_ROL, m_model.m_VOL, 0.0); + m_RVO.set(plib::constants::one / m_model.m_ROL, m_model.m_VOL, 0.0); m_RVO.solve_later(); } } diff --git a/src/lib/netlist/devices/nlid_cmos.h b/src/lib/netlist/devices/nlid_cmos.h index f9999aebcc0..053cc9b5b5e 100644 --- a/src/lib/netlist/devices/nlid_cmos.h +++ b/src/lib/netlist/devices/nlid_cmos.h @@ -8,8 +8,8 @@ #ifndef NLID_CMOS_H_ #define NLID_CMOS_H_ -#include "../nl_setup.h" #include "../nl_base.h" +#include "../nl_setup.h" namespace netlist { diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp index 741c864246d..44d3d3af9a5 100644 --- a/src/lib/netlist/devices/nlid_proxy.cpp +++ b/src/lib/netlist/devices/nlid_proxy.cpp @@ -29,10 +29,6 @@ namespace netlist m_proxy_term = proxy_inout; } - nld_base_proxy::~nld_base_proxy() - { - } - // ---------------------------------------------------------------------------------------- // nld_a_to_d_proxy // ---------------------------------------------------------------------------------------- @@ -44,18 +40,12 @@ namespace netlist { } - nld_base_a_to_d_proxy::~nld_base_a_to_d_proxy() {} - nld_a_to_d_proxy::nld_a_to_d_proxy(netlist_base_t &anetlist, const pstring &name, logic_input_t *in_proxied) : nld_base_a_to_d_proxy(anetlist, name, in_proxied, &m_I) , m_I(*this, "I") { } - nld_a_to_d_proxy::~nld_a_to_d_proxy() - { - } - NETLIB_RESET(a_to_d_proxy) { } @@ -88,10 +78,6 @@ namespace netlist { } - nld_base_d_to_a_proxy::~nld_base_d_to_a_proxy() - { - } - nld_d_to_a_proxy::nld_d_to_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *out_proxied) : nld_base_d_to_a_proxy(anetlist, name, out_proxied, m_RV.m_P) , m_GNDHack(*this, "_Q") @@ -139,13 +125,13 @@ namespace netlist m_last_state = -1; m_RV.reset(); m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices(); - m_RV.set(NL_FCONST(1.0) / logic_family()->R_low(), + m_RV.set(plib::constants::one / logic_family()->R_low(), logic_family()->low_V(0.0, supply_V), 0.0); } NETLIB_UPDATE(d_to_a_proxy) { - const int state = static_cast(m_I()); + const auto state = static_cast(m_I()); if (state != m_last_state) { // FIXME: Variable voltage @@ -160,7 +146,7 @@ namespace netlist { m_RV.update(); } - m_RV.set(NL_FCONST(1.0) / R, V, 0.0); + m_RV.set(plib::constants::one / R, V, 0.0); m_RV.solve_later(); } } diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h index eb1f2b3fe87..034f7c3d9ba 100644 --- a/src/lib/netlist/devices/nlid_proxy.h +++ b/src/lib/netlist/devices/nlid_proxy.h @@ -11,8 +11,8 @@ #ifndef NLID_PROXY_H_ #define NLID_PROXY_H_ -#include "../nl_setup.h" #include "../analog/nlid_twoterm.h" +#include "../nl_setup.h" namespace netlist { @@ -29,7 +29,7 @@ namespace netlist nld_base_proxy(netlist_base_t &anetlist, const pstring &name, logic_t *inout_proxied, detail::core_terminal_t *proxy_inout); - virtual ~nld_base_proxy(); + ~nld_base_proxy() override = default; logic_t &term_proxied() const { return *m_term_proxied; } detail::core_terminal_t &proxy_term() const { return *m_proxy_term; } @@ -49,7 +49,7 @@ namespace netlist { public: - virtual ~nld_base_a_to_d_proxy(); + ~nld_base_a_to_d_proxy() override = default; virtual logic_output_t &out() { return m_Q; } @@ -69,7 +69,7 @@ namespace netlist public: nld_a_to_d_proxy(netlist_base_t &anetlist, const pstring &name, logic_input_t *in_proxied); - virtual ~nld_a_to_d_proxy() override; + ~nld_a_to_d_proxy() override = default; analog_input_t m_I; @@ -88,7 +88,7 @@ namespace netlist NETLIB_OBJECT_DERIVED(base_d_to_a_proxy, base_proxy) { public: - virtual ~nld_base_d_to_a_proxy(); + ~nld_base_d_to_a_proxy() override = default; virtual logic_input_t &in() { return m_I; } @@ -105,7 +105,7 @@ namespace netlist { public: nld_d_to_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *out_proxied); - virtual ~nld_d_to_a_proxy() override {} + ~nld_d_to_a_proxy() override = default; protected: diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 7271084bbc1..f98a74f043f 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -11,9 +11,9 @@ #ifndef NLID_SYSTEM_H_ #define NLID_SYSTEM_H_ +#include "../analog/nlid_twoterm.h" #include "../nl_base.h" #include "../nl_setup.h" -#include "../analog/nlid_twoterm.h" #include "../plib/putil.h" namespace netlist @@ -27,7 +27,7 @@ namespace netlist NETLIB_OBJECT(netlistparams) { NETLIB_CONSTRUCTOR(netlistparams) - , m_use_deactivate(*this, "USE_DEACTIVATE", 0) + , m_use_deactivate(*this, "USE_DEACTIVATE", false) { } NETLIB_UPDATEI() { } @@ -125,18 +125,15 @@ namespace netlist std::vector pat(plib::psplit(m_pattern(),",")); m_off = netlist_time::from_double(m_offset()); - unsigned long pati[32]; - for (int pI = 0; pI < 32; pI++) - { - pati[pI] = 0; - } + netlist_time::mult_type pati[32] = { 0 }; + m_size = static_cast(pat.size()); - unsigned long total = 0; + netlist_time::mult_type total = 0; for (unsigned i=0; i(pat[i]); - pati[i] = plib::pstonum(pat[i]); + pati[i] = plib::pstonum(pat[i]); total += pati[i]; } netlist_time ttotal = netlist_time::zero(); @@ -177,7 +174,7 @@ namespace netlist { NETLIB_CONSTRUCTOR(logic_input) , m_Q(*this, "Q") - , m_IN(*this, "IN", 0) + , m_IN(*this, "IN", false) /* make sure we get the family first */ , m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)") { diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index 2377071c4e2..5eda50e0357 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -6,9 +6,9 @@ */ #include "nlid_truthtable.h" -#include "../plib/plists.h" #include "../nl_setup.h" #include "../plib/palloc.h" +#include "../plib/plists.h" #include @@ -394,7 +394,7 @@ void truthtable_parser::parse(const std::vector &truthtable) else nl_assert_always(outs == "0", "Unknown value (not 0 or 1"); // FIXME: error handling - netlist_time t = netlist_time::from_nsec(plib::pstonum(plib::trim(times[j]))); + netlist_time t = netlist_time::from_nsec(plib::pstonum(plib::trim(times[j]))); uint_least8_t k=0; while (m_timing_nt[k] != netlist_time::zero() && m_timing_nt[k] != t) k++; @@ -451,11 +451,6 @@ netlist_base_factory_truthtable_t::netlist_base_factory_truthtable_t(const pstri { } -netlist_base_factory_truthtable_t::~netlist_base_factory_truthtable_t() -{ -} - - #define ENTRYY(n, m, s) case (n * 100 + m): \ { using xtype = netlist_factory_truthtable_t; \ ret = plib::palloc(desc.name, desc.classname, desc.def_param, s); } break diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h index 6896c656750..c344feda2d4 100644 --- a/src/lib/netlist/devices/nlid_truthtable.h +++ b/src/lib/netlist/devices/nlid_truthtable.h @@ -10,8 +10,8 @@ #ifndef NLID_TRUTHTABLE_H_ #define NLID_TRUTHTABLE_H_ -#include "../nl_setup.h" #include "../nl_base.h" +#include "../nl_setup.h" #include "../plib/putil.h" #define NETLIB_TRUTHTABLE(cname, nIN, nOUT) \ @@ -90,8 +90,10 @@ namespace devices struct truthtable_t { truthtable_t() - : m_initialized(false) + : m_timing_index{0} + , m_initialized(false) {} + type_t m_out_state[m_size]; uint_least8_t m_timing_index[m_size * m_NO]; netlist_time m_timing_nt[16]; @@ -217,7 +219,7 @@ namespace devices netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname, const pstring &def_param, const pstring &sourcefile); - virtual ~netlist_base_factory_truthtable_t(); + ~netlist_base_factory_truthtable_t() override = default; std::vector m_desc; const logic_family_desc_t *m_family; diff --git a/src/lib/netlist/macro/nlm_cd4xxx.cpp b/src/lib/netlist/macro/nlm_cd4xxx.cpp index 9ce786ca85e..a9d622032fd 100644 --- a/src/lib/netlist/macro/nlm_cd4xxx.cpp +++ b/src/lib/netlist/macro/nlm_cd4xxx.cpp @@ -2,10 +2,10 @@ // copyright-holders:Couriersud #include "nlm_cd4xxx.h" -#include "../devices/nld_system.h" #include "../devices/nld_4020.h" #include "../devices/nld_4066.h" #include "../devices/nld_4316.h" +#include "../devices/nld_system.h" /* * CD4001BC: Quad 2-Input NOR Buffered B Series Gate diff --git a/src/lib/netlist/netlist_types.h b/src/lib/netlist/netlist_types.h index bbca9949e49..9edd19e0ace 100644 --- a/src/lib/netlist/netlist_types.h +++ b/src/lib/netlist/netlist_types.h @@ -9,13 +9,14 @@ #ifndef NETLIST_TYPES_H_ #define NETLIST_TYPES_H_ +#include +#include + #include "nl_config.h" #include "plib/pchrono.h" -#include "plib/pstring.h" #include "plib/pfmtlog.h" +#include "plib/pstring.h" -#include -#include namespace netlist { @@ -37,7 +38,7 @@ namespace netlist class callbacks_t { public: - virtual ~callbacks_t() {} + virtual ~callbacks_t() = default; /* logging callback */ virtual void vlog(const plib::plog_level &l, const pstring &ls) const = 0; @@ -74,7 +75,7 @@ namespace netlist */ using model_map_t = std::unordered_map; - } -} + } // namespace detail +} // namespace netlist #endif /* NETLIST_TYPES_H_ */ diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 24cb7cc8890..7447ddb5f02 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -8,18 +8,18 @@ #include "solver/nld_matrix_solver.h" #include "solver/nld_solver.h" -#include "plib/putil.h" #include "plib/palloc.h" +#include "plib/putil.h" -#include "nl_base.h" -#include "devices/nlid_system.h" #include "devices/nlid_proxy.h" +#include "devices/nlid_system.h" #include "macro/nlm_base.h" +#include "nl_base.h" #include "nl_errstr.h" -#include #include +#include #include namespace netlist @@ -56,26 +56,18 @@ namespace detail } } -} - -nl_exception::~nl_exception() -{ -} +} // namespace detail // ---------------------------------------------------------------------------------------- // logic_family_ttl_t // ---------------------------------------------------------------------------------------- +// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default) logic_family_desc_t::logic_family_desc_t() { } -logic_family_desc_t::~logic_family_desc_t() -{ -} - - class logic_family_ttl_t : public logic_family_desc_t { public: @@ -90,8 +82,8 @@ public: m_R_low = 1.0; m_R_high = 130.0; } - virtual plib::owned_ptr create_d_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - virtual plib::owned_ptr create_a_d_proxy(netlist_base_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + plib::owned_ptr create_d_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *proxied) const override; + plib::owned_ptr create_a_d_proxy(netlist_base_t &anetlist, const pstring &name, logic_input_t *proxied) const override; }; plib::owned_ptr logic_family_ttl_t::create_d_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *proxied) const @@ -117,8 +109,8 @@ public: m_R_low = 10.0; m_R_high = 10.0; } - virtual plib::owned_ptr create_d_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - virtual plib::owned_ptr create_a_d_proxy(netlist_base_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + plib::owned_ptr create_d_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *proxied) const override; + plib::owned_ptr create_a_d_proxy(netlist_base_t &anetlist, const pstring &name, logic_input_t *proxied) const override; }; plib::owned_ptr logic_family_cd4xxx_t::create_d_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *proxied) const @@ -166,6 +158,7 @@ void detail::queue_t::register_state(plib::state_manager_t &manager, const pstri void detail::queue_t::on_pre_save(plib::state_manager_t &manager) { + plib::unused_var(manager); m_qsize = this->size(); for (std::size_t i = 0; i < m_qsize; i++ ) { @@ -177,6 +170,7 @@ void detail::queue_t::on_pre_save(plib::state_manager_t &manager) void detail::queue_t::on_post_load(plib::state_manager_t &manager) { + plib::unused_var(manager); this->clear(); for (std::size_t i = 0; i < m_qsize; i++ ) { @@ -197,17 +191,15 @@ detail::netlist_ref::netlist_ref(netlist_state_t &nl) // ---------------------------------------------------------------------------------------- detail::object_t::object_t(const pstring &aname) - : m_name(plib::make_unique(aname)) +// : m_name(aname) { + name_hash().insert({this, aname}); } -detail::object_t::~object_t() +pstring detail::object_t::name() const { -} - -const pstring &detail::object_t::name() const -{ - return *m_name; + return name_hash().find(this)->second; + //return m_name; } // ---------------------------------------------------------------------------------------- @@ -258,10 +250,6 @@ netlist_t::netlist_t(const pstring &aname, std::unique_ptr callback run_state_manager().save_item(this, m_time, "m_time"); } -netlist_t::~netlist_t() -{ -} - // ---------------------------------------------------------------------------------------- // netlist_t // ---------------------------------------------------------------------------------------- @@ -355,7 +343,7 @@ void netlist_state_t::reset() // Reset all devices once ! log().verbose("Call reset on all devices:"); for (auto & dev : m_devices) - dev->reset(); + dev.second->reset(); // Make sure everything depending on parameters is set // Currently analog input and logic input also @@ -363,7 +351,7 @@ void netlist_state_t::reset() log().verbose("Call update_param on all devices:"); for (auto & dev : m_devices) - dev->update_param(); + dev.second->update_param(); // Step all devices once ! /* @@ -389,14 +377,14 @@ void netlist_state_t::reset() t.push_back(&term->m_delegate); term->m_delegate(); } - core_device_t *dev = reinterpret_cast(term->m_delegate.object()); + auto *dev = reinterpret_cast(term->m_delegate.object()); if (!plib::container::contains(d, dev)) d.push_back(dev); } log().verbose("Devices not yet updated:"); for (auto &dev : m_devices) - if (!plib::container::contains(d, dev.get())) - log().verbose("\t ...{1}", dev->name()); + if (!plib::container::contains(d, dev.second.get())) + log().verbose("\t ...{1}", dev.second->name()); //x->update_dev(); } break; @@ -409,7 +397,7 @@ void netlist_state_t::reset() std::size_t i = m_devices.size(); while (i>0) - m_devices[--i]->update(); + m_devices[--i].second->update(); for (auto &n : m_nets) // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1 n->update_inputs(); @@ -420,7 +408,7 @@ void netlist_state_t::reset() { log().verbose("Using brute force forward startup strategy"); for (auto &d : m_devices) - d->update(); + d.second->update(); } break; } @@ -434,11 +422,11 @@ void netlist_state_t::reset() void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT { + auto sm_guard(m_stat_mainloop.guard()); netlist_time stop(m_time + delta); m_queue.push(detail::queue_t::entry_t(stop, nullptr)); - auto sm_guard(m_stat_mainloop.guard()); if (m_mainclock == nullptr) { @@ -491,14 +479,14 @@ void netlist_t::print_stats() const index.push_back(i); std::sort(index.begin(), index.end(), - [&](size_t i1, size_t i2) { return m_state->m_devices[i1]->m_stat_total_time.total() < m_state->m_devices[i2]->m_stat_total_time.total(); }); + [&](size_t i1, size_t i2) { return m_state->m_devices[i1].second->m_stat_total_time.total() < m_state->m_devices[i2].second->m_stat_total_time.total(); }); nperftime_t::type total_time(0); - uint_least64_t total_count(0); + netlist_time::mult_type total_count(0); for (auto & j : index) { - auto entry = m_state->m_devices[j].get(); + auto entry = m_state->m_devices[j].second.get(); log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(), entry->m_stat_call_count(), entry->m_stat_total_time.count(), entry->m_stat_total_time.total(), entry->m_stat_inc_active()); @@ -543,12 +531,13 @@ void netlist_t::print_stats() const auto trigger = total_count * 200 / 1000000; // 200 ppm for (auto &entry : m_state->m_devices) { + auto ep = entry.second.get(); // Factor of 3 offers best performace increase - if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count() - && entry->m_stat_inc_active() > trigger) - log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", entry->name(), - static_cast(entry->m_stat_inc_active()) / static_cast(entry->m_stat_total_time.count()), - entry->m_stat_inc_active(), entry->m_stat_total_time.count()); + if (ep->m_stat_inc_active() > 3 * ep->m_stat_total_time.count() + && ep->m_stat_inc_active() > trigger) + log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(), + static_cast(ep->m_stat_inc_active()) / static_cast(ep->m_stat_total_time.count()), + ep->m_stat_inc_active(), ep->m_stat_total_time.count()); } } } @@ -558,12 +547,12 @@ core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool core_device_t *ret = nullptr; for (auto &d : m_devices) { - if (cc(d.get())) + if (cc(d.second.get())) { if (ret != nullptr) m_log.fatal(MF_1_MORE_THAN_ONE_1_DEVICE_FOUND, classname); else - ret = d.get(); + ret = d.second.get(); } } return ret; @@ -595,11 +584,7 @@ core_device_t::core_device_t(core_device_t &owner, const pstring &name) set_logic_family(owner.logic_family()); if (logic_family() == nullptr) set_logic_family(family_TTL()); - state().add_dev(plib::owned_ptr(this, false)); -} - -core_device_t::~core_device_t() -{ + state().add_dev(this->name(), plib::owned_ptr(this, false)); } void core_device_t::set_default_delegate(detail::core_terminal_t &term) @@ -627,11 +612,6 @@ device_t::device_t(core_device_t &owner, const pstring &name) { } -device_t::~device_t() -{ - //log().debug("~net_device_t\n"); -} - setup_t &device_t::setup() { return state().setup(); @@ -683,6 +663,11 @@ void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_term // family_setter_t // ----------------------------------------------------------------------------- +// NOLINTNEXTLINE(modernize-use-equals-default) +detail::family_setter_t::family_setter_t() +{ +} + detail::family_setter_t::family_setter_t(core_device_t &dev, const pstring &desc) { dev.set_logic_family(dev.setup().family_from_model(desc)); @@ -776,7 +761,7 @@ void detail::net_t::reset() m_new_Q = 0; m_cur_Q = 0; - analog_net_t *p = dynamic_cast(this); + auto *p = dynamic_cast(this); if (p != nullptr) p->m_cur_Analog = 0.0; @@ -833,10 +818,6 @@ logic_net_t::logic_net_t(netlist_base_t &nl, const pstring &aname, detail::core_ { } -logic_net_t::~logic_net_t() -{ -} - // ---------------------------------------------------------------------------------------- // analog_net_t // ---------------------------------------------------------------------------------------- @@ -848,10 +829,6 @@ analog_net_t::analog_net_t(netlist_base_t &nl, const pstring &aname, detail::cor { } -analog_net_t::~analog_net_t() -{ -} - // ---------------------------------------------------------------------------------------- // core_terminal_t // ---------------------------------------------------------------------------------------- @@ -869,19 +846,11 @@ detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &anam { } -detail::core_terminal_t::~core_terminal_t() -{ -} - analog_t::analog_t(core_device_t &dev, const pstring &aname, const state_e state) : core_terminal_t(dev, aname, state) { } -analog_t::~analog_t() -{ -} - logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state, nldelegate delegate) : core_terminal_t(dev, aname, state, delegate) @@ -890,28 +859,20 @@ logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state, { } -logic_t::~logic_t() -{ -} - // ---------------------------------------------------------------------------------------- // terminal_t // ---------------------------------------------------------------------------------------- -terminal_t::terminal_t(core_device_t &dev, const pstring &aname) +terminal_t::terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm) : analog_t(dev, aname, STATE_BIDIR) -, m_otherterm(nullptr) , m_Idr1(nullptr) , m_go1(nullptr) , m_gt1(nullptr) +, m_otherterm(otherterm) { state().setup().register_term(*this); } -terminal_t::~terminal_t() -{ -} - void terminal_t::solve_now() { // Nets may belong to railnets which do not have a solver attached @@ -950,10 +911,6 @@ logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname) state().setup().register_term(*this); } -logic_output_t::~logic_output_t() -{ -} - void logic_output_t::initial(const netlist_sig_t val) { if (has_net()) @@ -970,10 +927,6 @@ analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname) state().setup().register_term(*this); } -analog_input_t::~analog_input_t() -{ -} - // ---------------------------------------------------------------------------------------- // analog_output_t // ---------------------------------------------------------------------------------------- @@ -989,10 +942,6 @@ analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname) state().setup().register_term(*this); } -analog_output_t::~analog_output_t() -{ -} - void analog_output_t::initial(const nl_double val) { net().set_Q_Analog(val); @@ -1010,10 +959,6 @@ logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname, state().setup().register_term(*this); } -logic_input_t::~logic_input_t() -{ -} - // ---------------------------------------------------------------------------------------- // Parameters ... // ---------------------------------------------------------------------------------------- @@ -1024,10 +969,6 @@ param_t::param_t(device_t &device, const pstring &name) device.setup().register_param(this->name(), *this); } -param_t::~param_t() -{ -} - param_t::param_type_t param_t::param_type() const { if (dynamic_cast(this) != nullptr) @@ -1074,10 +1015,6 @@ param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &v m_param = device.setup().get_initial_param_val(this->name(),val); } -param_str_t::~param_str_t() -{ -} - void param_str_t::changed() { } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 507eb42d367..58563c91610 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -13,18 +13,20 @@ #error "nl_base.h included. Please correct." #endif -#include "netlist_types.h" -#include "nl_errstr.h" -#include "nl_lists.h" -#include "nl_time.h" +#include +#include + #include "plib/palloc.h" // owned_ptr #include "plib/pdynlib.h" -#include "plib/pstate.h" #include "plib/pfmtlog.h" -#include "plib/pstream.h" #include "plib/ppmf.h" +#include "plib/pstate.h" +#include "plib/pstream.h" -#include +#include "netlist_types.h" +#include "nl_errstr.h" +#include "nl_lists.h" +#include "nl_time.h" //============================================================ // MACROS / New Syntax @@ -186,7 +188,7 @@ namespace netlist class NETLIB_NAME(base_proxy); class NETLIB_NAME(base_d_to_a_proxy); class NETLIB_NAME(base_a_to_d_proxy); - } + } // namespace devices namespace detail { class object_t; @@ -196,13 +198,12 @@ namespace netlist struct family_setter_t; class queue_t; class net_t; - } + } // namespace detail class logic_output_t; class logic_input_t; class analog_net_t; class logic_net_t; - class net_t; class setup_t; class netlist_t; class netlist_state_t; @@ -228,8 +229,7 @@ namespace netlist ) : plib::pexception(text) { } /*! Copy constructor. */ - nl_exception(const nl_exception &e) : plib::pexception(e) { } - virtual ~nl_exception(); + nl_exception(const nl_exception &e) = default; }; /*! Logic families descriptors are used to create proxy devices. @@ -240,7 +240,7 @@ namespace netlist { public: logic_family_desc_t(); - virtual ~logic_family_desc_t(); + virtual ~logic_family_desc_t() = default; virtual plib::owned_ptr create_d_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *proxied) const = 0; @@ -250,8 +250,8 @@ namespace netlist double fixed_V() const { return m_fixed_V; } double low_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_low_thresh_PCNT; } double high_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_high_thresh_PCNT; } - double low_V(const double VN, const double VP) const { return VN + m_low_VO; } - double high_V(const double VN, const double VP) const { return VP - m_high_VO; } + double low_V(const double VN, const double VP) const { plib::unused_var(VP); return VN + m_low_VO; } + double high_V(const double VN, const double VP) const { plib::unused_var(VN); return VP - m_high_VO; } double R_low() const { return m_R_low; } double R_high() const { return m_R_high; } @@ -285,7 +285,7 @@ namespace netlist void set_logic_family(const logic_family_desc_t *fam) { m_logic_family = fam; } protected: - ~logic_family_t() { } // prohibit polymorphic destruction + ~logic_family_t() = default; // prohibit polymorphic destruction const logic_family_desc_t *m_logic_family; }; @@ -391,7 +391,7 @@ namespace netlist * memory allocation to enhance locality. Please refer to \ref USE_MEMPOOL as * well. */ - class detail::object_t + class detail::object_t : public plib::nocopyassignmove { public: @@ -405,17 +405,22 @@ namespace netlist * * \returns name of the object. */ - const pstring &name() const; + pstring name() const; - void * operator new (size_t size, void *ptr) { return ptr; } - void operator delete (void *ptr, void *) { } + void * operator new (size_t size, void *ptr) { plib::unused_var(size); return ptr; } + void operator delete (void *ptr, void *) { plib::unused_var(ptr); } void * operator new (size_t size); void operator delete (void * mem); protected: - ~object_t(); // only childs should be destructible + ~object_t() = default; // only childs should be destructible private: - std::unique_ptr m_name; + //pstring m_name; + static std::unordered_map &name_hash() + { + static std::unordered_map lhash; + return lhash; + } }; struct detail::netlist_ref @@ -508,7 +513,7 @@ namespace netlist core_terminal_t(core_device_t &dev, const pstring &aname, const state_e state, nldelegate delegate = nldelegate()); - virtual ~core_terminal_t(); + virtual ~core_terminal_t() = default; /*! The object type. * \returns type of the object @@ -562,7 +567,6 @@ namespace netlist public: analog_t(core_device_t &dev, const pstring &aname, const state_e state); - virtual ~analog_t(); const analog_net_t & net() const NL_NOEXCEPT; analog_net_t & net() NL_NOEXCEPT; @@ -576,8 +580,7 @@ namespace netlist { public: - terminal_t(core_device_t &dev, const pstring &aname); - virtual ~terminal_t(); + terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm); nl_double operator ()() const NL_NOEXCEPT; @@ -593,36 +596,28 @@ namespace netlist void set(const nl_double GO, const nl_double GT, const nl_double I) noexcept { - set_ptr(m_Idr1, I); - set_ptr(m_go1, GO); - set_ptr(m_gt1, GT); + if (m_go1 != nullptr) + { + if (*m_Idr1 != I) *m_Idr1 = I; + if (*m_go1 != GO) *m_go1 = GO; + if (*m_gt1 != GT) *m_gt1 = GT; + } } void solve_now(); void schedule_solve_after(const netlist_time after); - void set_ptrs(nl_double *gt, nl_double *go, nl_double *Idr) noexcept - { - m_gt1 = gt; - m_go1 = go; - m_Idr1 = Idr; - } - - terminal_t *m_otherterm; + void set_ptrs(nl_double *gt, nl_double *go, nl_double *Idr) noexcept; + terminal_t *otherterm() const noexcept { return m_otherterm; } private: - void set_ptr(nl_double *ptr, const nl_double val) noexcept - { - if (ptr != nullptr && *ptr != val) - { - *ptr = val; - } - } nl_double *m_Idr1; // drive current nl_double *m_go1; // conductance for Voltage from other term nl_double *m_gt1; // conductance for total conductance + terminal_t *m_otherterm; + }; @@ -635,7 +630,6 @@ namespace netlist public: logic_t(core_device_t &dev, const pstring &aname, const state_e state, nldelegate delegate = nldelegate()); - virtual ~logic_t(); bool has_proxy() const { return (m_proxy != nullptr); } devices::nld_base_proxy *get_proxy() const { return m_proxy; } @@ -659,7 +653,6 @@ namespace netlist public: logic_input_t(core_device_t &dev, const pstring &aname, nldelegate delegate = nldelegate()); - virtual ~logic_input_t(); netlist_sig_t operator()() const NL_NOEXCEPT { @@ -691,9 +684,6 @@ namespace netlist const pstring &aname /*!< name of terminal */ ); - /*! Destructor */ - virtual ~analog_input_t(); - /*! returns voltage at terminal. * \returns voltage at terminal. */ @@ -796,7 +786,6 @@ namespace netlist public: logic_net_t(netlist_base_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr); - virtual ~logic_net_t(); netlist_sig_t Q() const noexcept { return m_cur_Q; } void initial(const netlist_sig_t val) noexcept @@ -853,8 +842,6 @@ namespace netlist analog_net_t(netlist_base_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr); - virtual ~analog_net_t(); - nl_double Q_Analog() const NL_NOEXCEPT { return m_cur_Analog; } void set_Q_Analog(const nl_double v) NL_NOEXCEPT { m_cur_Analog = v; } nl_double *Q_Analog_state_ptr() NL_NOEXCEPT { return m_cur_Analog.ptr(); } @@ -877,7 +864,6 @@ namespace netlist public: logic_output_t(core_device_t &dev, const pstring &aname); - virtual ~logic_output_t(); void initial(const netlist_sig_t val); @@ -904,7 +890,6 @@ namespace netlist { public: analog_output_t(core_device_t &dev, const pstring &aname); - virtual ~analog_output_t(); void push(const nl_double val) NL_NOEXCEPT { set_Q(val); } void initial(const nl_double val); @@ -935,7 +920,7 @@ namespace netlist param_type_t param_type() const; protected: - virtual ~param_t(); /* not intended to be destroyed */ + virtual ~param_t() = default; /* not intended to be destroyed */ void update_param(); @@ -995,10 +980,9 @@ namespace netlist { public: param_str_t(device_t &device, const pstring &name, const pstring &val); - virtual ~param_str_t(); const pstring &operator()() const NL_NOEXCEPT { return Value(); } - void setTo(netlist_time time, const pstring ¶m) NL_NOEXCEPT + void setTo(const pstring ¶m) NL_NOEXCEPT { if (m_param != param) { @@ -1042,12 +1026,12 @@ namespace netlist const pstring model_value_str(const pstring &entity) /*const*/; const pstring model_type() /*const*/; + /* hide this */ + void setTo(const pstring ¶m) = delete; protected: - virtual void changed() override; + void changed() override; nl_double model_value(const pstring &entity) /*const*/; private: - /* hide this */ - void setTo(const pstring ¶m) = delete; detail::model_map_t m_map; }; @@ -1065,7 +1049,7 @@ namespace netlist std::unique_ptr stream(); protected: - virtual void changed() override { } + void changed() override { } }; // ----------------------------------------------------------------------------- @@ -1081,7 +1065,7 @@ namespace netlist const ST & operator[] (std::size_t n) NL_NOEXCEPT { return m_data[n]; } protected: - virtual void changed() override + void changed() override { stream()->read(reinterpret_cast(&m_data[0]),1<>; - using devices_collection_type = std::vector>; + + /* need to preserve order of device creation ... */ + using devices_collection_type = std::vector>>; netlist_state_t(const pstring &aname, std::unique_ptr &&callbacks, std::unique_ptr &&setup); @@ -1289,13 +1279,15 @@ namespace netlist plib::state_manager_t &run_state_manager() { return m_state; } - template void save(O &owner, C &state, const pstring &stname) + template + void save(O &owner, C &state, const pstring &module, const pstring &stname) { - this->run_state_manager().save_item(static_cast(&owner), state, owner.name() + pstring(".") + stname); + this->run_state_manager().save_item(static_cast(&owner), state, module + pstring(".") + stname); } - template void save(O &owner, C *state, const pstring &stname, const std::size_t count) + template + void save(O &owner, C *state, const pstring &module, const pstring &stname, const std::size_t count) { - this->run_state_manager().save_state_ptr(static_cast(&owner), owner.name() + pstring(".") + stname, plib::state_manager_t::datatype_f::f(), count, state); + this->run_state_manager().save_state_ptr(static_cast(&owner), module + pstring(".") + stname, plib::state_manager_t::dtype(), count, state); } core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const; @@ -1312,33 +1304,31 @@ namespace netlist std::vector tmp; for (auto &d : m_devices) { - device_class *dev = dynamic_cast(d.get()); + auto dev = dynamic_cast(d.second.get()); if (dev != nullptr) tmp.push_back(dev); } return tmp; } - void add_dev(plib::owned_ptr dev) + template + void add_dev(const pstring &name, plib::owned_ptr &&dev) { for (auto & d : m_devices) - if (d->name() == dev->name()) - log().fatal(MF_1_DUPLICATE_NAME_DEVICE_LIST, d->name()); - m_devices.push_back(std::move(dev)); + if (d.first == name) + log().fatal(MF_1_DUPLICATE_NAME_DEVICE_LIST, d.first); + //m_devices.push_back(std::move(dev)); + m_devices.insert(m_devices.end(), { name, std::move(dev) }); } void remove_dev(core_device_t *dev) { - m_devices.erase( - std::remove_if( - m_devices.begin(), - m_devices.end(), - [&] (plib::owned_ptr const& p) - { - return p.get() == dev; - }), - m_devices.end() - ); + for (auto it = m_devices.begin(); it != m_devices.end(); it++) + if (it->second.get() == dev) + { + m_devices.erase(it); + return; + } } /* sole use is to manage lifetime of family objects */ @@ -1379,7 +1369,7 @@ namespace netlist public: explicit netlist_t(const pstring &aname, std::unique_ptr callbacks); - ~netlist_t(); + ~netlist_t() = default; /* run functions */ @@ -1407,6 +1397,7 @@ namespace netlist template nl_double gmin(X *solv = nullptr) const NL_NOEXCEPT { + plib::unused_var(solv); return static_cast(m_solver)->gmin(); } @@ -1486,7 +1477,7 @@ namespace netlist if (found) { bool err = false; - T vald = plib::pstonum_ne(p, err); + auto vald = plib::pstonum_ne(p, err); if (err) device.state().log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, p); m_param = vald; @@ -1494,7 +1485,7 @@ namespace netlist else m_param = val; - device.state().save(*this, m_param, "m_param"); + device.state().save(*this, m_param, this->name(), "m_param"); } template @@ -1613,6 +1604,18 @@ namespace netlist inline nl_double terminal_t::operator ()() const NL_NOEXCEPT { return net().Q_Analog(); } + inline void terminal_t::set_ptrs(nl_double *gt, nl_double *go, nl_double *Idr) noexcept + { + if (!(gt && go && Idr) && (gt || go || Idr)) + state().log().fatal("Inconsistent nullptrs for terminal {}", name()); + else + { + m_gt1 = gt; + m_go1 = go; + m_Idr1 = Idr; + } + } + inline logic_net_t & logic_t::net() NL_NOEXCEPT { return static_cast(core_terminal_t::net()); @@ -1674,18 +1677,18 @@ namespace netlist state_var::state_var(O &owner, const pstring &name, const T &value) : m_value(value) { - owner.state().save(owner, m_value, name); + owner.state().save(owner, m_value, owner.name(), name); } template template state_var::state_var(O &owner, const pstring &name, const T & value) { - owner.state().save(owner, m_value, name); + owner.state().save(owner, m_value, owner.name(), name); for (std::size_t i=0; i> : ptype_traits { }; -} +} // namespace plib diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 69b5fad945c..de9a370db2f 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -62,8 +62,6 @@ // FIXME: Convert into solver parameter #define USE_LINEAR_PREDICTION (0) -#define NETLIST_GMIN_DEFAULT (1e-9) - //============================================================ // DEBUGGING //============================================================ @@ -98,16 +96,17 @@ #endif // !defined(USE_OPENMP) // Use nano-second resolution - Sufficient for now -#define NETLIST_INTERNAL_RES (UINT64_C(1000000000)) -#define NETLIST_CLOCK (NETLIST_INTERNAL_RES) + +static constexpr const auto NETLIST_INTERNAL_RES = 1000000000; +static constexpr const auto NETLIST_CLOCK = NETLIST_INTERNAL_RES; + +//#define NETLIST_INTERNAL_RES (UINT64_C(1000000000)) +//#define NETLIST_CLOCK (NETLIST_INTERNAL_RES) //#define NETLIST_INTERNAL_RES (UINT64_C(1000000000000)) //#define NETLIST_CLOCK (UINT64_C(1000000000)) //#define nl_double float -//#define NL_FCONST(x) (x ## f) - -#define NL_FCONST(x) x using nl_double = double; //============================================================ diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp index eca8de4d4b2..26ee33853e0 100644 --- a/src/lib/netlist/nl_factory.cpp +++ b/src/lib/netlist/nl_factory.cpp @@ -10,9 +10,9 @@ #include "nl_factory.h" #include "nl_base.h" +#include "nl_errstr.h" #include "nl_setup.h" #include "plib/putil.h" -#include "nl_errstr.h" namespace netlist { namespace factory { @@ -26,7 +26,7 @@ namespace netlist { namespace factory } protected: NETLIB_RESETI() { } - NETLIB_UPDATEI() { }; + NETLIB_UPDATEI() { } }; element_t::element_t(const pstring &name, const pstring &classname, @@ -43,10 +43,6 @@ namespace netlist { namespace factory { } - element_t::~element_t() - { - } - // ---------------------------------------------------------------------------------------- // net_device_t_base_factory // ---------------------------------------------------------------------------------------- @@ -98,4 +94,5 @@ namespace netlist { namespace factory } -} } +} // namespace factory + } // namespace netlist diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h index a20ba400234..ca0c266739e 100644 --- a/src/lib/netlist/nl_factory.h +++ b/src/lib/netlist/nl_factory.h @@ -49,10 +49,14 @@ namespace factory { const pstring &def_param); element_t(const pstring &name, const pstring &classname, const pstring &def_param, const pstring &sourcefile); - virtual ~element_t(); + virtual ~element_t() = default; virtual plib::owned_ptr Create(netlist_state_t &anetlist, const pstring &name) = 0; - virtual void macro_actions(netlist_state_t &anetlist, const pstring &name) {} + virtual void macro_actions(netlist_state_t &anetlist, const pstring &name) + { + plib::unused_var(anetlist); + plib::unused_var(name); + } const pstring &name() const { return m_name; } const pstring &classname() const { return m_classname; } @@ -133,7 +137,11 @@ namespace factory { library_element_t(setup_t &setup, const pstring &name, const pstring &classname, const pstring &def_param, const pstring &source) - : element_t(name, classname, def_param, source) { } + : element_t(name, classname, def_param, source) + { + // FIXME: if it is not used, remove it + plib::unused_var(setup); + } plib::owned_ptr Create(netlist_state_t &anetlist, const pstring &name) override; @@ -142,11 +150,11 @@ namespace factory { private: }; - } + } // namespace factory namespace devices { void initialize_factory(factory::list_t &factory); - } -} + } // namespace devices +} // namespace netlist #endif /* NLFACTORY_H_ */ diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h index 042a823259f..0c5b25c1a1b 100644 --- a/src/lib/netlist/nl_lists.h +++ b/src/lib/netlist/nl_lists.h @@ -10,16 +10,16 @@ #ifndef NLLISTS_H_ #define NLLISTS_H_ -#include "nl_config.h" #include "netlist_types.h" -#include "plib/plists.h" +#include "nl_config.h" #include "plib/pchrono.h" +#include "plib/plists.h" #include "plib/ptypes.h" +#include #include -#include #include -#include +#include #include // ---------------------------------------------------------------------------------------- @@ -33,7 +33,7 @@ namespace netlist class pspin_mutex { public: - pspin_mutex() noexcept { } + pspin_mutex() noexcept = default; void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } } void unlock() noexcept { m_lock.clear(std::memory_order_release); } private: @@ -309,6 +309,6 @@ namespace netlist template using timed_queue = timed_queue_linear; -} +} // namespace netlist #endif /* NLLISTS_H_ */ diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp index 460ff3819bf..f28eb822a09 100644 --- a/src/lib/netlist/nl_parser.cpp +++ b/src/lib/netlist/nl_parser.cpp @@ -6,9 +6,9 @@ */ #include "nl_parser.h" -#include "nl_factory.h" -#include "nl_errstr.h" #include "nl_base.h" +#include "nl_errstr.h" +#include "nl_factory.h" namespace netlist { @@ -395,7 +395,7 @@ void parser_t::device(const pstring &dev_type) // ---------------------------------------------------------------------------------------- -nl_double parser_t::eval_param(const token_t tok) +nl_double parser_t::eval_param(const token_t &tok) { static pstring macs[6] = {"", "RES_K", "RES_M", "CAP_U", "CAP_N", "CAP_P"}; static nl_double facs[6] = {1, 1e3, 1e6, 1e-6, 1e-9, 1e-12}; @@ -423,4 +423,4 @@ nl_double parser_t::eval_param(const token_t tok) } -} +} // namespace netlist diff --git a/src/lib/netlist/nl_parser.h b/src/lib/netlist/nl_parser.h index f14250ea7d1..16075ca4914 100644 --- a/src/lib/netlist/nl_parser.h +++ b/src/lib/netlist/nl_parser.h @@ -18,7 +18,7 @@ namespace netlist public: template parser_t(T &&strm, setup_t &setup) - : plib::ptokenizer(std::move(strm)) + : plib::ptokenizer(std::forward(strm)) , m_setup(setup) { } @@ -45,10 +45,10 @@ namespace netlist /* for debugging messages */ netlist_state_t &netlist() { return m_setup.netlist(); } - virtual void verror(const pstring &msg, int line_num, const pstring &line) override; + void verror(const pstring &msg, int line_num, const pstring &line) override; private: - nl_double eval_param(const token_t tok); + nl_double eval_param(const token_t &tok); token_id_t m_tok_param_left; token_id_t m_tok_param_right; @@ -75,6 +75,6 @@ namespace netlist setup_t &m_setup; }; -} +} // namespace netlist #endif /* NL_PARSER_H_ */ diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index cef51f481db..d60074c0e47 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -6,16 +6,16 @@ */ #include "plib/palloc.h" -#include "plib/putil.h" +#include "analog/nld_twoterm.h" +#include "devices/nlid_proxy.h" +#include "devices/nlid_system.h" +#include "devices/nlid_truthtable.h" #include "nl_base.h" -#include "nl_setup.h" -#include "nl_parser.h" #include "nl_factory.h" -#include "devices/nlid_system.h" -#include "devices/nlid_proxy.h" -#include "analog/nld_twoterm.h" +#include "nl_parser.h" +#include "nl_setup.h" +#include "plib/putil.h" #include "solver/nld_solver.h" -#include "devices/nlid_truthtable.h" #include @@ -88,17 +88,24 @@ void setup_t::register_dev(const pstring &classname, const pstring &name) auto f = factory().factory_by_name(classname); if (f == nullptr) log().fatal(MF_1_CLASS_1_NOT_FOUND, classname); - /* make sure we parse macro library entries */ - f->macro_actions(netlist(), name); - pstring key = build_fqn(name); - if (device_exists(key)) - log().fatal(MF_1_DEVICE_ALREADY_EXISTS_1, name); - m_device_factory[key] = f; + else + { + /* make sure we parse macro library entries */ + f->macro_actions(netlist(), name); + pstring key = build_fqn(name); + if (device_exists(key)) + log().fatal(MF_1_DEVICE_ALREADY_EXISTS_1, name); + else + m_device_factory.insert(m_device_factory.end(), {key, f}); + } } bool setup_t::device_exists(const pstring &name) const { - return (m_device_factory.find(name) != m_device_factory.end()); + for (auto &d : m_device_factory) + if (d.first == name) + return true; + return false; } @@ -398,7 +405,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) { nl_assert(out.is_logic()); - logic_output_t &out_cast = static_cast(out); + auto &out_cast = static_cast(out); devices::nld_base_proxy *proxy = out_cast.get_proxy(); if (proxy == nullptr) @@ -424,7 +431,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) proxy = new_proxy.get(); - m_netlist.nlstate().add_dev(std::move(new_proxy)); + m_netlist.nlstate().add_dev(new_proxy->name(), std::move(new_proxy)); } return proxy; } @@ -433,7 +440,7 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) { nl_assert(inp.is_logic()); - logic_input_t &incast = dynamic_cast(inp); + auto &incast = dynamic_cast(inp); devices::nld_base_proxy *proxy = incast.get_proxy(); if (proxy != nullptr) @@ -463,7 +470,7 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) inp.net().m_core_terms.clear(); // clear the list } ret->out().net().add_terminal(inp); - m_netlist.nlstate().add_dev(std::move(new_proxy)); + m_netlist.nlstate().add_dev(new_proxy->name(), std::move(new_proxy)); return ret; } } @@ -598,7 +605,7 @@ static detail::core_terminal_t &resolve_proxy(detail::core_terminal_t &term) { if (term.is_logic()) { - logic_t &out = dynamic_cast(term); + auto &out = dynamic_cast(term); if (out.has_proxy()) return out.get_proxy()->proxy_term(); } @@ -765,7 +772,7 @@ void setup_t::register_dynamic_log_devices() auto nc = factory().factory_by_name("LOG")->Create(netlist(), name); register_link(name + ".I", ll); log().debug(" dynamic link {1}: <{2}>\n",ll, name); - m_netlist.nlstate().add_dev(std::move(nc)); + m_netlist.nlstate().add_dev(nc->name(), std::move(nc)); } } } @@ -858,7 +865,7 @@ nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity) { pstring tmp = model_value_str(map, entity); - nl_double factor = NL_FCONST(1.0); + nl_double factor = plib::constants::one; auto p = std::next(tmp.begin(), static_cast(tmp.size() - 1)); switch (*p) { @@ -874,7 +881,7 @@ nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity) if (*p < '0' || *p > '9') log().fatal(MF_1_UNKNOWN_NUMBER_FACTOR_IN_1, entity); } - if (factor != NL_FCONST(1.0)) + if (factor != plib::constants::one) tmp = plib::left(tmp, tmp.size() - 1); // FIXME: check for errors return plib::pstonum(tmp) * factor; @@ -883,10 +890,10 @@ nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity) class logic_family_std_proxy_t : public logic_family_desc_t { public: - logic_family_std_proxy_t() { } - virtual plib::owned_ptr create_d_a_proxy(netlist_base_t &anetlist, + logic_family_std_proxy_t() = default; + plib::owned_ptr create_d_a_proxy(netlist_base_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - virtual plib::owned_ptr create_a_d_proxy(netlist_base_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + plib::owned_ptr create_a_d_proxy(netlist_base_t &anetlist, const pstring &name, logic_input_t *proxied) const override; }; plib::owned_ptr logic_family_std_proxy_t::create_d_a_proxy(netlist_base_t &anetlist, @@ -1017,8 +1024,7 @@ void setup_t::prepare_to_run() if ( factory().is_class(e.second) || factory().is_class(e.second)) { - auto dev = plib::owned_ptr(e.second->Create(netlist(), e.first)); - m_netlist.nlstate().add_dev(std::move(dev)); + m_netlist.nlstate().add_dev(e.first, plib::owned_ptr(e.second->Create(netlist(), e.first))); } } @@ -1036,7 +1042,22 @@ void setup_t::prepare_to_run() && !factory().is_class(e.second)) { auto dev = plib::owned_ptr(e.second->Create(netlist(), e.first)); - m_netlist.nlstate().add_dev(std::move(dev)); + m_netlist.nlstate().add_dev(dev->name(), std::move(dev)); + } + } + + log().debug("Looking for unknown parameters ...\n"); + for (auto &p : m_param_values) + { + auto f = m_params.find(p.first); + if (f == m_params.end()) + { + if (plib::endsWith(p.first, pstring(".HINT_NO_DEACTIVATE"))) + { + // FIXME: get device name, check for device + } + else + log().info("Unknown parameter: {}", p.first); } } @@ -1046,18 +1067,18 @@ void setup_t::prepare_to_run() { if (use_deactivate) { - auto p = m_param_values.find(d->name() + ".HINT_NO_DEACTIVATE"); + auto p = m_param_values.find(d.second->name() + ".HINT_NO_DEACTIVATE"); if (p != m_param_values.end()) { //FIXME: check for errors ... - double v = plib::pstonum(p->second); + auto v = plib::pstonum(p->second); if (std::abs(v - std::floor(v)) > 1e-6 ) log().fatal(MF_1_HND_VAL_NOT_SUPPORTED, p->second); - d->set_hint_deactivate(v == 0.0); + d.second->set_hint_deactivate(v == 0.0); } } else - d->set_hint_deactivate(false); + d.second->set_hint_deactivate(false); } /* resolve inputs */ @@ -1113,16 +1134,19 @@ bool source_t::parse(const pstring &name) std::unique_ptr source_string_t::stream(const pstring &name) { + plib::unused_var(name); return plib::make_unique_base(m_str.c_str(), std::strlen(m_str.c_str())); } std::unique_ptr source_mem_t::stream(const pstring &name) { + plib::unused_var(name); return plib::make_unique_base(m_str.c_str(), std::strlen(m_str.c_str())); } std::unique_ptr source_file_t::stream(const pstring &name) { + plib::unused_var(name); return plib::make_unique_base(m_filename); } @@ -1139,9 +1163,10 @@ bool source_proc_t::parse(const pstring &name) std::unique_ptr source_proc_t::stream(const pstring &name) { + plib::unused_var(name); std::unique_ptr p(nullptr); return p; } -} +} // namespace netlist diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index d0a5c002928..971f8d2e91d 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -8,20 +8,20 @@ #ifndef NLSETUP_H_ #define NLSETUP_H_ -#include "plib/pstring.h" -#include "plib/putil.h" -#include "plib/pstream.h" #include "plib/pparser.h" #include "plib/pstate.h" +#include "plib/pstream.h" +#include "plib/pstring.h" +#include "plib/putil.h" -#include "nl_factory.h" -#include "nl_config.h" #include "netlist_types.h" +#include "nl_config.h" #include "nl_errstr.h" +#include "nl_factory.h" +#include #include #include -#include //============================================================ // MACROS / inline netlist definitions @@ -100,10 +100,10 @@ void NETLIST_NAME(name)(netlist::setup_t &setup) \ desc.family = ""; #define TT_HEAD(x) \ - desc.desc.push_back(x); + desc.desc.emplace_back(x); #define TT_LINE(x) \ - desc.desc.push_back(x); + desc.desc.emplace_back(x); #define TT_FAMILY(x) \ desc.family = x; @@ -119,12 +119,12 @@ namespace netlist namespace detail { class core_terminal_t; class net_t; - } + } // namespace detail namespace devices { class nld_base_proxy; class nld_netlistparams; - } + } // namespace devices class core_device_t; class param_t; @@ -187,7 +187,7 @@ namespace netlist : m_setup(setup), m_type(type) {} - virtual ~source_t() { } + virtual ~source_t() = default; virtual bool parse(const pstring &name); setup_t &setup() { return m_setup; } @@ -339,8 +339,9 @@ namespace netlist devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out); devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp); - //std::vector> m_device_factory; - std::unordered_map m_device_factory; + /* need to preserve order of device creation ... */ + std::vector> m_device_factory; + //std::unordered_map m_device_factory; std::unordered_map m_alias; std::unordered_map m_param_values; @@ -376,7 +377,7 @@ namespace netlist } protected: - virtual std::unique_ptr stream(const pstring &name) override; + std::unique_ptr stream(const pstring &name) override; private: pstring m_str; @@ -392,7 +393,7 @@ namespace netlist } protected: - virtual std::unique_ptr stream(const pstring &name) override; + std::unique_ptr stream(const pstring &name) override; private: pstring m_filename; @@ -407,7 +408,7 @@ namespace netlist } protected: - virtual std::unique_ptr stream(const pstring &name) override; + std::unique_ptr stream(const pstring &name) override; private: pstring m_str; @@ -423,10 +424,10 @@ namespace netlist { } - virtual bool parse(const pstring &name) override; + bool parse(const pstring &name) override; protected: - virtual std::unique_ptr stream(const pstring &name) override; + std::unique_ptr stream(const pstring &name) override; private: void (*m_setup_func)(setup_t &); @@ -437,7 +438,7 @@ namespace netlist // inline implementations // ----------------------------------------------------------------------------- -} +} // namespace netlist #endif /* NLSETUP_H_ */ diff --git a/src/lib/netlist/nl_time.h b/src/lib/netlist/nl_time.h index b8ed1bb5a33..76e572a4772 100644 --- a/src/lib/netlist/nl_time.h +++ b/src/lib/netlist/nl_time.h @@ -8,33 +8,25 @@ #define NLTIME_H_ #include "nl_config.h" -#include "plib/ptypes.h" #include "plib/pstate.h" +#include "plib/ptypes.h" #include -//============================================================ -// MACROS -//============================================================ - -#define NLTIME_FROM_NS(t) netlist_time::from_nsec(t) -#define NLTIME_FROM_US(t) netlist_time::from_usec(t) -#define NLTIME_FROM_MS(t) netlist_time::from_msec(t) -#define NLTIME_IMMEDIATE netlist_time::from_nsec(1) - // ---------------------------------------------------------------------------------------- // netlist_time // ---------------------------------------------------------------------------------------- namespace netlist { + template struct ptime final { public: using internal_type = TYPE; - using mult_type = std::uint64_t; + using mult_type = TYPE; constexpr ptime() noexcept : m_time(0) {} @@ -114,8 +106,9 @@ namespace netlist C14CONSTEXPR internal_type *get_internaltype_ptr() noexcept { return &m_time; } static constexpr ptime from_nsec(const internal_type ns) noexcept { return ptime(ns, UINT64_C(1000000000)); } - static constexpr ptime from_usec(const internal_type us) noexcept { return ptime(us, UINT64_C(1000000)); } - static constexpr ptime from_msec(const internal_type ms) noexcept { return ptime(ms, UINT64_C(1000)); } + static constexpr ptime from_usec(const internal_type us) noexcept { return ptime(us, UINT64_C( 1000000)); } + static constexpr ptime from_msec(const internal_type ms) noexcept { return ptime(ms, UINT64_C( 1000)); } + static constexpr ptime from_sec(const internal_type s) noexcept { return ptime(s, UINT64_C( 1)); } static constexpr ptime from_hz(const internal_type hz) noexcept { return ptime(1 , hz); } static constexpr ptime from_raw(const internal_type raw) noexcept { return ptime(raw); } static constexpr ptime from_double(const double t) noexcept { return ptime(static_cast( t * static_cast(RES)), RES); } @@ -125,6 +118,11 @@ namespace netlist static constexpr ptime never() noexcept { return ptime(plib::numeric_limits::max(), RES); } static constexpr internal_type resolution() noexcept { return RES; } + constexpr internal_type in_nsec() const noexcept { return m_time / (RES / UINT64_C(1000000000)); } + constexpr internal_type in_usec() const noexcept { return m_time / (RES / UINT64_C( 1000000)); } + constexpr internal_type in_msec() const noexcept { return m_time / (RES / UINT64_C( 1000)); } + constexpr internal_type in_sec() const noexcept { return m_time / (RES / UINT64_C( 1)); } + private: static constexpr const double inv_res = 1.0 / static_cast(RES); internal_type m_time; @@ -133,16 +131,26 @@ namespace netlist #if (PHAS_INT128) using netlist_time = ptime; #else - using netlist_time = ptime; + using netlist_time = ptime; static_assert(noexcept(netlist_time::from_nsec(1)) == true, "Not evaluated as constexpr"); #endif -} + + //============================================================ + // MACROS + //============================================================ + + template inline constexpr netlist_time NLTIME_FROM_NS(T &&t) { return netlist_time::from_nsec(t); } + template inline constexpr netlist_time NLTIME_FROM_US(T &&t) { return netlist_time::from_usec(t); } + template inline constexpr netlist_time NLTIME_FROM_MS(T &&t) { return netlist_time::from_msec(t); } + +} // namespace netlist namespace plib { -template<> inline void state_manager_t::save_item(const void *owner, netlist::netlist_time &nlt, const pstring &stname) -{ - save_state_ptr(owner, stname, datatype_t(sizeof(netlist::netlist_time::internal_type), true, false), 1, nlt.get_internaltype_ptr()); -} -} + + template<> inline void state_manager_t::save_item(const void *owner, netlist::netlist_time &nlt, const pstring &stname) + { + save_state_ptr(owner, stname, datatype_t(sizeof(netlist::netlist_time::internal_type), true, false), 1, nlt.get_internaltype_ptr()); + } +} // namespace plib #endif /* NLTIME_H_ */ diff --git a/src/lib/netlist/plib/gmres.h b/src/lib/netlist/plib/gmres.h index edda011dc19..352ce721722 100644 --- a/src/lib/netlist/plib/gmres.h +++ b/src/lib/netlist/plib/gmres.h @@ -8,9 +8,9 @@ #ifndef PLIB_GMRES_H_ #define PLIB_GMRES_H_ -#include "pconfig.h" #include "mat_cr.h" #include "parray.h" +#include "pconfig.h" #include "vector_ops.h" #include @@ -246,13 +246,13 @@ namespace plib if (rho < rho_delta) return itr_used + 1; - vec_set_scalar(RESTART+1, m_g, NL_FCONST(0.0)); + vec_set_scalar(RESTART+1, m_g, constants::zero); m_g[0] = rho; //for (std::size_t i = 0; i < mr + 1; i++) // vec_set_scalar(mr, m_ht[i], NL_FCONST(0.0)); - vec_mult_scalar(n, residual, NL_FCONST(1.0) / rho, m_v[0]); + vec_mult_scalar(n, residual, constants::one / rho, m_v[0]); for (std::size_t k = 0; k < RESTART; k++) { @@ -269,7 +269,7 @@ namespace plib m_ht[kp1][k] = std::sqrt(vec_mult2(n, m_v[kp1])); if (m_ht[kp1][k] != 0.0) - vec_scale(n, m_v[kp1], NL_FCONST(1.0) / m_ht[kp1][k]); + vec_scale(n, m_v[kp1], constants::one / m_ht[kp1][k]); for (std::size_t j = 0; j < k; j++) givens_mult(m_c[j], m_s[j], m_ht[j][k], m_ht[j+1][k]); diff --git a/src/lib/netlist/plib/mat_cr.h b/src/lib/netlist/plib/mat_cr.h index 9490a07f367..7bb81e3c8e4 100644 --- a/src/lib/netlist/plib/mat_cr.h +++ b/src/lib/netlist/plib/mat_cr.h @@ -11,16 +11,18 @@ #define MAT_CR_H_ #include -#include #include -#include #include #include +#include +#include -#include "pconfig.h" #include "palloc.h" -#include "pstate.h" #include "parray.h" +#include "pconfig.h" +#include "pomp.h" +#include "pstate.h" +#include "putil.h" namespace plib { @@ -62,9 +64,7 @@ namespace plib A[i] = 0; } - ~matrix_compressed_rows_t() - { - } + ~matrix_compressed_rows_t() = default; index_type size() const { return m_size; } @@ -285,7 +285,7 @@ namespace plib template - void mult_vec(VTR & RESTRICT res, const VTV & RESTRICT x) + void mult_vec(VTR & res, const VTV & x) { /* * res = A * x @@ -513,6 +513,6 @@ namespace plib index_type m_size; }; -} +} // namespace plib #endif /* MAT_CR_H_ */ diff --git a/src/lib/netlist/plib/palloc.cpp b/src/lib/netlist/plib/palloc.cpp index 80fd2098a66..ab5b14d0618 100644 --- a/src/lib/netlist/plib/palloc.cpp +++ b/src/lib/netlist/plib/palloc.cpp @@ -7,8 +7,8 @@ #include "pconfig.h" #include "palloc.h" -#include "pfmtlog.h" #include "pexception.h" +#include "pfmtlog.h" #include @@ -37,7 +37,7 @@ mempool::~mempool() mempool::block * mempool::new_block() { - block *b = new block(); + auto *b = new block(); b->data = static_cast(::operator new(m_min_alloc)); b->cur_ptr = b->data; b->m_free = m_min_alloc; @@ -92,7 +92,7 @@ void mempool::free(void *ptr) auto i = reinterpret_cast(p - mininfosize()); block *b = i->m_block; if (b->m_num_alloc == 0) - plib::pexception("mempool::free - double free was called\n"); + throw plib::pexception("mempool::free - double free was called\n"); else { //b->m_free = m_min_alloc; @@ -101,4 +101,4 @@ void mempool::free(void *ptr) b->m_num_alloc--; } -} +} // namespace plib diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index de992b7bc50..e8d82277ed9 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -111,7 +111,7 @@ public: static owned_ptr Create(Args&&... args) { owned_ptr a; - DC *x = new DC(std::forward(args)...); + auto *x = new DC(std::forward(args)...); a.m_ptr = static_cast(x); return std::move(a); } @@ -176,6 +176,6 @@ public: }; -} +} // namespace plib #endif /* PALLOC_H_ */ diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h index df3f85ea927..6fc9cc430b2 100644 --- a/src/lib/netlist/plib/parray.h +++ b/src/lib/netlist/plib/parray.h @@ -11,11 +11,11 @@ #include "pconfig.h" #include "pexception.h" +#include #include +#include #include #include -#include -#include namespace plib { @@ -112,6 +112,6 @@ namespace plib { base_type m_a; size_type m_size; }; -} +} // namespace plib #endif /* PARRAY_H_ */ diff --git a/src/lib/netlist/plib/pchrono.cpp b/src/lib/netlist/plib/pchrono.cpp index 971d19b3645..953d948e062 100644 --- a/src/lib/netlist/plib/pchrono.cpp +++ b/src/lib/netlist/plib/pchrono.cpp @@ -49,5 +49,5 @@ exact_ticks::type exact_ticks::per_second() #endif -} -} +} // namespace chrono +} // namespace plib diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h index c3ea4ba9535..76f18bf4a83 100644 --- a/src/lib/netlist/plib/pchrono.h +++ b/src/lib/netlist/plib/pchrono.h @@ -10,8 +10,8 @@ #include "pconfig.h" -#include #include +#include namespace plib { namespace chrono { @@ -174,7 +174,10 @@ namespace chrono { struct guard_t { - guard_t(timer &m) : m_m(m) { m_m.m_time -= T::start();; } + guard_t() = delete; + guard_t(const guard_t &g) noexcept = default; + guard_t(guard_t &&g) noexcept = default; + guard_t(timer &m) noexcept : m_m(m) { m_m.m_time -= T::start(); } ~guard_t() { m_m.m_time += T::stop(); ++m_m.m_count; } private: timer &m_m; @@ -208,8 +211,14 @@ namespace chrono { struct guard_t { - guard_t() {} - ~guard_t() {} + guard_t() = default; + guard_t(const guard_t &g) noexcept = default; + guard_t(guard_t &&g) noexcept = default; + /* using default constructor will trigger warning on + * unused local variable. + */ + // NOLINTNEXTLINE(modernize-use-equals-default) + ~guard_t() { } }; constexpr type operator()() const { return 0; } diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 731ae1f18fd..71a5f25e0e8 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -76,15 +76,6 @@ typedef __uint128_t UINT128; typedef __int128_t INT128; #endif -#if defined(__GNUC__) -#ifdef RESTRICT -#undef RESTRICT -#endif -#define RESTRICT __restrict__ -#else -#define RESTRICT -#endif - //============================================================ // Standard defines //============================================================ diff --git a/src/lib/netlist/plib/pdynlib.cpp b/src/lib/netlist/plib/pdynlib.cpp index 13827eaf24c..f30ddc5d59a 100644 --- a/src/lib/netlist/plib/pdynlib.cpp +++ b/src/lib/netlist/plib/pdynlib.cpp @@ -91,6 +91,8 @@ dynlib::dynlib(const pstring libname) dynlib::dynlib(const pstring path, const pstring libname) : m_isLoaded(false), m_lib(nullptr) { + // FIXME: implement path search + plib::unused_var(path); // printf("win: loading <%s>\n", libname.c_str()); #ifdef _WIN32 TCHAR *buffer = tstring_from_utf8(libname.c_str()); @@ -148,4 +150,4 @@ void *dynlib::getsym_p(const pstring name) #endif } -} +} // namespace plib diff --git a/src/lib/netlist/plib/pdynlib.h b/src/lib/netlist/plib/pdynlib.h index 7c9412593c9..0ab498436b3 100644 --- a/src/lib/netlist/plib/pdynlib.h +++ b/src/lib/netlist/plib/pdynlib.h @@ -64,6 +64,6 @@ private: calltype m_sym; }; -} +} // namespace plib #endif /* PSTRING_H_ */ diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp index a4ed8f367e0..d26fc8fd12e 100644 --- a/src/lib/netlist/plib/pexception.cpp +++ b/src/lib/netlist/plib/pexception.cpp @@ -26,74 +26,48 @@ pexception::pexception(const pstring &text) { } -pexception::~pexception() noexcept -{ -} file_e::file_e(const pstring &fmt, const pstring &filename) : pexception(pfmt(fmt)(filename)) { } -file_e::~file_e() noexcept -{ -} file_open_e::file_open_e(const pstring &filename) : file_e("File open failed: {}", filename) { } -file_open_e::~file_open_e() noexcept -{ - -} file_read_e::file_read_e(const pstring &filename) : file_e("File read failed: {}", filename) { } -file_read_e::~file_read_e() noexcept -{ - -} file_write_e::file_write_e(const pstring &filename) : file_e("File write failed: {}", filename) { } -file_write_e::~file_write_e() noexcept -{ -} null_argument_e::null_argument_e(const pstring &argument) : pexception(pfmt("Null argument passed: {}")(argument)) { } -null_argument_e::~null_argument_e() noexcept -{ -} out_of_mem_e::out_of_mem_e(const pstring &location) : pexception(pfmt("Out of memory: {}")(location)) { } -out_of_mem_e::~out_of_mem_e() noexcept -{ -} fpexception_e::fpexception_e(const pstring &text) : pexception(pfmt("Out of memory: {}")(text)) { } -fpexception_e::~fpexception_e() noexcept -{ -} bool fpsignalenabler::m_enable = false; @@ -140,4 +114,4 @@ bool fpsignalenabler::global_enable(bool enable) } -} +} // namespace plib diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h index 1a5957099fd..7c798112c69 100644 --- a/src/lib/netlist/plib/pexception.h +++ b/src/lib/netlist/plib/pexception.h @@ -8,10 +8,11 @@ #ifndef PEXCEPTION_H_ #define PEXCEPTION_H_ -#include "pstring.h" - #include +#include "pstring.h" +#include "ptypes.h" + namespace plib { //============================================================ // exception base @@ -21,9 +22,6 @@ class pexception : public std::exception { public: explicit pexception(const pstring &text); - pexception(const pexception &e) : std::exception(e), m_text(e.m_text) { } - - virtual ~pexception() noexcept override; const pstring &text() { return m_text; } const char* what() const noexcept override { return m_text.c_str(); } @@ -36,48 +34,36 @@ class file_e : public plib::pexception { public: file_e(const pstring &fmt, const pstring &filename); - file_e(const file_e &e) : pexception(e) { } - virtual ~file_e() noexcept; }; class file_open_e : public file_e { public: explicit file_open_e(const pstring &filename); - file_open_e(const file_open_e &e) : file_e(e) { } - virtual ~file_open_e() noexcept; }; class file_read_e : public file_e { public: explicit file_read_e(const pstring &filename); - file_read_e(const file_read_e &e) : file_e(e) { } - virtual ~file_read_e() noexcept; }; class file_write_e : public file_e { public: explicit file_write_e(const pstring &filename); - file_write_e(const file_write_e &e) : file_e(e) { } - virtual ~file_write_e() noexcept; }; class null_argument_e : public plib::pexception { public: explicit null_argument_e(const pstring &argument); - null_argument_e(const null_argument_e &e) : pexception(e) { } - virtual ~null_argument_e() noexcept; }; class out_of_mem_e : public plib::pexception { public: explicit out_of_mem_e(const pstring &location); - out_of_mem_e(const out_of_mem_e &e) : pexception(e) { } - virtual ~out_of_mem_e() noexcept; }; /* FIXME: currently only a stub for later use. More use could be added by @@ -88,8 +74,6 @@ class fpexception_e : public pexception { public: explicit fpexception_e(const pstring &text); - fpexception_e(const fpexception_e &e) : pexception(e) { } - virtual ~fpexception_e() noexcept; }; static constexpr unsigned FP_INEXACT = 0x0001; @@ -103,7 +87,7 @@ static constexpr unsigned FP_ALL = 0x0001f; * Catch SIGFPE on linux for debugging purposes. */ -class fpsignalenabler +class fpsignalenabler : public nocopyassignmove { public: explicit fpsignalenabler(unsigned fpexceptions); @@ -121,6 +105,6 @@ private: }; -} +} // namespace plib #endif /* PEXCEPTION_H_ */ diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp index 2c120f6b7a4..f142a0cd73f 100644 --- a/src/lib/netlist/plib/pfmtlog.cpp +++ b/src/lib/netlist/plib/pfmtlog.cpp @@ -8,18 +8,19 @@ #include "pfmtlog.h" #include "palloc.h" -#include -#include -#include #include -#include +#include +#include +#include #include +#include namespace plib { pfmt &pfmt::format_element(const char *l, const unsigned cfmt_spec, ...) { va_list ap; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) va_start(ap, cfmt_spec); pstring fmt("%"); char buf[2048]; // FIXME @@ -87,4 +88,4 @@ pfmt &pfmt::format_element(const char *l, const unsigned cfmt_spec, ...) return *this; } -} +} // namespace plib diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index 9b7a85d8d8d..bf9d45fadd2 100644 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -136,7 +136,6 @@ struct ptype_traits : ptype_traits_base static char32_t fmt_spec() { return 'f'; } }; - template<> struct ptype_traits : ptype_traits_base { @@ -144,6 +143,13 @@ struct ptype_traits : ptype_traits_base static char32_t fmt_spec() { return 's'; } }; +template<> +struct ptype_traits : ptype_traits_base +{ + static const char *cast(const std::string &x) { return x.c_str(); } + static char32_t fmt_spec() { return 's'; } +}; + class pfmt { public: @@ -151,44 +157,50 @@ public: : m_str(fmt), m_arg(0) { } - - pfmt(const pfmt &rhs) : m_str(rhs.m_str), m_arg(rhs.m_arg) { } - - ~pfmt() - { - } + pfmt(const pfmt &rhs) = default; + ~pfmt() = default; operator pstring() const { return m_str; } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) pfmt & e(const double &x) {return format_element("", 'e', x); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) pfmt & g(const double &x) {return format_element("", 'g', x); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) pfmt & e(const float &x) {return format_element("", 'e', static_cast(x)); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) pfmt & g(const float &x) {return format_element("", 'g', static_cast(x)); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) pfmt &operator ()(const void *x) {return format_element("", 'p', x); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) pfmt &operator ()(const pstring &x) {return format_element("", 's', x.c_str() ); } template pfmt &operator ()(const T &x) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) return format_element(ptype_traits::size_spec(), ptype_traits::fmt_spec(), ptype_traits::cast(x)); } template pfmt &operator ()(const T *x) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) return format_element(ptype_traits::size_spec(), ptype_traits::fmt_spec(), ptype_traits::cast(x)); } template pfmt &x(const T &x) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) return format_element(ptype_traits::size_spec(), 'x', x); } template pfmt &o(const T &x) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) return format_element(ptype_traits::size_spec(), 'o', x); } @@ -237,7 +249,7 @@ public: bool is_enabled() const { return m_enabled; } protected: - ~pfmt_writer_t() { } + ~pfmt_writer_t() = default; private: pfmt &xlog(pfmt &fmt) const { return fmt; } @@ -258,7 +270,7 @@ class plog_channel : public pfmt_writer_t, bui friend class pfmt_writer_t, build_enabled>; public: explicit plog_channel(T &b) : pfmt_writer_t(), m_base(b) { } - ~plog_channel() { } + ~plog_channel() = default; protected: void vdowrite(const pstring &ls) const @@ -283,7 +295,7 @@ public: error(proxy), fatal(proxy) {} - virtual ~plog_base() {} + virtual ~plog_base() = default; plog_channel debug; plog_channel info; @@ -293,7 +305,7 @@ public: plog_channel fatal; }; -} +} // namespace plib template plib::pfmt& operator<<(plib::pfmt &p, T&& val) { return p(std::forward(val)); } diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp index 3a1ef9d841b..fc8f7248470 100644 --- a/src/lib/netlist/plib/pfunction.cpp +++ b/src/lib/netlist/plib/pfunction.cpp @@ -6,9 +6,9 @@ */ #include "pfunction.h" +#include "pexception.h" #include "pfmtlog.h" #include "putil.h" -#include "pexception.h" #include #include @@ -56,7 +56,7 @@ void pfunction::compile_postfix(const std::vector &inputs, { rc.m_cmd = RAND; stk += 1; } else { - for (unsigned i = 0; i < inputs.size(); i++) + for (std::size_t i = 0; i < inputs.size(); i++) { if (inputs[i] == cmd) { @@ -117,7 +117,7 @@ void pfunction::compile_infix(const std::vector &inputs, const pstring std::stack opstk; std::vector postfix; - for (unsigned i = 0; i < sexpr.size(); i++) + for (std::size_t i = 0; i < sexpr.size(); i++) { pstring &s = sexpr[i]; if (s=="(") @@ -181,14 +181,15 @@ void pfunction::compile_infix(const std::vector &inputs, const pstring #define OP(OP, ADJ, EXPR) \ case OP: \ - ptr-=ADJ; \ - stack[ptr-1] = EXPR; \ + ptr-= (ADJ); \ + stack[ptr-1] = (EXPR); \ break; double pfunction::evaluate(const std::vector &values) { double stack[20]; unsigned ptr = 0; + stack[0] = 0.0; for (auto &rc : m_precompiled) { switch (rc.m_cmd) @@ -214,4 +215,4 @@ double pfunction::evaluate(const std::vector &values) return stack[ptr-1]; } -} +} // namespace plib diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h index 7d5984f9d15..fbb6c508333 100644 --- a/src/lib/netlist/plib/pfunction.h +++ b/src/lib/netlist/plib/pfunction.h @@ -8,8 +8,8 @@ #ifndef PFUNCTION_H_ #define PFUNCTION_H_ -#include "pstring.h" #include "pstate.h" +#include "pstring.h" #include @@ -112,6 +112,6 @@ namespace plib { }; -} +} // namespace plib #endif /* PEXCEPTION_H_ */ diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h index 19e65cb7cdc..3ba7dd2fb4f 100644 --- a/src/lib/netlist/plib/plists.h +++ b/src/lib/netlist/plib/plists.h @@ -32,9 +32,7 @@ public: typedef C* iterator; typedef const C* const_iterator; - uninitialised_array_t() - { - } + uninitialised_array_t() = default; ~uninitialised_array_t() { @@ -202,8 +200,8 @@ public: explicit constexpr iter_t(LC* x) noexcept : p(x) { } explicit constexpr iter_t(iter_t &rhs) noexcept : p(rhs.p) { } iter_t(iter_t &&rhs) noexcept { std::swap(*this, rhs); } - iter_t& operator=(iter_t &rhs) { iter_t t(rhs); std::swap(*this, t); return *this; } - iter_t& operator=(iter_t &&rhs) { std::swap(*this, rhs); return *this; } + iter_t& operator=(const iter_t &rhs) { iter_t t(rhs); std::swap(*this, t); return *this; } + iter_t& operator=(iter_t &&rhs) noexcept { std::swap(*this, rhs); return *this; } iter_t& operator++() noexcept {p = p->next();return *this;} iter_t operator++(int) noexcept {iter_t tmp(*this); operator++(); return tmp;} constexpr bool operator==(const iter_t& rhs) const noexcept {return p == rhs.p;} @@ -265,6 +263,6 @@ private: LC *m_head; }; #endif -} +} // namespace plib #endif /* PLISTS_H_ */ diff --git a/src/lib/netlist/plib/pmain.cpp b/src/lib/netlist/plib/pmain.cpp index 30b4a1948bd..25022ed9734 100644 --- a/src/lib/netlist/plib/pmain.cpp +++ b/src/lib/netlist/plib/pmain.cpp @@ -43,11 +43,6 @@ namespace plib { } - app::~app() - { - - } - int app::main_utfX(int argc, char *argv[]) { auto r = this->parse(argc, argv); diff --git a/src/lib/netlist/plib/pmain.h b/src/lib/netlist/plib/pmain.h index e2f84b90de6..78e5213713f 100644 --- a/src/lib/netlist/plib/pmain.h +++ b/src/lib/netlist/plib/pmain.h @@ -11,12 +11,12 @@ #define PMAIN_H_ #include "poptions.h" +#include "pstream.h" #include "pstring.h" #include "putil.h" -#include "pstream.h" -#include #include +#include #ifdef _WIN32 #define PMAIN(appclass) \ @@ -36,7 +36,7 @@ namespace plib { { public: app(); - virtual ~app(); + virtual ~app() = default; virtual pstring usage() = 0; virtual int execute() = 0; @@ -62,7 +62,7 @@ namespace plib { }; -} +} // namespace plib diff --git a/src/lib/netlist/plib/pomp.h b/src/lib/netlist/plib/pomp.h index 19b39466025..d86326f4594 100644 --- a/src/lib/netlist/plib/pomp.h +++ b/src/lib/netlist/plib/pomp.h @@ -47,6 +47,8 @@ inline void set_num_threads(const std::size_t threads) { #if HAS_OPENMP && USE_OPENMP omp_set_num_threads(threads); +#else + plib::unused_var(threads); #endif } @@ -64,7 +66,7 @@ inline std::size_t get_max_threads() // pdynlib: dynamic loading of libraries ... // ---------------------------------------------------------------------------------------- -} -} +} // namespace omp +} // namespace plib #endif /* PSTRING_H_ */ diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index dcb8e3931f3..84e08715ec3 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -6,8 +6,8 @@ */ #include "poptions.h" -#include "ptypes.h" #include "pexception.h" +#include "ptypes.h" namespace plib { /*************************************************************************** @@ -20,28 +20,12 @@ namespace plib { parent.register_option(this); } - option_base::~option_base() - { - } - - option_group::~option_group() - { - } - - option_example::~option_example() - { - } - option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument) : option_base(parent, help), m_short(ashort), m_long(along), m_has_argument(has_argument), m_specified(false) { } - option::~option() - { - } - int option_str::parse(const pstring &argument) { m_val = argument; @@ -92,12 +76,12 @@ namespace plib { { for (auto &opt : m_opts) { - option *o = dynamic_cast