Пример #1
0
            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);
                }
            }
Пример #2
0
            //~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);
                    }
                }
            }