C++被OOM杀死的程序

发布于 2025-01-21 17:21:57 字数 6504 浏览 2 评论 0原文

我有一个C ++程序,呼叫Gurobi并在Ubuntu 20.04上运行。我正在解决混合整数线性程序(MILP),并且需要在时间限制后返回最佳解决方案。但是,该计划在某些情况下在此时间限制之前被杀死,而无需返回解决方案。 dmesg的输出表明该程序是由OOM杀死的,

[  +0,000003] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1000.slice/[email protected],task=LB,pid=56262,uid=1000

[  +0,000014] Out of memory: Killed process 56262 (LB) total-vm:5345884kB, anon-rss:5174060kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:10232kB oom_score_adj:0

我使用Valgrind来查看我是否有内存泄漏,但是看来我没有

==67757== HEAP SUMMARY:
==67757==     in use at exit: 0 bytes in 0 blocks
==67757==   total heap usage: 4,184,293 allocs, 4,184,293 frees, 4,996,993,663 bytes allocated
==67757== 
==67757== All heap blocks were freed -- no leaks are possible
==67757== 
==67757== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

代码的标头文件

    class MILP
{   
    GRBEnv env = GRBEnv();
    GRBModel model = GRBModel(env);

    GRBVar fun;
    std::vector<std::vector<GRBVar>> inter;
    std::vector<std::vector<std::vector<std::vector<GRBVar>>>> r;
    std::vector<std::vector<std::vector<std::vector<GRBVar>>>> R;
    
   
    void addvars();
    void addconstr();
    void addobj();

    void getobjval();

    void setparameters();

    int solvemodel();

public:

    int runMILP();
   };

.cpp

    void MILP::addvars()
    {
        
        fun=model.addVar(0, data::M, 0.0, GRB_CONTINUOUS, "");
    
        inter.reserve(data::P.size());
    
        for (int i = 0; i < data::P.size(); ++i)
        {    
            std::vector<GRBVar> row;
            row.reserve(data::P[0].size());
    
            for (int j = 0; j < data::P[0].size(); ++j)
            {
               row.push_back(model.addVar(data::P[i][j], data::M, 0.0, GRB_CONTINUOUS, ""));
            }
    
            inter.push_back(row);
        }  
        
        // variable R
        R.reserve(data::P.size());
    
        for (int i = 0; i < data::P.size(); ++i)
        {
    
            std::vector<std::vector<std::vector<GRBVar>>> threeDarray;
            threeDarray.reserve(data::P.size());
    
            for (int u = 0; u < data::P.size(); ++u)
            {
    
                std::vector<std::vector<GRBVar>> matrix;
                matrix.reserve(data::P[0].size());
    
                for (int j = 0; j < data::P[0].size(); ++j)
                {
    
                    std::vector<GRBVar> row;
    
                    if (j != 0)
                    {
                        row.reserve(j);
                        for (int k = 0; k < j; ++k)
                        {
                            row.push_back(model.addVar(0, (data::M - data::P[i][j] - data::P[u][k]), 0.0, GRB_CONTINUOUS, ""));
                        }
                    }
                    else
                    {
                        row.reserve(1);
                        row.push_back(model.addVar(0, 1, 0.0, GRB_BINARY, ""));
                    }
                    matrix.push_back(row);
                }
    
                threeDarray.push_back(matrix);
    
            }
            R.push_back(threeDarray);
        }
    }
    
    void MILP::addconstr(){
        
        for (int i = 0; i < data::P.size(); ++i)
        {
            for (int j = 0; j < data::P[0].size(); ++j)
            {
                model.addConstr(fun >= inter[i][j]);
            }
        }
    
     
        for (int j = 0; j < data::P[0].size(); ++j)
        {
            for (int k = 0; k < j; ++k)
            {
                if (data::C[j][k] == 1)
                {
                    for (int i = 0; i < data::P.size(); ++i)
                    {
                        for (int u = 0; u < data::P.size(); ++u)
                        {
                            if (u != i)
                            {
                                GRBLinExpr lhs = inter[i][j] -inter[u][k] + data::M * r[i][u][j][k] - data::P[i][j];
                                model.addConstr(lhs == R[i][u][j][k]);
                            }
                        }
                    }
                }
            }
        }
    }
    
    
    void MILP::addobj()
    {
       GRBLinExpr obj = fun;
       model.setObjective(obj);
    }
    
    void MILP::setparameters()
    {
    
        model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE);
            
        // limit the time spended
        model.set(GRB_DoubleParam_TimeLimit, 1800);
    }
    
    
    int MILP::solvemodel(){
    
        model.optimize();
    
        int status = model.get(GRB_IntAttr_Status);
    
        return status;
    }
    void MILP::getobjval()
    {
        objvalue = model.get(GRB_DoubleAttr_ObjVal);
    
    }

   
   int MILP::runMILP()
    {
        try
        {
            addvars();
            addconstr();
    
            setparameters();
            addobj();
            
            model.update();
    
            int status = solvemodel();
    
    
            if (status == GRB_OPTIMAL || status == GRB_TIME_LIMIT)
            {
                getobjval();
                return 1;
            }
            else if (status == GRB_INF_OR_UNBD ||
                     status == GRB_INFEASIBLE ||
                     status == GRB_UNBOUNDED)
            {
                std::cout << "The model cannot be solved because it is infeasible or unbounded" << std::endl;
    
                return 0;
            }
            else
            {
                std::cout << "Optimization was stopped with status " << status << std::endl;
    
                //freevariables();
                return 0;
            }
        }
        catch (GRBException e)
        {
            std::cout << "Error code = " << e.getErrorCode() << std::endl;
            std::cout << e.getMessage() << std::endl;
        }
        catch (...)
        {
            std::cout << "Exception during optimization" << std::endl;
        }
   
        return 0;
    }

