summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2017-01-26 10:41:58 +0100
committer couriersud <couriersud@gmx.org>2017-01-26 11:03:18 +0100
commitc4dbd267303f45ddb2d00bb5211a4352f3220499 (patch)
treeeb14a16d233b932bb54cb51e9da0cc3a64558c19 /src/lib/netlist
parent4c6cae2570e71a786b5f902ee7f53eaba2e453c4 (diff)
Fix netlist code generation. (nw)
Diffstat (limited to 'src/lib/netlist')
-rw-r--r--src/lib/netlist/documentation/mainpage.dox.h1
-rw-r--r--src/lib/netlist/prg/nltool.cpp10
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h24
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h79
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp43
-rw-r--r--src/lib/netlist/solver/nld_solver.h4
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();