mirror of
https://github.com/holub/mame
synced 2025-07-05 09:57:47 +03:00
netlist: more code cleanup. (nw)
- avoid duplication in solver parameter code - matrix sort type is now a parameter
This commit is contained in:
parent
552d31e6c0
commit
2de7ed7ddc
@ -1015,12 +1015,27 @@ namespace netlist
|
|||||||
public:
|
public:
|
||||||
param_num_t(device_t &device, const pstring &name, const T val);
|
param_num_t(device_t &device, const pstring &name, const T val);
|
||||||
|
|
||||||
const T operator()() const NL_NOEXCEPT { return m_param; }
|
T operator()() const NL_NOEXCEPT { return m_param; }
|
||||||
|
operator T() const NL_NOEXCEPT { return m_param; }
|
||||||
|
|
||||||
void setTo(const T ¶m) { set(m_param, param); }
|
void setTo(const T ¶m) { set(m_param, param); }
|
||||||
private:
|
private:
|
||||||
T m_param;
|
T m_param;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class param_enum_t final: public param_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
param_enum_t(device_t &device, const pstring &name, const T val);
|
||||||
|
|
||||||
|
T operator()() const NL_NOEXCEPT { return T(m_param); }
|
||||||
|
operator T() const NL_NOEXCEPT { return T(m_param); }
|
||||||
|
void setTo(const T ¶m) { set(m_param, static_cast<int>(param)); }
|
||||||
|
private:
|
||||||
|
int m_param;
|
||||||
|
};
|
||||||
|
|
||||||
/* FIXME: these should go as well */
|
/* FIXME: these should go as well */
|
||||||
using param_logic_t = param_num_t<bool>;
|
using param_logic_t = param_num_t<bool>;
|
||||||
using param_int_t = param_num_t<int>;
|
using param_int_t = param_num_t<int>;
|
||||||
@ -1628,6 +1643,24 @@ namespace netlist
|
|||||||
device.state().save(*this, m_param, this->name(), "m_param");
|
device.state().save(*this, m_param, this->name(), "m_param");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
param_enum_t<T>::param_enum_t(device_t &device, const pstring &name, const T val)
|
||||||
|
: param_t(device, name), m_param(val)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
pstring p = this->get_initial(device, &found);
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
T temp(val);
|
||||||
|
bool ok = temp.set_from_string(p);
|
||||||
|
if (!ok)
|
||||||
|
device.state().log().fatal(MF_INVALID_ENUM_CONVERSION_1_2(name, p));
|
||||||
|
m_param = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
device.state().save(*this, m_param, this->name(), "m_param");
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ST, std::size_t AW, std::size_t DW>
|
template <typename ST, std::size_t AW, std::size_t DW>
|
||||||
param_rom_t<ST, AW, DW>::param_rom_t(device_t &device, const pstring &name)
|
param_rom_t<ST, AW, DW>::param_rom_t(device_t &device, const pstring &name)
|
||||||
: param_data_t(device, name)
|
: param_data_t(device, name)
|
||||||
|
@ -69,6 +69,7 @@ namespace netlist
|
|||||||
PERRMSGV(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1, 1,"You must pass an equal number of pins to DIPPINS {1}")
|
PERRMSGV(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1, 1,"You must pass an equal number of pins to DIPPINS {1}")
|
||||||
PERRMSGV(MF_UNKNOWN_OBJECT_TYPE_1, 1, "Unknown object type {1}")
|
PERRMSGV(MF_UNKNOWN_OBJECT_TYPE_1, 1, "Unknown object type {1}")
|
||||||
PERRMSGV(MF_INVALID_NUMBER_CONVERSION_1_2, 2, "Invalid number conversion {1} : {2}")
|
PERRMSGV(MF_INVALID_NUMBER_CONVERSION_1_2, 2, "Invalid number conversion {1} : {2}")
|
||||||
|
PERRMSGV(MF_INVALID_ENUM_CONVERSION_1_2, 2, "Invalid element found {1} : {2}")
|
||||||
PERRMSGV(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST,1, "Error adding parameter {1} to parameter list")
|
PERRMSGV(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST,1, "Error adding parameter {1} to parameter list")
|
||||||
PERRMSGV(MF_ADDING_1_2_TO_TERMINAL_LIST, 2, "Error adding {1} {2} to terminal list")
|
PERRMSGV(MF_ADDING_1_2_TO_TERMINAL_LIST, 2, "Error adding {1} {2} to terminal list")
|
||||||
PERRMSGV(MF_NET_C_NEEDS_AT_LEAST_2_TERMINAL, 0, "You must pass at least 2 terminals to NET_C")
|
PERRMSGV(MF_NET_C_NEEDS_AT_LEAST_2_TERMINAL, 0, "You must pass at least 2 terminals to NET_C")
|
||||||
|
@ -139,7 +139,7 @@ namespace plib
|
|||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (auto &s : psplit(str, ",", false))
|
for (auto &s : psplit(str, ",", false))
|
||||||
{
|
{
|
||||||
if (s == x)
|
if (trim(s) == x)
|
||||||
return cnt;
|
return cnt;
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
@ -240,6 +240,7 @@ namespace plib
|
|||||||
struct ename : public plib::penum_base { \
|
struct ename : public plib::penum_base { \
|
||||||
enum E { __VA_ARGS__ }; \
|
enum E { __VA_ARGS__ }; \
|
||||||
ename (E v) : m_v(v) { } \
|
ename (E v) : m_v(v) { } \
|
||||||
|
template <typename T> explicit ename(T val) { m_v = static_cast<E>(val); } \
|
||||||
bool set_from_string (const std::string &s) { \
|
bool set_from_string (const std::string &s) { \
|
||||||
static char const *const strings = # __VA_ARGS__; \
|
static char const *const strings = # __VA_ARGS__; \
|
||||||
int f = from_string_int(strings, s.c_str()); \
|
int f = from_string_int(strings, s.c_str()); \
|
||||||
|
@ -44,7 +44,7 @@ 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 matrix_sort_type_e sort, const solver_parameters_t *params)
|
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,7 +56,6 @@ namespace devices
|
|||||||
, m_fb_sync(*this, "FB_sync")
|
, m_fb_sync(*this, "FB_sync")
|
||||||
, m_Q_sync(*this, "Q_sync")
|
, m_Q_sync(*this, "Q_sync")
|
||||||
, m_ops(0)
|
, m_ops(0)
|
||||||
, m_sort(sort)
|
|
||||||
{
|
{
|
||||||
connect_post_start(m_fb_sync, m_Q_sync);
|
connect_post_start(m_fb_sync, m_Q_sync);
|
||||||
}
|
}
|
||||||
@ -203,7 +202,7 @@ namespace devices
|
|||||||
case matrix_sort_type_e::ASCENDING:
|
case matrix_sort_type_e::ASCENDING:
|
||||||
case matrix_sort_type_e::DESCENDING:
|
case matrix_sort_type_e::DESCENDING:
|
||||||
{
|
{
|
||||||
int sort_order = (m_sort == matrix_sort_type_e::DESCENDING ? 1 : -1);
|
int sort_order = (sort == matrix_sort_type_e::DESCENDING ? 1 : -1);
|
||||||
|
|
||||||
for (std::size_t k = 0; k < iN - 1; k++)
|
for (std::size_t k = 0; k < iN - 1; k++)
|
||||||
for (std::size_t i = k+1; i < iN; i++)
|
for (std::size_t i = k+1; i < iN; i++)
|
||||||
@ -244,7 +243,7 @@ namespace devices
|
|||||||
// free all - no longer needed
|
// free all - no longer needed
|
||||||
m_rails_temp.clear();
|
m_rails_temp.clear();
|
||||||
|
|
||||||
sort_terms(m_sort);
|
sort_terms(m_params.m_sort_type);
|
||||||
|
|
||||||
this->set_pointers();
|
this->set_pointers();
|
||||||
|
|
||||||
@ -438,7 +437,7 @@ namespace devices
|
|||||||
if (this_resched > 1 && !m_Q_sync.net().is_queued())
|
if (this_resched > 1 && !m_Q_sync.net().is_queued())
|
||||||
{
|
{
|
||||||
log().warning(MW_NEWTON_LOOPS_EXCEEDED_ON_NET_1(this->name()));
|
log().warning(MW_NEWTON_LOOPS_EXCEEDED_ON_NET_1(this->name()));
|
||||||
m_Q_sync.net().toggle_and_push_to_queue(m_params.m_nr_recalc_delay);
|
m_Q_sync.net().toggle_and_push_to_queue(netlist_time::from_double(m_params.m_nr_recalc_delay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -21,22 +21,66 @@ namespace netlist
|
|||||||
{
|
{
|
||||||
namespace devices
|
namespace devices
|
||||||
{
|
{
|
||||||
/* FIXME: these should become proper devices */
|
P_ENUM(matrix_sort_type_e,
|
||||||
|
NOSORT,
|
||||||
|
ASCENDING,
|
||||||
|
DESCENDING,
|
||||||
|
PREFER_IDENTITY_TOP_LEFT,
|
||||||
|
PREFER_BAND_MATRIX
|
||||||
|
)
|
||||||
|
|
||||||
struct solver_parameters_t
|
struct solver_parameters_t
|
||||||
{
|
{
|
||||||
bool m_pivot;
|
solver_parameters_t(device_t &parent)
|
||||||
nl_double m_accuracy;
|
: m_freq(parent, "FREQ", 48000.0)
|
||||||
nl_double m_dynamic_lte;
|
|
||||||
|
/* iteration parameters */
|
||||||
|
, m_gs_sor(parent, "SOR_FACTOR", 1.059)
|
||||||
|
, m_method(parent, "METHOD", "MAT_CR")
|
||||||
|
, m_accuracy(parent, "ACCURACY", 1e-7)
|
||||||
|
, m_gs_loops(parent, "GS_LOOPS", 9) // Gauss-Seidel loops
|
||||||
|
|
||||||
|
/* general parameters */
|
||||||
|
, m_gmin(parent, "GMIN", 1e-9)
|
||||||
|
, m_pivot(parent, "PIVOT", false) // use pivoting - on supported solvers
|
||||||
|
, m_nr_loops(parent, "NR_LOOPS", 250) // Newton-Raphson loops
|
||||||
|
, m_nr_recalc_delay(parent, "NR_RECALC_DELAY", netlist_time::quantum().as_double()) // Delay to next solve attempt if nr loops exceeded
|
||||||
|
, m_parallel(parent, "PARALLEL", 0)
|
||||||
|
|
||||||
|
/* automatic time step */
|
||||||
|
, m_dynamic_ts(parent, "DYNAMIC_TS", false)
|
||||||
|
, m_dynamic_lte(parent, "DYNAMIC_LTE", 1e-5) // diff/timestep
|
||||||
|
, m_dynamic_min_ts(parent, "DYNAMIC_MIN_TIMESTEP", 1e-6) // nl_double timestep resolution
|
||||||
|
|
||||||
|
/* matrix sorting */
|
||||||
|
, m_sort_type(parent, "SORT_TYPE", matrix_sort_type_e::PREFER_IDENTITY_TOP_LEFT)
|
||||||
|
|
||||||
|
/* special */
|
||||||
|
, m_use_gabs(parent, "USE_GABS", true)
|
||||||
|
, m_use_linear_prediction(parent, "USE_LINEAR_PREDICTION", false) // // savings are eaten up by effort
|
||||||
|
|
||||||
|
{}
|
||||||
|
|
||||||
|
param_double_t m_freq;
|
||||||
|
param_double_t m_gs_sor;
|
||||||
|
param_str_t m_method;
|
||||||
|
param_double_t m_accuracy;
|
||||||
|
param_num_t<std::size_t> m_gs_loops;
|
||||||
|
param_double_t m_gmin;
|
||||||
|
param_logic_t m_pivot;
|
||||||
|
param_int_t m_nr_loops;
|
||||||
|
param_double_t m_nr_recalc_delay;
|
||||||
|
param_int_t m_parallel;
|
||||||
|
param_logic_t m_dynamic_ts;
|
||||||
|
param_double_t m_dynamic_lte;
|
||||||
|
param_double_t m_dynamic_min_ts;
|
||||||
|
param_enum_t<matrix_sort_type_e> m_sort_type;
|
||||||
|
|
||||||
|
param_logic_t m_use_gabs;
|
||||||
|
param_logic_t m_use_linear_prediction;
|
||||||
|
|
||||||
nl_double m_min_timestep;
|
nl_double m_min_timestep;
|
||||||
nl_double m_max_timestep;
|
nl_double m_max_timestep;
|
||||||
nl_double m_gs_sor;
|
|
||||||
bool m_dynamic_ts;
|
|
||||||
std::size_t m_gs_loops;
|
|
||||||
std::size_t m_nr_loops;
|
|
||||||
netlist_time m_nr_recalc_delay;
|
|
||||||
bool m_use_gabs;
|
|
||||||
bool m_use_linear_prediction;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -84,14 +128,6 @@ namespace devices
|
|||||||
analog_net_t *m_proxied_net; // only for proxy nets in analog input logic
|
analog_net_t *m_proxied_net; // only for proxy nets in analog input logic
|
||||||
};
|
};
|
||||||
|
|
||||||
P_ENUM(matrix_sort_type_e,
|
|
||||||
NOSORT,
|
|
||||||
ASCENDING,
|
|
||||||
DESCENDING,
|
|
||||||
PREFER_IDENTITY_TOP_LEFT,
|
|
||||||
PREFER_BAND_MATRIX
|
|
||||||
)
|
|
||||||
|
|
||||||
class matrix_solver_t : public device_t
|
class matrix_solver_t : public device_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -141,7 +177,7 @@ namespace devices
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
matrix_solver_t(netlist_state_t &anetlist, const pstring &name,
|
matrix_solver_t(netlist_state_t &anetlist, const pstring &name,
|
||||||
matrix_sort_type_e sort, 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);
|
||||||
|
|
||||||
@ -279,7 +315,6 @@ namespace devices
|
|||||||
void step(const netlist_time &delta);
|
void step(const netlist_time &delta);
|
||||||
|
|
||||||
std::size_t m_ops;
|
std::size_t m_ops;
|
||||||
const matrix_sort_type_e m_sort;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -30,7 +30,6 @@ 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 solver_parameters_t *params, const std::size_t size);
|
||||||
matrix_solver_direct_t(netlist_state_t &anetlist, const pstring &name, const matrix_sort_type_e sort, const solver_parameters_t *params, const std::size_t size);
|
|
||||||
|
|
||||||
void vsetup(analog_net_t::list_t &nets) override;
|
void vsetup(analog_net_t::list_t &nets) override;
|
||||||
void reset() override { matrix_solver_t::reset(); }
|
void reset() override { matrix_solver_t::reset(); }
|
||||||
@ -210,18 +209,7 @@ 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 solver_parameters_t *params, const std::size_t size)
|
||||||
: matrix_solver_t(anetlist, name, matrix_sort_type_e::ASCENDING, params)
|
: matrix_solver_t(anetlist, name, params)
|
||||||
, m_new_V(size)
|
|
||||||
, m_dim(size)
|
|
||||||
, m_pitch(m_pitch_ABS ? m_pitch_ABS : (((m_dim + 1) + 7) / 8) * 8)
|
|
||||||
, m_A(size * m_pitch)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename FT, int SIZE>
|
|
||||||
matrix_solver_direct_t<FT, SIZE>::matrix_solver_direct_t(netlist_state_t &anetlist, const pstring &name,
|
|
||||||
const matrix_sort_type_e sort, const solver_parameters_t *params, const std::size_t size)
|
|
||||||
: matrix_solver_t(anetlist, name, sort, 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)
|
||||||
|
@ -36,7 +36,7 @@ namespace devices
|
|||||||
|
|
||||||
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 solver_parameters_t *params, const std::size_t size)
|
||||||
: matrix_solver_t(anetlist, name, matrix_sort_type_e::PREFER_IDENTITY_TOP_LEFT, params)
|
: matrix_solver_t(anetlist, name, params)
|
||||||
, m_dim(size)
|
, m_dim(size)
|
||||||
, RHS(size)
|
, RHS(size)
|
||||||
, new_V(size)
|
, new_V(size)
|
||||||
|
@ -37,7 +37,7 @@ namespace devices
|
|||||||
*/
|
*/
|
||||||
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, const solver_parameters_t *params, const std::size_t size)
|
||||||
// matrix_solver_direct_t<FT, SIZE>(anetlist, name, matrix_solver_t::PREFER_BAND_MATRIX, params, size)
|
// matrix_solver_direct_t<FT, SIZE>(anetlist, name, matrix_solver_t::PREFER_BAND_MATRIX, params, size)
|
||||||
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, matrix_sort_type_e::PREFER_IDENTITY_TOP_LEFT, params, size)
|
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, params, size)
|
||||||
, m_ops(size, 0)
|
, m_ops(size, 0)
|
||||||
, m_gmres(size)
|
, m_gmres(size)
|
||||||
{
|
{
|
||||||
@ -118,7 +118,7 @@ namespace devices
|
|||||||
|
|
||||||
const float_type accuracy = this->m_params.m_accuracy;
|
const float_type accuracy = this->m_params.m_accuracy;
|
||||||
|
|
||||||
auto iter = std::max(plib::constants<std::size_t>::one(), this->m_params.m_gs_loops);
|
auto iter = std::max(plib::constants<std::size_t>::one(), this->m_params.m_gs_loops());
|
||||||
auto gsl = m_gmres.solve(m_ops, this->m_new_V, RHS, iter, accuracy);
|
auto gsl = m_gmres.solve(m_ops, this->m_new_V, RHS, iter, accuracy);
|
||||||
|
|
||||||
this->m_iterative_total += gsl;
|
this->m_iterative_total += gsl;
|
||||||
|
@ -297,7 +297,7 @@ namespace devices
|
|||||||
template <typename FT, int SIZE>
|
template <typename FT, int SIZE>
|
||||||
matrix_solver_sm_t<FT, SIZE>::matrix_solver_sm_t(netlist_state_t &anetlist, const pstring &name,
|
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)
|
const solver_parameters_t *params, const std::size_t size)
|
||||||
: matrix_solver_t(anetlist, name, matrix_sort_type_e::NOSORT, params)
|
: matrix_solver_t(anetlist, name, params)
|
||||||
, m_dim(size)
|
, m_dim(size)
|
||||||
, m_cnt(0)
|
, m_cnt(0)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@ 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, const solver_parameters_t *params, const std::size_t size)
|
||||||
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, matrix_sort_type_e::ASCENDING, params, size)
|
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, 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)
|
||||||
|
@ -33,7 +33,7 @@ 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, const solver_parameters_t *params, std::size_t size)
|
||||||
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, matrix_sort_type_e::ASCENDING, params, size)
|
: matrix_solver_direct_t<FT, SIZE>(anetlist, name, 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)
|
||||||
|
@ -369,7 +369,7 @@ unsigned matrix_solver_w_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphs
|
|||||||
template <typename FT, int SIZE>
|
template <typename FT, int SIZE>
|
||||||
matrix_solver_w_t<FT, SIZE>::matrix_solver_w_t(netlist_state_t &anetlist, const pstring &name,
|
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)
|
const solver_parameters_t *params, const std::size_t size)
|
||||||
: matrix_solver_t(anetlist, name, matrix_sort_type_e::NOSORT, params)
|
: matrix_solver_t(anetlist, name, params)
|
||||||
, m_cnt(0)
|
, m_cnt(0)
|
||||||
, m_dim(size)
|
, m_dim(size)
|
||||||
{
|
{
|
||||||
|
@ -80,7 +80,7 @@ namespace devices
|
|||||||
/* FIXME: Needs a more elegant solution */
|
/* FIXME: Needs a more elegant solution */
|
||||||
bool force_solve = (now < netlist_time::from_double(2 * m_params.m_max_timestep));
|
bool force_solve = (now < netlist_time::from_double(2 * m_params.m_max_timestep));
|
||||||
|
|
||||||
std::size_t nthreads = std::min(static_cast<std::size_t>(m_parallel()), plib::omp::get_max_threads());
|
std::size_t nthreads = std::min(static_cast<std::size_t>(m_params.m_parallel()), plib::omp::get_max_threads());
|
||||||
|
|
||||||
std::vector<matrix_solver_t *> &solvers = (force_solve ? m_mat_solvers_all : m_mat_solvers_timestepping);
|
std::vector<matrix_solver_t *> &solvers = (force_solve ? m_mat_solvers_all : m_mat_solvers_timestepping);
|
||||||
|
|
||||||
@ -119,13 +119,13 @@ namespace devices
|
|||||||
template <typename FT, int SIZE>
|
template <typename FT, int SIZE>
|
||||||
pool_owned_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(std::size_t size, const pstring &solvername)
|
pool_owned_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(std::size_t size, const pstring &solvername)
|
||||||
{
|
{
|
||||||
if (m_method() == "SOR_MAT")
|
if (m_params.m_method() == "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, m_params, size);
|
||||||
//typedef matrix_solver_SOR_mat_t<m_N,storage_N> solver_sor_mat;
|
//typedef matrix_solver_SOR_mat_t<m_N,storage_N> solver_sor_mat;
|
||||||
//return plib::make_unique<solver_sor_mat>(state(), solvername, &m_params, size);
|
//return plib::make_unique<solver_sor_mat>(state(), solvername, &m_params, size);
|
||||||
}
|
}
|
||||||
else if (m_method() == "MAT_CR")
|
else if (m_params.m_method() == "MAT_CR")
|
||||||
{
|
{
|
||||||
if (size > 0) // GCR always outperforms MAT solver
|
if (size > 0) // GCR always outperforms MAT solver
|
||||||
{
|
{
|
||||||
@ -136,54 +136,35 @@ namespace devices
|
|||||||
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, m_params, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_method() == "MAT")
|
else if (m_params.m_method() == "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, m_params, size);
|
||||||
}
|
}
|
||||||
else if (m_method() == "SM")
|
else if (m_params.m_method() == "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, m_params, size);
|
||||||
}
|
}
|
||||||
else if (m_method() == "W")
|
else if (m_params.m_method() == "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, m_params, size);
|
||||||
}
|
}
|
||||||
else if (m_method() == "SOR")
|
else if (m_params.m_method() == "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, m_params, size);
|
||||||
}
|
}
|
||||||
else if (m_method() == "GMRES")
|
else if (m_params.m_method() == "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, m_params, size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log().fatal(MF_UNKNOWN_SOLVER_TYPE(m_method()));
|
log().fatal(MF_UNKNOWN_SOLVER_TYPE(m_params.m_method()));
|
||||||
return pool_owned_ptr<matrix_solver_t>();
|
return pool_owned_ptr<matrix_solver_t>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FT, int SIZE>
|
|
||||||
pool_owned_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver_x(std::size_t size, const pstring &solvername)
|
|
||||||
{
|
|
||||||
if (SIZE > 0)
|
|
||||||
{
|
|
||||||
if (size == SIZE)
|
|
||||||
return create_solver<FT, SIZE>(size, solvername);
|
|
||||||
else
|
|
||||||
return this->create_solver_x<FT, SIZE-1>(size, solvername);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (size * 2 > -SIZE )
|
|
||||||
return create_solver<FT, SIZE>(size, solvername);
|
|
||||||
else
|
|
||||||
return this->create_solver_x<FT, SIZE / 2>(size, solvername);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct net_splitter
|
struct net_splitter
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -245,22 +226,8 @@ namespace devices
|
|||||||
|
|
||||||
void NETLIB_NAME(solver)::post_start()
|
void NETLIB_NAME(solver)::post_start()
|
||||||
{
|
{
|
||||||
m_params.m_pivot = m_pivot();
|
m_params.m_min_timestep = m_params.m_dynamic_min_ts();
|
||||||
m_params.m_accuracy = m_accuracy();
|
m_params.m_max_timestep = netlist_time::from_double(1.0 / m_params.m_freq()).as_double();
|
||||||
/* FIXME: Throw when negative */
|
|
||||||
m_params.m_gs_loops = static_cast<unsigned>(m_gs_loops());
|
|
||||||
m_params.m_nr_loops = static_cast<unsigned>(m_nr_loops());
|
|
||||||
m_params.m_nr_recalc_delay = netlist_time::from_double(m_nr_recalc_delay());
|
|
||||||
m_params.m_dynamic_lte = m_dynamic_lte();
|
|
||||||
m_params.m_gs_sor = m_gs_sor();
|
|
||||||
|
|
||||||
m_params.m_min_timestep = m_dynamic_min_ts();
|
|
||||||
m_params.m_dynamic_ts = (m_dynamic_ts() == 1 ? true : false);
|
|
||||||
m_params.m_max_timestep = netlist_time::from_double(1.0 / m_freq()).as_double();
|
|
||||||
|
|
||||||
m_params.m_use_gabs = m_use_gabs();
|
|
||||||
m_params.m_use_linear_prediction = m_use_linear_prediction();
|
|
||||||
|
|
||||||
|
|
||||||
if (m_params.m_dynamic_ts)
|
if (m_params.m_dynamic_ts)
|
||||||
{
|
{
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
//#define ATTR_ALIGNED(N) __attribute__((aligned(N)))
|
|
||||||
#define ATTR_ALIGNED(N) ATTR_ALIGN
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// solver
|
// solver
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
@ -36,31 +33,7 @@ namespace devices
|
|||||||
NETLIB_CONSTRUCTOR(solver)
|
NETLIB_CONSTRUCTOR(solver)
|
||||||
, m_fb_step(*this, "FB_step")
|
, m_fb_step(*this, "FB_step")
|
||||||
, m_Q_step(*this, "Q_step")
|
, m_Q_step(*this, "Q_step")
|
||||||
, m_freq(*this, "FREQ", 48000.0)
|
, m_params(*this)
|
||||||
|
|
||||||
/* iteration parameters */
|
|
||||||
, m_gs_sor(*this, "SOR_FACTOR", 1.059)
|
|
||||||
, m_method(*this, "METHOD", "MAT_CR")
|
|
||||||
, m_accuracy(*this, "ACCURACY", 1e-7)
|
|
||||||
, m_gs_loops(*this, "GS_LOOPS", 9) // Gauss-Seidel loops
|
|
||||||
|
|
||||||
/* general parameters */
|
|
||||||
, m_gmin(*this, "GMIN", 1e-9)
|
|
||||||
, m_pivot(*this, "PIVOT", false) // use pivoting - on supported solvers
|
|
||||||
, m_nr_loops(*this, "NR_LOOPS", 250) // Newton-Raphson loops
|
|
||||||
, m_nr_recalc_delay(*this, "NR_RECALC_DELAY", netlist_time::quantum().as_double()) // Delay to next solve attempt if nr loops exceeded
|
|
||||||
, m_parallel(*this, "PARALLEL", 0)
|
|
||||||
|
|
||||||
/* automatic time step */
|
|
||||||
, m_dynamic_ts(*this, "DYNAMIC_TS", false)
|
|
||||||
, m_dynamic_lte(*this, "DYNAMIC_LTE", 1e-5) // diff/timestep
|
|
||||||
, m_dynamic_min_ts(*this, "DYNAMIC_MIN_TIMESTEP", 1e-6) // nl_double timestep resolution
|
|
||||||
|
|
||||||
/* special */
|
|
||||||
, m_use_gabs(*this, "USE_GABS", true)
|
|
||||||
, m_use_linear_prediction(*this, "USE_LINEAR_PREDICTION", false) // // savings are eaten up by effort
|
|
||||||
|
|
||||||
, m_params()
|
|
||||||
{
|
{
|
||||||
// internal staff
|
// internal staff
|
||||||
|
|
||||||
@ -70,7 +43,7 @@ namespace devices
|
|||||||
void post_start();
|
void post_start();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
nl_double gmin() const { return m_gmin(); }
|
nl_double gmin() const { return m_params.m_gmin(); }
|
||||||
|
|
||||||
void create_solver_code(std::map<pstring, pstring> &mp);
|
void create_solver_code(std::map<pstring, pstring> &mp);
|
||||||
|
|
||||||
@ -82,23 +55,6 @@ namespace devices
|
|||||||
logic_input_t m_fb_step;
|
logic_input_t m_fb_step;
|
||||||
logic_output_t m_Q_step;
|
logic_output_t m_Q_step;
|
||||||
|
|
||||||
param_double_t m_freq;
|
|
||||||
param_double_t m_gs_sor;
|
|
||||||
param_str_t m_method;
|
|
||||||
param_double_t m_accuracy;
|
|
||||||
param_int_t m_gs_loops;
|
|
||||||
param_double_t m_gmin;
|
|
||||||
param_logic_t m_pivot;
|
|
||||||
param_int_t m_nr_loops;
|
|
||||||
param_double_t m_nr_recalc_delay;
|
|
||||||
param_int_t m_parallel;
|
|
||||||
param_logic_t m_dynamic_ts;
|
|
||||||
param_double_t m_dynamic_lte;
|
|
||||||
param_double_t m_dynamic_min_ts;
|
|
||||||
|
|
||||||
param_logic_t m_use_gabs;
|
|
||||||
param_logic_t m_use_linear_prediction;
|
|
||||||
|
|
||||||
std::vector<pool_owned_ptr<matrix_solver_t>> m_mat_solvers;
|
std::vector<pool_owned_ptr<matrix_solver_t>> m_mat_solvers;
|
||||||
std::vector<matrix_solver_t *> m_mat_solvers_all;
|
std::vector<matrix_solver_t *> m_mat_solvers_all;
|
||||||
std::vector<matrix_solver_t *> m_mat_solvers_timestepping;
|
std::vector<matrix_solver_t *> m_mat_solvers_timestepping;
|
||||||
@ -107,12 +63,9 @@ namespace devices
|
|||||||
|
|
||||||
template <typename FT, int SIZE>
|
template <typename FT, int SIZE>
|
||||||
pool_owned_ptr<matrix_solver_t> create_solver(std::size_t size, const pstring &solvername);
|
pool_owned_ptr<matrix_solver_t> create_solver(std::size_t size, const pstring &solvername);
|
||||||
|
|
||||||
template <typename FT, int SIZE>
|
|
||||||
pool_owned_ptr<matrix_solver_t> create_solver_x(std::size_t size, const pstring &solvername);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace devices
|
} // namespace devices
|
||||||
} // namespace netlist
|
} // namespace netlist
|
||||||
|
|
||||||
#endif /* NLD_SOLVER_H_ */
|
#endif /* NLD_SOLVER_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user