[Clp] Core Dump found when using Clp 1.15

郑一源 yiyuan.zheng at gmail.com
Thu Mar 12 10:34:45 EDT 2015


Hi all.
We are using Clp to solve linear program in an online system., run on
redhat linux, Clp is called as native code in Java using JNI. The
problem is large and sparse, so we are using the GUB technique as the
example codes.  There are times the program crashes, and I need help.
In the beginning I found the following core dump as below. The program
crashes when deleting the ClpSImplex. The memory has been in invalid
state.

#0  0x0000003a95e30265 in raise () from /lib64/libc.so.6
#1  0x0000003a95e31d10 in abort () from /lib64/libc.so.6
#2  0x0000003a95e6a84b in __libc_message () from /lib64/libc.so.6
#3  0x0000003a95e7230f in _int_free () from /lib64/libc.so.6
#4  0x0000003a95e7276b in free () from /lib64/libc.so.6
#5  0x00002aaab9205890 in ClpDynamicMatrix::~ClpDynamicMatrix() ()
from /data/stormdata/libCallClpGub.so
#6  0x00002aaab921543f in ClpModel::gutsOfDelete(int) () from
/data/stormdata/libCallClpGub.so
#7  0x00002aaab9222ed1 in ClpModel::~ClpModel() () from
/data/stormdata/libCallClpGub.so
#8  0x00002aaab92055ff in
Java_com_adsame_rtb_duallearner_gap_clp_CLPSolverGUB_solveDual () from
/data/stormdata/libCallClpGub.so

To debug this issue, I make Clp again with --enable-debug flag. And I
found two type of core dump shown below. As you may see in the dump,
asserts in the files are triggered during the run.
ClpPackedMatrix.cpp:2490
ClpNonLinearCost.cpp:754

It seems like the solver has encountered some exceptional cases. I
guess this might result in invalid memory access which may be the
cause of the segmentation fault above.

#0  0x0000003a95e30265 in raise () from /lib64/libc.so.6
#1  0x0000003a95e31d10 in abort () from /lib64/libc.so.6
#2  0x0000003a95e296e6 in __assert_fail () from /lib64/libc.so.6
#3  0x00002aaab9286bb0 in ClpPackedMatrix::fillBasis
(this=0x2aaab1848b00, model=0x2aaab1737740,
whichColumn=0x2aaab1220be8, numberColumnBasic=@0x45467a58,
    indexRowU=0x2aaabceed7f0, start=0x2aaabc03cd58,
rowCount=0x2aaabc828e70, columnCount=0x2aaabc15d388,
elementU=0x2aaabc5dc9c0) at ClpPackedMatrix.cpp:2490
#4  0x00002aaab9245a8b in ClpFactorization::factorize
(this=0x2aaab1768880, model=0x2aaab1737740, solveType=1,
valuesPass=false) at ClpFactorization.cpp:1985
#5  0x00002aaab92e05b1 in ClpSimplex::internalFactorize
(this=0x2aaab1737740, solveType=1) at ClpSimplex.cpp:1823
#6  0x00002aaab9351e62 in ClpSimplexPrimal::statusOfProblemInPrimal
(this=0x2aaab1737740, lastCleaned=@0x4546812c, type=1,
progress=0x2aaab1737c80, doFactorization=true,
    ifValuesPass=0, originalModel=0x0) at ClpSimplexPrimal.cpp:828
#7  0x00002aaab9359dcc in ClpSimplexPrimal::primal
(this=0x2aaab1737740, ifValuesPass=0, startFinishOptions=0) at
ClpSimplexPrimal.cpp:343
#8  0x00002aaab92edc28 in ClpSimplex::primal (this=0x2aaab1737740,
ifValuesPass=0, startFinishOptions=0) at ClpSimplex.cpp:5770
#9  0x00002aaab9230e8f in solveDuals(ClpSimplex&, double) () from
/data/stormdata/libCallClpGubHeapModel.so



#2  0x0000003a95e296e6 in __assert_fail () from /lib64/libc.so.6
#3  0x00002aaab52621bb in ClpNonLinearCost::checkInfeasibilities
(this=0x53c3c140, oldTolerance=0) at ClpNonLinearCost.cpp:754
#4  0x00002aaab52cc04b in ClpSimplex::gutsOfSolution (this=0x54551b60,
givenDuals=0x0, givenPrimals=0x0, valuesPass=false) at
ClpSimplex.cpp:576
#5  0x00002aaab533b99c in ClpSimplexPrimal::statusOfProblemInPrimal
(this=0x54551b60, lastCleaned=@0x44caa2ac, type=2,
progress=0x545520a0, doFactorization=true,
    ifValuesPass=0, originalModel=0x0) at ClpSimplexPrimal.cpp:969
