Fix netlist code generation. (nw)

This commit is contained in:
couriersud 2017-01-26 10:41:58 +01:00
parent 4c6cae2570
commit c4dbd26730
6 changed files with 98 additions and 71 deletions

View File

@ -161,5 +161,4 @@ equation solver.
The formal representation of the circuit will stay the same, thus scales. The formal representation of the circuit will stay the same, thus scales.
*/ */

View File

@ -320,7 +320,15 @@ static void static_compile(tool_options_t &opts)
opts.opt_logs(), opts.opt_logs(),
opts.opt_defines(), opts.opt_rfolders()); 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(); nt.stop();

View File

@ -44,14 +44,14 @@ public:
void add(terminal_t *term, int net_other, bool sorted); 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 terminal_t **terms() { return m_terms.data(); }
inline int *connected_net_idx() { return m_connected_net_idx.data(); } inline int *connected_net_idx() { return m_connected_net_idx.data(); }
inline nl_double *gt() { return m_gt.data(); } inline nl_double *gt() { return m_gt.data(); }
inline nl_double *go() { return m_go.data(); } inline nl_double *go() { return m_go.data(); }
inline nl_double *Idr() { return m_Idr.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(); void set_pointers();
@ -135,9 +135,9 @@ public:
virtual void log_stats(); 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: protected:
@ -226,12 +226,14 @@ void matrix_solver_t::build_LE_A()
const unsigned iN = child.N(); const unsigned iN = child.N();
for (unsigned k = 0; k < iN; k++) for (unsigned k = 0; k < iN; k++)
{ {
terms_for_net_t *terms = m_terms[k].get();
for (unsigned i=0; i < iN; i++) for (unsigned i=0; i < iN; i++)
child.A(k,i) = 0.0; child.A(k,i) = 0.0;
const std::size_t terms_count = m_terms[k]->count(); const std::size_t terms_count = terms->count();
const std::size_t railstart = m_terms[k]->m_railstart; const std::size_t railstart = terms->m_railstart;
const nl_double * RESTRICT gt = m_terms[k]->gt(); const nl_double * const RESTRICT gt = terms->gt();
{ {
nl_double akk = 0.0; nl_double akk = 0.0;
@ -241,8 +243,8 @@ void matrix_solver_t::build_LE_A()
child.A(k,k) = akk; child.A(k,k) = akk;
} }
const nl_double * RESTRICT go = m_terms[k]->go(); const nl_double * const RESTRICT go = terms->go();
const int * RESTRICT net_other = m_terms[k]->connected_net_idx(); int * RESTRICT net_other = terms->connected_net_idx();
for (std::size_t i = 0; i < railstart; i++) for (std::size_t i = 0; i < railstart; i++)
child.A(k,net_other[i]) -= go[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; nl_double rhsk_b = 0.0;
const std::size_t terms_count = m_terms[k]->count(); const std::size_t terms_count = m_terms[k]->count();
const nl_double * RESTRICT go = m_terms[k]->go(); const nl_double * const RESTRICT go = m_terms[k]->go();
const nl_double * RESTRICT Idr = m_terms[k]->Idr(); const nl_double * const RESTRICT Idr = m_terms[k]->Idr();
const nl_double * const * RESTRICT other_cur_analog = m_terms[k]->connected_net_V(); const nl_double * const * RESTRICT other_cur_analog = m_terms[k]->connected_net_V();
for (std::size_t i = 0; i < terms_count; i++) for (std::size_t i = 0; i < terms_count; i++)

View File

@ -52,7 +52,7 @@ public:
virtual void vsetup(analog_net_t::list_t &nets) override; virtual void vsetup(analog_net_t::list_t &nets) override;
virtual unsigned vsolve_non_dynamic(const bool newton_raphson) 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: private:
@ -60,15 +60,7 @@ private:
using extsolver = void (*)(double * RESTRICT m_A, double * RESTRICT RHS); using extsolver = void (*)(double * RESTRICT m_A, double * RESTRICT RHS);
pstring static_compile_name() 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);
}
unsigned m_dim; unsigned m_dim;
std::vector<unsigned> m_term_cr[storage_N]; 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; unsigned ops = 0;
const bool static_compile = false;
for (unsigned k = 0; k < iN; k++) for (unsigned k = 0; k < iN; k++)
{ {
ops++; // 1/A(k,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++) for (unsigned row = k + 1; row < iN; row++)
{ {
if (touched[row][k]) if (touched[row][k])
{ {
ops++; ops++;
fc++; 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++) for (unsigned col = k + 1; col < iN; col++)
if (touched[k][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; touched[row][col] = true;
ops += 2; 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) if (m_proc != nullptr)
this->log().verbose("External static solver {1} found ...", symname); this->log().verbose("External static solver {1} found ...", symname);
else 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]; unsigned pi = mat.diag[i];
//const nl_double f = 1.0 / m_A[pi++]; //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++; pi++;
const unsigned piie = mat.ia[i+1]; 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++; pj++;
//const nl_double f1 = - m_A[pj++] * f; //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++; pj++;
// subtract row i from j */ // 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]) while (mat.ja[pj] < mat.ja[pii])
pj++; pj++;
//m_A[pj++] += m_A[pii++] * f1; //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++; pj++; pii++;
} }
//RHS[j] += f1 * RHS[i]; //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>
void matrix_solver_GCR_t<m_N, storage_N>::create_solver_code(plib::putf8_fmt_writer &strm)
{
//const unsigned iN = N();
strm.writeline(plib::pfmt("extern \"C\" void {1}(double * _restrict m_A, double * _restrict RHS)")(static_compile_name())); template <unsigned m_N, unsigned storage_N>
strm.writeline("{"); 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>
std::pair<pstring, pstring> matrix_solver_GCR_t<m_N, storage_N>::create_solver_code()
{
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)\n")(name));
strm.writeline("{\n");
csc_private(strm); 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 go = t->go();
const nl_double * const RESTRICT Idr = t->Idr(); const nl_double * const RESTRICT Idr = t->Idr();
const nl_double * const * RESTRICT other_cur_analog = t->connected_net_V(); 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) #if (0 ||NL_USE_SSE)
__m128d mg = _mm_set_pd(0.0, 0.0); __m128d mg = _mm_set_pd(0.0, 0.0);
__m128d mr = _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; m_A[mat.diag[k]] = gtot_t;
for (unsigned i = 0; i < railstart; i++) for (unsigned i = 0; i < railstart; i++)
{ m_A[tcr[i]] -= go[i];
const unsigned pi = m_term_cr[k][i];
m_A[pi] -= go[i];
}
} }
#else
for (std::size_t i = 0; i < railstart; 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; mat.ia[iN] = mat.nz_num;
/* now solve it */ /* now solve it */

View File

@ -10,23 +10,24 @@
*/ */
#if 0 #if 0
#pragma GCC optimize "-ffast-math" #pragma GCC optimize "fast-math"
#pragma GCC optimize "-fstrict-aliasing" #pragma GCC optimize "strict-aliasing"
#pragma GCC optimize "-ftree-vectorizer-verbose=2" #pragma GCC optimize "tree-vectorize"
#pragma GCC optimize "-fopt-info-vec" #pragma GCC optimize "tree-vectorizer-verbose=7"
#pragma GCC optimize "-fopt-info-vec-missed" #pragma GCC optimize "opt-info-vec"
//#pragma GCC optimize "-ftree-parallelize-loops=4" #pragma GCC optimize "opt-info-vec-missed"
#pragma GCC optimize "-funroll-loops" //#pragma GCC optimize "tree-parallelize-loops=4"
#pragma GCC optimize "-funswitch-loops" #pragma GCC optimize "unroll-loops"
#pragma GCC optimize "-fvariable-expansion-in-unroller" #pragma GCC optimize "unswitch-loops"
#pragma GCC optimize "-funsafe-loop-optimizations" #pragma GCC optimize "variable-expansion-in-unroller"
#pragma GCC optimize "-fvect-cost-model" #pragma GCC optimize "unsafe-loop-optimizations"
#pragma GCC optimize "-fvariable-expansion-in-unroller" #pragma GCC optimize "vect-cost-model"
#pragma GCC optimize "-ftree-loop-if-convert-stores" #pragma GCC optimize "variable-expansion-in-unroller"
#pragma GCC optimize "-ftree-loop-distribution" #pragma GCC optimize "tree-loop-if-convert-stores"
#pragma GCC optimize "-ftree-loop-im" #pragma GCC optimize "tree-loop-distribution"
#pragma GCC optimize "-ftree-loop-ivcanon" #pragma GCC optimize "tree-loop-im"
#pragma GCC optimize "-fivopts" #pragma GCC optimize "tree-loop-ivcanon"
#pragma GCC optimize "ivopts"
#endif #endif
#include <iostream> #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) 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) NETLIB_DEVICE_IMPL(solver)

View File

@ -8,6 +8,8 @@
#ifndef NLD_SOLVER_H_ #ifndef NLD_SOLVER_H_
#define NLD_SOLVER_H_ #define NLD_SOLVER_H_
#include <map>
#include "nl_setup.h" #include "nl_setup.h"
#include "nl_base.h" #include "nl_base.h"
#include "plib/pstream.h" #include "plib/pstream.h"
@ -79,7 +81,7 @@ NETLIB_OBJECT(solver)
inline nl_double gmin() { return m_gmin(); } 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_UPDATEI();
NETLIB_RESETI(); NETLIB_RESETI();