Further work on vectorization. Works but not yet finished.

This commit is contained in:
Couriersud 2014-05-29 14:03:07 +00:00
parent d17e376dc6
commit f27ccb3303
4 changed files with 194 additions and 146 deletions

View File

@ -41,7 +41,7 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_analog_net_t::list_t &nets
for (int k = 0; k < nets.count(); k++) for (int k = 0; k < nets.count(); k++)
{ {
m_nets.add(net_entry(nets[k])); m_nets.add(nets[k]);
} }
for (int k = 0; k < nets.count(); k++) for (int k = 0; k < nets.count(); k++)
@ -80,11 +80,13 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_analog_net_t::list_t &nets
netlist_terminal_t *pterm = dynamic_cast<netlist_terminal_t *>(p); netlist_terminal_t *pterm = dynamic_cast<netlist_terminal_t *>(p);
// for gauss seidel // for gauss seidel
pterm->m_new_analog_ptr = &pterm->m_otherterm->net().as_analog().m_new_Analog; pterm->m_new_analog_ptr = &pterm->m_otherterm->net().as_analog().m_new_Analog;
#if 0
if (pterm->m_otherterm->net().isRailNet()) if (pterm->m_otherterm->net().isRailNet())
m_nets[k].m_rails.add(pterm); m_nets[k].m_rails.add(pterm);
else else
m_nets[k].m_terms.add(pterm); m_nets[k].m_terms.add(pterm);
#endif
add_term(k, pterm);
} }
NL_VERBOSE_OUT(("Added terminal\n")); NL_VERBOSE_OUT(("Added terminal\n"));
break; break;
@ -139,7 +141,7 @@ ATTR_HOT double netlist_matrix_solver_direct_t<m_N, _storage_N>::compute_next_ti
#else #else
for (int k = 0; k < N(); k++) for (int k = 0; k < N(); k++)
{ {
netlist_analog_net_t *n = m_nets[k].m_net; netlist_analog_net_t *n = m_nets[k];
#endif #endif
double DD_n = (n->m_cur_Analog - n->m_last_Analog); double DD_n = (n->m_cur_Analog - n->m_last_Analog);
@ -190,7 +192,7 @@ ATTR_HOT void netlist_matrix_solver_t::update_inputs()
#if 1 #if 1
for (int k = 0; k < m_nets.count(); k++) for (int k = 0; k < m_nets.count(); k++)
{ {
netlist_analog_net_t *p= m_nets[k].m_net; netlist_analog_net_t *p= m_nets[k];
p->m_last_Analog = p->m_cur_Analog; p->m_last_Analog = p->m_cur_Analog;
} }
#else #else
@ -323,19 +325,51 @@ void netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::log_stats()
ATTR_COLD int netlist_matrix_solver_t::get_net_idx(netlist_net_t *net) ATTR_COLD int netlist_matrix_solver_t::get_net_idx(netlist_net_t *net)
{ {
for (int k = 0; k < m_nets.count(); k++) for (int k = 0; k < m_nets.count(); k++)
if (m_nets[k].m_net == net) if (m_nets[k] == net)
return k; return k;
return -1; return -1;
} }
template <int m_N, int _storage_N>
ATTR_COLD void netlist_matrix_solver_direct_t<m_N, _storage_N>::add_term(int k, netlist_terminal_t *term)
{
if (term->m_otherterm->net().isRailNet())
{
//m_nets[k].m_rails.add(pterm);
m_rails[k].add(terms_t(term, -1));
}
else
{
int ot = get_net_idx(&term->m_otherterm->net());
if (ot>=0)
{
m_terms[k].add(terms_t(term, ot));
SOLVER_VERBOSE_OUT(("Net %d Term %s %f %f\n", k, terms[i]->name().cstr(), terms[i]->m_gt, terms[i]->m_go));
}
/* Should this be allowed ? */
else // if (ot<0)
{
m_rails[k].add(terms_t(term, ot));
netlist().error("found term with missing othernet %s\n", term->name().cstr());
}
}
}
template <int m_N, int _storage_N> template <int m_N, int _storage_N>
ATTR_COLD void netlist_matrix_solver_direct_t<m_N, _storage_N>::vsetup(netlist_analog_net_t::list_t &nets) ATTR_COLD void netlist_matrix_solver_direct_t<m_N, _storage_N>::vsetup(netlist_analog_net_t::list_t &nets)
{ {
m_dim = nets.count(); m_dim = nets.count();
netlist_matrix_solver_t::setup(nets);
m_terms.clear(); for (int k = 0; k < N(); k++)
m_rail_start = 0; {
m_terms[k].clear();
m_rails[k].clear();
}
netlist_matrix_solver_t::setup(nets);
#if 0
for (int k = 0; k < N(); k++) for (int k = 0; k < N(); k++)
{ {
const netlist_terminal_t::list_t &terms = m_nets[k].m_terms; const netlist_terminal_t::list_t &terms = m_nets[k].m_terms;
@ -344,31 +378,38 @@ ATTR_COLD void netlist_matrix_solver_direct_t<m_N, _storage_N>::vsetup(netlist_a
int ot = get_net_idx(&terms[i]->m_otherterm->net()); int ot = get_net_idx(&terms[i]->m_otherterm->net());
if (ot>=0) if (ot>=0)
{ {
m_terms.add(terms_t(terms[i], k, ot)); m_terms[k].add(terms_t(terms[i], ot));
SOLVER_VERBOSE_OUT(("Net %d Term %s %f %f\n", k, terms[i]->name().cstr(), terms[i]->m_gt, terms[i]->m_go)); SOLVER_VERBOSE_OUT(("Net %d Term %s %f %f\n", k, terms[i]->name().cstr(), terms[i]->m_gt, terms[i]->m_go));
} }
} }
} }
m_rail_start = m_terms.count();
/* Should this be allowed ? */
for (int k = 0; k < N(); k++) for (int k = 0; k < N(); k++)
{ {
const netlist_terminal_t::list_t &terms = m_nets[k].m_terms; const netlist_terminal_t::list_t &terms = m_nets[k].m_terms;
const netlist_terminal_t::list_t &rails = m_nets[k].m_rails;
for (int i = 0; i < terms.count(); i++) for (int i = 0; i < terms.count(); i++)
{ {
int ot = get_net_idx(&terms[i]->m_otherterm->net()); int ot = get_net_idx(&terms[i]->m_otherterm->net());
if (ot<0) if (ot<0)
{ {
m_terms.add(terms_t(terms[i], k, ot)); m_rails[k].add(terms_t(terms[i], ot));
netlist().warning("found term with missing othernet %s\n", terms[i]->name().cstr()); netlist().warning("found term with missing othernet %s\n", terms[i]->name().cstr());
} }
} }
}
for (int k = 0; k < N(); k++)
{
const netlist_terminal_t::list_t &rails = m_nets[k].m_rails;
for (int i = 0; i < rails.count(); i++) for (int i = 0; i < rails.count(); i++)
{ {
m_terms.add(terms_t(rails[i], k, -1)); m_rails[k].add(terms_t(rails[i], -1));
SOLVER_VERBOSE_OUT(("Net %d Rail %s %f %f\n", k, rails[i]->name().cstr(), rails[i]->m_gt, rails[i]->m_go)); SOLVER_VERBOSE_OUT(("Net %d Rail %s %f %f\n", k, rails[i]->name().cstr(), rails[i]->m_gt, rails[i]->m_go));
} }
} }
#endif
} }
template <int m_N, int _storage_N> template <int m_N, int _storage_N>
@ -378,43 +419,35 @@ ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::build_LE()
for (int i=0; i < _storage_N; i++) for (int i=0; i < _storage_N; i++)
m_A[k][i] = 0.0; m_A[k][i] = 0.0;
for (int k=0; k < _storage_N; k++) for (int k = 0; k < N(); k++)
m_RHS[k] = 0.0;
#if 0
for (int i = 0; i < m_term_num; i++)
{ {
terms_t &t = m_terms[i]; double rhsk = 0.0;
m_RHS[t.m_net_this] += t.m_term->m_Idr; double akk = 0.0;
m_A[t.m_net_this][t.m_net_this] += t.m_term->m_gt; const int terms_count = m_terms[k].count();
if (t.m_net_other >= 0) const terms_t *terms = m_terms[k];
for (int i = 0; i < terms_count; i++)
{ {
//m_A[t.net_other][t.net_other] += t.term->m_otherterm->m_gt; //printf("A %d %d %s %f %f\n",t.net_this, t.net_other, t.term->name().cstr(), t.term->m_gt, t.term->m_go);
m_A[t.m_net_this][t.m_net_other] += -t.m_term->m_go;
//m_A[t.net_other][t.net_this] += -t.term->m_otherterm->m_go; rhsk = rhsk + terms[i].m_term->m_Idr;
akk = akk + terms[i].m_term->m_gt;
m_A[k][terms[i].m_net_other] += -terms[i].m_term->m_go;
} }
else
m_RHS[t.m_net_this] += t.m_term->m_go * t.m_term->m_otherterm->net().as_analog().Q_Analog();
}
#else
for (int i = 0; i < m_rail_start; i++)
{
const terms_t &t = m_terms[i];
//printf("A %d %d %s %f %f\n",t.net_this, t.net_other, t.term->name().cstr(), t.term->m_gt, t.term->m_go);
m_RHS[t.m_net_this] += t.m_term->m_Idr; const int rails_count = m_rails[k].count();
m_A[t.m_net_this][t.m_net_this] += t.m_term->m_gt; const terms_t *rails = m_rails[k];
m_A[t.m_net_this][t.m_net_other] += -t.m_term->m_go;
}
for (int i = m_rail_start; i < m_terms.count(); i++)
{
const terms_t &t = m_terms[i];
m_RHS[t.m_net_this] += t.m_term->m_Idr; for (int i = 0; i < rails_count; i++)
m_A[t.m_net_this][t.m_net_this] += t.m_term->m_gt; {
m_RHS[t.m_net_this] += t.m_term->m_go * t.m_term->m_otherterm->net().as_analog().Q_Analog(); const terms_t t = rails[i];
}
#endif rhsk = rhsk + t.m_term->m_Idr + t.m_term->m_go * t.m_term->m_otherterm->net().as_analog().Q_Analog();
akk = akk + t.m_term->m_gt;
}
m_RHS[k] = rhsk;
m_A[k][k] += akk;
}
} }
template <int m_N, int _storage_N> template <int m_N, int _storage_N>
@ -504,7 +537,7 @@ ATTR_HOT double netlist_matrix_solver_direct_t<m_N, _storage_N>::delta(
double cerr2 = 0; double cerr2 = 0;
for (int i = 0; i < this->N(); i++) for (int i = 0; i < this->N(); i++)
{ {
const double e = (V[i] - this->m_nets[i].m_net->m_cur_Analog); const double e = (V[i] - this->m_nets[i]->m_cur_Analog);
const double e2 = (m_RHS[i] - this->m_last_RHS[i]); const double e2 = (m_RHS[i] - this->m_last_RHS[i]);
cerr = (fabs(e) > cerr ? fabs(e) : cerr); cerr = (fabs(e) > cerr ? fabs(e) : cerr);
cerr2 = (fabs(e2) > cerr2 ? fabs(e2) : cerr2); cerr2 = (fabs(e2) > cerr2 ? fabs(e2) : cerr2);
@ -519,7 +552,7 @@ ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::store(
{ {
for (int i = 0; i < this->N(); i++) for (int i = 0; i < this->N(); i++)
{ {
this->m_nets[i].m_net->m_cur_Analog = this->m_nets[i].m_net->m_new_Analog = V[i]; this->m_nets[i]->m_cur_Analog = this->m_nets[i]->m_new_Analog = V[i];
} }
if (store_RHS) if (store_RHS)
{ {
@ -569,7 +602,7 @@ ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic
ATTR_HOT int netlist_matrix_solver_direct1_t::vsolve_non_dynamic() ATTR_HOT int netlist_matrix_solver_direct1_t::vsolve_non_dynamic()
{ {
netlist_analog_net_t *net = m_nets[0].m_net; netlist_analog_net_t *net = m_nets[0];
this->build_LE(); this->build_LE();
//NL_VERBOSE_OUT(("%f %f\n", new_val, m_RHS[0] / m_A[0][0]); //NL_VERBOSE_OUT(("%f %f\n", new_val, m_RHS[0] / m_A[0][0]);
@ -646,7 +679,7 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolve_non_d
for (int k = 0; k < iN; k++) for (int k = 0; k < iN; k++)
{ {
new_v[k] = this->m_nets[k].m_net->m_cur_Analog; new_v[k] = this->m_nets[k]->m_cur_Analog;
} }
do { do {
resched = false; resched = false;
@ -708,7 +741,7 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolve_non_d
for (int k = 0; k < iN; k++) for (int k = 0; k < iN; k++)
{ {
this->m_nets[k].m_net->m_new_Analog = this->m_nets[k].m_net->m_cur_Analog; this->m_nets[k]->m_new_Analog = this->m_nets[k]->m_cur_Analog;
} }
for (int k = 0; k < iN; k++) for (int k = 0; k < iN; k++)
@ -717,25 +750,26 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolve_non_d
double gabs_t = 0.0; double gabs_t = 0.0;
double RHS_t = 0.0; double RHS_t = 0.0;
//const netlist_analog_net_t &net = *this->m_nets[k]; const typename netlist_matrix_solver_direct_t<m_N, _storage_N>::xlist_t &terms = this->m_terms[k];
const netlist_terminal_t::list_t &terms = this->m_nets[k].m_terms; const typename netlist_matrix_solver_direct_t<m_N, _storage_N>::xlist_t &rails = this->m_rails[k];
const netlist_terminal_t::list_t &rails = this->m_nets[k].m_rails;
const int term_count = terms.count(); const int term_count = terms.count();
const int rail_count = rails.count(); const int rail_count = rails.count();
for (int i = 0; i < rail_count; i++) for (int i = 0; i < rail_count; i++)
{ {
gtot_t += rails[i]->m_gt; const netlist_terminal_t *rail = rails[i].m_term;
gabs_t += fabs(rails[i]->m_go); gtot_t += rail->m_gt;
RHS_t += rails[i]->m_Idr; gabs_t += fabs(rail->m_go);
RHS_t += rails[i]->m_go * rails[i]->m_otherterm->net().as_analog().Q_Analog(); RHS_t += rail->m_Idr;
RHS_t += rail->m_go * rail->m_otherterm->net().as_analog().Q_Analog();
} }
for (int i = 0; i < term_count; i++) for (int i = 0; i < term_count; i++)
{ {
gtot_t += terms[i]->m_gt; const netlist_terminal_t *term = terms[i].m_term;
gabs_t += fabs(terms[i]->m_go); gtot_t += term->m_gt;
RHS_t += terms[i]->m_Idr; gabs_t += fabs(term->m_go);
RHS_t += term->m_Idr;
} }
gabs_t *= 1.0; gabs_t *= 1.0;
@ -760,13 +794,13 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolve_non_d
for (int k = 0; k < iN; k++) for (int k = 0; k < iN; k++)
{ {
netlist_analog_net_t & RESTRICT net = *this->m_nets[k].m_net; netlist_analog_net_t & RESTRICT net = *this->m_nets[k];
const netlist_terminal_t::list_t &terms = this->m_nets[k].m_terms; const typename netlist_matrix_solver_direct_t<m_N, _storage_N>::xlist_t &terms = this->m_terms[k];
const int term_count = terms.count(); const int term_count = terms.count();
double Idrive = 0; double Idrive = 0;
for (int i = 0; i < term_count; i++) for (int i = 0; i < term_count; i++)
Idrive += terms[i]->m_go * *(terms[i]->m_new_analog_ptr); Idrive += terms[i].m_term->m_go * *(terms[i].m_term->m_new_analog_ptr);
//double new_val = (net->m_cur_Analog * gabs[k] + iIdr) / (gtot[k]); //double new_val = (net->m_cur_Analog * gabs[k] + iIdr) / (gtot[k]);
const double new_val = net.m_new_Analog * one_m_w[k] + (Idrive + RHS[k]) * w[k]; const double new_val = net.m_new_Analog * one_m_w[k] + (Idrive + RHS[k]) * w[k];
@ -796,7 +830,7 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolve_non_d
this->m_calculations++; this->m_calculations++;
for (int k = 0; k < this->N(); k++) for (int k = 0; k < this->N(); k++)
this->m_nets[k].m_net->m_cur_Analog = this->m_nets[k].m_net->m_new_Analog; this->m_nets[k]->m_cur_Analog = this->m_nets[k]->m_new_Analog;
return resched_cnt; return resched_cnt;
} }
@ -906,11 +940,29 @@ NETLIB_UPDATE(solver)
} }
} }
template <int m_N, int _storage_N>
netlist_matrix_solver_t * NETLIB_NAME(solver)::create_solver(const int gs_threshold, const bool use_specific)
{
if (use_specific && m_N == 1)
return new netlist_matrix_solver_direct1_t();
else if (use_specific && m_N == 2)
return new netlist_matrix_solver_direct2_t();
else
{
if (_storage_N >= gs_threshold)
return new netlist_matrix_solver_gauss_seidel_t<m_N,_storage_N>();
else
return new netlist_matrix_solver_direct_t<m_N, _storage_N>();
}
}
ATTR_COLD void NETLIB_NAME(solver)::post_start() ATTR_COLD void NETLIB_NAME(solver)::post_start()
{ {
netlist_analog_net_t::list_t groups[100]; netlist_analog_net_t::list_t groups[100];
int cur_group = -1; int cur_group = -1;
// FIXME: Turn into parameters ...
const int gs_threshold = 5;
const bool use_specific = true;
m_params.m_accuracy = m_accuracy.Value(); m_params.m_accuracy = m_accuracy.Value();
m_params.m_gs_loops = m_gs_loops.Value(); m_params.m_gs_loops = m_gs_loops.Value();
@ -956,53 +1008,42 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
switch (net_count) switch (net_count)
{ {
#if 1
case 1: case 1:
ms = new netlist_matrix_solver_direct1_t(); ms = create_solver<1,1>(gs_threshold, use_specific);
break; break;
case 2: case 2:
ms = new netlist_matrix_solver_direct2_t(); ms = create_solver<2,2>(gs_threshold, use_specific);
break; break;
case 3: case 3:
ms = new netlist_matrix_solver_direct_t<3,3>(); ms = create_solver<3,3>(gs_threshold, use_specific);
//ms = new netlist_matrix_solver_gauss_seidel_t<3,3>();
break; break;
case 4: case 4:
ms = new netlist_matrix_solver_direct_t<4,4>(); ms = create_solver<4,4>(gs_threshold, use_specific);
//ms = new netlist_matrix_solver_gauss_seidel_t<4,4>();
break; break;
case 5: case 5:
ms = new netlist_matrix_solver_direct_t<5,5>(); ms = create_solver<5,5>(gs_threshold, use_specific);
//ms = new netlist_matrix_solver_gauss_seidel_t<5,5>();
break; break;
case 6: case 6:
ms = new netlist_matrix_solver_direct_t<6,6>(); ms = create_solver<6,6>(gs_threshold, use_specific);
//ms = new netlist_matrix_solver_gauss_seidel_t<6,6>();
break; break;
case 7: case 7:
//ms = new netlist_matrix_solver_direct_t<6,6>(); ms = create_solver<7,7>(gs_threshold, use_specific);
ms = new netlist_matrix_solver_gauss_seidel_t<7,7>();
break; break;
case 8: case 8:
//ms = new netlist_matrix_solver_direct_t<6,6>(); ms = create_solver<8,8>(gs_threshold, use_specific);
ms = new netlist_matrix_solver_gauss_seidel_t<8,8>();
break; break;
#endif
default: default:
if (net_count <= 16) if (net_count <= 16)
{ {
//ms = new netlist_matrix_solver_direct_t<0,16>(); ms = create_solver<0,16>(gs_threshold, use_specific);
ms = new netlist_matrix_solver_gauss_seidel_t<0,16>();
} }
else if (net_count <= 32) else if (net_count <= 32)
{ {
//ms = new netlist_matrix_solver_direct_t<0,16>(); ms = create_solver<0,32>(gs_threshold, use_specific);
ms = new netlist_matrix_solver_gauss_seidel_t<0,32>();
} }
else if (net_count <= 64) else if (net_count <= 64)
{ {
//ms = new netlist_matrix_solver_direct_t<0,16>(); ms = create_solver<0,64>(gs_threshold, use_specific);
ms = new netlist_matrix_solver_gauss_seidel_t<0,64>();
} }
else else
{ {

View File

@ -9,6 +9,9 @@
#include "../nl_setup.h" #include "../nl_setup.h"
#include "../nl_base.h" #include "../nl_base.h"
//#define ATTR_ALIGNED(N) __attribute__((aligned(N)))
#define ATTR_ALIGNED(N) ATTR_ALIGN
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// Macros // Macros
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -37,7 +40,7 @@ struct netlist_solver_parameters_t
netlist_time m_nt_sync_delay; netlist_time m_nt_sync_delay;
}; };
class netlist_matrix_solver_t : public netlist_device_t class ATTR_ALIGNED(64) netlist_matrix_solver_t : public netlist_device_t
{ {
public: public:
typedef plinearlist_t<netlist_matrix_solver_t *> list_t; typedef plinearlist_t<netlist_matrix_solver_t *> list_t;
@ -67,40 +70,15 @@ public:
protected: protected:
class net_entry
{
public:
net_entry(netlist_analog_net_t *net) : m_net(net) {}
net_entry() : m_net(NULL) {}
net_entry(const net_entry &rhs)
{
m_net = rhs.m_net;
m_terms = rhs.m_terms;
m_rails = rhs.m_rails;
}
net_entry &operator=(const net_entry &rhs)
{
m_net = rhs.m_net;
m_terms = rhs.m_terms;
m_rails = rhs.m_rails;
return *this;
}
netlist_analog_net_t * RESTRICT m_net;
netlist_terminal_t::list_t m_terms;
netlist_terminal_t::list_t m_rails;
};
ATTR_COLD void setup(netlist_analog_net_t::list_t &nets); ATTR_COLD void setup(netlist_analog_net_t::list_t &nets);
// return true if a reschedule is needed ... // return true if a reschedule is needed ...
ATTR_HOT virtual int vsolve_non_dynamic() = 0; ATTR_HOT virtual int vsolve_non_dynamic() = 0;
ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term) = 0;
int m_calculations; int m_calculations;
plinearlist_t<net_entry> m_nets; plinearlist_t<netlist_analog_net_t *> m_nets;
plinearlist_t<netlist_analog_output_t *> m_inps; plinearlist_t<netlist_analog_output_t *> m_inps;
private: private:
@ -126,14 +104,13 @@ private:
}; };
template <int m_N, int _storage_N> template <int m_N, int _storage_N>
class netlist_matrix_solver_direct_t: public netlist_matrix_solver_t class ATTR_ALIGNED(64) netlist_matrix_solver_direct_t: public netlist_matrix_solver_t
{ {
public: public:
netlist_matrix_solver_direct_t() netlist_matrix_solver_direct_t()
: netlist_matrix_solver_t() : netlist_matrix_solver_t()
, m_dim(0) , m_dim(0)
, m_rail_start(0)
{} {}
virtual ~netlist_matrix_solver_direct_t() {} virtual ~netlist_matrix_solver_direct_t() {}
@ -144,6 +121,8 @@ public:
ATTR_HOT inline const int N() const { if (m_N == 0) return m_dim; else return m_N; } ATTR_HOT inline const int N() const { if (m_N == 0) return m_dim; else return m_N; }
protected: protected:
ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term);
ATTR_HOT virtual int vsolve_non_dynamic(); ATTR_HOT virtual int vsolve_non_dynamic();
ATTR_HOT int solve_non_dynamic(); ATTR_HOT int solve_non_dynamic();
ATTR_HOT inline void build_LE(); ATTR_HOT inline void build_LE();
@ -154,31 +133,35 @@ protected:
ATTR_HOT virtual double compute_next_timestep(const double); ATTR_HOT virtual double compute_next_timestep(const double);
double m_A[_storage_N][_storage_N]; ATTR_ALIGNED(64) double m_A[_storage_N][_storage_N];
double m_RHS[_storage_N]; ATTR_ALIGNED(64) double m_RHS[_storage_N];
double m_last_RHS[_storage_N]; // right hand side - contains currents ATTR_ALIGNED(64) double m_last_RHS[_storage_N]; // right hand side - contains currents
struct terms_t{ struct ATTR_ALIGNED(64) terms_t{
terms_t(netlist_terminal_t *term, int net_this, int net_other) terms_t(netlist_terminal_t *term, int net_other)
: m_term(term), m_net_this(net_this), m_net_other(net_other) : m_term(term), m_net_other(net_other)
{} {}
terms_t() terms_t()
: m_term(NULL), m_net_this(-1), m_net_other(-1) : m_term(NULL), m_net_other(-1)
{} {}
netlist_terminal_t * RESTRICT m_term; ATTR_ALIGNED(64) netlist_terminal_t ATTR_ALIGNED(64) * RESTRICT m_term;
int m_net_this;
int m_net_other; int m_net_other;
}; };
typedef plinearlist_t<terms_t> xlist_t;
xlist_t m_terms[_storage_N];
xlist_t m_rails[_storage_N];
plinearlist_t<double> xx[_storage_N];
private:
int m_dim; int m_dim;
int m_rail_start;
plinearlist_t<terms_t> m_terms;
}; };
template <int m_N, int _storage_N> template <int m_N, int _storage_N>
class netlist_matrix_solver_gauss_seidel_t: public netlist_matrix_solver_direct_t<m_N, _storage_N> class ATTR_ALIGNED(64) netlist_matrix_solver_gauss_seidel_t: public netlist_matrix_solver_direct_t<m_N, _storage_N>
{ {
public: public:
@ -201,22 +184,39 @@ private:
}; };
class netlist_matrix_solver_direct1_t: public netlist_matrix_solver_direct_t<1,1> class ATTR_ALIGNED(64) netlist_matrix_solver_direct1_t: public netlist_matrix_solver_direct_t<1,1>
{ {
protected: protected:
ATTR_HOT int vsolve_non_dynamic(); ATTR_HOT int vsolve_non_dynamic();
private: private:
}; };
class netlist_matrix_solver_direct2_t: public netlist_matrix_solver_direct_t<2,2> class ATTR_ALIGNED(64) netlist_matrix_solver_direct2_t: public netlist_matrix_solver_direct_t<2,2>
{ {
protected: protected:
ATTR_HOT int vsolve_non_dynamic(); ATTR_HOT int vsolve_non_dynamic();
private: private:
}; };
NETLIB_DEVICE_WITH_PARAMS(solver, class ATTR_ALIGNED(64) NETLIB_NAME(solver) : public netlist_device_t
typedef netlist_core_device_t::list_t dev_list_t; {
public:
NETLIB_NAME(solver)()
: netlist_device_t() { }
ATTR_COLD virtual ~NETLIB_NAME(solver)();
ATTR_COLD void post_start();
ATTR_HOT inline double gmin() { return m_gmin.Value(); }
protected:
ATTR_HOT void update();
ATTR_HOT void start();
ATTR_HOT void reset();
ATTR_HOT void update_param();
//typedef netlist_core_device_t::list_t dev_list_t;
netlist_ttl_input_t m_fb_step; netlist_ttl_input_t m_fb_step;
netlist_ttl_output_t m_Q_step; netlist_ttl_output_t m_Q_step;
@ -234,17 +234,14 @@ NETLIB_DEVICE_WITH_PARAMS(solver,
netlist_param_int_t m_parallel; netlist_param_int_t m_parallel;
netlist_matrix_solver_t::list_t m_mat_solvers; netlist_matrix_solver_t::list_t m_mat_solvers;
public:
ATTR_COLD virtual ~NETLIB_NAME(solver)();
ATTR_COLD void post_start();
ATTR_HOT inline double gmin() { return m_gmin.Value(); }
private: private:
netlist_solver_parameters_t m_params;
); netlist_solver_parameters_t m_params;
template <int m_N, int _storage_N>
netlist_matrix_solver_t *create_solver(int gs_threshold, bool use_specific);
};
#endif /* NLD_SOLVER_H_ */ #endif /* NLD_SOLVER_H_ */

View File

@ -424,7 +424,7 @@ private:
NETLIST_SAVE_TYPE(netlist_core_terminal_t::state_e, DT_INT); NETLIST_SAVE_TYPE(netlist_core_terminal_t::state_e, DT_INT);
class netlist_terminal_t : public netlist_core_terminal_t class ATTR_ALIGN netlist_terminal_t : public netlist_core_terminal_t
{ {
NETLIST_PREVENT_COPYING(netlist_terminal_t) NETLIST_PREVENT_COPYING(netlist_terminal_t)
public: public:

View File

@ -64,6 +64,19 @@ public:
m_list = NULL; m_list = NULL;
} }
ATTR_HOT inline operator _ListClass * () { return m_list; }
ATTR_HOT inline operator const _ListClass * const () { return m_list; }
/* using the [] operator will not allow gcc to vectorize code because
* basically a pointer is returned.
* array works around this.
*/
ATTR_HOT inline _ListClass *array() { return m_list; }
ATTR_HOT inline _ListClass& operator[](const int index) { return m_list[index]; }
ATTR_HOT inline const _ListClass& operator[](const int index) const { return m_list[index]; }
ATTR_HOT inline void add(const _ListClass &elem) ATTR_HOT inline void add(const _ListClass &elem)
{ {
if (m_count >= m_num_elements){ if (m_count >= m_num_elements){
@ -140,9 +153,6 @@ public:
clear(); clear();
} }
ATTR_HOT inline _ListClass& operator[](const int & index) { return m_list[index]; }
ATTR_HOT inline const _ListClass& operator[](const int & index) const { return m_list[index]; }
private: private:
ATTR_HOT inline void resize(const int new_size) ATTR_HOT inline void resize(const int new_size)
{ {