From f12f735f54966b992d23d0502027e8e6d9e1dd95 Mon Sep 17 00:00:00 2001 From: couriersud Date: Fri, 11 Jan 2019 21:50:43 +0100 Subject: Fix clang-8 warnings. (nw) --- src/lib/netlist/plib/pomp.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/lib/netlist/plib/pomp.h') diff --git a/src/lib/netlist/plib/pomp.h b/src/lib/netlist/plib/pomp.h index 6559207f09d..221c0d61c00 100644 --- a/src/lib/netlist/plib/pomp.h +++ b/src/lib/netlist/plib/pomp.h @@ -18,8 +18,8 @@ namespace plib { namespace omp { -template -void for_static(const int start, const int end, const T &what) +template +void for_static(const I start, const I end, const T &what) { #if HAS_OPENMP && USE_OPENMP #pragma omp parallel @@ -28,19 +28,19 @@ void for_static(const int start, const int end, const T &what) #if HAS_OPENMP && USE_OPENMP #pragma omp for schedule(static) #endif - for (int i = start; i < end; i++) + for (I i = start; i < end; i++) what(i); } } -inline void set_num_threads(const int threads) +inline void set_num_threads(const std::size_t threads) { #if HAS_OPENMP && USE_OPENMP omp_set_num_threads(threads); #endif } -inline int get_max_threads() +inline std::size_t get_max_threads() { #if HAS_OPENMP && USE_OPENMP return omp_get_max_threads(); -- cgit v1.2.3-70-g09d2 From 0a17d35c13f770e8b69fb0a68f1485631dfc3578 Mon Sep 17 00:00:00 2001 From: couriersud Date: Sun, 13 Jan 2019 19:57:39 +0100 Subject: netlist: Fix logging during object construction. (nw) --- src/devices/machine/netlist.cpp | 37 +++++++++++++++++--------- src/devices/machine/netlist.h | 1 + src/lib/netlist/analog/nlid_twoterm.h | 20 +++++++++----- src/lib/netlist/netlist_types.h | 28 ++++++++++++++++++++ src/lib/netlist/nl_base.cpp | 13 ++++----- src/lib/netlist/nl_base.h | 50 ++++++++++++----------------------- src/lib/netlist/nl_setup.cpp | 4 +-- src/lib/netlist/nl_setup.h | 4 +-- src/lib/netlist/plib/pomp.h | 2 ++ src/lib/netlist/plib/pparser.cpp | 2 +- src/lib/netlist/prg/nltool.cpp | 24 ++++++++++++----- src/lib/netlist/solver/nld_solver.cpp | 2 +- 12 files changed, 114 insertions(+), 73 deletions(-) (limited to 'src/lib/netlist/plib/pomp.h') diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 137c9e6cf6c..ffd99d5437a 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -49,21 +49,16 @@ DEFINE_DEVICE_TYPE(NETLIST_STREAM_OUTPUT, netlist_mame_stream_output_device, "nl // Special netlist extension devices .... // ---------------------------------------------------------------------------------------- -class netlist_mame_device::netlist_mame_t : public netlist::netlist_t +class netlist_mame_device::netlist_mame_callbacks_t : public netlist::callbacks_t { public: - netlist_mame_t(netlist_mame_device &parent, const pstring &aname) - : netlist::netlist_t(aname) + netlist_mame_callbacks_t(netlist_mame_device &parent) + : netlist::callbacks_t() , m_parent(parent) { } - running_machine &machine() { return m_parent.machine(); } - - - netlist_mame_device &parent() { return m_parent; } - protected: void vlog(const plib::plog_level &l, const pstring &ls) const override { @@ -95,6 +90,24 @@ private: }; +class netlist_mame_device::netlist_mame_t : public netlist::netlist_t +{ +public: + + netlist_mame_t(netlist_mame_device &parent, const pstring &aname) + : netlist::netlist_t(aname, plib::make_unique(parent)) + , m_parent(parent) + { + } + + running_machine &machine() { return m_parent.machine(); } + netlist_mame_device &parent() { return m_parent; } + +private: + netlist_mame_device &m_parent; +}; + + namespace { // ---------------------------------------------------------------------------------------- @@ -173,7 +186,7 @@ public: NETLIB_UPDATEI() { - netlist_sig_t cur = m_in(); + netlist::netlist_sig_t cur = m_in(); // FIXME: make this a parameter // avoid calls due to noise @@ -190,7 +203,7 @@ private: netlist::logic_input_t m_in; netlist_mame_logic_output_device::output_delegate m_callback; netlist_mame_cpu_device *m_cpu_device; - netlist::state_var m_last; + netlist::state_var m_last; }; // ---------------------------------------------------------------------------------------- @@ -505,7 +518,7 @@ void netlist_mame_cpu_device::state_string_export(const device_state_entry &entr if (entry.index() & 1) str = string_format("%10.6f", *((double *)entry.dataptr())); else - str = string_format("%d", *((netlist_sig_t *)entry.dataptr())); + str = string_format("%d", *((netlist::netlist_sig_t *)entry.dataptr())); } } @@ -837,8 +850,6 @@ void netlist_mame_device::device_start() m_netlist = global_alloc(netlist_mame_t(*this, "netlist")); - m_netlist->load_base_libraries(); - // register additional devices nl_register_devices(); diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index b400acdf32a..dbd862a12e2 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -99,6 +99,7 @@ class netlist_mame_device : public device_t { public: class netlist_mame_t; + class netlist_mame_callbacks_t; // construction/destruction netlist_mame_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h index 624dd98e558..4ab5fcda89b 100644 --- a/src/lib/netlist/analog/nlid_twoterm.h +++ b/src/lib/netlist/analog/nlid_twoterm.h @@ -48,6 +48,20 @@ namespace netlist // nld_twoterm // ----------------------------------------------------------------------------- + template + inline core_device_t &bselect(bool b, C &d1, core_device_t &d2) + { + core_device_t *h = dynamic_cast(&d1); + return b ? *h : d2; + } + template<> + inline core_device_t &bselect(bool b, netlist_t &d1, core_device_t &d2) + { + if (b) + throw nl_exception("bselect with netlist and b==true"); + return d2; + } + NETLIB_OBJECT(twoterm) { NETLIB_CONSTRUCTOR_EX(twoterm, bool terminals_owned = false) @@ -87,12 +101,6 @@ public: } private: - template - static core_device_t &bselect(bool b, C &d1, core_device_t &d2) - { - core_device_t *h = dynamic_cast(&d1); - return b ? *h : d2; - } }; diff --git a/src/lib/netlist/netlist_types.h b/src/lib/netlist/netlist_types.h index d5fe7b11e20..bbca9949e49 100644 --- a/src/lib/netlist/netlist_types.h +++ b/src/lib/netlist/netlist_types.h @@ -12,12 +12,40 @@ #include "nl_config.h" #include "plib/pchrono.h" #include "plib/pstring.h" +#include "plib/pfmtlog.h" #include #include namespace netlist { + /*! @brief netlist_sig_t is the type used for logic signals. + * + * This may be any of bool, uint8_t, uint16_t, uin32_t and uint64_t. + * The choice has little to no impact on performance. + */ + using netlist_sig_t = std::uint32_t; + + /** + * @brief Interface definition for netlist callbacks into calling code + * + * A class inheriting from netlist_callbacks_t has to be passed to the netlist_t + * constructor. Netlist does processing during construction and thus needs + * the object passed completely constructed. + * + */ + class callbacks_t + { + public: + virtual ~callbacks_t() {} + + /* logging callback */ + virtual void vlog(const plib::plog_level &l, const pstring &ls) const = 0; + }; + + using log_type = plib::plog_base; + + //============================================================ // Performance tracking //============================================================ diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 6a8ac148151..4bdec442f17 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -239,20 +239,22 @@ detail::terminal_type detail::core_terminal_t::type() const // netlist_t // ---------------------------------------------------------------------------------------- -netlist_t::netlist_t(const pstring &aname) +netlist_t::netlist_t(const pstring &aname, std::unique_ptr callbacks) : m_time(netlist_time::zero()) , m_queue(*this) , m_mainclock(nullptr) , m_solver(nullptr) , m_params(nullptr) , m_name(aname) - , m_log(*this) , m_lib(nullptr) , m_state() + , m_callbacks(std::move(callbacks)) // Order is important here + , m_log(*m_callbacks) { state().save_item(this, static_cast(m_queue), "m_queue"); state().save_item(this, m_time, "m_time"); m_setup = plib::make_unique(*this); + NETLIST_NAME(base)(*m_setup); } netlist_t::~netlist_t() @@ -261,11 +263,6 @@ netlist_t::~netlist_t() m_devices.clear(); } -void netlist_t::load_base_libraries() -{ - NETLIST_NAME(base)(*m_setup); -} - nl_double netlist_t::gmin() const NL_NOEXCEPT { return solver()->gmin(); @@ -694,7 +691,7 @@ void core_device_t::set_default_delegate(detail::core_terminal_t &term) term.m_delegate.set(&core_device_t::update, this); } -plib::plog_base &core_device_t::log() +log_type & core_device_t::log() { return netlist().log(); } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 24129821b4b..6e4f9c50543 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -9,6 +9,11 @@ #ifndef NLBASE_H_ #define NLBASE_H_ +#ifdef NL_PROHIBIT_BASEH_INCLUDE +#error "nl_base.h included. Please correct." +#endif + +#include "netlist_types.h" #include "nl_lists.h" #include "nl_time.h" #include "plib/palloc.h" // owned_ptr @@ -20,21 +25,6 @@ #include -#ifdef NL_PROHIBIT_BASEH_INCLUDE -#error "nl_base.h included. Please correct." -#endif - -// ---------------------------------------------------------------------------------------- -// Type definitions -// ---------------------------------------------------------------------------------------- - -/*! @brief netlist_sig_t is the type used for logic signals. - * - * This may be any of bool, uint8_t, uint16_t, uin32_t and uint64_t. - * The choice has little to no impact on performance. - */ -using netlist_sig_t = std::uint32_t; - //============================================================ // MACROS / New Syntax //============================================================ @@ -221,6 +211,7 @@ namespace netlist class netlist_t; class core_device_t; class device_t; + class callbacks_t; //============================================================ // Exceptions @@ -1115,7 +1106,7 @@ namespace netlist update(); } - plib::plog_base &log(); + log_type & log(); public: virtual void timestep(const nl_double st) { plib::unused_var(st); } @@ -1178,6 +1169,7 @@ namespace netlist // ----------------------------------------------------------------------------- // nld_base_dummy : basis for dummy devices + // FIXME: this is not the right place to define this // ----------------------------------------------------------------------------- NETLIB_OBJECT(base_dummy) @@ -1223,16 +1215,8 @@ namespace netlist { public: - explicit netlist_t(const pstring &aname); - virtual ~netlist_t(); - - /** - * @brief Load base libraries for diodes, transistors ... - * - * This must be called after netlist_t is created. - * - */ - void load_base_libraries(); + explicit netlist_t(const pstring &aname, std::unique_ptr callbacks); + ~netlist_t(); /* run functions */ @@ -1292,8 +1276,9 @@ namespace netlist /* logging and name */ pstring name() const { return m_name; } - plib::plog_base &log() { return m_log; } - const plib::plog_base &log() const { return m_log; } + + log_type & log() { return m_log; } + const log_type &log() const { return m_log; } /* state related */ @@ -1319,9 +1304,6 @@ namespace netlist // FIXME: sort rebuild_lists out void rebuild_lists(); /* must be called after post_load ! */ - /* logging callback */ - virtual void vlog(const plib::plog_level &l, const pstring &ls) const = 0; - protected: void print_stats() const; @@ -1345,8 +1327,6 @@ namespace netlist devices::NETLIB_NAME(netlistparams) *m_params; pstring m_name; - std::unique_ptr m_setup; - plib::plog_base m_log; std::unique_ptr m_lib; // external lib needs to be loaded as long as netlist exists plib::state_manager_t m_state; @@ -1356,6 +1336,10 @@ namespace netlist nperfcount_t m_perf_out_processed; std::vector> m_devices; + + std::unique_ptr m_callbacks; + log_type m_log; + std::unique_ptr m_setup; }; // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index a02d5f5bbae..e876b2f7e8b 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -768,11 +768,11 @@ void setup_t::start_devices() } } -plib::plog_base &setup_t::log() +log_type &setup_t::log() { return netlist().log(); } -const plib::plog_base &setup_t::log() const +const log_type &setup_t::log() const { return netlist().log(); } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index cae829023a4..3894cad5415 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -288,8 +288,8 @@ namespace netlist /* helper - also used by nltool */ const pstring resolve_alias(const pstring &name) const; - plib::plog_base &log(); - const plib::plog_base &log() const; + log_type &log(); + const log_type &log() const; //std::vector> m_device_factory; std::unordered_map m_device_factory; diff --git a/src/lib/netlist/plib/pomp.h b/src/lib/netlist/plib/pomp.h index 221c0d61c00..f13df2539ac 100644 --- a/src/lib/netlist/plib/pomp.h +++ b/src/lib/netlist/plib/pomp.h @@ -9,6 +9,8 @@ #ifndef POMP_H_ #define POMP_H_ +#include + #include "pconfig.h" #if HAS_OPENMP diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp index f70001530c4..43ed9e14d41 100644 --- a/src/lib/netlist/plib/pparser.cpp +++ b/src/lib/netlist/plib/pparser.cpp @@ -318,7 +318,7 @@ void ppreprocessor::error(const pstring &err) int ppreprocessor::expr(const std::vector &sexpr, std::size_t &start, int prio) { - int val; + int val = 0; pstring tok=sexpr[start]; if (tok == "(") { diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index c7c3ac652fd..0a5fba22d9e 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -132,22 +132,35 @@ std::unique_ptr netlist_data_folder_t::stream(const pstring &fil return std::unique_ptr(nullptr); } +class netlist_tool_callbacks_t : public netlist::callbacks_t +{ +public: + netlist_tool_callbacks_t(tool_app_t &app) + : netlist::callbacks_t() + , m_app(app) + { } + + void vlog(const plib::plog_level &l, const pstring &ls) const override; + +private: + tool_app_t &m_app; +}; + class netlist_tool_t : public netlist::netlist_t { public: netlist_tool_t(tool_app_t &app, const pstring &aname) - : netlist::netlist_t(aname), m_app(app) + : netlist::netlist_t(aname, plib::make_unique(app)) { } - virtual ~netlist_tool_t() override + ~netlist_tool_t() { } void init() { - load_base_libraries(); } void read_netlist(const pstring &filename, const pstring &name, @@ -234,13 +247,10 @@ public: protected: - void vlog(const plib::plog_level &l, const pstring &ls) const override; - private: - tool_app_t &m_app; }; -void netlist_tool_t::vlog(const plib::plog_level &l, const pstring &ls) const +void netlist_tool_callbacks_t::vlog(const plib::plog_level &l, const pstring &ls) const { pstring err = plib::pfmt("{}: {}\n")(l.name())(ls.c_str()); // FIXME: ... diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 760b7088e67..f9de00d417d 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -104,7 +104,7 @@ NETLIB_UPDATE(solver) if (nthreads > 1 && solvers.size() > 1) { plib::omp::set_num_threads(nthreads); - plib::omp::for_static(static_cast(0), solvers.size(), [this, &solvers](std::size_t i) + plib::omp::for_static(static_cast(0), solvers.size(), [&solvers](std::size_t i) { const netlist_time ts = solvers[i]->solve(); plib::unused_var(ts); -- cgit v1.2.3-70-g09d2 From 1513c777b47d19c7df99ba43142d7a334392a0b5 Mon Sep 17 00:00:00 2001 From: couriersud Date: Wed, 30 Jan 2019 02:28:55 +0100 Subject: netlist: Refactoring continues ... plus some innovations (nw) Still some work ahead to separate interface from execution. This is a preparation to switch to another sparse matrix format easily which may be better suited for parallel processing. On the linear algebra side there are some nice additions: - Two additional sort modes: One tries to obtain a upper left identity matrix, the other prefers a diagonal band matrix structure. Both deliver slightly better performance than just sorting. - Parallel execution analysis for Gaussian elimination and LU solve. This determines which operations may be done independently. All of this is not really useful right now. The matrix sizes are below 100 nets. I estimate that we at least need four times more so that CPU parallel processing overhead pays off. For GPU, add another order. But it's nice to have code which may scale. --- src/lib/netlist/build/makefile | 2 +- src/lib/netlist/devices/nlid_truthtable.h | 15 +- src/lib/netlist/plib/gmres.h | 444 +++++++++++++++++++++++ src/lib/netlist/plib/mat_cr.h | 518 +++++++++++++++++++++++++++ src/lib/netlist/plib/pomp.h | 10 +- src/lib/netlist/plib/putil.h | 4 +- src/lib/netlist/plib/vector_ops.h | 115 ++++++ src/lib/netlist/prg/nltool.cpp | 7 - src/lib/netlist/solver/mat_cr.h | 432 ---------------------- src/lib/netlist/solver/nld_matrix_solver.cpp | 226 +++++++++--- src/lib/netlist/solver/nld_matrix_solver.h | 20 +- src/lib/netlist/solver/nld_ms_direct.h | 38 +- src/lib/netlist/solver/nld_ms_direct_lu.h | 14 +- src/lib/netlist/solver/nld_ms_gcr.h | 56 ++- src/lib/netlist/solver/nld_ms_gmres.h | 392 +++++--------------- src/lib/netlist/solver/nld_ms_sm.h | 23 +- src/lib/netlist/solver/nld_ms_sor.h | 26 +- src/lib/netlist/solver/nld_ms_sor_mat.h | 52 +-- src/lib/netlist/solver/nld_ms_w.h | 28 +- src/lib/netlist/solver/nld_solver.cpp | 2 +- src/lib/netlist/solver/nld_solver.h | 2 +- src/lib/netlist/solver/vector_base.h | 127 ------- src/mame/audio/nl_kidniki.cpp | 10 +- 23 files changed, 1490 insertions(+), 1073 deletions(-) create mode 100644 src/lib/netlist/plib/gmres.h create mode 100644 src/lib/netlist/plib/mat_cr.h create mode 100644 src/lib/netlist/plib/vector_ops.h delete mode 100644 src/lib/netlist/solver/mat_cr.h delete mode 100644 src/lib/netlist/solver/vector_base.h (limited to 'src/lib/netlist/plib/pomp.h') diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index e291737dd71..33618e346b5 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-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" + $(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" 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" diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h index 529c229f3b4..f0f85e037de 100644 --- a/src/lib/netlist/devices/nlid_truthtable.h +++ b/src/lib/netlist/devices/nlid_truthtable.h @@ -29,17 +29,9 @@ namespace netlist { - namespace devices - { +namespace devices +{ -#if 0 - template struct uint_for_size { typedef uint_least32_t type; }; - template - struct need_bytes_for_bits - { - enum { value = 4 }; - }; -#else template struct need_bytes_for_bits { @@ -56,7 +48,6 @@ namespace netlist template<> struct uint_for_size<2> { typedef uint_least16_t type; }; template<> struct uint_for_size<4> { typedef uint_least32_t type; }; template<> struct uint_for_size<8> { typedef uint_least64_t type; }; -#endif template struct aa @@ -270,7 +261,7 @@ namespace netlist void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile); - } //namespace devices +} //namespace devices } // namespace netlist diff --git a/src/lib/netlist/plib/gmres.h b/src/lib/netlist/plib/gmres.h new file mode 100644 index 00000000000..7a24de8e03f --- /dev/null +++ b/src/lib/netlist/plib/gmres.h @@ -0,0 +1,444 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * gmres.h + * + */ + +#ifndef PLIB_GMRES_H_ +#define PLIB_GMRES_H_ + +#include "pconfig.h" +#include "mat_cr.h" +#include "parray.h" +#include "vector_ops.h" + +#include +#include + + +namespace plib +{ + + template + struct mat_precondition_ILU + { + typedef plib::matrix_compressed_rows_t mat_type; + + mat_precondition_ILU(std::size_t size, int ilu_scale = 4 + , std::size_t bw = plib::matrix_compressed_rows_t::FILL_INFINITY) + : m_mat(static_cast(size)) + , m_LU(static_cast(size)) + , m_use_iLU_preconditioning(ilu_scale >= 0) + , m_ILU_scale(static_cast(ilu_scale)) + , m_band_width(bw) + { + } + + template + void build(M &fill) + { + m_mat.build_from_fill_mat(fill, 0); + if (m_use_iLU_preconditioning) + { + m_LU.gaussian_extend_fill_mat(fill); + m_LU.build_from_fill_mat(fill, m_ILU_scale, m_band_width); // ILU(2) + //m_LU.build_from_fill_mat(fill, 9999, 20); // Band matrix width 20 + } + } + + + template + void calc_rhs(R &rhs, const V &v) + { + m_mat.mult_vec(rhs, v); + } + + void precondition() + { + if (m_use_iLU_preconditioning) + { + if (m_ILU_scale < 1) + m_LU.raw_copy_from(m_mat); + else + m_LU.reduction_copy_from(m_mat); + m_LU.incomplete_LU_factorization(); + } + } + + template + void solve_LU_inplace(V &v) + { + if (m_use_iLU_preconditioning) + { + m_LU.solveLUx(v); + } + } + + mat_type m_mat; + mat_type m_LU; + bool m_use_iLU_preconditioning; + std::size_t m_ILU_scale; + std::size_t m_band_width; + }; + + template + struct mat_precondition_diag + { + mat_precondition_diag(std::size_t size) + : m_mat(size) + , m_diag(size) + , m_use_iLU_preconditioning(true) + { + } + + template + void build(M &fill) + { + m_mat.build_from_fill_mat(fill, 0); + } + + template + void calc_rhs(R &rhs, const V &v) + { + m_mat.mult_vec(rhs, v); + } + + void precondition() + { + if (m_use_iLU_preconditioning) + { + for (std::size_t i = 0; i< m_diag.size(); i++) + { + m_diag[i] = 1.0 / m_mat.A[m_mat.diag[i]]; + } + } + } + + template + void solve_LU_inplace(V &v) + { + if (m_use_iLU_preconditioning) + { + for (std::size_t i = 0; i< m_diag.size(); i++) + v[i] = v[i] * m_diag[i]; + } + } + + plib::matrix_compressed_rows_t m_mat; + plib::parray m_diag; + bool m_use_iLU_preconditioning; + }; + + /* FIXME: hardcoding RESTART to 20 becomes an issue on very large + * systems. + */ + template + struct gmres_t + { + public: + + typedef FT float_type; + // FIXME: dirty hack to make this compile + static constexpr const std::size_t storage_N = plib::sizeabs::ABS(); + + gmres_t(std::size_t size) + : m_use_more_precise_stop_condition(false) + , residual(size) + , Ax(size) + , m_size(size) + { + } + + void givens_mult( const FT c, const FT s, FT & g0, FT & g1 ) + { + const FT g0_last(g0); + + g0 = c * g0 - s * g1; + g1 = s * g0_last + c * g1; + } + + std::size_t size() const { return (SIZE<=0) ? m_size : static_cast(SIZE); } + + template + std::size_t solve(OPS &ops, VT &x, const VRHS & rhs, const std::size_t itr_max, float_type accuracy) + { + /*------------------------------------------------------------------------- + * The code below was inspired by code published by John Burkardt under + * the LPGL here: + * + * http://people.sc.fsu.edu/~jburkardt/cpp_src/mgmres/mgmres.html + * + * The code below was completely written from scratch based on the pseudo code + * found here: + * + * http://de.wikipedia.org/wiki/GMRES-Verfahren + * + * The Algorithm itself is described in + * + * Yousef Saad, + * Iterative Methods for Sparse Linear Systems, + * Second Edition, + * SIAM, 20003, + * ISBN: 0898715342, + * LC: QA188.S17. + * + *------------------------------------------------------------------------*/ + + std::size_t itr_used = 0; + double rho_delta = 0.0; + + const std::size_t n = size(); + + ops.precondition(); + + if (m_use_more_precise_stop_condition) + { + /* derive residual for a given delta x + * + * LU y = A dx + * + * ==> rho / accuracy = sqrt(y * y) + * + * This approach will approximate the iterative stop condition + * based |xnew - xold| pretty precisely. But it is slow, or expressed + * differently: The invest doesn't pay off. + */ + + vec_set_scalar(n, residual, accuracy); + ops.calc_rhs(Ax, residual); + + ops.solve_LU_inplace(Ax); + + const float_type rho_to_accuracy = std::sqrt(vec_mult2(n, Ax)) / accuracy; + + rho_delta = accuracy * rho_to_accuracy; + //printf("%e %e\n", rho_delta, accuracy * std::sqrt(static_cast(n))); + } + else + rho_delta = accuracy * std::sqrt(static_cast(n)); + + /* + * Using + * + * vec_set(n, x, rhs); + * ops.solve_LU_inplace(x); + * + * to get a starting point for x degrades convergence speed compared + * to using the last solution for x. + * + * LU x = b; solve for x; + * + */ + + while (itr_used < itr_max) + { + std::size_t last_k = RESTART; + float_type rho; + + ops.calc_rhs(Ax, x); + + vec_sub(n, rhs, Ax, residual); + + ops.solve_LU_inplace(residual); + + rho = std::sqrt(vec_mult2(n, residual)); + + if (rho < rho_delta) + return itr_used + 1; + + vec_set_scalar(RESTART+1, m_g, NL_FCONST(0.0)); + 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]); + + for (std::size_t k = 0; k < RESTART; k++) + { + const std::size_t kp1 = k + 1; + + ops.calc_rhs(m_v[kp1], m_v[k]); + ops.solve_LU_inplace(m_v[kp1]); + + for (std::size_t j = 0; j <= k; j++) + { + m_ht[j][k] = vec_mult(n, m_v[kp1], m_v[j]); + vec_add_mult_scalar(n, m_v[j], -m_ht[j][k], m_v[kp1]); + } + 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]); + + 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 float_type mu = 1.0 / std::hypot(m_ht[k][k], m_ht[kp1][k]); + + m_c[k] = m_ht[k][k] * mu; + m_s[k] = -m_ht[kp1][k] * mu; + m_ht[k][k] = m_c[k] * m_ht[k][k] - m_s[k] * m_ht[kp1][k]; + m_ht[kp1][k] = 0.0; + + givens_mult(m_c[k], m_s[k], m_g[k], m_g[kp1]); + + rho = std::abs(m_g[kp1]); + + itr_used = itr_used + 1; + + if (rho <= rho_delta) + { + last_k = k; + break; + } + } + + if (last_k >= RESTART) + /* didn't converge within accuracy */ + last_k = RESTART - 1; + + /* Solve the system H * y = g */ + /* x += m_v[j] * m_y[j] */ + for (std::size_t i = last_k + 1; i-- > 0;) + { + 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 (rho <= rho_delta) + break; + + } + return itr_used; + } + + private: + + bool m_use_more_precise_stop_condition; + + //typedef typename plib::mat_cr_t::index_type mattype; + + plib::parray residual; + plib::parray Ax; + + float_type m_c[RESTART + 1]; /* mr + 1 */ + float_type m_g[RESTART + 1]; /* mr + 1 */ + float_type m_ht[RESTART + 1][RESTART]; /* (mr + 1), mr */ + float_type m_s[RESTART + 1]; /* mr + 1 */ + float_type m_y[RESTART + 1]; /* mr + 1 */ + + //plib::parray m_v[RESTART + 1]; /* mr + 1, n */ + float_type m_v[RESTART + 1][storage_N]; /* mr + 1, n */ + + std::size_t m_size; + + }; + + +#if 0 + /* Example of a Chebyshev iteration solver. This one doesn't work yet, + * it needs to be extended for non-symmetric matrix operation and + * depends on spectral radius estimates - which we don't have. + * + * Left here as another example. + */ + + template + struct ch_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); + + ch_t(std::size_t size) + : residual(size) + , Ax(size) + , m_size(size) + { + } + + std::size_t size() const { return (SIZE<=0) ? m_size : static_cast(SIZE); } + + template + std::size_t solve(OPS &ops, VT &x0, const VRHS & rhs, const std::size_t iter_max, float_type accuracy) + { + /*------------------------------------------------------------------------- + * + * + *------------------------------------------------------------------------*/ + + ops.precondition(); + + const FT lmax = 20.0; + const FT lmin = 0.0001; + + const FT d = (lmax+lmin)/2.0; + const FT c = (lmax-lmin)/2.0; + FT alpha = 0; + FT beta = 0; + std::size_t itr_used = 0; + + plib::parray x(size()); + plib::parray p(size()); + + plib::vec_set(size(), x, x0); + + ops.calc_rhs(Ax, x); + vec_sub(size(), rhs, Ax, residual); + + FT rho_delta = accuracy * std::sqrt(static_cast(size())); + + rho_delta = 1e-9; + + for (int i = 0; i < iter_max; i++) + { + ops.solve_LU_inplace(residual); + if (i==0) + { + vec_set(size(), p, residual); + alpha = 2.0 / d; + } + else + { + beta = alpha * ( c / 2.0)*( c / 2.0); + alpha = 1.0 / (d - beta); + for (std::size_t k = 0; k < size(); k++) + p[k] = residual[k] + beta * p[k]; + } + plib::vec_add_mult_scalar(size(), p, alpha, x); + ops.calc_rhs(Ax, x); + plib::vec_sub(size(), rhs, Ax, residual); + FT rho = std::sqrt(plib::vec_mult2(size(), residual)); + if (rho < rho_delta) + break; + itr_used++; + } + return itr_used; + } + private: + + //typedef typename plib::mat_cr_t::index_type mattype; + + plib::parray residual; + plib::parray Ax; + + std::size_t m_size; + + }; +#endif + +} // namespace plib + +#endif /* PLIB_GMRES_H_ */ diff --git a/src/lib/netlist/plib/mat_cr.h b/src/lib/netlist/plib/mat_cr.h new file mode 100644 index 00000000000..9490a07f367 --- /dev/null +++ b/src/lib/netlist/plib/mat_cr.h @@ -0,0 +1,518 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * mat_cr.h + * + * Compressed row format matrices + * + */ + +#ifndef MAT_CR_H_ +#define MAT_CR_H_ + +#include +#include +#include +#include +#include +#include + +#include "pconfig.h" +#include "palloc.h" +#include "pstate.h" +#include "parray.h" + +namespace plib +{ + + template + struct matrix_compressed_rows_t + { + typedef C index_type; + typedef T value_type; + + enum constants_e + { + FILL_INFINITY = 9999999 + }; + + 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, N > nzbd; // Support for gaussian elimination + // contains elimination rows below the diagonal + // FIXME: convert to pvector + std::vector> m_ge_par; + + index_type nz_num; + + explicit matrix_compressed_rows_t(const index_type n) + : diag(n) + , row_idx(n+1) + , col_idx(n*n) + , A(n*n) + //, nzbd(n * (n+1) / 2) + , nzbd(n) + , nz_num(0) + , m_size(n) + { + for (index_type 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; + } + } + + 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; + } + } + } + } + build_parallel_gaussian_execution_scheme(fill); + return { fill_max, ops }; + } + + template + void build_from_fill_mat(const M &f, std::size_t max_fill = FILL_INFINITY - 1, + std::size_t 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 */ + + 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[k].push_back(static_cast(j)); + nzbd[k].push_back(0); // end of sequence + } + } + + template + void gaussian_elimination(V & RHS) + { + const std::size_t iN = size(); + + for (std::size_t i = 0; i < iN - 1; i++) + { + std::size_t nzbdp = 0; + std::size_t pi = diag[i]; + const value_type f = 1.0 / A[pi++]; + const std::size_t piie = row_idx[i+1]; + const auto &nz = nzbd[i]; + + while (auto j = nz[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 + // fill-in available assumed, i.e. matrix was prepared + + for (std::size_t pii = pi; pii + void gaussian_elimination_parallel(V & RHS) + { + // FIXME: move into solver creation ... + plib::omp::set_num_threads(4); + for (auto l = 0ul; l < m_ge_par.size(); l++) + plib::omp::for_static(0ul, m_ge_par[l].size(), [this, &RHS, &l] (unsigned ll) + { + auto &i = m_ge_par[l][ll]; + { + std::size_t nzbdp = 0; + 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[i][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 + // fill-in available assumed, i.e. matrix was prepared + 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(VTR & RESTRICT res, const VTV & RESTRICT x) + { + /* + * res = A * x + */ + + std::size_t row = 0; + std::size_t k = 0; + const std::size_t oe = nz_num; + + while (k < oe) + { + T tmp = 0.0; + const std::size_t e = row_idx[row+1]; + for (; k < e; k++) + tmp += A[k] * x[col_idx[k]]; + res[row++] = tmp; + } + } + + /* 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 + * + * Result is stored in matrix LU + * + * For i = 1,...,N-1 + * For k = 0, ... , i - 1 + * If a[i,k] != 0 + * a[i,k] = a[i,k] / a[k,k] + * For j = k + 1, ... , N - 1 + * If a[i,j] != 0 + * a[i,j] = a[i,j] - a[i,k] * a[k,j] + * j=j+1 + * k=k+1 + * i=i+1 + * + */ + + 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]]; + + std::size_t k_j = diag[k] + 1; + std::size_t i_j = i_k + 1; + + while (i_j < p_i_end && k_j < p_k_end ) // pj = (i, j) + { + // we can assume that within a row ja increases continuously */ + const auto c_i_j = col_idx[i_j]; // row i, column j + const auto c_k_j = col_idx[k_j]; // row i, column j + if (c_k_j < c_i_j) + k_j++; + else if (c_k_j == c_i_j) + A[i_j++] -= LUp_i_k * A[k_j++]; + else + i_j++; + } + } + } + } + + template + void solveLUx (R &r) + { + /* + * Solve a linear equation Ax = r + * where + * A = L*U + * + * L unit lower triangular + * U upper triangular + * + * ==> LUx = r + * + * ==> Ux = L⁻¹ r = w + * + * ==> r = Lw + * + * This can be solved for w using backwards elimination in L. + * + * Now Ux = w + * + * This can be solved for x using backwards elimination in U. + * + */ + for (std::size_t i = 1; i < m_size; ++i ) + { + T tmp = 0.0; + 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 += A[j] * r[col_idx[j]]; + + r[i] -= tmp; + } + // i now is equal to n; + 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 = row_idx[i+1]; + for (std::size_t j = di + 1; j < j2; j++ ) + tmp += A[j] * r[col_idx[j]]; + r[i] = (r[i] - tmp) / A[di]; + } + } + private: + template + void build_parallel_gaussian_execution_scheme(const M &fill) + { + // calculate parallel scheme for gaussian elimination + std::vector> rt(size()); + for (index_type k = 0; k < size(); k++) + { + for (index_type j = k+1; j < size(); j++) + { + if (fill[j][k] < FILL_INFINITY) + { + rt[k].push_back(j); + } + } + } + + std::vector levGE(size(), 0); + index_type cl = 0; + + for (index_type k = 0; k < size(); k++ ) + { + if (levGE[k] >= cl) + { + std::vector t = rt[k]; + for (index_type j = k+1; j < size(); j++ ) + { + bool overlap = false; + // is there overlap + if (plib::container::contains(t, j)) + overlap = true; + for (auto &x : rt[j]) + if (plib::container::contains(t, x)) + { + overlap = true; + break; + } + if (overlap) + levGE[j] = cl + 1; + else + { + t.push_back(j); + for (auto &x : rt[j]) + t.push_back(x); + } + } + cl++; + } + } + + m_ge_par.clear(); + m_ge_par.resize(cl+1); + for (index_type k = 0; k < size(); k++) + m_ge_par[levGE[k]].push_back(k); + } + + index_type m_size; + }; + +} + +#endif /* MAT_CR_H_ */ diff --git a/src/lib/netlist/plib/pomp.h b/src/lib/netlist/plib/pomp.h index f13df2539ac..19b39466025 100644 --- a/src/lib/netlist/plib/pomp.h +++ b/src/lib/netlist/plib/pomp.h @@ -28,13 +28,21 @@ void for_static(const I start, const I end, const T &what) #endif { #if HAS_OPENMP && USE_OPENMP - #pragma omp for schedule(static) + #pragma omp for //schedule(static) #endif for (I i = start; i < end; i++) what(i); } } +template +void for_static_np(const I start, const I end, const T &what) +{ + for (I i = start; i < end; i++) + what(i); +} + + inline void set_num_threads(const std::size_t threads) { #if HAS_OPENMP && USE_OPENMP diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h index ed27867af6b..4212677c81c 100644 --- a/src/lib/netlist/plib/putil.h +++ b/src/lib/netlist/plib/putil.h @@ -25,8 +25,8 @@ namespace plib namespace container { - template - bool contains(C &con, const typename C::value_type &elem) + template + bool contains(C &con, const T &elem) { return std::find(con.begin(), con.end(), elem) != con.end(); } diff --git a/src/lib/netlist/plib/vector_ops.h b/src/lib/netlist/plib/vector_ops.h new file mode 100644 index 00000000000..9bcdb6ee8c1 --- /dev/null +++ b/src/lib/netlist/plib/vector_ops.h @@ -0,0 +1,115 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * vector_ops.h + * + * Base vector operations + * + */ + +#ifndef PLIB_VECTOR_OPS_H_ +#define PLIB_VECTOR_OPS_H_ + +#include +#include +#include + +#include "pconfig.h" + +#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + +namespace plib +{ + template + void vec_set_scalar (const std::size_t n, VT &v, const T & scalar) + { + for ( std::size_t i = 0; i < n; i++ ) + v[i] = scalar; + } + + 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; + 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 VT &v) + { + T value = 0.0; + 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 VV & v, const T & scalar, VR & result) + { + 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 VV & v, const T scalar, VR & result) + { + for ( std::size_t i = 0; i < n; i++ ) + result[i] = result[i] + scalar * v[i]; + } + + template + void vec_add_mult_scalar_p(const std::size_t & n, const T * RESTRICT v, const T scalar, T * RESTRICT result) + { + for ( std::size_t i = 0; i < n; i++ ) + result[i] += scalar * v[i]; + } + + 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 V1 &v1, const V2 & v2, VR & result) + { + for ( std::size_t i = 0; i < n; i++ ) + result[i] = v1[i] - v2[i]; + } + + template + void vec_scale(const std::size_t n, V & v, const T scalar) + { + for ( std::size_t i = 0; i < n; i++ ) + v[i] = scalar * v[i]; + } + + 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++ ) + ret = std::max(ret, std::abs(v[i])); + + return ret; + } +} + +#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) +#pragma GCC diagnostic pop +#endif + +#endif /* PLIB_VECTOR_OPS_H_ */ diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 39a19f21897..1a82df36dcc 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -783,13 +783,6 @@ int tool_app_t::execute() perr("plib exception caught: {}\n", e.text()); } -#if 0 -#define str(x) # x -#define strx(x) str(x) -#define ttt strx(__cplusplus) - printf("%s\n", ttt); -#endif - return 0; } diff --git a/src/lib/netlist/solver/mat_cr.h b/src/lib/netlist/solver/mat_cr.h deleted file mode 100644 index 0116742c3ab..00000000000 --- a/src/lib/netlist/solver/mat_cr.h +++ /dev/null @@ -1,432 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Couriersud -/* - * mat_cr.h - * - * Compressed row format matrices - * - */ - -#ifndef MAT_CR_H_ -#define MAT_CR_H_ - -#include -#include -#include -#include -#include -#include - -#include "../plib/pconfig.h" -#include "../plib/palloc.h" -#include "../plib/pstate.h" -#include "../plib/parray.h" - -namespace plib -{ - -template -struct mat_cr_t -{ - typedef C index_type; - typedef T value_type; - - 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 m_size; - std::size_t nz_num; - - explicit mat_cr_t(const std::size_t 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) - { - 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 - */ - - std::size_t i = 0; - std::size_t k = 0; - const std::size_t oe = nz_num; - - while (k < oe) - { - T tmp = 0.0; - const std::size_t e = row_idx[i+1]; - for (; k < e; k++) - tmp += A[k] * x[col_idx[k]]; - res[i++] = tmp; - } - } - - /* 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 - * - * Result is stored in matrix LU - * - */ - -#if 0 - const std::size_t lnz = nz_num; - - for (std::size_t i = 1; row_idx[i] < lnz; i++) // 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 = 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 p_k_j = row_idx[k]; - - 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 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]; - - 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 - * where - * A = L*U - * - * L unit lower triangular - * U upper triangular - * - * ==> LUx = r - * - * ==> Ux = L⁻¹ r = w - * - * ==> r = Lw - * - * This can be solved for w using backwards elimination in L. - * - * Now Ux = w - * - * This can be solved for x using backwards elimination in U. - * - */ - for (std::size_t i = 1; i < m_size; ++i ) - { - T tmp = 0.0; - 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 += A[j] * r[col_idx[j]]; - - r[i] -= tmp; - } - // i now is equal to n; - 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 = row_idx[i+1]; - for (std::size_t j = di + 1; j < j2; j++ ) - 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.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp index d43d37eaf18..2c530b219cc 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.cpp +++ b/src/lib/netlist/solver/nld_matrix_solver.cpp @@ -40,7 +40,7 @@ void terms_for_net_t::clear() void terms_for_net_t::add(terminal_t *term, int net_other, bool sorted) { if (sorted) - for (unsigned i=0; i < m_connected_net_idx.size(); i++) + for (std::size_t i=0; i < m_connected_net_idx.size(); i++) { if (m_connected_net_idx[i] > net_other) { @@ -63,7 +63,7 @@ void terms_for_net_t::add(terminal_t *term, int net_other, bool sorted) void terms_for_net_t::set_pointers() { - for (unsigned i = 0; i < count(); i++) + for (std::size_t i = 0; i < count(); i++) { m_terms[i]->set_ptrs(&m_gt[i], &m_go[i], &m_Idr[i]); m_connected_net_V[i] = m_terms[i]->m_otherterm->net().Q_Analog_state_ptr(); @@ -141,7 +141,7 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) { proxied_analog_output_t *net_proxy_output = nullptr; for (auto & input : m_inps) - if (input->m_proxied_net == &p->net()) + if (input->proxied_net() == &p->net()) { net_proxy_output = input.get(); break; @@ -150,11 +150,10 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) if (net_proxy_output == nullptr) { pstring nname = this->name() + "." + pstring(plib::pfmt("m{1}")(m_inps.size())); - auto net_proxy_output_u = plib::make_unique(*this, nname); + nl_assert(p->net().is_analog()); + auto net_proxy_output_u = plib::make_unique(*this, nname, static_cast(&p->net())); net_proxy_output = net_proxy_output_u.get(); m_inps.push_back(std::move(net_proxy_output_u)); - nl_assert(p->net().is_analog()); - net_proxy_output->m_proxied_net = static_cast(&p->net()); } net_proxy_output->net().add_terminal(*p); // FIXME: repeated calling - kind of brute force @@ -175,27 +174,8 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) setup_matrix(); } -void matrix_solver_t::setup_matrix() +void matrix_solver_t::sort_terms(eSortType sort) { - const std::size_t iN = m_nets.size(); - - for (std::size_t k = 0; k < iN; k++) - { - m_terms[k]->m_railstart = m_terms[k]->count(); - for (std::size_t i = 0; i < m_rails_temp[k]->count(); i++) - this->m_terms[k]->add(m_rails_temp[k]->terms()[i], m_rails_temp[k]->connected_net_idx()[i], false); - - m_terms[k]->set_pointers(); - } - - for (terms_for_net_t *rt : m_rails_temp) - { - rt->clear(); // no longer needed - plib::pfree(rt); // no longer needed - } - - m_rails_temp.clear(); - /* Sort in descending order by number of connected matrix voltages. * The idea is, that for Gauss-Seidel algo the first voltage computed * depends on the greatest number of previous voltages thus taking into @@ -216,28 +196,98 @@ void matrix_solver_t::setup_matrix() * */ - if (m_sort != NOSORT) - { - int sort_order = (m_sort == DESCENDING ? 1 : -1); + const std::size_t iN = m_nets.size(); - for (unsigned k = 0; k < iN - 1; k++) - for (unsigned i = k+1; i < iN; i++) + switch (sort) + { + case PREFER_BAND_MATRIX: { - if ((static_cast(m_terms[k]->m_railstart) - static_cast(m_terms[i]->m_railstart)) * sort_order < 0) + for (std::size_t k = 0; k < iN - 1; k++) { - std::swap(m_terms[i], m_terms[k]); - std::swap(m_nets[i], m_nets[k]); + auto pk = get_weight_around_diag(k,k); + for (std::size_t i = k+1; i < iN; i++) + { + auto pi = get_weight_around_diag(i,k); + if (pi < pk) + { + std::swap(m_terms[i], m_terms[k]); + std::swap(m_nets[i], m_nets[k]); + pk = get_weight_around_diag(k,k); + } + } } } + break; + case PREFER_IDENTITY_TOP_LEFT: + { + for (std::size_t k = 0; k < iN - 1; k++) + { + auto pk = get_left_right_of_diag(k,k); + for (std::size_t i = k+1; i < iN; i++) + { + auto pi = get_left_right_of_diag(i,k); + if (pi.first <= pk.first && pi.second >= pk.second) + { + std::swap(m_terms[i], m_terms[k]); + std::swap(m_nets[i], m_nets[k]); + pk = get_left_right_of_diag(k,k); + } + } + } + } + break; + case ASCENDING: + case DESCENDING: + { + int sort_order = (m_sort == DESCENDING ? 1 : -1); - for (auto &term : m_terms) - { - int *other = term->connected_net_idx(); - for (unsigned i = 0; i < term->count(); i++) - if (other[i] != -1) - other[i] = get_net_idx(&term->terms()[i]->m_otherterm->net()); - } + for (std::size_t k = 0; k < iN - 1; k++) + for (std::size_t i = k+1; i < iN; i++) + { + if ((static_cast(m_terms[k]->m_railstart) - static_cast(m_terms[i]->m_railstart)) * sort_order < 0) + { + std::swap(m_terms[i], m_terms[k]); + std::swap(m_nets[i], m_nets[k]); + } + } + } + break; + case NOSORT: + break; + } + /* rebuild */ + for (auto &term : m_terms) + { + int *other = term->connected_net_idx(); + for (std::size_t i = 0; i < term->count(); i++) + //FIXME: this is weird + if (other[i] != -1) + other[i] = get_net_idx(&term->terms()[i]->m_otherterm->net()); } +} + +void matrix_solver_t::setup_matrix() +{ + const std::size_t iN = m_nets.size(); + + for (std::size_t k = 0; k < iN; k++) + { + m_terms[k]->m_railstart = m_terms[k]->count(); + for (std::size_t i = 0; i < m_rails_temp[k]->count(); i++) + this->m_terms[k]->add(m_rails_temp[k]->terms()[i], m_rails_temp[k]->connected_net_idx()[i], false); + + m_terms[k]->set_pointers(); + } + + for (terms_for_net_t *rt : m_rails_temp) + { + rt->clear(); // no longer needed + plib::pfree(rt); // no longer needed + } + + m_rails_temp.clear(); + + sort_terms(m_sort); /* create a list of non zero elements. */ for (unsigned k = 0; k < iN; k++) @@ -248,7 +298,7 @@ void matrix_solver_t::setup_matrix() t->m_nz.clear(); - for (unsigned i = 0; i < t->m_railstart; i++) + for (std::size_t i = 0; i < t->m_railstart; i++) if (!plib::container::contains(t->m_nz, static_cast(other[i]))) t->m_nz.push_back(static_cast(other[i])); @@ -262,7 +312,7 @@ void matrix_solver_t::setup_matrix() * These list anticipate the population of array elements by * Gaussian elimination. */ - for (unsigned k = 0; k < iN; k++) + for (std::size_t k = 0; k < iN; k++) { terms_for_net_t * t = m_terms[k].get(); /* pretty brutal */ @@ -282,7 +332,7 @@ void matrix_solver_t::setup_matrix() } } - for (unsigned i = 0; i < t->m_railstart; i++) + for (std::size_t i = 0; i < t->m_railstart; i++) if (!plib::container::contains(t->m_nzrd, static_cast(other[i])) && other[i] >= static_cast(k + 1)) t->m_nzrd.push_back(static_cast(other[i])); @@ -295,14 +345,14 @@ void matrix_solver_t::setup_matrix() */ bool **touched = plib::palloc_array(iN); - for (unsigned k=0; k(iN); - for (unsigned k = 0; k < iN; k++) + for (std::size_t k = 0; k < iN; k++) { - for (unsigned j = 0; j < iN; j++) + for (std::size_t j = 0; j < iN; j++) touched[k][j] = false; - for (unsigned j = 0; j < m_terms[k]->m_nz.size(); j++) + for (std::size_t j = 0; j < m_terms[k]->m_nz.size(); j++) touched[k][m_terms[k]->m_nz[j]] = true; } @@ -317,7 +367,7 @@ void matrix_solver_t::setup_matrix() m_ops++; if (!plib::container::contains(m_terms[k]->m_nzbd, row)) m_terms[k]->m_nzbd.push_back(row); - for (unsigned col = k + 1; col < iN; col++) + for (std::size_t col = k + 1; col < iN; col++) if (touched[k][col]) { touched[row][col] = true; @@ -329,10 +379,10 @@ void matrix_solver_t::setup_matrix() log().verbose("Number of mults/adds for {1}: {2}", name(), m_ops); if ((0)) - for (unsigned k = 0; k < iN; k++) + for (std::size_t k = 0; k < iN; k++) { pstring line = plib::pfmt("{1:3}")(k); - for (unsigned j = 0; j < m_terms[k]->m_nzrd.size(); j++) + for (std::size_t j = 0; j < m_terms[k]->m_nzrd.size(); j++) line += plib::pfmt(" {1:3}")(m_terms[k]->m_nzrd[j]); log().verbose("{1}", line); } @@ -340,7 +390,7 @@ void matrix_solver_t::setup_matrix() /* * save states */ - for (unsigned k = 0; k < iN; k++) + for (std::size_t k = 0; k < iN; k++) { pstring num = plib::pfmt("{1}")(k); @@ -353,7 +403,7 @@ void matrix_solver_t::setup_matrix() state().save(*this, m_terms[k]->Idr(),"IDR" + num , m_terms[k]->count()); } - for (unsigned k=0; kpush(inp->m_proxied_net->Q_Analog()); + inp->push(inp->proxied_net()->Q_Analog()); } void matrix_solver_t::update_dynamic() @@ -413,8 +463,8 @@ void matrix_solver_t::solve_base() ++m_stat_vsolver_calls; if (has_dynamic_devices()) { - unsigned this_resched; - unsigned newton_loops = 0; + std::size_t this_resched; + std::size_t newton_loops = 0; do { update_dynamic(); @@ -464,6 +514,70 @@ int matrix_solver_t::get_net_idx(detail::net_t *net) return -1; } +std::pair matrix_solver_t::get_left_right_of_diag(std::size_t irow, std::size_t idiag) +{ + /* + * return the maximum column left of the diagonal (-1 if no cols found) + * return the minimum column right of the diagonal (999999 if no cols found) + */ + + const int row = static_cast(irow); + const int diag = static_cast(idiag); + + int colmax = -1; + int colmin = 999999; + + auto &term = m_terms[irow]; + + for (std::size_t i = 0; i < term->count(); i++) + { + auto col = get_net_idx(&term->terms()[i]->m_otherterm->net()); + if (col != -1) + { + if (col==row) col = diag; + else if (col==diag) col = row; + + if (col > diag && col < colmin) + colmin = col; + else if (col < diag && col > colmax) + colmax = col; + } + } + return std::pair(colmax, colmin); +} + +double matrix_solver_t::get_weight_around_diag(std::size_t row, std::size_t diag) +{ + { + /* + * return average absolute distance + */ + + std::vector touched(1024, false); // FIXME! + + double weight = 0.0; + auto &term = m_terms[row]; + for (std::size_t i = 0; i < term->count(); i++) + { + auto col = get_net_idx(&term->terms()[i]->m_otherterm->net()); + if (col >= 0) + { + std::size_t colu = static_cast(col); + if (!touched[colu]) + { + if (colu==row) colu = static_cast(diag); + else if (colu==diag) colu = static_cast(row); + + weight = weight + std::abs(static_cast(colu) - static_cast(diag)); + touched[colu] = true; + } + } + } + return weight; // / static_cast(term->m_railstart); + } +} + + void matrix_solver_t::add_term(std::size_t k, terminal_t *term) { if (term->m_otherterm->net().isRailNet()) diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index e6ba72d9717..cd785db9cba 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -110,12 +110,14 @@ class proxied_analog_output_t : public analog_output_t { public: - proxied_analog_output_t(core_device_t &dev, const pstring &aname) + proxied_analog_output_t(core_device_t &dev, const pstring &aname, analog_net_t *pnet) : analog_output_t(dev, aname) - , m_proxied_net(nullptr) + , m_proxied_net(pnet) { } virtual ~proxied_analog_output_t(); + analog_net_t *proxied_net() const { return m_proxied_net;} +private: analog_net_t *m_proxied_net; // only for proxy nets in analog input logic }; @@ -129,7 +131,9 @@ public: { NOSORT, ASCENDING, - DESCENDING + DESCENDING, + PREFER_IDENTITY_TOP_LEFT, + PREFER_BAND_MATRIX }; virtual ~matrix_solver_t() override; @@ -162,6 +166,8 @@ public: public: int get_net_idx(detail::net_t *net); + std::pair get_left_right_of_diag(std::size_t row, std::size_t diag); + double get_weight_around_diag(std::size_t row, std::size_t diag); virtual void log_stats(); @@ -176,7 +182,9 @@ public: protected: matrix_solver_t(netlist_base_t &anetlist, const pstring &name, - const eSortType sort, const solver_parameters_t *params); + eSortType sort, const solver_parameters_t *params); + + void sort_terms(eSortType sort); void setup_base(analog_net_t::list_t &nets); void update_dynamic(); @@ -259,7 +267,7 @@ 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"); - const std::size_t iN = child.N(); + const std::size_t iN = child.size(); for (std::size_t k = 0; k < iN; k++) { terms_for_net_t *terms = m_terms[k].get(); @@ -294,7 +302,7 @@ void matrix_solver_t::build_LE_RHS(T &child) static_assert(std::is_base_of::value, "T must derive from matrix_solver_t"); typedef typename T::float_type float_type; - const std::size_t iN = child.N(); + const std::size_t iN = child.size(); for (std::size_t k = 0; k < iN; k++) { float_type rhsk_a = 0.0; diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index 1e07ba90e99..e1583d27be6 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -8,13 +8,13 @@ #ifndef NLD_MS_DIRECT_H_ #define NLD_MS_DIRECT_H_ +#include +#include #include #include #include "nld_solver.h" #include "nld_matrix_solver.h" -#include "vector_base.h" -#include "mat_cr.h" namespace netlist { @@ -41,7 +41,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 (SIZE > 0) ? static_cast(SIZE) : m_dim; } + constexpr std::size_t size() const { return (SIZE > 0) ? static_cast(SIZE) : m_dim; } void LE_solve(); @@ -49,8 +49,7 @@ protected: void LE_back_subst(T & RESTRICT x); 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; + FT &RHS(std::size_t r) { return m_A[r * m_pitch + size()]; } plib::parray m_new_V; private: @@ -78,17 +77,15 @@ void matrix_solver_direct_t::vsetup(analog_net_t::list_t &nets) matrix_solver_t::setup_base(nets); /* add RHS element */ - for (std::size_t k = 0; k < N(); k++) + for (std::size_t k = 0; k < size(); k++) { terms_for_net_t * t = m_terms[k].get(); - if (!plib::container::contains(t->m_nzrd, static_cast(N()))) - t->m_nzrd.push_back(static_cast(N())); + if (!plib::container::contains(t->m_nzrd, static_cast(size()))) + t->m_nzrd.push_back(static_cast(size())); } - state().save(*this, m_last_RHS.data(), "m_last_RHS", m_last_RHS.size()); - - for (std::size_t k = 0; k < N(); k++) + for (std::size_t k = 0; k < size(); k++) state().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k)); } @@ -96,7 +93,7 @@ void matrix_solver_direct_t::vsetup(analog_net_t::list_t &nets) template void matrix_solver_direct_t::LE_solve() { - const std::size_t kN = N(); + const std::size_t kN = size(); if (!m_params.m_pivot) { for (std::size_t i = 0; i < kN; i++) @@ -149,7 +146,7 @@ void matrix_solver_direct_t::LE_solve() 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); + plib::vec_add_mult_scalar_p(kN-i,pi,f1,pj); #else vec_add_mult_scalar_p(kN-i-1,pj,f1,pi); //for (unsigned k = i+1; k < kN; k++) @@ -169,7 +166,7 @@ template void matrix_solver_direct_t::LE_back_subst( T & RESTRICT x) { - const std::size_t kN = N(); + const std::size_t kN = size(); /* back substitution */ if (m_params.m_pivot) @@ -214,9 +211,6 @@ unsigned matrix_solver_direct_t::vsolve_non_dynamic(const bool newton_ 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); - this->m_stat_calculations++; return this->solve_non_dynamic(newton_raphson); } @@ -225,32 +219,22 @@ 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) { - 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, 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) { - for (std::size_t k = 0; k < N(); k++) - { - m_last_RHS[k] = 0.0; - } } } //namespace devices diff --git a/src/lib/netlist/solver/nld_ms_direct_lu.h b/src/lib/netlist/solver/nld_ms_direct_lu.h index 2832fb2d82d..86ddf015807 100644 --- a/src/lib/netlist/solver/nld_ms_direct_lu.h +++ b/src/lib/netlist/solver/nld_ms_direct_lu.h @@ -143,8 +143,6 @@ protected: //nl_double m_A[storage_N][((storage_N + 7) / 8) * 8]; nl_double m_RHS[storage_N]; - nl_double m_last_RHS[storage_N]; // right hand side - contains currents - nl_double m_last_V[storage_N]; terms_for_net_t *m_rails_temp; @@ -355,7 +353,6 @@ void matrix_solver_direct_t::vsetup(analog_net_t::list_t &nets) * save states */ save(NLNAME(m_RHS)); - save(NLNAME(m_last_RHS)); save(NLNAME(m_last_V)); for (unsigned k = 0; k < N(); k++) @@ -593,10 +590,7 @@ template int matrix_solver_direct_t::vsolve_non_dynamic(const bool newton_raphson) { this->build_LE_A(); - this->build_LE_RHS(m_last_RHS); - - for (unsigned i=0, iN=N(); i < iN; i++) - m_RHS[i] = m_last_RHS[i]; + this->build_LE_RHS(m_RHS); return this->solve_non_dynamic(newton_raphson); } @@ -608,11 +602,6 @@ matrix_solver_direct_t::matrix_solver_direct_t(const solver_para , m_lp_fact(0) { m_rails_temp = palloc_array(terms_for_net_t, N()); - - for (unsigned k = 0; k < N(); k++) - { - m_last_RHS[k] = 0.0; - } } template @@ -626,7 +615,6 @@ matrix_solver_direct_t::matrix_solver_direct_t(const eSolverType for (unsigned k = 0; k < N(); k++) { m_terms[k] = palloc(terms_for_net_t); - m_last_RHS[k] = 0.0; } } diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h index e708cdfb281..31476b7e2a5 100644 --- a/src/lib/netlist/solver/nld_ms_gcr.h +++ b/src/lib/netlist/solver/nld_ms_gcr.h @@ -10,13 +10,13 @@ #ifndef NLD_MS_GCR_H_ #define NLD_MS_GCR_H_ +#include #include #include "../plib/pdynlib.h" -#include "mat_cr.h" #include "nld_ms_direct.h" #include "nld_solver.h" -#include "vector_base.h" +#include "../plib/vector_ops.h" #include "../plib/pstream.h" namespace netlist @@ -29,16 +29,17 @@ class matrix_solver_GCR_t: public matrix_solver_t { public: + typedef plib::matrix_compressed_rows_t mat_type; // 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) + : matrix_solver_t(anetlist, name, matrix_solver_t::PREFER_IDENTITY_TOP_LEFT, params) , m_dim(size) , RHS(size) , new_V(size) - , mat(size) + , mat(static_cast(size)) , m_proc() { } @@ -57,7 +58,7 @@ public: private: //typedef typename mat_cr_t::type mattype; - typedef typename plib::mat_cr_t::index_type mat_index_type; + typedef typename plib::matrix_compressed_rows_t::index_type mat_index_type; void csc_private(plib::putf8_fmt_writer &strm); @@ -71,7 +72,7 @@ private: std::vector m_term_cr[storage_N]; - plib::mat_cr_t mat; + mat_type mat; //extsolver m_proc; plib::dynproc m_proc; @@ -82,6 +83,16 @@ private: // matrix_solver - GCR // ---------------------------------------------------------------------------------------- +// FIXME: namespace or static class member +template +std::size_t inline get_level(const V &v, std::size_t k) +{ + for (std::size_t i = 0; i < v.size(); i++) + if (plib::container::contains(v[i], k)) + return i; + throw plib::pexception("Error in get_level"); +} + template void matrix_solver_GCR_t::vsetup(analog_net_t::list_t &nets) { @@ -108,18 +119,46 @@ void matrix_solver_GCR_t::vsetup(analog_net_t::list_t &nets) auto gr = mat.gaussian_extend_fill_mat(fill); + /* FIXME: move this to the cr matrix class and use computed + * parallel ordering once it makes sense. + */ + + std::vector levL(iN, 0); + std::vector levU(iN, 0); + + // parallel scheme for L x = y + for (std::size_t k = 0; k < iN; k++) + { + unsigned lm=0; + for (std::size_t j = 0; j 0; ) + { + unsigned lm=0; + for (std::size_t j = iN; --j > k; ) + if (fill[k][j] < decltype(mat)::FILL_INFINITY) + lm = std::max(lm, levU[j]); + levU[k] = 1+lm; + } + + for (std::size_t k = 0; k < iN; k++) { unsigned fm = 0; pstring ml = ""; for (std::size_t j = 0; j < iN; j++) { - ml += fill[k][j] < decltype(mat)::FILL_INFINITY ? "X" : "_"; + ml += fill[k][j] == 0 ? "X" : fill[k][j] < decltype(mat)::FILL_INFINITY ? "+" : "."; 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); + this->log().verbose("{1:4} {2} {3:4} {4:4} {5:4} {6:4}", k, ml, levL[k], levU[k], get_level(mat.m_ge_par, k), fm); } @@ -273,6 +312,7 @@ unsigned matrix_solver_GCR_t::vsolve_non_dynamic(const bool newton_rap } else { + // mat.gaussian_elimination_parallel(RHS); mat.gaussian_elimination(RHS); /* backward substitution */ mat.gaussian_back_substitution(new_V, RHS); diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index 8ff4b1c7d33..735b6d76334 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -1,362 +1,150 @@ // license:GPL-2.0+ // copyright-holders:Couriersud /* - * nld_ms_sor.h - * - * Generic successive over relaxation solver. - * - * Fow w==1 we will do the classic Gauss-Seidel approach + * nld_ms_gmres.h * */ #ifndef NLD_MS_GMRES_H_ #define NLD_MS_GMRES_H_ -#include -#include - +#include "../plib/mat_cr.h" #include "../plib/parray.h" -#include "mat_cr.h" #include "nld_ms_direct.h" #include "nld_solver.h" -#include "vector_base.h" +#include "../plib/vector_ops.h" +#include "../plib/gmres.h" + +#include +#include + namespace netlist { - namespace devices - { - -template -class matrix_solver_GMRES_t: public matrix_solver_direct_t +namespace devices { -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) - , m_use_iLU_preconditioning(true) - , 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) - { - } - virtual ~matrix_solver_GMRES_t() override + template + class matrix_solver_GMRES_t: public matrix_solver_direct_t { - } - - virtual void vsetup(analog_net_t::list_t &nets) override; - virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; - -private: - - //typedef typename mat_cr_t::type mattype; - typedef typename plib::mat_cr_t::index_type mattype; - - 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); - - - bool m_use_iLU_preconditioning; - bool m_use_more_precise_stop_condition; - 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; - - plib::mat_cr_t m_LU; + public: - 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 */ + typedef FT float_type; - //plib::parray m_v[restart_N + 1]; /* mr + 1, n */ - float_type m_v[restart_N + 1][storage_N]; /* mr + 1, n */ - -}; - -// ---------------------------------------------------------------------------------------- -// matrix_solver - GMRES -// ---------------------------------------------------------------------------------------- - -template -void matrix_solver_GMRES_t::vsetup(analog_net_t::list_t &nets) -{ - matrix_solver_direct_t::vsetup(nets); - - const std::size_t iN = this->N(); - - std::vector> fill(iN); + /* Sort rows in ascending order. This should minimize fill-in and thus + * maximize the efficiency of the incomplete LUT. + * This is already preconditioning. + */ + 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::PREFER_BAND_MATRIX, params, size) + , m_term_cr(size) + //, m_ops(size, 2) + , m_ops(size, 4) + , m_gmres(size) + { + } - for (std::size_t k=0; km_terms[k].get(); - for (std::size_t j=0; jm_nz.size(); j++) + virtual ~matrix_solver_GMRES_t() override { - 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 + virtual void vsetup(analog_net_t::list_t &nets) override; + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; - /* build pointers into the compressed row format matrix for each terminal */ + private: - for (std::size_t k=0; km_terms[k]->m_railstart;j++) - { - 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(&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]]); - } -} - -template -unsigned matrix_solver_GMRES_t::vsolve_non_dynamic(const bool newton_raphson) -{ - const std::size_t iN = this->N(); + typedef typename plib::matrix_compressed_rows_t::index_type mattype; - plib::parray RHS(iN); - //float_type new_V[storage_N]; + plib::parray, SIZE> m_term_cr; + plib::mat_precondition_ILU m_ops; + //plib::mat_precondition_diag m_ops; + plib::gmres_t m_gmres; + }; - mat.set_scalar(0.0); + // ---------------------------------------------------------------------------------------- + // matrix_solver - GMRES + // ---------------------------------------------------------------------------------------- - /* populate matrix and V for first estimate */ - for (std::size_t k = 0; k < iN; k++) + template + void matrix_solver_GMRES_t::vsetup(analog_net_t::list_t &nets) { - this->m_terms[k]->fill_matrix(m_term_cr[k], RHS[k]); - this->m_new_V[k] = this->m_nets[k]->Q_Analog(); - } - + matrix_solver_direct_t::vsetup(nets); - //mat.row_idx[iN] = static_cast(mat.nz_num); - const float_type accuracy = this->m_params.m_accuracy; + const std::size_t iN = this->size(); - const std::size_t mr = (iN > 3 ) ? static_cast(std::sqrt(iN) * 2.0) : iN; - 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; + std::vector> fill(iN); - this->m_iterative_total += gsl; - this->m_stat_calculations++; - - if (gsl >= failed) - { - this->m_iterative_fail++; - return matrix_solver_direct_t::vsolve_non_dynamic(newton_raphson); - } - - //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 g0_last(g0); - - g0 = c * g0 - s * g1; - g1 = s * g0_last + c * g1; -} - -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 - * the LPGL here: - * - * http://people.sc.fsu.edu/~jburkardt/cpp_src/mgmres/mgmres.html - * - * The code below was completely written from scratch based on the pseudo code - * found here: - * - * http://de.wikipedia.org/wiki/GMRES-Verfahren - * - * The Algorithm itself is described in - * - * Yousef Saad, - * Iterative Methods for Sparse Linear Systems, - * Second Edition, - * SIAM, 20003, - * ISBN: 0898715342, - * LC: QA188.S17. - * - *------------------------------------------------------------------------*/ - - 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) - { - 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) - { - /* derive residual for a given delta x - * - * LU y = A dx - * - * ==> rho / accuracy = sqrt(y * y) - * - * This approach will approximate the iterative stop condition - * based |xnew - xold| pretty precisely. But it is slow, or expressed - * differently: The invest doesn't pay off. - * Therefore we use the approach in the else part. - */ - vec_set_scalar(n, residual, accuracy); - mat.mult_vec(residual, Ax); - - m_LU.solveLUx(Ax); - - 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(static_cast(n)) * m_accuracy_mult; - - for (std::size_t itr = 0; itr < restart_max; itr++) - { - std::size_t last_k = mr; - float_type rho; - - mat.mult_vec(x, Ax); - - vec_sub(n, rhs, Ax, residual); - - if (m_use_iLU_preconditioning) + for (std::size_t k=0; km_terms[k].get(); + for (std::size_t j=0; j < row->m_nz.size(); j++) + { + fill[k][static_cast(row->m_nz[j])] = 0; + } } - rho = std::sqrt(vec_mult2(n, residual)); - - if (rho < rho_delta) - return itr_used + 1; - - 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_scalar(mr, m_ht[i], NL_FCONST(0.0)); + m_ops.build(fill); - vec_mult_scalar(n, residual, NL_FCONST(1.0) / rho, m_v[0]); + /* build pointers into the compressed row format matrix for each terminal */ - for (std::size_t k = 0; k < mr; k++) + for (std::size_t k=0; km_terms[k]->m_railstart;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]); + for (std::size_t i = m_ops.m_mat.row_idx[k]; im_terms[k]->connected_net_idx()[j] == static_cast(m_ops.m_mat.col_idx[i])) + { + m_term_cr[k].push_back(&m_ops.m_mat.A[i]); + break; + } } - 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]); + nl_assert(m_term_cr[k].size() == this->m_terms[k]->m_railstart); + m_term_cr[k].push_back(&m_ops.m_mat.A[m_ops.m_mat.diag[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]); + template + unsigned matrix_solver_GMRES_t::vsolve_non_dynamic(const bool newton_raphson) + { + const std::size_t iN = this->size(); - const float_type mu = 1.0 / std::hypot(m_ht[k][k], m_ht[k1][k]); + plib::parray RHS(iN); + //float_type new_V[storage_N]; - m_c[k] = m_ht[k][k] * mu; - m_s[k] = -m_ht[k1][k] * mu; - m_ht[k][k] = m_c[k] * m_ht[k][k] - m_s[k] * m_ht[k1][k]; - m_ht[k1][k] = 0.0; + m_ops.m_mat.set_scalar(0.0); - givens_mult(m_c[k], m_s[k], m_g[k], m_g[k1]); + /* populate matrix and V for first estimate */ + for (std::size_t k = 0; k < iN; k++) + { + this->m_terms[k]->fill_matrix(m_term_cr[k], RHS[k]); + this->m_new_V[k] = this->m_nets[k]->Q_Analog(); + } - rho = std::abs(m_g[k1]); - itr_used = itr_used + 1; + const float_type accuracy = this->m_params.m_accuracy; - if (rho <= rho_delta) - { - last_k = k; - break; - } - } + const std::size_t iter = std::max(1u, this->m_params.m_gs_loops); + std::size_t gsl = m_gmres.solve(m_ops, this->m_new_V, RHS, iter, accuracy); - if (last_k >= mr) - /* didn't converge within accuracy */ - last_k = mr - 1; + this->m_iterative_total += gsl; + this->m_stat_calculations++; - /* Solve the system H * y = g */ - /* x += m_v[j] * m_y[j] */ - for (std::size_t i = last_k + 1; i-- > 0;) + if (gsl > iter) { - 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]; + this->m_iterative_fail++; + return matrix_solver_direct_t::vsolve_non_dynamic(newton_raphson); } - for (std::size_t i = 0; i <= last_k; i++) - vec_add_mult_scalar(n, m_v[i], m_y[i], x); - - if (rho <= rho_delta) - break; - + 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; } - return itr_used; -} - } //namespace devices + +} // namespace devices } // namespace netlist #endif /* NLD_MS_GMRES_H_ */ diff --git a/src/lib/netlist/solver/nld_ms_sm.h b/src/lib/netlist/solver/nld_ms_sm.h index 02e83bd5bbd..c48d85bd2b7 100644 --- a/src/lib/netlist/solver/nld_ms_sm.h +++ b/src/lib/netlist/solver/nld_ms_sm.h @@ -37,7 +37,7 @@ #include "nld_solver.h" #include "nld_matrix_solver.h" -#include "vector_base.h" +#include "../plib/vector_ops.h" namespace netlist { @@ -68,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_dim; } + constexpr std::size_t size() const { return m_dim; } void LE_invert(); @@ -91,8 +91,6 @@ protected: template float_ext_type &lAinv(const T1 &r, const T2 &c) { return m_lAinv[r][c]; } - 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; float_ext_type m_A[storage_N][m_pitch]; @@ -124,9 +122,7 @@ void matrix_solver_sm_t::vsetup(analog_net_t::list_t &nets) { matrix_solver_t::setup_base(nets); - state().save(*this, m_last_RHS, "m_last_RHS"); - - for (unsigned k = 0; k < N(); k++) + for (unsigned k = 0; k < size(); k++) state().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k)); } @@ -135,7 +131,7 @@ void matrix_solver_sm_t::vsetup(analog_net_t::list_t &nets) template void matrix_solver_sm_t::LE_invert() { - const std::size_t kN = N(); + const std::size_t kN = size(); for (std::size_t i = 0; i < kN; i++) { @@ -200,7 +196,7 @@ template void matrix_solver_sm_t::LE_compute_x( T * RESTRICT x) { - const std::size_t kN = N(); + const std::size_t kN = size(); for (std::size_t i=0; i unsigned matrix_solver_sm_t::solve_non_dynamic(const bool newton_raphson) { static constexpr const bool incremental = true; - const std::size_t iN = N(); + const std::size_t iN = size(); float_type new_V[storage_N]; // = { 0.0 }; @@ -301,9 +297,6 @@ unsigned matrix_solver_sm_t::vsolve_non_dynamic(const bool newton_raph 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); - this->m_stat_calculations++; return this->solve_non_dynamic(newton_raphson); } @@ -315,10 +308,6 @@ matrix_solver_sm_t::matrix_solver_sm_t(netlist_base_t &anetlist, const , m_dim(size) , m_cnt(0) { - for (std::size_t k = 0; k < N(); k++) - { - m_last_RHS[k] = 0.0; - } } } //namespace devices diff --git a/src/lib/netlist/solver/nld_ms_sor.h b/src/lib/netlist/solver/nld_ms_sor.h index 23944043d8b..9629bbcc1dc 100644 --- a/src/lib/netlist/solver/nld_ms_sor.h +++ b/src/lib/netlist/solver/nld_ms_sor.h @@ -35,7 +35,7 @@ public: , w(size, 0.0) , one_m_w(size, 0.0) , RHS(size, 0.0) - , new_V(size, 0.0) + //, new_V(size, 0.0) { } @@ -49,7 +49,7 @@ private: std::vector w; std::vector one_m_w; std::vector RHS; - std::vector new_V; + //std::vector new_V; }; // ---------------------------------------------------------------------------------------- @@ -66,7 +66,7 @@ void matrix_solver_SOR_t::vsetup(analog_net_t::list_t &nets) template unsigned matrix_solver_SOR_t::vsolve_non_dynamic(const bool newton_raphson) { - const std::size_t iN = this->N(); + const std::size_t iN = this->size(); bool resched = false; unsigned resched_cnt = 0; @@ -92,7 +92,7 @@ unsigned matrix_solver_SOR_t::vsolve_non_dynamic(const bool newton_rap 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(); + this->m_new_V[k] = this->m_nets[k]->Q_Analog(); for (std::size_t i = 0; i < term_count; i++) { @@ -142,20 +142,19 @@ unsigned matrix_solver_SOR_t::vsolve_non_dynamic(const bool newton_rap float_type Idrive = 0.0; for (std::size_t i = 0; i < railstart; i++) - Idrive = Idrive + go[i] * new_V[static_cast(net_other[i])]; + Idrive = Idrive + go[i] * this->m_new_V[static_cast(net_other[i])]; - const float_type new_val = new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k]; + const float_type new_val = this->m_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; + err = std::max(std::abs(new_val - this->m_new_V[k]), err); + this->m_new_V[k] = new_val; } if (err > accuracy) resched = true; resched_cnt++; - //} while (resched && (resched_cnt < this->m_params.m_gs_loops)); - } while (resched && ((resched_cnt < this->m_params.m_gs_loops))); + } while (resched && (resched_cnt < this->m_params.m_gs_loops)); this->m_iterative_total += resched_cnt; this->m_stat_calculations++; @@ -167,10 +166,9 @@ unsigned matrix_solver_SOR_t::vsolve_non_dynamic(const bool newton_rap return matrix_solver_direct_t::vsolve_non_dynamic(newton_raphson); } - for (std::size_t k = 0; k < iN; k++) - this->m_nets[k]->set_Q_Analog(new_V[k]); - - return resched_cnt; + 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; } } //namespace devices diff --git a/src/lib/netlist/solver/nld_ms_sor_mat.h b/src/lib/netlist/solver/nld_ms_sor_mat.h index 5eb4405600e..1892ed472f5 100644 --- a/src/lib/netlist/solver/nld_ms_sor_mat.h +++ b/src/lib/netlist/solver/nld_ms_sor_mat.h @@ -33,13 +33,10 @@ 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) + : matrix_solver_direct_t(anetlist, name, matrix_solver_t::ASCENDING, 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) { } @@ -55,10 +52,7 @@ private: state_var m_omega; state_var m_lp_fact; - state_var m_gs_fail; - state_var m_gs_total; - std::vector new_V; }; // ---------------------------------------------------------------------------------------- @@ -81,13 +75,13 @@ float_type matrix_solver_SOR_mat_t::vsolve() */ if (USE_LINEAR_PREDICTION) - for (unsigned k = 0; k < this->N(); k++) + for (unsigned k = 0; k < this->size(); k++) { this->m_last_V[k] = this->m_nets[k]->m_cur_Analog; this->m_nets[k]->m_cur_Analog = this->m_nets[k]->m_cur_Analog + this->m_Vdelta[k] * this->current_timestep() * m_lp_fact; } else - for (unsigned k = 0; k < this->N(); k++) + for (unsigned k = 0; k < this->size(); k++) { this->m_last_V[k] = this->m_nets[k]->m_cur_Analog; } @@ -99,7 +93,7 @@ float_type matrix_solver_SOR_mat_t::vsolve() 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++) + for (unsigned k = 0; k < this->size(); k++) { const analog_net_t *n = this->m_nets[k]; const float_type nv = (n->Q_Analog() - this->m_last_V[k]) * rez_cts ; @@ -129,7 +123,7 @@ unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool newton */ - const std::size_t iN = this->N(); + const std::size_t iN = this->size(); this->build_LE_A(*this); this->build_LE_RHS(*this); @@ -176,7 +170,7 @@ unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool newton #endif for (std::size_t k = 0; k < iN; k++) - new_V[k] = this->m_nets[k]->Q_Analog(); + this->m_new_V[k] = this->m_nets[k]->Q_Analog(); do { resched = false; @@ -190,11 +184,26 @@ unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool newton 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]]; - - const float_type delta = m_omega * (this->RHS(k) - Idrive) / this->A(k,k); + Idrive = Idrive + this->A(k,p[i]) * this->m_new_V[p[i]]; + + FT w = m_omega / this->A(k,k); + if (USE_GABS) + { + FT gabs_t = 0.0; + for (std::size_t i = 0; i < e; i++) + if (p[i] != k) + gabs_t = gabs_t + std::abs(this->A(k,p[i])); + + gabs_t *= NL_FCONST(1.0); // derived by try and error + if (gabs_t > this->A(k,k)) + { + w = NL_FCONST(1.0) / (this->A(k,k) + gabs_t); + } + } + + const float_type delta = w * (this->RHS(k) - Idrive) ; cerr = std::max(cerr, std::abs(delta)); - new_V[k] += delta; + this->m_new_V[k] += delta; } if (cerr > this->m_params.m_accuracy) @@ -206,20 +215,17 @@ unsigned matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool newton this->m_stat_calculations++; this->m_iterative_total += resched_cnt; - this->m_gs_total += resched_cnt; if (resched) { this->m_iterative_fail++; //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); } - else { - this->store(new_V.data()); - return resched_cnt; - } + + 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; } diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h index 7ce2802336d..d448facd5d0 100644 --- a/src/lib/netlist/solver/nld_ms_w.h +++ b/src/lib/netlist/solver/nld_ms_w.h @@ -44,7 +44,7 @@ #include "nld_solver.h" #include "nld_matrix_solver.h" -#include "vector_base.h" +#include "../plib/vector_ops.h" namespace netlist { @@ -74,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_dim; } + constexpr std::size_t size() const { return m_dim; } void LE_invert(); @@ -97,7 +97,6 @@ protected: template float_ext_type &lA(const T1 &r, const T2 &c) { return m_lA[r][c]; } - 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; @@ -136,9 +135,7 @@ void matrix_solver_w_t::vsetup(analog_net_t::list_t &nets) { matrix_solver_t::setup_base(nets); - state().save(*this, m_last_RHS, "m_last_RHS"); - - for (unsigned k = 0; k < N(); k++) + for (unsigned k = 0; k < size(); k++) state().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k)); } @@ -147,7 +144,7 @@ void matrix_solver_w_t::vsetup(analog_net_t::list_t &nets) template void matrix_solver_w_t::LE_invert() { - const std::size_t kN = N(); + const std::size_t kN = size(); for (std::size_t i = 0; i < kN; i++) { @@ -211,7 +208,7 @@ template void matrix_solver_w_t::LE_compute_x( T * RESTRICT x) { - const std::size_t kN = N(); + const std::size_t kN = size(); for (std::size_t i=0; i::LE_compute_x( template unsigned matrix_solver_w_t::solve_non_dynamic(const bool newton_raphson) { - const auto iN = N(); + const auto iN = size(); float_type new_V[storage_N]; // = { 0.0 }; - if ((m_cnt % 100) == 0) + if ((m_cnt % 50) == 0) { /* complete calculation */ this->LE_invert(); @@ -369,9 +366,6 @@ unsigned matrix_solver_w_t::vsolve_non_dynamic(const bool newton_raphs 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); - this->m_stat_calculations++; return this->solve_non_dynamic(newton_raphson); } @@ -379,14 +373,10 @@ unsigned matrix_solver_w_t::vsolve_non_dynamic(const bool newton_raphs 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) + : matrix_solver_t(anetlist, name, NOSORT, params) + , m_cnt(0) , m_dim(size) { - for (std::size_t k = 0; k < N(); k++) - { - m_last_RHS[k] = 0.0; - } } } //namespace devices diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 2997f1c8e45..a7c2f1fc196 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -301,7 +301,7 @@ void NETLIB_NAME(solver)::post_start() else ms = create_solver(2, sname); break; -#if 1 +#if 0 case 3: ms = create_solver(3, sname); break; diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index a07917b195d..19eca289264 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -41,7 +41,7 @@ NETLIB_OBJECT(solver) , m_gs_sor(*this, "SOR_FACTOR", 1.059) , m_method(*this, "METHOD", "MAT_CR") , m_accuracy(*this, "ACCURACY", 1e-7) - , m_gs_loops(*this, "GS_LOOPS",9) // Gauss-Seidel loops + , m_gs_loops(*this, "GS_LOOPS", 9) // Gauss-Seidel loops /* general parameters */ , m_gmin(*this, "GMIN", NETLIST_GMIN_DEFAULT) diff --git a/src/lib/netlist/solver/vector_base.h b/src/lib/netlist/solver/vector_base.h deleted file mode 100644 index 61ca2f3d9c0..00000000000 --- a/src/lib/netlist/solver/vector_base.h +++ /dev/null @@ -1,127 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Couriersud -/* - * vector_base.h - * - * Base vector operations - * - */ - -#ifndef VECTOR_BASE_H_ -#define VECTOR_BASE_H_ - -#include -#include -#include -#include "../plib/pconfig.h" - -#if 0 -template -struct pvector -{ - pvector(unsigned size) - : m_N(size) { } - - unsigned size() { - if (storage_N) - } - - double m_V[storage_N]; -private: - unsigned m_N; -}; -#endif - -#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - -template -void vec_set_scalar (const std::size_t n, VT &v, const T & scalar) -{ - for ( std::size_t i = 0; i < n; i++ ) - v[i] = scalar; -} - -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; - 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 VT &v) -{ - T value = 0.0; - 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 VV & v, const T & scalar, VR & result) -{ - 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 VV & v, const T scalar, VR & result) -{ - for ( std::size_t i = 0; i < n; i++ ) - result[i] = result[i] + scalar * v[i]; -} - -template -void vec_add_mult_scalar_p(const std::size_t & n, const T * RESTRICT v, const T scalar, T * RESTRICT result) -{ - for ( std::size_t i = 0; i < n; i++ ) - result[i] += scalar * v[i]; -} - -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 V1 &v1, const V2 & v2, VR & result) -{ - for ( std::size_t i = 0; i < n; i++ ) - result[i] = v1[i] - v2[i]; -} - -template -void vec_scale(const std::size_t n, V & v, const T scalar) -{ - for ( std::size_t i = 0; i < n; i++ ) - v[i] = scalar * v[i]; -} - -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++ ) - ret = std::max(ret, std::abs(v[i])); - - return ret; -} -#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) -#pragma GCC diagnostic pop -#endif - -#endif /* MAT_CR_H_ */ diff --git a/src/mame/audio/nl_kidniki.cpp b/src/mame/audio/nl_kidniki.cpp index 7916f992dee..7865ea40750 100644 --- a/src/mame/audio/nl_kidniki.cpp +++ b/src/mame/audio/nl_kidniki.cpp @@ -317,7 +317,7 @@ NETLIST_START(kidniki) PARAM(Solver.METHOD, "MAT_CR") //PARAM(Solver.METHOD, "MAT") //PARAM(Solver.METHOD, "GMRES") - PARAM(Solver.SOR_FACTOR, 1.0) + PARAM(Solver.SOR_FACTOR, 1.313) PARAM(Solver.DYNAMIC_TS, 0) PARAM(Solver.DYNAMIC_LTE, 5e-4) PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 20e-6) @@ -325,9 +325,11 @@ NETLIST_START(kidniki) SOLVER(Solver, 18000) PARAM(Solver.ACCURACY, 1e-7) PARAM(Solver.NR_LOOPS, 100) - PARAM(Solver.GS_LOOPS, 20) - //PARAM(Solver.METHOD, "MAT_CR") - PARAM(Solver.METHOD, "GMRES") + PARAM(Solver.GS_LOOPS, 300) + PARAM(Solver.METHOD, "MAT_CR") + //PARAM(Solver.METHOD, "GMRES") + //PARAM(Solver.SOR_FACTOR, 1.73) + //PARAM(Solver.METHOD, "SOR") #endif #if (USE_FRONTIERS) -- 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/pomp.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