mirror of
https://github.com/holub/mame
synced 2025-06-30 16:00:01 +03:00
Fix netlist code generation. (nw)
This commit is contained in:
parent
4c6cae2570
commit
c4dbd26730
@ -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.
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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++)
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user