#6  0x00002aaab5342dcc in ClpSimplexPrimal::primal (this=0x54551b60,
ifValuesPass=0, startFinishOptions=0) at ClpSimplexPrimal.cpp:343
#7  0x00002aaab52d6c28 in ClpSimplex::primal (this=0x54551b60,
ifValuesPass=0, startFinishOptions=0) at ClpSimplex.cpp:5770
#8  0x00002aaab5219e8f in solveDuals(ClpSimplex&, double) () from
/data/stormdata/libCallClpGubHeapModel.so

Will you please give some guide? My code is in the attachment
-------------- next part --------------
#include "com_adsame_rtb_duallearner_gap_clp_CLPSolverGUB.h"
#include "ClpSimplex.hpp"
#include "ClpDynamicExampleMatrix.hpp"
#include "ClpPrimalColumnSteepest.hpp"
#include "CoinSort.hpp"
#include "CoinHelperFunctions.hpp"
#include "CoinTime.hpp"
#include "CoinMpsIO.hpp"
#include "ClpDualRowSteepest.hpp"

void initialDummyModel(ClpSimplex& model, int numRows, const double* rowUpper);

void initialGubMatrix(ClpSimplex& model, int numGubRow, int numGubColumns,
        const double* values, const int *gubRowStartColIndices,
        const double* weightsByCol, const int* weightsRowIndices,
        const int* weightsStarts);

void solveDuals(ClpSimplex& model, double maxSolveSeconds);
/*
 *  This is the method called by Java
 *  Solve an linear program and returns the duals 
 */
JNIEXPORT jdoubleArray JNICALL Java_com_adsame_rtb_duallearner_gap_clp_CLPSolverGUB_solveDual
(JNIEnv *env, jclass jobj, jdoubleArray values, jdoubleArray weightsByCol,
        jintArray weightsRowIndices, jintArray weightsStarts,
        jdoubleArray capacities, jint numColumns, jint numPacks,
        jint numItems, jintArray itemStartCols, jdouble maxSolveSeconds) {

    const int OPTIMAL = 0;
    const int STOP_ON_LIMIT = 3;

    double *nativeValues =
            (double*) env->GetPrimitiveArrayCritical(values, NULL);
    double *nativeWeightsByCol =
            (double*) env->GetPrimitiveArrayCritical(weightsByCol, NULL);
    int *nativeWeightsRowIndices =
            (int*) env->GetPrimitiveArrayCritical(weightsRowIndices, NULL);
    int *nativeWeightsStarts =
            (int*) env->GetPrimitiveArrayCritical(weightsStarts, NULL);
    double *nativeCapacities =
            (double*) env->GetPrimitiveArrayCritical(capacities, NULL);
    int *nativeItemStartCols =
            (int*) env->GetPrimitiveArrayCritical(itemStartCols, NULL);

#ifdef MY_DEBUG
    {
        printf("values = ");
        for (int i = 0; i < env->GetArrayLength(values); i++) {
            printf("%.2f, ", nativeValues[i]);
        }
        printf("\n");

        printf("weightsByCol = ");
        for (int i = 0; i < env->GetArrayLength(weightsByCol); i++) {
            printf("%.2f, ", nativeWeightsByCol[i]);
        }
        printf("\n");

        printf("weightsRowIndices = ");
        for (int i = 0; i < env->GetArrayLength(weightsRowIndices); i++) {
            printf("%d, ", nativeWeightsRowIndices[i]);
        }
        printf("\n");

        printf("weightsStarts = ");
        for (int i = 0; i < env->GetArrayLength(weightsStarts); i++) {
            printf("%d, ", nativeWeightsStarts[i]);
        }
        printf("\n");

        printf("capacities = ");
        for (int i = 0; i < env->GetArrayLength(capacities); i++) {
            printf("%.2f, ", nativeCapacities[i]);
        }
        printf("\n");

        printf("itemStartCols = ");
        for (int i = 0; i < env->GetArrayLength(itemStartCols); i++) {
            printf("%d, ", nativeItemStartCols[i]);
        }
        printf("\n");

        printf("numColumns = %d, numPacks = %d, numItems = %d\n",
                numColumns, numPacks, numItems);

    }
#endif

    ClpSimplex *model = new ClpSimplex();

    initialDummyModel(*model, numPacks, nativeCapacities);
    initialGubMatrix(*model, numItems, numColumns, nativeValues,
            nativeItemStartCols, nativeWeightsByCol,
            nativeWeightsRowIndices, nativeWeightsStarts);
    solveDuals(*model, maxSolveSeconds);

    env->ReleasePrimitiveArrayCritical(itemStartCols, nativeItemStartCols, JNI_ABORT);
    env->ReleasePrimitiveArrayCritical(capacities, nativeCapacities, JNI_ABORT);
    env->ReleasePrimitiveArrayCritical(weightsStarts, nativeWeightsStarts, JNI_ABORT);
    env->ReleasePrimitiveArrayCritical(weightsRowIndices, nativeWeightsRowIndices, JNI_ABORT);
    env->ReleasePrimitiveArrayCritical(weightsByCol, nativeWeightsByCol, JNI_ABORT);
    env->ReleasePrimitiveArrayCritical(values, nativeValues, JNI_ABORT);

    int status = model->problemStatus();
    // 0 means optimal, 3 means stop on time or iteration limit
    if (!(status == OPTIMAL || status == STOP_ON_LIMIT)) {
        return NULL;
    }

    jdoubleArray returnValue = env->NewDoubleArray(numPacks + 1);

    double *tempArray = new double[numPacks + 1];

    const double * duals = model->getRowPrice();
    tempArray[0] = model->objectiveValue();
    memcpy(tempArray + 1, duals, numPacks * sizeof(double));

    env->SetDoubleArrayRegion(returnValue, 0, numPacks + 1, tempArray);

    delete[] tempArray;
    delete model;

#ifdef MY_DEBUG
    {

        printf("problem status = %d\n", status);
        printf("model objectiveValue = %f\n", model.objectiveValue());
        for (int i = 0; i < model.getNumRows(); i++) {
            printf("%.2f ", duals[i]);
        }
    }
#endif

    return returnValue;
}

