netlist solvers: fix some bad design. (nw)

This commit is contained in:
couriersud 2019-10-30 20:42:49 +01:00
parent c18a414fcc
commit 7c6fdaf499
13 changed files with 215 additions and 264 deletions

View File

@ -42,7 +42,8 @@ namespace devices
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
matrix_solver_t::matrix_solver_t(netlist_state_t &anetlist, const pstring &name, matrix_solver_t::matrix_solver_t(netlist_state_t &anetlist, const pstring &name,
const solver_parameters_t *params) const analog_net_t::list_t &nets,
const solver_parameters_t *params)
: device_t(anetlist, name) : device_t(anetlist, name)
, m_params(*params) , m_params(*params)
, m_stat_calculations(*this, "m_stat_calculations", 0) , m_stat_calculations(*this, "m_stat_calculations", 0)
@ -56,9 +57,10 @@ namespace devices
, m_ops(0) , m_ops(0)
{ {
connect_post_start(m_fb_sync, m_Q_sync); connect_post_start(m_fb_sync, m_Q_sync);
setup_base(nets);
} }
void matrix_solver_t::setup_base(analog_net_t::list_t &nets) void matrix_solver_t::setup_base(const analog_net_t::list_t &nets)
{ {
log().debug("New solver setup\n"); log().debug("New solver setup\n");

View File

@ -162,11 +162,6 @@ namespace devices
public: public:
using list_t = std::vector<matrix_solver_t *>; using list_t = std::vector<matrix_solver_t *>;
void setup(analog_net_t::list_t &nets)
{
vsetup(nets);
}
void solve_base(); void solve_base();
/* after every call to solve, update inputs must be called. /* after every call to solve, update inputs must be called.
@ -206,14 +201,13 @@ namespace devices
protected: protected:
matrix_solver_t(netlist_state_t &anetlist, const pstring &name, matrix_solver_t(netlist_state_t &anetlist, const pstring &name,
const analog_net_t::list_t &nets,
const solver_parameters_t *params); const solver_parameters_t *params);
void sort_terms(matrix_sort_type_e sort); void sort_terms(matrix_sort_type_e sort);
void setup_base(analog_net_t::list_t &nets);
void update_dynamic(); void update_dynamic();
virtual void vsetup(analog_net_t::list_t &nets) = 0;
virtual unsigned vsolve_non_dynamic(const bool newton_raphson) = 0; virtual unsigned vsolve_non_dynamic(const bool newton_raphson) = 0;
netlist_time compute_next_timestep(const double cur_ts); netlist_time compute_next_timestep(const double cur_ts);
@ -391,9 +385,6 @@ namespace devices
state_var<int> m_iterative_fail; state_var<int> m_iterative_fail;
state_var<int> m_iterative_total; state_var<int> m_iterative_total;
private: private:
state_var<netlist_time> m_last_step; state_var<netlist_time> m_last_step;
@ -403,6 +394,9 @@ namespace devices
logic_input_t m_fb_sync; logic_input_t m_fb_sync;
logic_output_t m_Q_sync; logic_output_t m_Q_sync;
/* base setup - called from constructor */
void setup_base(const analog_net_t::list_t &nets);
/* calculate matrix */ /* calculate matrix */
void setup_matrix(); void setup_matrix();

View File

@ -29,9 +29,10 @@ namespace devices
using float_type = FT; using float_type = FT;
matrix_solver_direct_t(netlist_state_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size); matrix_solver_direct_t(netlist_state_t &anetlist, const pstring &name,
const analog_net_t::list_t &nets,
const solver_parameters_t *params, const std::size_t size);
void vsetup(analog_net_t::list_t &nets) override;
void reset() override { matrix_solver_t::reset(); } void reset() override { matrix_solver_t::reset(); }
protected: protected:
@ -65,25 +66,6 @@ namespace devices
// matrix_solver_direct // matrix_solver_direct
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename FT, int SIZE>
void matrix_solver_direct_t<FT, SIZE>::vsetup(analog_net_t::list_t &nets)
{
matrix_solver_t::setup_base(nets);
/* add RHS element */
for (std::size_t k = 0; k < size(); k++)
{
terms_for_net_t & t = m_terms[k];
if (!plib::container::contains(t.m_nzrd, static_cast<unsigned>(size())))
t.m_nzrd.push_back(static_cast<unsigned>(size()));
}
// FIXME: This shouldn't be necessary ...
for (std::size_t k = 0; k < size(); k++)
state().save(*this, RHS(k), this->name(), plib::pfmt("RHS.{1}")(k));
}
template <typename FT, int SIZE> template <typename FT, int SIZE>
void matrix_solver_direct_t<FT, SIZE>::LE_solve() void matrix_solver_direct_t<FT, SIZE>::LE_solve()
{ {
@ -210,13 +192,27 @@ namespace devices
template <typename FT, int SIZE> template <typename FT, int SIZE>
matrix_solver_direct_t<FT, SIZE>::matrix_solver_direct_t(netlist_state_t &anetlist, const pstring &name, matrix_solver_direct_t<FT, SIZE>::matrix_solver_direct_t(netlist_state_t &anetlist, const pstring &name,
const solver_parameters_t *params, const std::size_t size) const analog_net_t::list_t &nets,
: matrix_solver_t(anetlist, name, params) const solver_parameters_t *params,
const std::size_t size)
: matrix_solver_t(anetlist, name, nets, params)
, m_new_V(size) , m_new_V(size)
, m_dim(size) , m_dim(size)
, m_pitch(m_pitch_ABS ? m_pitch_ABS : (((m_dim + 1) + 7) / 8) * 8) , m_pitch(m_pitch_ABS ? m_pitch_ABS : (((m_dim + 1) + 7) / 8) * 8)
, m_A(size, m_pitch) , m_A(size, m_pitch)
{ {
/* add RHS element */
for (std::size_t k = 0; k < this->size(); k++)
{
terms_for_net_t & t = m_terms[k];
if (!plib::container::contains(t.m_nzrd, static_cast<unsigned>(this->size())))
t.m_nzrd.push_back(static_cast<unsigned>(this->size()));
}
// FIXME: This shouldn't be necessary ...
for (std::size_t k = 0; k < this->size(); k++)
state().save(*this, RHS(k), this->name(), plib::pfmt("RHS.{1}")(k));
} }
} // namespace devices } // namespace devices

View File

@ -23,8 +23,10 @@ namespace devices
using float_type = FT; using float_type = FT;
using base_type = matrix_solver_direct_t<FT, 1>; using base_type = matrix_solver_direct_t<FT, 1>;
matrix_solver_direct1_t(netlist_state_t &anetlist, const pstring &name, const solver_parameters_t *params) matrix_solver_direct1_t(netlist_state_t &anetlist, const pstring &name,
: matrix_solver_direct_t<FT, 1>(anetlist, name, params, 1) const analog_net_t::list_t &nets,
const solver_parameters_t *params)
: matrix_solver_direct_t<FT, 1>(anetlist, name, nets, params, 1)
{} {}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------

View File

@ -27,9 +27,11 @@ namespace devices
using float_type = FT; using float_type = FT;
matrix_solver_direct2_t(netlist_state_t &anetlist, const pstring &name, const solver_parameters_t *params) matrix_solver_direct2_t(netlist_state_t &anetlist, const pstring &name,
: matrix_solver_direct_t<double, 2>(anetlist, name, params, 2) const analog_net_t::list_t &nets,
{} const solver_parameters_t *params)
: matrix_solver_direct_t<FT, 2>(anetlist, name, nets, params, 2)
{}
unsigned vsolve_non_dynamic(const bool newton_raphson) override unsigned vsolve_non_dynamic(const bool newton_raphson) override
{ {
this->build_LE_A(*this); this->build_LE_A(*this);

View File

@ -35,19 +35,84 @@ namespace devices
static constexpr const std::size_t storage_N = 100; static constexpr const std::size_t storage_N = 100;
matrix_solver_GCR_t(netlist_state_t &anetlist, const pstring &name, matrix_solver_GCR_t(netlist_state_t &anetlist, const pstring &name,
const solver_parameters_t *params, const std::size_t size) const analog_net_t::list_t &nets,
: matrix_solver_t(anetlist, name, params) const solver_parameters_t *params, const std::size_t size)
, m_dim(size) : matrix_solver_t(anetlist, name, nets, params)
, RHS(size) , m_dim(size)
, new_V(size) , RHS(size)
, mat(static_cast<typename mat_type::index_type>(size)) , new_V(size)
, m_proc() , mat(static_cast<typename mat_type::index_type>(size))
, m_proc()
{
const std::size_t iN = this->N();
/* build the final matrix */
std::vector<std::vector<unsigned>> fill(iN);
std::size_t raw_elements = 0;
for (std::size_t k = 0; k < iN; k++)
{ {
fill[k].resize(iN, decltype(mat)::FILL_INFINITY);
for (auto &j : this->m_terms[k].m_nz)
{
fill[k][j] = 0;
raw_elements++;
}
} }
auto gr = mat.gaussian_extend_fill_mat(fill);
log_fill(fill, mat);
mat.build_from_fill_mat(fill);
for (mat_index_type k=0; k<iN; k++)
{
std::size_t cnt(0);
/* build pointers into the compressed row format matrix for each terminal */
for (std::size_t j=0; j< this->m_terms[k].railstart();j++)
{
int other = this->m_terms[k].m_connected_net_idx[j];
for (auto i = mat.row_idx[k]; i < mat.row_idx[k+1]; i++)
if (other == static_cast<int>(mat.col_idx[i]))
{
m_mat_ptr[k][j] = &mat.A[i];
cnt++;
break;
}
}
nl_assert(cnt == this->m_terms[k].railstart());
m_mat_ptr[k][this->m_terms[k].railstart()] = &mat.A[mat.diag[k]];
}
this->log().verbose("maximum fill: {1}", gr.first);
this->log().verbose("Post elimination occupancy ratio: {2} Ops: {1}", gr.second,
static_cast<double>(mat.nz_num) / static_cast<double>(iN * iN));
this->log().verbose(" Pre elimination occupancy ratio: {2}",
static_cast<double>(raw_elements) / static_cast<double>(iN * iN));
// FIXME: Move me
if (state().lib().isLoaded())
{
pstring symname = static_compile_name();
m_proc.load(this->state().lib(), symname);
if (m_proc.resolved())
{
this->log().info("External static solver {1} found ...", symname);
}
else
{
this->log().warning("External static solver {1} not found ...", symname);
}
}
}
constexpr std::size_t N() const { return m_dim; } constexpr std::size_t N() const { return m_dim; }
void vsetup(analog_net_t::list_t &nets) override;
unsigned vsolve_non_dynamic(const bool newton_raphson) override; unsigned vsolve_non_dynamic(const bool newton_raphson) override;
std::pair<pstring, pstring> create_solver_code() override; std::pair<pstring, pstring> create_solver_code() override;
@ -74,78 +139,6 @@ namespace devices
// matrix_solver - GCR // matrix_solver - GCR
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename FT, int SIZE>
void matrix_solver_GCR_t<FT, SIZE>::vsetup(analog_net_t::list_t &nets)
{
setup_base(nets);
const std::size_t iN = this->N();
/* build the final matrix */
std::vector<std::vector<unsigned>> fill(iN);
std::size_t raw_elements = 0;
for (std::size_t k = 0; k < iN; k++)
{
fill[k].resize(iN, decltype(mat)::FILL_INFINITY);
for (auto &j : this->m_terms[k].m_nz)
{
fill[k][j] = 0;
raw_elements++;
}
}
auto gr = mat.gaussian_extend_fill_mat(fill);
log_fill(fill, mat);
mat.build_from_fill_mat(fill);
for (mat_index_type k=0; k<iN; k++)
{
std::size_t cnt(0);
/* build pointers into the compressed row format matrix for each terminal */
for (std::size_t j=0; j< this->m_terms[k].railstart();j++)
{
int other = this->m_terms[k].m_connected_net_idx[j];
for (auto i = mat.row_idx[k]; i < mat.row_idx[k+1]; i++)
if (other == static_cast<int>(mat.col_idx[i]))
{
m_mat_ptr[k][j] = &mat.A[i];
cnt++;
break;
}
}
nl_assert(cnt == this->m_terms[k].railstart());
m_mat_ptr[k][this->m_terms[k].railstart()] = &mat.A[mat.diag[k]];
}
this->log().verbose("maximum fill: {1}", gr.first);
this->log().verbose("Post elimination occupancy ratio: {2} Ops: {1}", gr.second,
static_cast<double>(mat.nz_num) / static_cast<double>(iN * iN));
this->log().verbose(" Pre elimination occupancy ratio: {2}",
static_cast<double>(raw_elements) / static_cast<double>(iN * iN));
// FIXME: Move me
if (state().lib().isLoaded())
{
pstring symname = static_compile_name();
m_proc.load(this->state().lib(), symname);
if (m_proc.resolved())
{
this->log().info("External static solver {1} found ...", symname);
}
else
{
this->log().warning("External static solver {1} not found ...", symname);
}
}
}
template <typename FT, int SIZE> template <typename FT, int SIZE>
void matrix_solver_GCR_t<FT, SIZE>::generate_code(plib::putf8_fmt_writer &strm) void matrix_solver_GCR_t<FT, SIZE>::generate_code(plib::putf8_fmt_writer &strm)
{ {

View File

@ -35,15 +35,51 @@ namespace devices
* maximize the efficiency of the incomplete LUT. * maximize the efficiency of the incomplete LUT.
* This is already preconditioning. * This is already preconditioning.
*/ */
matrix_solver_GMRES_t(netlist_state_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size) matrix_solver_GMRES_t(netlist_state_t &anetlist, const pstring &name,
// matrix_solver_direct_t<FT, SIZE>(anetlist, name, matrix_solver_t::PREFER_BAND_MATRIX, params, size) analog_net_t::list_t &nets,
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, params, size) const solver_parameters_t *params,
const std::size_t size)
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, nets, params, size)
, m_ops(size, 0) , m_ops(size, 0)
, m_gmres(size) , m_gmres(size)
{ {
const std::size_t iN = this->size();
std::vector<std::vector<unsigned>> fill(iN);
for (std::size_t k=0; k<iN; k++)
{
fill[k].resize(iN, decltype(m_ops.m_mat)::FILL_INFINITY);
terms_for_net_t & row = this->m_terms[k];
for (const auto &nz_j : row.m_nz)
{
fill[k][static_cast<mattype>(nz_j)] = 0;
}
} }
void vsetup(analog_net_t::list_t &nets) override; m_ops.build(fill);
this->log_fill(fill, m_ops.m_mat);
/* build pointers into the compressed row format matrix for each terminal */
for (std::size_t k=0; k<iN; k++)
{
std::size_t cnt = 0;
for (std::size_t j=0; j< this->m_terms[k].railstart();j++)
{
for (std::size_t i = m_ops.m_mat.row_idx[k]; i<m_ops.m_mat.row_idx[k+1]; i++)
if (this->m_terms[k].m_connected_net_idx[j] == static_cast<int>(m_ops.m_mat.col_idx[i]))
{
this->m_mat_ptr[k][j] = &m_ops.m_mat.A[i];
cnt++;
break;
}
}
nl_assert(cnt == this->m_terms[k].railstart());
this->m_mat_ptr[k][this->m_terms[k].railstart()] = &m_ops.m_mat.A[m_ops.m_mat.diag[k]];
}
}
unsigned vsolve_non_dynamic(const bool newton_raphson) override; unsigned vsolve_non_dynamic(const bool newton_raphson) override;
private: private:
@ -60,48 +96,6 @@ namespace devices
// matrix_solver - GMRES // matrix_solver - GMRES
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename FT, int SIZE>
void matrix_solver_GMRES_t<FT, SIZE>::vsetup(analog_net_t::list_t &nets)
{
matrix_solver_direct_t<FT, SIZE>::vsetup(nets);
const std::size_t iN = this->size();
std::vector<std::vector<unsigned>> fill(iN);
for (std::size_t k=0; k<iN; k++)
{
fill[k].resize(iN, decltype(m_ops.m_mat)::FILL_INFINITY);
terms_for_net_t & row = this->m_terms[k];
for (const auto &nz_j : row.m_nz)
{
fill[k][static_cast<mattype>(nz_j)] = 0;
}
}
m_ops.build(fill);
this->log_fill(fill, m_ops.m_mat);
/* build pointers into the compressed row format matrix for each terminal */
for (std::size_t k=0; k<iN; k++)
{
std::size_t cnt = 0;
for (std::size_t j=0; j< this->m_terms[k].railstart();j++)
{
for (std::size_t i = m_ops.m_mat.row_idx[k]; i<m_ops.m_mat.row_idx[k+1]; i++)
if (this->m_terms[k].m_connected_net_idx[j] == static_cast<int>(m_ops.m_mat.col_idx[i]))
{
this->m_mat_ptr[k][j] = &m_ops.m_mat.A[i];
cnt++;
break;
}
}
nl_assert(cnt == this->m_terms[k].railstart());
this->m_mat_ptr[k][this->m_terms[k].railstart()] = &m_ops.m_mat.A[m_ops.m_mat.diag[k]];
}
}
template <typename FT, int SIZE> template <typename FT, int SIZE>
unsigned matrix_solver_GMRES_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson) unsigned matrix_solver_GMRES_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson)
{ {

View File

@ -57,9 +57,17 @@ namespace devices
static constexpr const std::size_t storage_N = 100; static constexpr const std::size_t storage_N = 100;
matrix_solver_sm_t(netlist_state_t &anetlist, const pstring &name, matrix_solver_sm_t(netlist_state_t &anetlist, const pstring &name,
const solver_parameters_t *params, const std::size_t size); const analog_net_t::list_t &nets,
const solver_parameters_t *params, const std::size_t size)
: matrix_solver_t(anetlist, name, nets, params)
, m_dim(size)
, m_cnt(0)
{
/* FIXME: Shouldn't be necessary */
for (std::size_t k = 0; k < this->size(); k++)
state().save(*this, RHS(k), this->name(), plib::pfmt("RHS.{1}")(k));
}
void vsetup(analog_net_t::list_t &nets) override;
void reset() override { matrix_solver_t::reset(); } void reset() override { matrix_solver_t::reset(); }
protected: protected:
@ -112,16 +120,6 @@ namespace devices
// matrix_solver_direct // matrix_solver_direct
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename FT, int SIZE>
void matrix_solver_sm_t<FT, SIZE>::vsetup(analog_net_t::list_t &nets)
{
matrix_solver_t::setup_base(nets);
/* FIXME: Shouldn't be necessary */
for (std::size_t k = 0; k < size(); k++)
state().save(*this, RHS(k), this->name(), plib::pfmt("RHS.{1}")(k));
}
template <typename FT, int SIZE> template <typename FT, int SIZE>
void matrix_solver_sm_t<FT, SIZE>::LE_invert() void matrix_solver_sm_t<FT, SIZE>::LE_invert()
{ {
@ -298,14 +296,6 @@ namespace devices
return this->solve_non_dynamic(newton_raphson); return this->solve_non_dynamic(newton_raphson);
} }
template <typename FT, int SIZE>
matrix_solver_sm_t<FT, SIZE>::matrix_solver_sm_t(netlist_state_t &anetlist, const pstring &name,
const solver_parameters_t *params, const std::size_t size)
: matrix_solver_t(anetlist, name, params)
, m_dim(size)
, m_cnt(0)
{
}
} // namespace devices } // namespace devices
} // namespace netlist } // namespace netlist

View File

@ -29,8 +29,10 @@ public:
using float_type = FT; using float_type = FT;
matrix_solver_SOR_t(netlist_state_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size) matrix_solver_SOR_t(netlist_state_t &anetlist, const pstring &name,
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, params, size) analog_net_t::list_t &nets,
const solver_parameters_t *params, const std::size_t size)
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, nets, params, size)
, m_lp_fact(*this, "m_lp_fact", 0) , m_lp_fact(*this, "m_lp_fact", 0)
, w(size, 0.0) , w(size, 0.0)
, one_m_w(size, 0.0) , one_m_w(size, 0.0)
@ -39,7 +41,6 @@ public:
{ {
} }
void vsetup(analog_net_t::list_t &nets) override;
unsigned vsolve_non_dynamic(const bool newton_raphson) override; unsigned vsolve_non_dynamic(const bool newton_raphson) override;
private: private:
@ -54,13 +55,6 @@ private:
// matrix_solver - Gauss - Seidel // matrix_solver - Gauss - Seidel
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename FT, int SIZE>
void matrix_solver_SOR_t<FT, SIZE>::vsetup(analog_net_t::list_t &nets)
{
matrix_solver_direct_t<FT, SIZE>::vsetup(nets);
}
template <typename FT, int SIZE> template <typename FT, int SIZE>
unsigned matrix_solver_SOR_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson) unsigned matrix_solver_SOR_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson)
{ {

View File

@ -32,16 +32,16 @@ namespace devices
using float_type = FT; using float_type = FT;
matrix_solver_SOR_mat_t(netlist_state_t &anetlist, const pstring &name, const solver_parameters_t *params, std::size_t size) matrix_solver_SOR_mat_t(netlist_state_t &anetlist, const pstring &name,
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, params, size) const analog_net_t::list_t &nets,
const solver_parameters_t *params, std::size_t size)
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, nets, params, size)
, m_Vdelta(*this, "m_Vdelta", std::vector<float_type>(size)) , m_Vdelta(*this, "m_Vdelta", std::vector<float_type>(size))
, m_omega(*this, "m_omega", params->m_gs_sor) , m_omega(*this, "m_omega", params->m_gs_sor)
, m_lp_fact(*this, "m_lp_fact", 0) , m_lp_fact(*this, "m_lp_fact", 0)
{ {
} }
void vsetup(analog_net_t::list_t &nets) override;
unsigned vsolve_non_dynamic(const bool newton_raphson) override; unsigned vsolve_non_dynamic(const bool newton_raphson) override;
private: private:
@ -57,12 +57,6 @@ namespace devices
// matrix_solver - Gauss - Seidel // matrix_solver - Gauss - Seidel
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename FT, int SIZE>
void matrix_solver_SOR_mat_t<FT, SIZE>::vsetup(analog_net_t::list_t &nets)
{
matrix_solver_direct_t<FT, SIZE>::vsetup(nets);
}
#if 0 #if 0
//FIXME: move to solve_base //FIXME: move to solve_base
template <unsigned m_N, unsigned storage_N> template <unsigned m_N, unsigned storage_N>

