diff options
author | couriersud <couriersud@gmx.org> | 2017-01-26 10:41:58 +0100 |
---|---|---|
committer | couriersud <couriersud@gmx.org> | 2017-01-26 11:03:18 +0100 |
commit | c4dbd267303f45ddb2d00bb5211a4352f3220499 (patch) | |
tree | eb14a16d233b932bb54cb51e9da0cc3a64558c19 /src/lib/netlist | |
parent | 4c6cae2570e71a786b5f902ee7f53eaba2e453c4 (diff) |
Fix netlist code generation. (nw)
Diffstat (limited to 'src/lib/netlist')
-rw-r--r-- | src/lib/netlist/documentation/mainpage.dox.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/prg/nltool.cpp | 10 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_matrix_solver.h | 24 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_ms_gcr.h | 79 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_solver.cpp | 43 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_solver.h | 4 |
6 files changed, 94 insertions, 67 deletions
diff --git a/src/lib/netlist/documentation/mainpage.dox.h b/src/lib/netlist/documentation/mainpage.dox.h index 75df1a18065..744abe642e6 100644 --- a/src/lib/netlist/documentation/mainpage.dox.h +++ b/src/lib/netlist/documentation/mainpage.dox.h @@ -161,5 +161,4 @@ equation solver. The formal representation of the circuit will stay the same, thus scales. - */ diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 19b453cb069..f63369839ef 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -320,7 +320,15 @@ static void static_compile(tool_options_t &opts) opts.opt_logs(), opts.opt_defines(), opts.opt_rfolders()); - nt.solver()->create_solver_code(pout_strm); + plib::putf8_writer w(pout_strm); + std::map<pstring, pstring> mp; + + nt.solver()->create_solver_code(mp); + + for (auto &e : mp) + { + w.write(e.second); + } nt.stop(); diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 3a095fbe1ee..e5f7bcf38b1 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -44,14 +44,14 @@ public: void add(terminal_t *term, int net_other, bool sorted); - inline std::size_t count() { return m_terms.size(); } + inline std::size_t count() const { return m_terms.size(); } inline terminal_t **terms() { return m_terms.data(); } inline int *connected_net_idx() { return m_connected_net_idx.data(); } inline nl_double *gt() { return m_gt.data(); } inline nl_double *go() { return m_go.data(); } inline nl_double *Idr() { return m_Idr.data(); } - inline nl_double **connected_net_V() { return m_connected_net_V.data(); } + inline nl_double * const *connected_net_V() const { return m_connected_net_V.data(); } void set_pointers(); @@ -135,9 +135,9 @@ public: virtual void log_stats(); - virtual void create_solver_code(plib::putf8_fmt_writer &strm) + virtual std::pair<pstring, pstring> create_solver_code() { - strm.writeline(plib::pfmt("/* {1} doesn't support static compile */")); + return std::pair<pstring, pstring>("", plib::pfmt("/* {1} doesn't support static compile */")); } protected: @@ -226,12 +226,14 @@ void matrix_solver_t::build_LE_A() const unsigned iN = child.N(); for (unsigned k = 0; k < iN; k++) { + terms_for_net_t *terms = m_terms[k].get(); + for (unsigned i=0; i < iN; i++) child.A(k,i) = 0.0; - const std::size_t terms_count = m_terms[k]->count(); - const std::size_t railstart = m_terms[k]->m_railstart; - const nl_double * RESTRICT gt = m_terms[k]->gt(); + const std::size_t terms_count = terms->count(); + const std::size_t railstart = terms->m_railstart; + const nl_double * const RESTRICT gt = terms->gt(); { nl_double akk = 0.0; @@ -241,8 +243,8 @@ void matrix_solver_t::build_LE_A() child.A(k,k) = akk; } - const nl_double * RESTRICT go = m_terms[k]->go(); - const int * RESTRICT net_other = m_terms[k]->connected_net_idx(); + const nl_double * const RESTRICT go = terms->go(); + int * RESTRICT net_other = terms->connected_net_idx(); for (std::size_t i = 0; i < railstart; i++) child.A(k,net_other[i]) -= go[i]; @@ -262,8 +264,8 @@ void matrix_solver_t::build_LE_RHS() nl_double rhsk_b = 0.0; const std::size_t terms_count = m_terms[k]->count(); - const nl_double * RESTRICT go = m_terms[k]->go(); - const nl_double * RESTRICT Idr = m_terms[k]->Idr(); + const nl_double * const RESTRICT go = m_terms[k]->go(); + const nl_double * const RESTRICT Idr = m_terms[k]->Idr(); const nl_double * const * RESTRICT other_cur_analog = m_terms[k]->connected_net_V(); for (std::size_t i = 0; i < terms_count; i++) diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h index 99fde152f51..11d71c531fa 100644 --- a/src/lib/netlist/solver/nld_ms_gcr.h +++ b/src/lib/netlist/solver/nld_ms_gcr.h @@ -52,7 +52,7 @@ public: virtual void vsetup(analog_net_t::list_t &nets) override; virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; - virtual void create_solver_code(plib::putf8_fmt_writer &strm) override; + virtual std::pair<pstring, pstring> create_solver_code() override; private: @@ -60,15 +60,7 @@ private: using extsolver = void (*)(double * RESTRICT m_A, double * RESTRICT RHS); - pstring static_compile_name() - { - plib::postringstream t; - plib::putf8_fmt_writer w(t); - csc_private(w); - std::hash<pstring> h; - - return plib::pfmt("nl_gcr_{1:x}_{2}")(h( t.str() ))(mat.nz_num); - } + pstring static_compile_name(); unsigned m_dim; std::vector<unsigned> m_term_cr[storage_N]; @@ -104,32 +96,21 @@ void matrix_solver_GCR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) unsigned ops = 0; - const bool static_compile = false; for (unsigned k = 0; k < iN; k++) { ops++; // 1/A(k,k) - if (static_compile) printf("const double fd%d = 1.0 / A(%d,%d); \n", k, k, k); for (unsigned row = k + 1; row < iN; row++) { if (touched[row][k]) { ops++; fc++; - if (static_compile) printf(" const double f%d = -fd%d * A(%d,%d); \n", fc, k, row, k); for (unsigned col = k + 1; col < iN; col++) if (touched[k][col]) { - if (touched[row][col]) - { - if (static_compile) printf(" A(%d,%d) += f%d * A(%d,%d); \n", row, col, fc, k, col); - } else - { - if (static_compile) printf(" A(%d,%d) = f%d * A(%d,%d); \n", row, col, fc, k, col); - } touched[row][col] = true; ops += 2; } - if (static_compile) printf(" RHS(%d) += f%d * RHS(%d); \n", row, fc, k); } } } @@ -180,7 +161,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) if (m_proc != nullptr) this->log().verbose("External static solver {1} found ...", symname); else - this->log().verbose("External static solver {1} not found ...", symname); + this->log().warning("External static solver {1} not found ...", symname); } } @@ -198,7 +179,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::csc_private(plib::putf8_fmt_writer &st unsigned pi = mat.diag[i]; //const nl_double f = 1.0 / m_A[pi++]; - strm("const double f{1} = 1.0 / m_A[{2}];", i,pi); + strm("const double f{1} = 1.0 / m_A[{2}];\n", i, pi); pi++; const unsigned piie = mat.ia[i+1]; @@ -211,7 +192,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::csc_private(plib::putf8_fmt_writer &st pj++; //const nl_double f1 = - m_A[pj++] * f; - strm("\tconst double f{1}_{2} = -f{3} * m_A[{4}];", i, j, i, pj); + strm("\tconst double f{1}_{2} = -f{3} * m_A[{4}];\n", i, j, i, pj); pj++; // subtract row i from j */ @@ -220,25 +201,40 @@ void matrix_solver_GCR_t<m_N, storage_N>::csc_private(plib::putf8_fmt_writer &st while (mat.ja[pj] < mat.ja[pii]) pj++; //m_A[pj++] += m_A[pii++] * f1; - strm("\tm_A[{1}] += m_A[{2}] * f{3}_{4};", pj, pii, i, j); + strm("\tm_A[{1}] += m_A[{2}] * f{3}_{4};\n", pj, pii, i, j); pj++; pii++; } //RHS[j] += f1 * RHS[i]; - strm("\tRHS[{1}] += f{2}_{3} * RHS[{4}];", j, i, j, i); + strm("\tRHS[{1}] += f{2}_{3} * RHS[{4}];\n", j, i, j, i); } } } } + +template <unsigned m_N, unsigned storage_N> +pstring matrix_solver_GCR_t<m_N, storage_N>::static_compile_name() +{ + plib::postringstream t; + plib::putf8_fmt_writer w(t); + csc_private(w); + std::hash<pstring> h; + + return plib::pfmt("nl_gcr_{1:x}_{2}")(h( t.str() ))(mat.nz_num); +} + template <unsigned m_N, unsigned storage_N> -void matrix_solver_GCR_t<m_N, storage_N>::create_solver_code(plib::putf8_fmt_writer &strm) +std::pair<pstring, pstring> matrix_solver_GCR_t<m_N, storage_N>::create_solver_code() { - //const unsigned iN = N(); + plib::postringstream t; + plib::putf8_fmt_writer strm(t); + pstring name = static_compile_name(); - strm.writeline(plib::pfmt("extern \"C\" void {1}(double * _restrict m_A, double * _restrict RHS)")(static_compile_name())); - strm.writeline("{"); + strm.writeline(plib::pfmt("extern \"C\" void {1}(double * __restrict m_A, double * __restrict RHS)\n")(name)); + strm.writeline("{\n"); csc_private(strm); - strm.writeline("}"); + strm.writeline("}\n"); + return std::pair<pstring, pstring>(name, t.str()); } @@ -265,7 +261,9 @@ unsigned matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newt const nl_double * const RESTRICT go = t->go(); const nl_double * const RESTRICT Idr = t->Idr(); const nl_double * const * RESTRICT other_cur_analog = t->connected_net_V(); + const unsigned * const RESTRICT tcr = m_term_cr[k].data(); +#if 1 #if (0 ||NL_USE_SSE) __m128d mg = _mm_set_pd(0.0, 0.0); __m128d mr = _mm_set_pd(0.0, 0.0); @@ -298,11 +296,26 @@ unsigned matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newt m_A[mat.diag[k]] = gtot_t; for (unsigned i = 0; i < railstart; i++) + m_A[tcr[i]] -= go[i]; + } +#else + for (std::size_t i = 0; i < railstart; i++) { - const unsigned pi = m_term_cr[k][i]; - m_A[pi] -= go[i]; + m_A[tcr[i]] -= go[i]; + gtot_t = gtot_t + gt[i]; + RHS_t = RHS_t + Idr[i]; } + + for (std::size_t i = railstart; i < term_count; i++) + { + RHS_t += (Idr[i] + go[i] * *other_cur_analog[i]); + gtot_t += gt[i]; + } + + RHS[k] = RHS_t; + m_A[mat.diag[k]] += gtot_t; } +#endif mat.ia[iN] = mat.nz_num; /* now solve it */ diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index fe60d6f3c95..cfdf411c553 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -10,23 +10,24 @@ */ #if 0 -#pragma GCC optimize "-ffast-math" -#pragma GCC optimize "-fstrict-aliasing" -#pragma GCC optimize "-ftree-vectorizer-verbose=2" -#pragma GCC optimize "-fopt-info-vec" -#pragma GCC optimize "-fopt-info-vec-missed" -//#pragma GCC optimize "-ftree-parallelize-loops=4" -#pragma GCC optimize "-funroll-loops" -#pragma GCC optimize "-funswitch-loops" -#pragma GCC optimize "-fvariable-expansion-in-unroller" -#pragma GCC optimize "-funsafe-loop-optimizations" -#pragma GCC optimize "-fvect-cost-model" -#pragma GCC optimize "-fvariable-expansion-in-unroller" -#pragma GCC optimize "-ftree-loop-if-convert-stores" -#pragma GCC optimize "-ftree-loop-distribution" -#pragma GCC optimize "-ftree-loop-im" -#pragma GCC optimize "-ftree-loop-ivcanon" -#pragma GCC optimize "-fivopts" +#pragma GCC optimize "fast-math" +#pragma GCC optimize "strict-aliasing" +#pragma GCC optimize "tree-vectorize" +#pragma GCC optimize "tree-vectorizer-verbose=7" +#pragma GCC optimize "opt-info-vec" +#pragma GCC optimize "opt-info-vec-missed" +//#pragma GCC optimize "tree-parallelize-loops=4" +#pragma GCC optimize "unroll-loops" +#pragma GCC optimize "unswitch-loops" +#pragma GCC optimize "variable-expansion-in-unroller" +#pragma GCC optimize "unsafe-loop-optimizations" +#pragma GCC optimize "vect-cost-model" +#pragma GCC optimize "variable-expansion-in-unroller" +#pragma GCC optimize "tree-loop-if-convert-stores" +#pragma GCC optimize "tree-loop-distribution" +#pragma GCC optimize "tree-loop-im" +#pragma GCC optimize "tree-loop-ivcanon" +#pragma GCC optimize "ivopts" #endif #include <iostream> @@ -399,11 +400,13 @@ void NETLIB_NAME(solver)::post_start() } } -void NETLIB_NAME(solver)::create_solver_code(plib::postream &strm) +void NETLIB_NAME(solver)::create_solver_code(std::map<pstring, pstring> &mp) { - plib::putf8_fmt_writer w(strm); for (auto & s : m_mat_solvers) - s->create_solver_code(w); + { + auto r = s->create_solver_code(); + mp[r.first] = r.second; // automatically overwrites identical names + } } NETLIB_DEVICE_IMPL(solver) diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index 5430fc4ce28..d982b81ec0c 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -8,6 +8,8 @@ #ifndef NLD_SOLVER_H_ #define NLD_SOLVER_H_ +#include <map> + #include "nl_setup.h" #include "nl_base.h" #include "plib/pstream.h" @@ -79,7 +81,7 @@ NETLIB_OBJECT(solver) inline nl_double gmin() { return m_gmin(); } - void create_solver_code(plib::postream &strm); + void create_solver_code(std::map<pstring, pstring> &mp); NETLIB_UPDATEI(); NETLIB_RESETI(); |