//NETLIB_CONSTRUCTOR(solver) //detail.family_setter_t m_famsetter; //template <class CLASS> //NETLIB_CONSTRUCTOR(solver) public nld_solver(object owner, string name) : base(owner, name) { m_fb_step = new logic_input_t(this, "FB_step", fb_step <bool_const_false>); //, m_fb_step(*this, "FB_step", NETLIB_DELEGATE(fb_step<false>)) m_Q_step = new logic_output_t(this, "Q_step"); m_params = new solver.solver_parameters_t(this, "", solver.solver_parameter_defaults.get_instance()); m_queue = new nld_solver_queue_type(config.MAX_SOLVER_QUEUE_SIZE, get_solver_id, //queue_type::id_delegate(&NETLIB_NAME(solver).get_solver_id, this), solver_by_id); //queue_type::obj_delegate(&NETLIB_NAME(solver).solver_by_id, this)); // internal stuff state().save(this, (plib.state_manager_t.callback_t)m_queue, this.name(), "m_queue"); connect("FB_step", "Q_step"); }
//typedef FT float_type; //typedef matrix_solver_direct_t<FT, 1> base_type; public matrix_solver_direct1_t(devices.nld_solver main_solver, string name, matrix_solver_t_net_list_t nets, solver.solver_parameters_t params_) : base(main_solver, name, nets, params_, 1) { }
plib.dynproc m_proc; //plib::dynproc<void, FT *, nl_fptype *, nl_fptype *, nl_fptype *, nl_fptype ** > m_proc; public matrix_solver_GCR_t(devices.nld_solver main_solver, string name, matrix_solver_t_net_list_t nets, solver.solver_parameters_t params_, size_t size) : base(main_solver, name, nets, params_, size) { mat = new plib.pGEmatrix_cr <FT, FT_OPS, int_SIZE>((uint16_t)size); //mat(static_cast<typename mat_type::index_type>(size)) m_proc = new plib.dynproc(); size_t iN = this.size(); // build the final matrix std.vector <std.vector <unsigned> > fill = new std.vector <std.vector <unsigned> >(iN); fill.Fill(() => { return(new std.vector <unsigned>()); }); size_t raw_elements = 0; for (size_t k = 0; k < iN; k++) { fill[k].resize(iN, (unsigned)plib.pGEmatrix_cr <FT, FT_OPS, int_SIZE> .constants_e.FILL_INFINITY); foreach (var j in this.m_terms[k].m_nz) { fill[k][j] = 0; raw_elements++; } } var gr = mat.gaussian_extend_fill_mat(fill); this.log_fill(fill, mat); mat.build_from_fill_mat(fill); for (mat_index_type k = 0; k < iN; k++) { size_t cnt = 0; // build pointers into the compressed row format matrix for each terminal for (size_t j = 0; j < this.m_terms[k].railstart(); j++) { int other = this.m_terms[k].m_connected_net_idx[j]; for (var i = mat.row_idx[k]; i < mat.row_idx[k + 1]; i++) { if (other == (int)mat.col_idx[i]) { this.m_mat_ptr.op(k)[j] = new Pointer <FT>(mat.A, i); //this->m_mat_ptr[k][j] = &mat.A[i]; cnt++; break; } } } nl_assert(cnt == this.m_terms[k].railstart()); this.m_mat_ptr.op(k)[this.m_terms[k].railstart()] = new Pointer <FT>(mat.A, mat.diag[k]); //this->m_mat_ptr[k][this->m_terms[k].railstart()] = &mat.A[mat.diag[k]]; } this.state().log().verbose.op("maximum fill: {0}", gr.first); this.state().log().verbose.op("Post elimination occupancy ratio: {1} Ops: {0}", gr.second, (matrix_solver_t_fptype)mat.nz_num / (matrix_solver_t_fptype)(iN * iN)); this.state().log().verbose.op(" Pre elimination occupancy ratio: {0}", (matrix_solver_t_fptype)raw_elements / (matrix_solver_t_fptype)(iN * iN)); // FIXME: Move me // if (this.state().static_solver_lib().isLoaded()) { string symname = static_compile_name(); m_proc.load(this.state().static_solver_lib(), symname); if (m_proc.resolved()) { this.state().log().info.op("External static solver {0} found ...", symname); } else { this.state().log().warning.op("External static solver {0} not found ...", symname); } } }
public void post_start() { log().verbose.op("Scanning net groups ..."); // determine net groups net_splitter splitter = new net_splitter(); splitter.run(state()); log().verbose.op("Found {1} net groups in {2} nets\n", splitter.groups.size(), state().nets().size()); int num_errors = 0; log().verbose.op("checking net consistency ..."); foreach (var grp in splitter.groups) { int railterms = 0; string nets_in_grp = ""; foreach (var n in grp) { nets_in_grp += (n.name() + " "); if (!n.is_analog()) { state().log().error.op(ME_SOLVER_CONSISTENCY_NOT_ANALOG_NET(n.name())); num_errors++; } if (n.is_rail_net()) { state().log().error.op(ME_SOLVER_CONSISTENCY_RAIL_NET(n.name())); num_errors++; } foreach (var t in state().core_terms(n)) { if (!t.has_net()) { state().log().error.op(ME_SOLVER_TERMINAL_NO_NET(t.name())); num_errors++; } else { var otherterm = t is terminal_t ? (terminal_t)t : null; //auto *otherterm = dynamic_cast<terminal_t *>(t); if (otherterm != null) { if (state().setup().get_connected_terminal(otherterm).net().is_rail_net()) { railterms++; } } } } } if (railterms == 0) { state().log().error.op(ME_SOLVER_NO_RAIL_TERMINAL(nets_in_grp)); num_errors++; } } if (num_errors > 0) { throw new nl_exception(MF_SOLVER_CONSISTENCY_ERRORS(num_errors)); } // setup the solvers foreach (var grp in splitter.groups) { nld_solver_solver_ptr ms = null; string sname = new plib.pfmt("Solver_{0}").op(m_mat_solvers.size()); nld_solver_params_uptr params_ = new solver.solver_parameters_t(this, sname + ".", m_params); //params_uptr params = plib::make_unique<solver::solver_parameters_t, solver_arena>(*this, sname + ".", m_params); switch (params_.m_fp_type.op()) { case solver.matrix_fp_type_e.FLOAT: if (!config.use_float_matrix) { log().info.op("FPTYPE {0} not supported. Using DOUBLE", params_.m_fp_type.op().ToString()); } //ms = create_solvers<std::conditional_t<config::use_float_matrix::value, float, double>>(sname, params.get(), grp); if (config.use_float_matrix) { ms = create_solvers <float, plib.constants_operators_float>(sname, params_, grp); } else { ms = create_solvers <double, plib.constants_operators_double>(sname, params_, grp); } break; case solver.matrix_fp_type_e.DOUBLE: ms = create_solvers <double, plib.constants_operators_double>(sname, params_, grp); //ms = create_solvers<double>(sname, params.get(), grp); break; case solver.matrix_fp_type_e.LONGDOUBLE: if (!config.use_long_double_matrix) { log().info.op("FPTYPE {0} not supported. Using DOUBLE", params_.m_fp_type.op().ToString()); } //ms = create_solvers<std::conditional_t<config::use_long_double_matrix::value, long double, double>>(sname, params.get(), grp); if (config.use_long_double_matrix) { throw new emu_unimplemented(); //ms = create_solvers<long double>(sname, params_, grp); } else { ms = create_solvers <double, plib.constants_operators_double>(sname, params_, grp); } break; case solver.matrix_fp_type_e.FLOATQ128: #if (NL_USE_FLOAT128) ms = create_solvers <FLOAT128>(sname, params.get(), grp); #else log().info.op("FPTYPE {0} not supported. Using DOUBLE", params_.m_fp_type.op().ToString()); ms = create_solvers <double, plib.constants_operators_double>(sname, params_, grp); //ms = create_solvers<double>(sname, params.get(), grp); #endif break; } log().verbose.op("Solver {0}", ms.name()); log().verbose.op(" ==> {0} nets", grp.size()); log().verbose.op(" has {0} dynamic elements", ms.dynamic_device_count()); log().verbose.op(" has {0} timestep elements", ms.timestep_device_count()); foreach (var n in grp) { log().verbose.op("Net {0}", n.name()); foreach (var t in state().core_terms(n)) { log().verbose.op(" {0}", t.name()); } } m_mat_params.push_back(params_); m_mat_solvers.push_back(ms); } }
//template <typename FT, int SIZE> nld_solver_solver_ptr create_solver <FT, FT_OPS, int_SIZE>(size_t size, string solvername, solver.solver_parameters_t params_, nld_solver_net_list_t nets) //solver_ptr create_solver(std::size_t size, const pstring &solvername, const solver::solver_parameters_t *params,net_list_t &nets); where FT_OPS : plib.constants_operators <FT>, new() where int_SIZE : int_const, new() { switch (m_params.m_method.op()) { case solver.matrix_type_e.MAT_CR: return(create_it <solver.matrix_solver_GCR_t <FT, FT_OPS, int_SIZE>, FT, FT_OPS, int_SIZE>(this, solvername, nets, params_, size)); //return create_it<solver::matrix_solver_GCR_t<FT, SIZE>>(*this, solvername, nets, params, size); case solver.matrix_type_e.MAT: throw new emu_unimplemented(); #if false return(create_it <solver::matrix_solver_direct_t <FT, SIZE> >(*this, solvername, nets, params, size)); #endif case solver.matrix_type_e.GMRES: throw new emu_unimplemented(); #if false return(create_it <solver::matrix_solver_GMRES_t <FT, SIZE> >(*this, solvername, nets, params, size)); #endif #if NL_USE_ACADEMIC_SOLVERS case solver::matrix_type_e::SOR: return(create_it <solver::matrix_solver_SOR_t <FT, SIZE> >(*this, solvername, nets, params, size)); case solver::matrix_type_e::SOR_MAT: return(create_it <solver::matrix_solver_SOR_mat_t <FT, SIZE> >(*this, solvername, nets, params, size)); case solver::matrix_type_e::SM: // Sherman-Morrison Formula return(create_it <solver::matrix_solver_sm_t <FT, SIZE> >(*this, solvername, nets, params, size)); case solver::matrix_type_e::W: // Woodbury Formula return(create_it <solver::matrix_solver_w_t <FT, SIZE> >(*this, solvername, nets, params, size)); #else //case solver.matrix_type_e.GMRES: case solver.matrix_type_e.SOR: case solver.matrix_type_e.SOR_MAT: case solver.matrix_type_e.SM: case solver.matrix_type_e.W: state().log().warning.op(MW_SOLVER_METHOD_NOT_SUPPORTED(params_.m_method.op().ToString(), "MAT_CR")); throw new emu_unimplemented(); #if false return(create_it <solver::matrix_solver_GCR_t <FT, SIZE> >(*this, solvername, nets, params, size)); #endif #endif } throw new emu_unimplemented(); #if false return(solver_ptr()); #endif }
// FIXME: should be created in device space //template <class C> solver.matrix_solver_t create_it <C, FT, FT_OPS, int_SIZE>(nld_solver main_solver, string name, analog_net_t_list_t nets, solver.solver_parameters_t params_, size_t size) //NETLIB_NAME(solver)::solver_ptr create_it(NETLIB_NAME(solver) &main_solver, pstring name, NETLIB_NAME(solver)::net_list_t &nets, const solver::solver_parameters_t *params, std::size_t size) where FT_OPS : plib.constants_operators <FT>, new() where int_SIZE : int_const, new() { if (typeof(C) == typeof(solver.matrix_solver_GCR_t <FT, FT_OPS, int_SIZE>)) { return(new solver.matrix_solver_GCR_t <FT, FT_OPS, int_SIZE>(main_solver, name, nets, params_, size)); //return plib::make_unique<C, device_arena>(main_solver, name, nets, params, size); } else { throw new emu_unimplemented(); } }
//template <typename FT> solver.matrix_solver_t create_solvers <FT, FT_OPS>(string sname, solver.solver_parameters_t params_, nld_solver_net_list_t nets) //NETLIB_NAME(solver)::solver_ptr NETLIB_NAME(solver)::create_solvers(const pstring &sname, const solver::solver_parameters_t *params, net_list_t &nets) where FT_OPS : plib.constants_operators <FT>, new() { size_t net_count = nets.size(); switch (net_count) { case 1: return(new solver.matrix_solver_direct1_t <FT, FT_OPS>(this, sname, nets, params_)); //return plib::make_unique<solver::matrix_solver_direct1_t<FT>, device_arena>(*this, sname, nets, params); case 2: return(new solver.matrix_solver_direct2_t <FT, FT_OPS>(this, sname, nets, params_)); //return plib::make_unique<solver::matrix_solver_direct2_t<FT>, device_arena>(*this, sname, nets, params); case 3: return(create_solver <FT, FT_OPS, int_const_3>(3, sname, params_, nets)); //return create_solver<FT, 3>(3, sname, params, nets); case 4: return(create_solver <FT, FT_OPS, int_const_4>(4, sname, params_, nets)); //return create_solver<FT, 4>(4, sname, params, nets); case 5: return(create_solver <FT, FT_OPS, int_const_5>(5, sname, params_, nets)); //return create_solver<FT, 5>(5, sname, params, nets); case 6: return(create_solver <FT, FT_OPS, int_const_6>(6, sname, params_, nets)); //return create_solver<FT, 6>(6, sname, params, nets); case 7: return(create_solver <FT, FT_OPS, int_const_7>(7, sname, params_, nets)); //return create_solver<FT, 7>(7, sname, params, nets); case 8: return(create_solver <FT, FT_OPS, int_const_8>(8, sname, params_, nets)); //return create_solver<FT, 8>(8, sname, params, nets); default: log().info.op(MI_NO_SPECIFIC_SOLVER(net_count)); if (net_count <= 16) { return(create_solver <FT, FT_OPS, int_const_n16>(net_count, sname, params_, nets)); } if (net_count <= 32) { return(create_solver <FT, FT_OPS, int_const_n32>(net_count, sname, params_, nets)); } if (net_count <= 64) { return(create_solver <FT, FT_OPS, int_const_n64>(net_count, sname, params_, nets)); } if (net_count <= 128) { return(create_solver <FT, FT_OPS, int_const_n128>(net_count, sname, params_, nets)); } if (net_count <= 256) { return(create_solver <FT, FT_OPS, int_const_n256>(net_count, sname, params_, nets)); } if (net_count <= 512) { return(create_solver <FT, FT_OPS, int_const_n512>(net_count, sname, params_, nets)); } return(create_solver <FT, FT_OPS, int_const_0>(net_count, sname, params_, nets)); } }
size_t m_dim; //const std::size_t m_dim; protected matrix_solver_ext_t(devices.nld_solver main_solver, string name, matrix_solver_t_net_list_t nets, solver.solver_parameters_t params_, size_t size) : base(main_solver, name, nets, params_) { m_new_V = new FT [size]; m_RHS = new FT [size]; m_mat_ptr = new plib.pmatrix2d <Pointer <FT> >(size, this.max_railstart() + 1); m_last_V = new FT [size]; std.fill(m_last_V, ops.cast(nlconst.zero())); m_DD_n_m_1 = new FT [size]; std.fill(m_DD_n_m_1, ops.cast(nlconst.zero())); m_h_n_m_1 = new FT [size]; std.fill(m_h_n_m_1, ops.cast(nlconst.magic(1e-6))); // we need a non zero value here m_dim = size; // // save states // state().save(this, m_last_V, this.name(), "m_last_V"); state().save(this, m_DD_n_m_1, this.name(), "m_DD_n_m_1"); state().save(this, m_h_n_m_1, this.name(), "m_h_n_m_1"); }
protected MemoryContainer <MemoryContainer <FT> > m_A; //plib::parray2D<FT, SIZE, m_pitch_ABS> m_A; protected matrix_solver_direct_t(devices.nld_solver main_solver, string name, matrix_solver_t_net_list_t nets, solver.solver_parameters_t params_, size_t size) : base(main_solver, name, nets, params_, size) { m_pitch = m_pitch_ABS != 0 ? m_pitch_ABS : (((size + 0) + 7) / 8) * 8; //, m_A(size, m_pitch) m_A = new MemoryContainer <MemoryContainer <FT> >((int)size); for (int i = 0; i < (int)size; i++) { m_A[i] = new MemoryContainer <FT>((int)m_pitch); } this.build_mat_ptr(m_A); }