//#define ENTRYY(n, m, s) case (n * 100 + m): \ // { using xtype = netlist_factory_truthtable_t<n, m>; \ // ret = plib::palloc<xtype>(desc.name, desc.classname, desc.def_param, s); } break //#define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \ // ENTRYY(n, 4, s); ENTRYY(n, 5, s); ENTRYY(n, 6, s); \ // ENTRYY(n, 7, s); ENTRYY(n, 8, s) public static void tt_factory_create(setup_t setup, tt_desc desc, string sourcefile) { netlist_base_factory_truthtable_t ret; //switch (desc.ni * 100 + desc.no) //{ // ENTRY(1, sourcefile); // ENTRY(2, sourcefile); // ENTRY(3, sourcefile); // ENTRY(4, sourcefile); // ENTRY(5, sourcefile); // ENTRY(6, sourcefile); // ENTRY(7, sourcefile); // ENTRY(8, sourcefile); // ENTRY(9, sourcefile); // ENTRY(10, sourcefile); // ENTRY(11, sourcefile); // ENTRY(12, sourcefile); // default: // pstring msg = plib::pfmt("unable to create truthtable<{1},{2}>")(desc.ni)(desc.no); // nl_assert_always(false, msg); //} // re-write of the above case statement if (desc.ni >= 1 && desc.ni <= 12 && desc.no >= 1 && desc.no <= 8) { ret = new netlist_factory_truthtable_t(desc.ni, desc.no, desc.name, desc.classname, desc.def_param, sourcefile); } else { string msg = new plib.pfmt("unable to create truthtable<{0},{1}>").op(desc.ni, desc.no); nl_base_global.nl_assert_always(false, msg); ret = new netlist_factory_truthtable_t(0, 0, null, null, null, null); } ret.desc = desc.desc; if (desc.family != "") { ret.family = setup.family_from_model(desc.family); } setup.factory().register_device(ret); //std::unique_ptr<netlist_base_factory_truthtable_t>(ret)); }
protected void error(string errs) //void ptoken_reader::error(const perrmsg &errs) { string s = ""; string trail = " from "; string trail_first = "In file included from "; string e = new plib.pfmt("{0}:{1}:0: error: {2}\n") .op(m_source_location.back().file_name(), m_source_location.back().line(), errs); m_source_location.pop_back(); while (!m_source_location.empty()) { if (m_source_location.size() == 1) { trail = trail_first; } s = new plib.pfmt("{0}{1}:{2}:0\n{3}").op(trail, m_source_location.back().file_name(), m_source_location.back().line(), s); m_source_location.pop_back(); } verror("\n" + s + e + " " + m_line + "\n"); }
void error(string err) { string s = ""; string trail = " from "; string trail_first = "In file included from "; string e = new plib.pfmt("{0}:{1}:0: error: {2}\n") .op(m_stack.back().m_name, m_stack.back().m_lineno, err); m_stack.pop_back(); while (!m_stack.empty()) { if (m_stack.size() == 1) { trail = trail_first; } s = new plib.pfmt("{0}{1}:{2}:0\n{3}").op(trail, m_stack.back().m_name, m_stack.back().m_lineno, s); m_stack.pop_back(); } throw new pexception("\n" + s + e + " " + m_line + "\n"); }
public void register_frontier(string attach, string r_IN, string r_OUT) { string frontier_name = new plib.pfmt("frontier_{0}").op(m_frontier_cnt); m_frontier_cnt++; register_dev("FRONTIER_DEV", frontier_name); register_param(frontier_name + ".RIN", r_IN); register_param(frontier_name + ".ROUT", r_OUT); register_link(frontier_name + ".G", "GND"); string attfn = build_fqn(attach); string front_fqn = build_fqn(frontier_name); bool found = false; for (int i = 0; i < m_abstract.m_links.Count; i++) //for (auto & link : m_abstract.m_links) { var link = m_abstract.m_links[i]; if (link.first == attfn) { m_abstract.m_links[i] = new abstract_t_link_t(front_fqn + ".I", link.second); //link.first = front_fqn + ".I"; found = true; } else if (link.second == attfn) { m_abstract.m_links[i] = new abstract_t_link_t(link.first, front_fqn + ".I"); //link.second = front_fqn + ".I"; found = true; } } if (!found) { log().fatal.op(MF_FOUND_NO_OCCURRENCE_OF_1(attach)); throw new nl_exception(MF_FOUND_NO_OCCURRENCE_OF_1(attach)); } register_link(attach, frontier_name + ".Q"); }
//template <typename FT, int SIZE> void generate_code(out string strm) //void matrix_solver_GCR_t<FT, SIZE>::generate_code(plib::putf8_fmt_writer &strm) { strm = ""; size_t iN = this.size(); string fptype = fp_constants_double.name(); //pstring fptype(fp_constants<FT>::name()); string fpsuffix = fp_constants_double.suffix(); //pstring fpsuffix(fp_constants<FT>::suffix()); // avoid unused variable warnings strm += string.Format("\tplib::unused_var({0});\n", "cnV"); for (size_t i = 0; i < mat.nz_num; i++) { strm += string.Format("\t{0} m_A{1}(0.0);\n", fptype, i, i); } for (size_t k = 0; k < iN; k++) { var net = this.m_terms[k]; // FIXME: gonn, gtn and Idr - which float types should they have? //auto gtot_t = std::accumulate(gt, gt + term_count, plib::constants<FT>::zero()); //*tcr_r[railstart] = static_cast<FT>(gtot_t); //mat.A[mat.diag[k]] += gtot_t; var pd = this.m_mat_ptr.op(k)[net.railstart()] - new Pointer <FT>(this.mat.A, 0); //auto pd = this->m_mat_ptr[k][net.railstart()] - &this->mat.A[0]; #if false string terms = new plib.pfmt("m_A{0} = gt[{1}]").op(pd.Offset, this.m_gtn.didx(k, 0)); for (size_t i = 1; i < net.count(); i++) { terms += new plib.pfmt(" + gt[{0}]").op(this.m_gtn.didx(k, i)); } strm += string.Format("\t{0};\n", terms); #else for (size_t i = 0; i < net.count(); i++) { strm += string.Format("\tm_A{0} += gt[{1}];\n", pd, this.m_gtn.didx(k, i)); } #endif //for (std::size_t i = 0; i < railstart; i++) // *tcr_r[i] += static_cast<FT>(go[i]); for (size_t i = 0; i < net.railstart(); i++) { var p = this.m_mat_ptr.op(k)[i] - new Pointer <FT>(this.mat.A, 0); //auto p = this->m_mat_ptr[k][i] - &this->mat.A[0]; strm += string.Format("\tm_A{0} += go[{1}];\n", p, this.m_gonn.didx(k, i)); } #if false //auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<FT>::zero())); terms = new plib.pfmt("{0} RHS{1} = Idr[{2}]").op(fptype, k, this.m_Idrn.didx(k, 0)); for (size_t i = 1; i < net.count(); i++) { terms += new plib.pfmt(" + Idr[{0}]").op(this.m_Idrn.didx(k, i)); } //for (std::size_t i = railstart; i < term_count; i++) // RHS_t += (- go[i]) * *cnV[i]; for (size_t i = net.railstart(); i < net.count(); i++) { terms += new plib.pfmt(" - go[{0}] * *cnV[{1}]").op(this.m_gonn.didx(k, i), this.m_connected_net_Vn.didx(k, i)); } strm += string.Format("\t{0};\n", terms); #else //auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<FT>::zero())); strm += string.Format("\t{0} RHS{1} = Idr[{2}];\n", fptype, k, this.m_Idrn.didx(k, 0)); for (size_t i = 1; i < net.count(); i++) { strm += string.Format("\tRHS{0} += Idr[{1}];\n", k, this.m_Idrn.didx(k, i)); } //for (std::size_t i = railstart; i < term_count; i++) // RHS_t += (- go[i]) * *cnV[i]; for (size_t i = net.railstart(); i < net.count(); i++) { strm += string.Format("\tRHS{0} -= go[{1}] * *cnV[{2}];\n", k, this.m_gonn.didx(k, i), this.m_connected_net_Vn.didx(k, i)); } #endif } for (size_t i = 0; i < iN - 1; i++) { //const auto &nzbd = this->m_terms[i].m_nzbd; var nzbd = mat.nzbd(i); var nzbd_count = mat.nzbd_count(i); if (nzbd_count > 0) { size_t pi = mat.diag[i]; //const FT f = 1.0 / m_A[pi++]; strm += string.Format("\tconst {0} f{1} = 1.0{2} / m_A{3};\n", fptype, i, fpsuffix, pi); pi++; size_t piie = mat.row_idx[i + 1]; //for (auto & j : nzbd) for (size_t jj = 0; jj < nzbd_count; jj++) { size_t j = nzbd[jj]; // proceed to column i size_t pj = mat.row_idx[j]; while (mat.col_idx[pj] < i) { pj++; } //const FT f1 = - m_A[pj++] * f; strm += string.Format("\tconst {0} f{1}_{2} = -f{3} * m_A{4};\n", fptype, i, j, i, pj); pj++; // subtract row i from j for (size_t pii = pi; pii < piie;) { while (mat.col_idx[pj] < mat.col_idx[pii]) { pj++; } //m_A[pj++] += m_A[pii++] * f1; strm += string.Format("\tm_A{0} += m_A{1} * f{2}_{3};\n", pj, pii, i, j); pj++; pii++; } //RHS[j] += f1 * RHS[i]; strm += string.Format("\tRHS{0} += f{1}_{2} * RHS{3};\n", j, i, j, i); } } } //new_V[iN - 1] = RHS[iN - 1] / mat.A[mat.diag[iN - 1]]; strm += string.Format("\tV[{0}] = RHS{1} / m_A{2};\n", iN - 1, iN - 1, mat.diag[iN - 1]); for (size_t j = iN - 1; j-- > 0;) { #if true strm += string.Format("\t{0} tmp{1} = 0.0{2};\n", fptype, j, fpsuffix); size_t e = mat.row_idx[j + 1]; for (size_t pk = (size_t)mat.diag[j] + 1; pk < e; pk++) { strm += string.Format("\ttmp{0} += m_A{1} * V[{2}];\n", j, pk, mat.col_idx[pk]); } strm += string.Format("\tV[{0}] = (RHS{0} - tmp{0}) / m_A{3};\n", j, j, j, mat.diag[j]); #else pstring tmp; const std::size_t e = mat.row_idx[j + 1]; for (std::size_t pk = mat.diag[j] + 1; pk < e; pk++) { tmp = tmp + plib::pfmt(" + m_A{2} * V[{3}]")(j, pk, mat.col_idx[pk]); } if (tmp.empty()) { strm("\tV[{1}] = RHS{1} / m_A{2};\n", j, mat.diag[j]); } else { //strm("\tconst {1} tmp{2} = {3};\n", fptype, j, tmp.substr(3)); //strm("\tV[{1}] = (RHS{1} - tmp{1}) / m_A{2};\n", j, mat.diag[j]); strm("\tV[{1}] = (RHS{1} - ({2})) / m_A{3};\n", j, tmp.substr(3), mat.diag[j]); } #endif } }
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); } }
//bool parse(plib::istream_uptr &&strm, const pstring &nlname); public bool parse(parser_t_token_store tokstor, string nlname) { set_token_source(tokstor); bool in_nl = false; while (true) { // FIXME: line numbers in cached local netlists are wrong // need to process raw tokens here. parser_t_token_t token = get_token_raw(); if (token.is_type(parser_t_token_type.ENDOFFILE)) { return(false); } if (token.is_(m_tok_NETLIST_END) || token.is_(m_tok_TRUTHTABLE_END)) { if (!in_nl) { error(MF_PARSER_UNEXPECTED_1(token.str())); } else { in_nl = false; } require_token(m_tok_paren_left); require_token(m_tok_paren_right); m_cur_local.push_back(token); m_cur_local.push_back(new parser_t_token_t(m_tok_paren_left)); m_cur_local.push_back(new parser_t_token_t(m_tok_paren_right)); } else if (token.is_(m_tok_NETLIST_START) || token.is_(m_tok_TRUTHTABLE_START)) { if (in_nl) { error(MF_PARSER_UNEXPECTED_1(token.str())); } require_token(m_tok_paren_left); parser_t_token_t name = get_token(); if (token.is_(m_tok_NETLIST_START) && (name.str() == nlname || nlname.empty())) { require_token(m_tok_paren_right); parse_netlist(); return(true); } if (token.is_(m_tok_TRUTHTABLE_START) && name.str() == nlname) { net_truthtable_start(nlname); return(true); } // create a new cached local store m_local.emplace(name.str(), new parser_t_token_store()); m_cur_local = m_local[name.str()]; var sl = sourceloc(); var li = new plib.pfmt("# {0} \"{1}\"").op(sl.line(), sl.file_name()); m_cur_local.push_back(new parser_t_token_t(parser_t_token_type.LINEMARKER, li)); m_cur_local.push_back(token); m_cur_local.push_back(new parser_t_token_t(m_tok_paren_left)); m_cur_local.push_back(name); //m_cur_local->push_back(token_t(m_tok_paren_right)); in_nl = true; } // FIXME: do we really need this going forward ? there should be no need // for NETLIST_EXTERNAL in netlist files else if (token.is_(m_tok_NETLIST_EXTERNAL)) { if (in_nl) { error(MF_UNEXPECTED_NETLIST_EXTERNAL()); } require_token(m_tok_paren_left); parser_t_token_t name = get_token(); require_token(m_tok_paren_right); } else if (!in_nl) { if (!token.is_(m_tok_static) && !token.is_type(parser_t_token_type.SOURCELINE) && !token.is_type(parser_t_token_type.LINEMARKER)) { error(MF_EXPECTED_NETLIST_START_1(token.str())); } } else { m_cur_local.push_back(token); } } }
//template <typename T> //void store(const T * RESTRICT V); //template <typename T> //T delta(const T * RESTRICT V); //template <typename T> //void build_LE_A(); //template <typename T> //void build_LE_RHS(); /* calculate matrix */ void setup_matrix() { UInt32 iN = (UInt32)m_nets.size(); for (UInt32 k = 0; k < iN; k++) { m_terms[k].railstart = m_terms[k].count(); for (UInt32 i = 0; i < m_rails_temp[k].count(); i++) { this.m_terms[k].add(m_rails_temp[k].terms()[i], m_rails_temp[k].connected_net_idx()[i], false); } m_terms[k].set_pointers(); } foreach (terms_for_net_t rt in m_rails_temp) { rt.clear(); // no longer needed //plib::pfree(rt); // no longer needed } m_rails_temp.clear(); /* Sort in descending order by number of connected matrix voltages. * The idea is, that for Gauss-Seidel algo the first voltage computed * depends on the greatest number of previous voltages thus taking into * account the maximum amout of information. * * This actually improves performance on popeye slightly. Average * GS computations reduce from 2.509 to 2.370 * * Smallest to largest : 2.613 * Unsorted : 2.509 * Largest to smallest : 2.370 * * Sorting as a general matrix pre-conditioning is mentioned in * literature but I have found no articles about Gauss Seidel. * * For Gaussian Elimination however increasing order is better suited. * NOTE: Even better would be to sort on elements right of the matrix diagonal. * */ if (m_sort != eSortType.NOSORT) { int sort_order = (m_sort == eSortType.DESCENDING ? 1 : -1); for (UInt32 k = 0; k < iN - 1; k++) { for (UInt32 i = k + 1; i < iN; i++) { if (((int)(m_terms[k].railstart) - (int)(m_terms[i].railstart)) * sort_order < 0) { //std::swap(m_terms[i], m_terms[k]); var termsTemp = m_terms[i]; m_terms[i] = m_terms[k]; m_terms[k] = termsTemp; //std::swap(m_nets[i], m_nets[k]); var netsTemp = m_nets[i]; m_nets[i] = m_nets[k]; m_nets[k] = netsTemp; } } } foreach (var term in m_terms) { var other = term.connected_net_idx(); for (UInt32 i = 0; i < term.count(); i++) { if (other[i] != -1) { other[i] = get_net_idx(term.terms()[i].otherterm.net()); } } } } /* create a list of non zero elements. */ for (UInt32 k = 0; k < iN; k++) { terms_for_net_t t = m_terms[k]; /* pretty brutal */ var other = t.connected_net_idx(); t.nz.clear(); for (UInt32 i = 0; i < t.railstart; i++) { if (!t.nz.Contains((UInt32)other[i])) //if (!plib::container::contains(t->m_nz, static_cast<unsigned>(other[i]))) { t.nz.push_back((UInt32)other[i]); } } t.nz.push_back(k); // add diagonal /* and sort */ t.nz.Sort(); //std::sort(t.m_nz.begin(), t.m_nz.end()); } /* create a list of non zero elements right of the diagonal * These list anticipate the population of array elements by * Gaussian elimination. */ for (UInt32 k = 0; k < iN; k++) { terms_for_net_t t = m_terms[k]; /* pretty brutal */ var other = t.connected_net_idx(); if (k == 0) { t.nzrd.clear(); } else { t.nzrd = m_terms[k - 1].nzrd; for (var jIdx = 0; jIdx < t.nzrd.Count;) //for (var j = t.nzrd.begin(); j != t.nzrd.end(); ) { var j = t.nzrd[jIdx]; if (j < k + 1) { t.nzrd.erase(jIdx); } else { ++jIdx; } } } for (UInt32 i = 0; i < t.railstart; i++) { if (!t.nzrd.Contains((UInt32)other[i]) && other[i] >= (int)(k + 1)) //if (!plib::container::contains(t->m_nzrd, static_cast<unsigned>(other[i])) && other[i] >= static_cast<int>(k + 1)) { t.nzrd.push_back((UInt32)other[i]); } } /* and sort */ t.nzrd.Sort(); //std::sort(t.m_nzrd.begin(), t.m_nzrd.end()); } /* create a list of non zero elements below diagonal k * This should reduce cache misses ... */ bool [,] touched = new bool [iN, iN]; //bool **touched = plib::palloc_array<bool *>(iN); //for (UInt32 k = 0; k < iN; k++) // touched[k] = plib::palloc_array<bool>(iN); for (UInt32 k = 0; k < iN; k++) { for (UInt32 j = 0; j < iN; j++) { touched[k, j] = false; } for (UInt32 j = 0; j < m_terms[k].nz.size(); j++) { touched[k, m_terms[k].nz[j]] = true; } } m_ops = 0; for (UInt32 k = 0; k < iN; k++) { m_ops++; // 1/A(k,k) for (UInt32 row = k + 1; row < iN; row++) { if (touched[row, k]) { m_ops++; if (!m_terms[k].nzbd.Contains(row)) //if (!plib::container::contains(m_terms[k]->m_nzbd, row)) { m_terms[k].nzbd.push_back(row); } for (UInt32 col = k + 1; col < iN; col++) { if (touched[k, col]) { touched[row, col] = true; m_ops += 2; } } } } } log().verbose.op("Number of mults/adds for {0}: {1}", name(), m_ops); #if false if ((0)) { for (unsigned k = 0; k < iN; k++) { pstring line = plib::pfmt("{1:3}")(k); for (unsigned j = 0; j < m_terms[k]->m_nzrd.size(); j++) { line += plib::pfmt(" {1:3}")(m_terms[k]->m_nzrd[j]); } log().verbose("{1}", line); } } #endif /* * save states */ for (UInt32 k = 0; k < iN; k++) { string num = new plib.pfmt("{0}").op(k); state().save(this, m_terms[k].last_V, "lastV." + num); state().save(this, m_terms[k].DD_n_m_1, "m_DD_n_m_1." + num); state().save(this, m_terms[k].h_n_m_1, "m_h_n_m_1." + num); state().save(this, m_terms[k].go(), "GO" + num, m_terms[k].count()); state().save(this, m_terms[k].gt(), "GT" + num, m_terms[k].count()); state().save(this, m_terms[k].Idr(), "IDR" + num, m_terms[k].count()); } //for (UInt32 k = 0; k < iN; k++) // plib::pfree_array(touched[k]); //plib::pfree_array(touched); touched = null; }
//#define ENTRYY(n, m, s) case (n * 100 + m): \ // { using xtype = devices::netlist_factory_truthtable_t<n, m>; \ // auto cs=s; \ // ret = plib::make_unique<xtype, host_arena>(desc.name, std::move(cs)); } \ // break //#define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \ // ENTRYY(n, 4, s); ENTRYY(n, 5, s); ENTRYY(n, 6, s); \ // ENTRYY(n, 7, s); ENTRYY(n, 8, s); ENTRYY(n, 9, s); \ // ENTRYY(n, 10, s) public static truthtable_base_element_t truthtable_create(tt_desc desc, properties props) { truthtable_base_element_t ret = null; switch (desc.ni * 100 + desc.no) { //ENTRY(1, props); case (1 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_1>(desc.name, props); break; case (1 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_2>(desc.name, props); break; case (1 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_3>(desc.name, props); break; case (1 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_4>(desc.name, props); break; case (1 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_5>(desc.name, props); break; case (1 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_6>(desc.name, props); break; case (1 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_7>(desc.name, props); break; case (1 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_8>(desc.name, props); break; case (1 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_9>(desc.name, props); break; case (1 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_1, u32_const_10>(desc.name, props); break; //ENTRY(2, props); case (2 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_1>(desc.name, props); break; case (2 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_2>(desc.name, props); break; case (2 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_3>(desc.name, props); break; case (2 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_4>(desc.name, props); break; case (2 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_5>(desc.name, props); break; case (2 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_6>(desc.name, props); break; case (2 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_7>(desc.name, props); break; case (2 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_8>(desc.name, props); break; case (2 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_9>(desc.name, props); break; case (2 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_2, u32_const_10>(desc.name, props); break; //ENTRY(3, props); case (3 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_1>(desc.name, props); break; case (3 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_2>(desc.name, props); break; case (3 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_3>(desc.name, props); break; case (3 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_4>(desc.name, props); break; case (3 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_5>(desc.name, props); break; case (3 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_6>(desc.name, props); break; case (3 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_7>(desc.name, props); break; case (3 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_8>(desc.name, props); break; case (3 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_9>(desc.name, props); break; case (3 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_3, u32_const_10>(desc.name, props); break; //ENTRY(4, props); case (4 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_1>(desc.name, props); break; case (4 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_2>(desc.name, props); break; case (4 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_3>(desc.name, props); break; case (4 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_4>(desc.name, props); break; case (4 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_5>(desc.name, props); break; case (4 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_6>(desc.name, props); break; case (4 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_7>(desc.name, props); break; case (4 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_8>(desc.name, props); break; case (4 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_9>(desc.name, props); break; case (4 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_4, u32_const_10>(desc.name, props); break; //ENTRY(5, props); case (5 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_1>(desc.name, props); break; case (5 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_2>(desc.name, props); break; case (5 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_3>(desc.name, props); break; case (5 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_4>(desc.name, props); break; case (5 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_5>(desc.name, props); break; case (5 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_6>(desc.name, props); break; case (5 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_7>(desc.name, props); break; case (5 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_8>(desc.name, props); break; case (5 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_9>(desc.name, props); break; case (5 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_5, u32_const_10>(desc.name, props); break; //ENTRY(6, props); case (6 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_1>(desc.name, props); break; case (6 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_2>(desc.name, props); break; case (6 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_3>(desc.name, props); break; case (6 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_4>(desc.name, props); break; case (6 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_5>(desc.name, props); break; case (6 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_6>(desc.name, props); break; case (6 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_7>(desc.name, props); break; case (6 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_8>(desc.name, props); break; case (6 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_9>(desc.name, props); break; case (6 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_6, u32_const_10>(desc.name, props); break; //ENTRY(7, props); case (7 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_1>(desc.name, props); break; case (7 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_2>(desc.name, props); break; case (7 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_3>(desc.name, props); break; case (7 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_4>(desc.name, props); break; case (7 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_5>(desc.name, props); break; case (7 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_6>(desc.name, props); break; case (7 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_7>(desc.name, props); break; case (7 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_8>(desc.name, props); break; case (7 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_9>(desc.name, props); break; case (7 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_7, u32_const_10>(desc.name, props); break; //ENTRY(8, props); case (8 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_1>(desc.name, props); break; case (8 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_2>(desc.name, props); break; case (8 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_3>(desc.name, props); break; case (8 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_4>(desc.name, props); break; case (8 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_5>(desc.name, props); break; case (8 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_6>(desc.name, props); break; case (8 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_7>(desc.name, props); break; case (8 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_8>(desc.name, props); break; case (8 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_9>(desc.name, props); break; case (8 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_8, u32_const_10>(desc.name, props); break; //ENTRY(9, props); case (9 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_1>(desc.name, props); break; case (9 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_2>(desc.name, props); break; case (9 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_3>(desc.name, props); break; case (9 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_4>(desc.name, props); break; case (9 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_5>(desc.name, props); break; case (9 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_6>(desc.name, props); break; case (9 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_7>(desc.name, props); break; case (9 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_8>(desc.name, props); break; case (9 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_9>(desc.name, props); break; case (9 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_9, u32_const_10>(desc.name, props); break; //ENTRY(10, props); case (10 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_1>(desc.name, props); break; case (10 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_2>(desc.name, props); break; case (10 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_3>(desc.name, props); break; case (10 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_4>(desc.name, props); break; case (10 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_5>(desc.name, props); break; case (10 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_6>(desc.name, props); break; case (10 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_7>(desc.name, props); break; case (10 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_8>(desc.name, props); break; case (10 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_9>(desc.name, props); break; case (10 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_10, u32_const_10>(desc.name, props); break; //ENTRY(11, props); case (11 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_1>(desc.name, props); break; case (11 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_2>(desc.name, props); break; case (11 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_3>(desc.name, props); break; case (11 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_4>(desc.name, props); break; case (11 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_5>(desc.name, props); break; case (11 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_6>(desc.name, props); break; case (11 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_7>(desc.name, props); break; case (11 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_8>(desc.name, props); break; case (11 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_9>(desc.name, props); break; case (11 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_11, u32_const_10>(desc.name, props); break; //ENTRY(12, props); case (12 * 100 + 1): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_1>(desc.name, props); break; case (12 * 100 + 2): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_2>(desc.name, props); break; case (12 * 100 + 3): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_3>(desc.name, props); break; case (12 * 100 + 4): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_4>(desc.name, props); break; case (12 * 100 + 5): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_5>(desc.name, props); break; case (12 * 100 + 6): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_6>(desc.name, props); break; case (12 * 100 + 7): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_7>(desc.name, props); break; case (12 * 100 + 8): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_8>(desc.name, props); break; case (12 * 100 + 9): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_9>(desc.name, props); break; case (12 * 100 + 10): ret = new devices.netlist_factory_truthtable_t <u32_const_12, u32_const_10>(desc.name, props); break; default: string msg = new plib.pfmt("unable to create truthtable<{0},{2}>").op(desc.ni, desc.no); nl_assert_always(false, msg); break; } ret.m_desc = desc.desc; ret.m_family_name = !desc.family.empty() ? desc.family : config.DEFAULT_LOGIC_FAMILY(); return(ret); }
//~nld_solver() //{ // for (auto &s : m_mat_solvers) // { // plib::pfree(s); // } //} public void post_start() { const bool use_specific = true; m_params.m_pivot = m_pivot.op() ? 1 : 0; m_params.m_accuracy = m_accuracy.op(); /* FIXME: Throw when negative */ m_params.m_gs_loops = (UInt32)m_gs_loops.op(); m_params.m_nr_loops = (UInt32)m_nr_loops.op(); m_params.m_nr_recalc_delay = netlist_time.from_double(m_nr_recalc_delay.op()); m_params.m_dynamic_lte = m_dynamic_lte.op(); m_params.m_gs_sor = m_gs_sor.op(); m_params.m_min_timestep = m_dynamic_min_ts.op(); m_params.m_dynamic_ts = (m_dynamic_ts.op() == true ? true : false); m_params.m_max_timestep = netlist_time.from_double(1.0 / m_freq.op()).as_double(); if (m_params.m_dynamic_ts) { m_params.m_max_timestep *= 1;//NL_FCONST(1000.0); } else { m_params.m_min_timestep = m_params.m_max_timestep; } //m_params.m_max_timestep = std::max(m_params.m_max_timestep, m_params.m_max_timestep::) // Override log statistics string p = ""; //plib::util::environment("NL_STATS", ""); if (p != "") { m_params.m_log_stats = plib.pstring_global.pstonum_bool(p); //plib::pstonum<decltype(m_params.m_log_stats)>(p); } else { m_params.m_log_stats = m_log_stats.op(); } log().verbose.op("Scanning net groups ..."); // determine net groups net_splitter splitter = new net_splitter(); splitter.run(state()); // setup the solvers log().verbose.op("Found {0} net groups in {1} nets\n", splitter.groups.size(), state().nets().size()); foreach (var grp in splitter.groups) { matrix_solver_t ms; UInt32 net_count = (UInt32)grp.size(); string sname = new plib.pfmt("Solver_{0}").op(m_mat_solvers.size()); switch (net_count) { #if true case 1: if (use_specific) { ms = new matrix_solver_direct1_t(state(), sname, m_params); //ms = plib::palloc<matrix_solver_direct1_t<double>>(state(), sname, &m_params); } else { ms = create_solver/*<double, 1>*/ (1, 1, sname); } break; case 2: if (use_specific) { ms = new matrix_solver_direct2_t(state(), sname, m_params); //ms = plib::palloc<matrix_solver_direct2_t<double>>(state(), sname, &m_params); } else { ms = create_solver/*<double, 2>*/ (2, 2, sname); } break; #if false case 3: ms = create_solver <double, 3>(3, sname); break; case 4: ms = create_solver <double, 4>(4, sname); break; case 5: ms = create_solver <double, 5>(5, sname); break; case 6: ms = create_solver <double, 6>(6, sname); break; case 7: ms = create_solver <double, 7>(7, sname); break; case 8: ms = create_solver <double, 8>(8, sname); break; case 9: ms = create_solver <double, 9>(9, sname); break; case 10: ms = create_solver <double, 10>(10, sname); break; case 11: ms = create_solver <double, 11>(11, sname); break; case 12: ms = create_solver <double, 12>(12, sname); break; case 15: ms = create_solver <double, 15>(15, sname); break; case 31: ms = create_solver <double, 31>(31, sname); break; case 35: ms = create_solver <double, 35>(35, sname); break; case 43: ms = create_solver <double, 43>(43, sname); break; case 49: ms = create_solver <double, 49>(49, sname); break; #endif #if false case 87: ms = create_solver <87, 87>(87, sname); break; #endif #endif default: log().warning.op(nl_errstr_global.MW_1_NO_SPECIFIC_SOLVER, net_count); if (net_count <= 8) { ms = create_solver/*<double, -8>*/ (-8, net_count, sname); } else if (net_count <= 16) { ms = create_solver/*<double, -16>*/ (-16, net_count, sname); } else if (net_count <= 32) { ms = create_solver/*<double, -32>*/ (-32, net_count, sname); } else if (net_count <= 64) { ms = create_solver/*<double, -64>*/ (-64, net_count, sname); } else if (net_count <= 128) { ms = create_solver/*<double, -128>*/ (-128, net_count, sname); } else { log().fatal.op(nl_errstr_global.MF_1_NETGROUP_SIZE_EXCEEDED_1, 128); ms = null; /* tease compilers */ } break; } // FIXME ... ms.setup(grp); log().verbose.op("Solver {0}", ms.name()); log().verbose.op(" ==> {0} nets", grp.size()); log().verbose.op(" has {0} elements", ms.has_dynamic_devices() ? "dynamic" : "no dynamic"); log().verbose.op(" has {0} elements", ms.has_timestep_devices() ? "timestep" : "no timestep"); foreach (var n in grp) { log().verbose.op("Net {0}", n.name()); foreach (var pcore in n.core_terms) { log().verbose.op(" {0}", pcore.name()); } } m_mat_solvers.push_back(ms); if (ms.has_timestep_devices()) { m_mat_solvers_timestepping.push_back(ms); } } }