在那里一种方法来防止该程序在不记忆之前停止对古罗比的呼吁,从而允许处理下一个迭代?以及如何返回求解器到目前为止找到的最佳解决方案?

I have a C++ program calling Gurobi and running on Ubuntu 20.04. I am solving a Mixed Integer Linear Program (MILP), and I need to return the best solution found after a time limit. However, the program was killed before this time limit for some instances without returning the solution. The output of dmesg shows that the program was killed by OOM

[  +0,000003] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1000.slice/[email protected],task=LB,pid=56262,uid=1000

[  +0,000014] Out of memory: Killed process 56262 (LB) total-vm:5345884kB, anon-rss:5174060kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:10232kB oom_score_adj:0

I used Valgrind to see if I have a memory leak, but it seems that I don't have

==67757== HEAP SUMMARY:
==67757==     in use at exit: 0 bytes in 0 blocks
==67757==   total heap usage: 4,184,293 allocs, 4,184,293 frees, 4,996,993,663 bytes allocated
==67757== 
==67757== All heap blocks were freed -- no leaks are possible
==67757== 
==67757== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Header file of my code

    class MILP
{   
    GRBEnv env = GRBEnv();
    GRBModel model = GRBModel(env);

    GRBVar fun;
    std::vector<std::vector<GRBVar>> inter;
    std::vector<std::vector<std::vector<std::vector<GRBVar>>>> r;
    std::vector<std::vector<std::vector<std::vector<GRBVar>>>> R;
    
   
    void addvars();
    void addconstr();
    void addobj();

    void getobjval();

    void setparameters();

    int solvemodel();

public:

    int runMILP();
   };