View File

@ -63,9 +63,18 @@ public:
// FIXME: dirty hack to make this compile // FIXME: dirty hack to make this compile
static constexpr const std::size_t storage_N = 100; static constexpr const std::size_t storage_N = 100;
matrix_solver_w_t(netlist_state_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size); matrix_solver_w_t(netlist_state_t &anetlist, const pstring &name,
const analog_net_t::list_t &nets,
const solver_parameters_t *params, const std::size_t size)
: matrix_solver_t(anetlist, name, nets, params)
, m_cnt(0)
, m_dim(size)
{
// FIXME: This shouldn't be necessary, recalculate on each entry ...
for (std::size_t k = 0; k < this->size(); k++)
state().save(*this, RHS(k), this->name(), plib::pfmt("RHS.{1}")(k));
}
void vsetup(analog_net_t::list_t &nets) override;
void reset() override { matrix_solver_t::reset(); } void reset() override { matrix_solver_t::reset(); }
protected: protected:
@ -125,18 +134,6 @@ private:
// matrix_solver_direct // matrix_solver_direct
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename FT, int SIZE>
void matrix_solver_w_t<FT, SIZE>::vsetup(analog_net_t::list_t &nets)
{
matrix_solver_t::setup_base(nets);
// FIXME: This shouldn't be necessary, recalculate on each entry ...
for (std::size_t k = 0; k < size(); k++)
state().save(*this, RHS(k), this->name(), plib::pfmt("RHS.{1}")(k));
}
template <typename FT, int SIZE> template <typename FT, int SIZE>
void matrix_solver_w_t<FT, SIZE>::LE_invert() void matrix_solver_w_t<FT, SIZE>::LE_invert()
{ {
@ -369,15 +366,6 @@ unsigned matrix_solver_w_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphs
return this->solve_non_dynamic(newton_raphson); return this->solve_non_dynamic(newton_raphson);
} }
template <typename FT, int SIZE>
matrix_solver_w_t<FT, SIZE>::matrix_solver_w_t(netlist_state_t &anetlist, const pstring &name,
const solver_parameters_t *params, const std::size_t size)
: matrix_solver_t(anetlist, name, params)
, m_cnt(0)
, m_dim(size)
{
}
} //namespace devices } //namespace devices
} // namespace netlist } // namespace netlist