/*
 * init the model to be one dummy column, the variable does not appear in values
 * each row has upper bound equal to demands of the packs
 */
void initialDummyModel(ClpSimplex& model, int numRows, const double* rowUpper) {
    int *rows = new int[numRows];
    double *elements = new double[numRows];
    double value = 0.0;

    //column [0, COIN_DBL_MAX]
    double *columLower = NULL;
    double *columUpper = NULL;

    // rowlower equals -COIN_DBL_MAX
    double *rowLower = NULL;

    int vecStarts[2] = {0, numRows};

    for (int i = 0; i < numRows; i++) {
        rows[i] = i;
        elements[i] = 1.0;
    }

    model.loadProblem(1, numRows, vecStarts, rows, elements, columLower,
            columUpper, &value, rowLower, rowUpper);
    delete[] rows;
    delete[] elements;
}

/*
 * load Gub matrix and replace oringinal matrix in model
 * this is copied from testGub.cpp
 */
void initialGubMatrix(ClpSimplex& model, int numGubRow, int numGubColumns,
        const double* values, const int *gubRowStartColIndices,
        const double* weightsByCol, const int* weightsRowIndices,
        const int* weightsStarts) {
    double *gubRowLower = new double[numGubRow];
    double *gubRowUpper = new double[numGubRow];

    //column [0, COIN_DBL_MAX]
    double *colLower = NULL;
    double *colUpper = NULL;

    // in our case, all gub rows have upper bound 1
    for(int i = 0; i < numGubRow; i++) {
        // setting this value to 0 causes error, and it can not be left null
        gubRowLower[i] = -COIN_DBL_MAX;
        gubRowUpper[i] = 1.0;
    }

    ClpDynamicMatrix * newMatrix = new ClpDynamicMatrix(&model, numGubRow,
            numGubColumns, gubRowStartColIndices,
            gubRowLower, gubRowUpper,
            weightsStarts, weightsRowIndices, weightsByCol,
            values,
            colLower, colUpper);
    // true to delete current matrix, otherwise it leaks
    model.replaceMatrix(newMatrix, true);
    newMatrix->switchOffCheck();
    // unknown heuristic
    newMatrix->setRefreshFrequency(1000);

    delete[] gubRowLower;
    delete[] gubRowUpper;
}

/*
 * all the heuristic are copied from testGub.cpp
 * By default it do minimization
 */
void solveDuals(ClpSimplex& model, double maxSolveSeconds) {
    model.setSpecialOptions(4); // exactly to bound
    // For now scaling off
    model.scaling(0);

    // why use 5 is not known
    ClpPrimalColumnSteepest steepest(5);
    model.setPrimalColumnPivotAlgorithm(steepest);
    // switch off logging
    model.messageHandler()->setLogLevel(0);

    // unknown heuristic
    model.setFactorizationFrequency(100);

    model.setMaximumSeconds(maxSolveSeconds);

    model.primal();
}


More information about the Clp mailing list