The .cpp

    void MILP::addvars()
    {
        
        fun=model.addVar(0, data::M, 0.0, GRB_CONTINUOUS, "");
    
        inter.reserve(data::P.size());
    
        for (int i = 0; i < data::P.size(); ++i)
        {    
            std::vector<GRBVar> row;
            row.reserve(data::P[0].size());
    
            for (int j = 0; j < data::P[0].size(); ++j)
            {
               row.push_back(model.addVar(data::P[i][j], data::M, 0.0, GRB_CONTINUOUS, ""));
            }
    
            inter.push_back(row);
        }  
        
        // variable R
        R.reserve(data::P.size());
    
        for (int i = 0; i < data::P.size(); ++i)
        {
    
            std::vector<std::vector<std::vector<GRBVar>>> threeDarray;
            threeDarray.reserve(data::P.size());
    
            for (int u = 0; u < data::P.size(); ++u)
            {
    
                std::vector<std::vector<GRBVar>> matrix;
                matrix.reserve(data::P[0].size());
    
                for (int j = 0; j < data::P[0].size(); ++j)
                {
    
                    std::vector<GRBVar> row;
    
                    if (j != 0)
                    {
                        row.reserve(j);
                        for (int k = 0; k < j; ++k)
                        {
                            row.push_back(model.addVar(0, (data::M - data::P[i][j] - data::P[u][k]), 0.0, GRB_CONTINUOUS, ""));
                        }
                    }
                    else
                    {
                        row.reserve(1);
                        row.push_back(model.addVar(0, 1, 0.0, GRB_BINARY, ""));
                    }
                    matrix.push_back(row);
                }
    
                threeDarray.push_back(matrix);
    
            }
            R.push_back(threeDarray);
        }
    }
    
    void MILP::addconstr(){
        
        for (int i = 0; i < data::P.size(); ++i)
        {
            for (int j = 0; j < data::P[0].size(); ++j)
            {
                model.addConstr(fun >= inter[i][j]);
            }
        }
    
     
        for (int j = 0; j < data::P[0].size(); ++j)
        {
            for (int k = 0; k < j; ++k)
            {
                if (data::C[j][k] == 1)
                {
                    for (int i = 0; i < data::P.size(); ++i)
                    {
                        for (int u = 0; u < data::P.size(); ++u)
                        {
                            if (u != i)
                            {
                                GRBLinExpr lhs = inter[i][j] -inter[u][k] + data::M * r[i][u][j][k] - data::P[i][j];
                                model.addConstr(lhs == R[i][u][j][k]);
                            }
                        }
                    }
                }
            }
        }
    }
    
    
    void MILP::addobj()
    {
       GRBLinExpr obj = fun;
       model.setObjective(obj);
    }
    
    void MILP::setparameters()
    {
    
        model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE);
            
        // limit the time spended
        model.set(GRB_DoubleParam_TimeLimit, 1800);
    }
    
    
    int MILP::solvemodel(){
    
        model.optimize();
    
        int status = model.get(GRB_IntAttr_Status);
    
        return status;
    }
    void MILP::getobjval()
    {
        objvalue = model.get(GRB_DoubleAttr_ObjVal);
    
    }

   
   int MILP::runMILP()
    {
        try
        {
            addvars();
            addconstr();
    
            setparameters();
            addobj();
            
            model.update();
    
            int status = solvemodel();
    
    
            if (status == GRB_OPTIMAL || status == GRB_TIME_LIMIT)
            {
                getobjval();
                return 1;
            }
            else if (status == GRB_INF_OR_UNBD ||
                     status == GRB_INFEASIBLE ||
                     status == GRB_UNBOUNDED)
            {
                std::cout << "The model cannot be solved because it is infeasible or unbounded" << std::endl;
    
                return 0;
            }
            else
            {
                std::cout << "Optimization was stopped with status " << status << std::endl;
    
                //freevariables();
                return 0;
            }
        }
        catch (GRBException e)
        {
            std::cout << "Error code = " << e.getErrorCode() << std::endl;
            std::cout << e.getMessage() << std::endl;
        }
        catch (...)
        {
            std::cout << "Exception during optimization" << std::endl;
        }
   
        return 0;
    }

Is there a way to prevent the program from being killed by stopping the call to Gurobi before having an out of memory and thus allow the next iteration to be processed? And how to return the best solution found so far by the solver?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文