View File

@ -110,39 +110,43 @@ namespace devices
} }
template <class C> template <class C>
plib::unique_ptr<matrix_solver_t> create_it(netlist_state_t &nl, pstring name, solver_parameters_t &params, std::size_t size) plib::unique_ptr<matrix_solver_t> create_it(netlist_state_t &nl, pstring name,
analog_net_t::list_t &nets,
solver_parameters_t &params, std::size_t size)
{ {
return plib::make_unique<C>(nl, name, &params, size); return plib::make_unique<C>(nl, name, nets, &params, size);
} }
template <typename FT, int SIZE> template <typename FT, int SIZE>
plib::unique_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(std::size_t size, const pstring &solvername) plib::unique_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(std::size_t size,
const pstring &solvername,
analog_net_t::list_t &nets)
{ {
switch (m_params.m_method()) switch (m_params.m_method())
{ {
case matrix_type_e::MAT_CR: case matrix_type_e::MAT_CR:
if (size > 0) // GCR always outperforms MAT solver if (size > 0) // GCR always outperforms MAT solver
{ {
return create_it<matrix_solver_GCR_t<FT, SIZE>>(state(), solvername, m_params, size); return create_it<matrix_solver_GCR_t<FT, SIZE>>(state(), solvername, nets, m_params, size);
} }
else else
{ {
return create_it<matrix_solver_direct_t<FT, SIZE>>(state(), solvername, m_params, size); return create_it<matrix_solver_direct_t<FT, SIZE>>(state(), solvername, nets, m_params, size);
} }
case matrix_type_e::SOR_MAT: case matrix_type_e::SOR_MAT:
return create_it<matrix_solver_SOR_mat_t<FT, SIZE>>(state(), solvername, m_params, size); return create_it<matrix_solver_SOR_mat_t<FT, SIZE>>(state(), solvername, nets, m_params, size);
case matrix_type_e::MAT: case matrix_type_e::MAT:
return create_it<matrix_solver_direct_t<FT, SIZE>>(state(), solvername, m_params, size); return create_it<matrix_solver_direct_t<FT, SIZE>>(state(), solvername, nets, m_params, size);
case matrix_type_e::SM: case matrix_type_e::SM:
/* Sherman-Morrison Formula */ /* Sherman-Morrison Formula */
return create_it<matrix_solver_sm_t<FT, SIZE>>(state(), solvername, m_params, size); return create_it<matrix_solver_sm_t<FT, SIZE>>(state(), solvername, nets, m_params, size);
case matrix_type_e::W: case matrix_type_e::W:
/* Woodbury Formula */ /* Woodbury Formula */
return create_it<matrix_solver_w_t<FT, SIZE>>(state(), solvername, m_params, size); return create_it<matrix_solver_w_t<FT, SIZE>>(state(), solvername, nets, m_params, size);
case matrix_type_e::SOR: case matrix_type_e::SOR:
return create_it<matrix_solver_SOR_t<FT, SIZE>>(state(), solvername, m_params, size); return create_it<matrix_solver_SOR_t<FT, SIZE>>(state(), solvername, nets, m_params, size);
case matrix_type_e::GMRES: case matrix_type_e::GMRES:
return create_it<matrix_solver_GMRES_t<FT, SIZE>>(state(), solvername, m_params, size); return create_it<matrix_solver_GMRES_t<FT, SIZE>>(state(), solvername, nets, m_params, size);
} }
return plib::unique_ptr<matrix_solver_t>(); return plib::unique_ptr<matrix_solver_t>();
} }
@ -227,35 +231,35 @@ namespace devices
switch (net_count) switch (net_count)
{ {
case 1: case 1:
ms = plib::make_unique<matrix_solver_direct1_t<double>>(state(), sname, &m_params); ms = plib::make_unique<matrix_solver_direct1_t<double>>(state(), sname, grp, &m_params);
break; break;
case 2: case 2:
ms = plib::make_unique<matrix_solver_direct2_t<double>>(state(), sname, &m_params); ms = plib::make_unique<matrix_solver_direct2_t<double>>(state(), sname, grp, &m_params);
break; break;
#if 1 #if 0
case 3: case 3:
ms = create_solver<double, 3>(3, sname); ms = create_solver<double, 3>(3, sname, grp);
break; break;
case 4: case 4:
ms = create_solver<double, 4>(4, sname); ms = create_solver<double, 4>(4, sname, grp);
break; break;
case 5: case 5:
ms = create_solver<double, 5>(5, sname); ms = create_solver<double, 5>(5, sname, grp);
break; break;
case 6: case 6:
ms = create_solver<double, 6>(6, sname); ms = create_solver<double, 6>(6, sname, grp);
break; break;
case 7: case 7:
ms = create_solver<double, 7>(7, sname); ms = create_solver<double, 7>(7, sname, grp);
break; break;
case 8: case 8:
ms = create_solver<double, 8>(8, sname); ms = create_solver<double, 8>(8, sname, grp);
break; break;
case 9: case 9:
ms = create_solver<double, 9>(9, sname); ms = create_solver<double, 9>(9, sname, grp);
break; break;
case 10: case 10:
ms = create_solver<double, 10>(10, sname); ms = create_solver<double, 10>(10, sname, grp);
break; break;
#if 0 #if 0
case 11: case 11:
@ -282,7 +286,7 @@ namespace devices
#endif #endif
#if 1 #if 1
case 87: case 87:
ms = create_solver<double,86>(86, sname); ms = create_solver<double,86>(86, sname, grp);
break; break;
#endif #endif
#endif #endif
@ -290,42 +294,39 @@ namespace devices
log().info(MI_NO_SPECIFIC_SOLVER(net_count)); log().info(MI_NO_SPECIFIC_SOLVER(net_count));
if (net_count <= 8) if (net_count <= 8)
{ {
ms = create_solver<double, -8>(net_count, sname); ms = create_solver<double, -8>(net_count, sname, grp);
} }
else if (net_count <= 16) else if (net_count <= 16)
{ {
ms = create_solver<double, -16>(net_count, sname); ms = create_solver<double, -16>(net_count, sname, grp);
} }
else if (net_count <= 32) else if (net_count <= 32)
{ {
ms = create_solver<double, -32>(net_count, sname); ms = create_solver<double, -32>(net_count, sname, grp);
} }
else if (net_count <= 64) else if (net_count <= 64)
{ {
ms = create_solver<double, -64>(net_count, sname); ms = create_solver<double, -64>(net_count, sname, grp);
} }
else if (net_count <= 128) else if (net_count <= 128)
{ {
ms = create_solver<double, -128>(net_count, sname); ms = create_solver<double, -128>(net_count, sname, grp);
} }
else if (net_count <= 256) else if (net_count <= 256)
{ {
ms = create_solver<double, -256>(net_count, sname); ms = create_solver<double, -256>(net_count, sname, grp);
} }
else if (net_count <= 512) else if (net_count <= 512)
{ {
ms = create_solver<double, -512>(net_count, sname); ms = create_solver<double, -512>(net_count, sname, grp);
} }
else else
{ {
ms = create_solver<double, 0>(net_count, sname); ms = create_solver<double, 0>(net_count, sname, grp);
} }
break; break;
} }
// FIXME ...
ms->setup(grp);
log().verbose("Solver {1}", ms->name()); log().verbose("Solver {1}", ms->name());
log().verbose(" ==> {1} nets", grp.size()); log().verbose(" ==> {1} nets", grp.size());
log().verbose(" has {1} elements", ms->has_dynamic_devices() ? "dynamic" : "no dynamic"); log().verbose(" has {1} elements", ms->has_dynamic_devices() ? "dynamic" : "no dynamic");

View File

@ -58,7 +58,8 @@ namespace devices
solver_parameters_t m_params; solver_parameters_t m_params;
template <typename FT, int SIZE> template <typename FT, int SIZE>
plib::unique_ptr<matrix_solver_t> create_solver(std::size_t size, const pstring &solvername); plib::unique_ptr<matrix_solver_t> create_solver(std::size_t size,
const pstring &solvername, analog_net_t::list_t &nets);
}; };
} // namespace devices } // namespace devices