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.
*/

View File

@ -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();

View File

@ -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++)

View File

@ -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>
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()));
strm.writeline("{");
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>
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);
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++)
{
const unsigned pi = m_term_cr[k][i];
m_A[pi] -= go[i];
}
m_A[tcr[i]] -= 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;
/* now solve it */

View File

@ -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)

View File

@ -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();