Ejemplo n.º 1
0
            //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");
            }
Ejemplo n.º 2
0
            //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)
            {
            }
Ejemplo n.º 3
0
            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);
                    }
                }
            }
Ejemplo n.º 4
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);
                }
            }
Ejemplo n.º 5
0
            //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
            }
Ejemplo n.º 6
0
 // 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();
     }
 }
Ejemplo n.º 7
0
            //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));
                }
            }
Ejemplo n.º 8
0
            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");
            }
Ejemplo n.º 9
0
            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);
            }