Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Commit

Permalink
Fix crash is default linear solver
Browse files Browse the repository at this point in the history
If an expression makes a longjmp, the linear solver data was not
restored. This fix makes it so the solver data does not need to be
patched depending on which linear solver is running; it simply allocates
memory for an extra void* to hold the fallback solver's data.

Belonging to [master]:
  - #1894
  • Loading branch information
sjoelund authored and OpenModelica-Hudson committed Oct 13, 2017
1 parent aba3685 commit 0406ea2
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 54 deletions.
2 changes: 1 addition & 1 deletion SimulationRuntime/c/simulation/solver/linearSolverKlu.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ solveKlu(DATA *data, threadData_t *threadData, int sysNumber)
{
void *dataAndThreadData[2] = {data, threadData};
LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->linearSystemData[sysNumber]);
DATA_KLU* solverData = (DATA_KLU*)systemData->solverData;
DATA_KLU* solverData = (DATA_KLU*)systemData->solverData[0];

int i, j, status = 0, success = 0, n = systemData->size, eqSystemNumber = systemData->equationIndex, indexes[2] = {1,eqSystemNumber};
double tmpJacEvalTime;
Expand Down
9 changes: 6 additions & 3 deletions SimulationRuntime/c/simulation/solver/linearSolverLapack.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ extern int dgesv_(int *n, int *nrhs, double *a, int *lda,
*/
int allocateLapackData(int size, void** voiddata)
{
DATA_LAPACK* data = (DATA_LAPACK*) malloc(sizeof(DATA_LAPACK));
DATA_LAPACK* data = (DATA_LAPACK*) calloc(1, sizeof(DATA_LAPACK));

data->ipiv = (int*) malloc(size*sizeof(int));
data->ipiv = (int*) calloc(size, sizeof(int));
assertStreamPrint(NULL, 0 != data->ipiv, "Could not allocate data for linear solver lapack.");
data->nrhs = 1;
data->info = 0;
Expand Down Expand Up @@ -84,6 +84,9 @@ int freeLapackData(void **voiddata)
_omc_destroyVector(data->b);
_omc_destroyMatrix(data->A);

free(data);
voiddata[0] = 0;

return 0;
}

Expand Down Expand Up @@ -160,7 +163,7 @@ int solveLapack(DATA *data, threadData_t *threadData, int sysNumber)
void *dataAndThreadData[2] = {data, threadData};
int i, iflag = 1;
LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->linearSystemData[sysNumber]);
DATA_LAPACK* solverData = (DATA_LAPACK*)systemData->solverData;
DATA_LAPACK* solverData = (DATA_LAPACK*)systemData->solverData[0];

int success = 1;

Expand Down
2 changes: 1 addition & 1 deletion SimulationRuntime/c/simulation/solver/linearSolverLis.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ solveLis(DATA *data, threadData_t *threadData, int sysNumber)
{
void *dataAndThreadData[2] = {data, threadData};
LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->linearSystemData[sysNumber]);
DATA_LIS* solverData = (DATA_LIS*)systemData->solverData;
DATA_LIS* solverData = (DATA_LIS*)systemData->solverData[0];
int i, ret, success = 1, ni, iflag = 1, n = systemData->size, eqSystemNumber = systemData->equationIndex;
char *lis_returncode[] = {"LIS_SUCCESS", "LIS_ILL_OPTION", "LIS_BREAKDOWN", "LIS_OUT_OF_MEMORY", "LIS_MAXITER", "LIS_NOT_IMPLEMENTED", "LIS_ERR_FILE_IO"};
LIS_INT err;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ int allocateTotalPivotData(int size, void** voiddata)
data->indRow =(int*) calloc(size,sizeof(int));
data->indCol =(int*) calloc(size+1,sizeof(int));

*voiddata = (void*)data;
voiddata[1] = (void*)data;
return 0;
}

Expand All @@ -291,7 +291,7 @@ int allocateTotalPivotData(int size, void** voiddata)
*/
int freeTotalPivotData(void** voiddata)
{
DATA_TOTALPIVOT* data = (DATA_TOTALPIVOT*) *voiddata;
DATA_TOTALPIVOT* data = (DATA_TOTALPIVOT*) voiddata[1];

/* memory for linear system */
free(data->Ab);
Expand All @@ -302,6 +302,9 @@ int freeTotalPivotData(void** voiddata)
free(data->indRow);
free(data->indCol);

free(voiddata[1]);
voiddata[1] = 0;

return 0;
}

Expand Down Expand Up @@ -383,7 +386,7 @@ int solveTotalPivot(DATA *data, threadData_t *threadData, int sysNumber)
void *dataAndThreadData[2] = {data, threadData};
int i, j;
LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->linearSystemData[sysNumber]);
DATA_TOTALPIVOT* solverData = (DATA_TOTALPIVOT*)systemData->solverData;
DATA_TOTALPIVOT* solverData = (DATA_TOTALPIVOT*) systemData->solverData[1];
int n = systemData->size, status;
double fdeps = 1e-8;
double xTol = 1e-8;
Expand Down
4 changes: 2 additions & 2 deletions SimulationRuntime/c/simulation/solver/linearSolverUmfpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ solveUmfPack(DATA *data, threadData_t *threadData, int sysNumber)
{
void *dataAndThreadData[2] = {data, threadData};
LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->linearSystemData[sysNumber]);
DATA_UMFPACK* solverData = (DATA_UMFPACK*)systemData->solverData;
DATA_UMFPACK* solverData = (DATA_UMFPACK*)systemData->solverData[0];

int i, j, status = UMFPACK_OK, success = 0, ni=0, n = systemData->size, eqSystemNumber = systemData->equationIndex, indexes[2] = {1,eqSystemNumber};
int casualTearingSet = systemData->strictTearingFunctionCall != NULL;
Expand Down Expand Up @@ -354,7 +354,7 @@ solveUmfPack(DATA *data, threadData_t *threadData, int sysNumber)
int solveSingularSystem(LINEAR_SYSTEM_DATA* systemData)
{

DATA_UMFPACK* solverData = (DATA_UMFPACK*) systemData->solverData;
DATA_UMFPACK* solverData = (DATA_UMFPACK*) systemData->solverData[0];
double *Ux, *Rs, r_ii, *b, sum, *y, *z;
int *Up, *Ui, *Q, do_recip, rank = 0, current_rank, current_unz, i, j, k, l,
success = 0, status, stop = 0;
Expand Down
75 changes: 32 additions & 43 deletions SimulationRuntime/c/simulation/solver/linearSystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,6 @@ static void setBElementLis(int row, double value, void *data, threadData_t*);

int check_linear_solution(DATA *data, int printFailingSystems, int sysNumber);

/* Data structure for the default solver
* where two different solverData for lapack and
* totalpivot as fallback
*/
struct dataLapackAndTotalPivot{
void* lapackData;
void* totalpivotData;
};

/*! \fn int initializeLinearSystems(DATA *data)
*
* This function allocates memory for all linear systems.
Expand All @@ -78,7 +69,6 @@ int initializeLinearSystems(DATA *data, threadData_t *threadData)
int i, nnz;
int size;
LINEAR_SYSTEM_DATA *linsys = data->simulationInfo->linearSystemData;
struct dataLapackAndTotalPivot *defaultSolverData;

infoStreamPrint(LOG_LS, 1, "initialize linear system solvers");
infoStreamPrint(LOG_LS, 0, "%ld linear systems", data->modelData->nLinearSystems);
Expand Down Expand Up @@ -134,19 +124,19 @@ int initializeLinearSystems(DATA *data, threadData_t *threadData)
case LSS_LIS:
linsys[i].setAElement = setAElementLis;
linsys[i].setBElement = setBElementLis;
allocateLisData(size, size, nnz, &linsys[i].solverData);
allocateLisData(size, size, nnz, linsys[i].solverData);
break;
#endif
#ifdef WITH_UMFPACK
case LSS_UMFPACK:
linsys[i].setAElement = setAElementUmfpack;
linsys[i].setBElement = setBElement;
allocateUmfPackData(size, size, nnz, &linsys[i].solverData);
allocateUmfPackData(size, size, nnz, linsys[i].solverData);
break;
case LSS_KLU:
linsys[i].setAElement = setAElementKlu;
linsys[i].setBElement = setBElement;
allocateKluData(size, size, nnz, &linsys[i].solverData);
allocateKluData(size, size, nnz, linsys[i].solverData);
break;
#else
case LSS_UMFPACK:
Expand All @@ -166,26 +156,26 @@ int initializeLinearSystems(DATA *data, threadData_t *threadData)
linsys[i].A = (double*) malloc(size*size*sizeof(double));
linsys[i].setAElement = setAElement;
linsys[i].setBElement = setBElement;
allocateLapackData(size, &linsys[i].solverData);
allocateLapackData(size, linsys[i].solverData);
break;

#if !defined(OMC_MINIMAL_RUNTIME)
case LS_LIS:
linsys[i].setAElement = setAElementLis;
linsys[i].setBElement = setBElementLis;
allocateLisData(size, size, nnz, &linsys[i].solverData);
allocateLisData(size, size, nnz, linsys[i].solverData);
break;
#endif
#ifdef WITH_UMFPACK
case LS_UMFPACK:
linsys[i].setAElement = setAElementUmfpack;
linsys[i].setBElement = setBElement;
allocateUmfPackData(size, size, nnz, &linsys[i].solverData);
allocateUmfPackData(size, size, nnz, linsys[i].solverData);
break;
case LS_KLU:
linsys[i].setAElement = setAElementKlu;
linsys[i].setBElement = setBElement;
allocateKluData(size, size, nnz, &linsys[i].solverData);
allocateKluData(size, size, nnz, linsys[i].solverData);
break;
#else
case LS_UMFPACK:
Expand All @@ -197,19 +187,17 @@ int initializeLinearSystems(DATA *data, threadData_t *threadData)
linsys[i].A = (double*) malloc(size*size*sizeof(double));
linsys[i].setAElement = setAElement;
linsys[i].setBElement = setBElement;
allocateTotalPivotData(size, &(linsys[i].solverData));
allocateTotalPivotData(size, linsys[i].solverData);
break;

case LS_DEFAULT:
defaultSolverData = (struct dataLapackAndTotalPivot*) malloc(sizeof(struct dataLapackAndTotalPivot));
linsys[i].A = (double*) malloc(size*size*sizeof(double));
linsys[i].setAElement = setAElement;
linsys[i].setBElement = setBElement;

allocateLapackData(size, &(defaultSolverData->lapackData));
allocateTotalPivotData(size, &(defaultSolverData->totalpivotData));
allocateLapackData(size, linsys[i].solverData);
allocateTotalPivotData(size, linsys[i].solverData);

linsys[i].solverData = (void*) defaultSolverData;
break;

default:
Expand Down Expand Up @@ -298,16 +286,16 @@ int freeLinearSystems(DATA *data, threadData_t *threadData)
{
#if !defined(OMC_MINIMAL_RUNTIME)
case LSS_LIS:
freeLisData(&linsys[i].solverData);
freeLisData(linsys[i].solverData);
break;
#endif

#ifdef WITH_UMFPACK
case LSS_UMFPACK:
freeUmfPackData(&linsys[i].solverData);
freeUmfPackData(linsys[i].solverData);
break;
case LSS_KLU:
freeKluData(&linsys[i].solverData);
freeKluData(linsys[i].solverData);
break;
#else
case LSS_UMFPACK:
Expand All @@ -324,22 +312,22 @@ int freeLinearSystems(DATA *data, threadData_t *threadData)
switch(data->simulationInfo->lsMethod)
{
case LS_LAPACK:
freeLapackData(&linsys[i].solverData);
freeLapackData(linsys[i].solverData);
free(linsys[i].A);
break;

#if !defined(OMC_MINIMAL_RUNTIME)
case LS_LIS:
freeLisData(&linsys[i].solverData);
freeLisData(linsys[i].solverData);
break;
#endif

#ifdef WITH_UMFPACK
case LS_UMFPACK:
freeUmfPackData(&linsys[i].solverData);
freeUmfPackData(linsys[i].solverData);
break;
case LS_KLU:
freeKluData(&linsys[i].solverData);
freeKluData(linsys[i].solverData);
break;
#else
case LS_UMFPACK:
Expand All @@ -349,21 +337,28 @@ int freeLinearSystems(DATA *data, threadData_t *threadData)

case LS_TOTALPIVOT:
free(linsys[i].A);
freeTotalPivotData(&(linsys[i].solverData));
freeTotalPivotData(linsys[i].solverData);
break;

case LS_DEFAULT:
free(linsys[i].A);
freeLapackData(&((struct dataLapackAndTotalPivot*) linsys[i].solverData)->lapackData);
freeTotalPivotData(&((struct dataLapackAndTotalPivot*) linsys[i].solverData)->totalpivotData);
freeLapackData(linsys[i].solverData);
freeTotalPivotData(linsys[i].solverData);
break;

default:
throwStreamPrint(threadData, "unrecognized linear solver");
}
}

free(linsys[i].solverData);
if (linsys[i].solverData[0]) {
free(linsys[i].solverData[0]);
linsys[i].solverData[0] = 0;
}
if (linsys[i].solverData[1]) {
free(linsys[i].solverData[1]);
linsys[i].solverData[1] = 0;
}
}

messageClose(LOG_LS_V);
Expand All @@ -386,7 +381,6 @@ int solve_linear_system(DATA *data, threadData_t *threadData, int sysNumber)
int retVal;
int logLevel;
LINEAR_SYSTEM_DATA* linsys = &(data->simulationInfo->linearSystemData[sysNumber]);
struct dataLapackAndTotalPivot *defaultSolverData;

rt_ext_tp_tick(&(linsys->totalTimeClock));

Expand Down Expand Up @@ -460,9 +454,6 @@ int solve_linear_system(DATA *data, threadData_t *threadData, int sysNumber)
break;

case LS_DEFAULT:
defaultSolverData = linsys->solverData;
linsys->solverData = defaultSolverData->lapackData;

success = solveLapack(data, threadData, sysNumber);

/* check if solution process was successful, if not use alternative tearing set if available (dynamic tearing)*/
Expand All @@ -486,14 +477,12 @@ int solve_linear_system(DATA *data, threadData_t *threadData, int sysNumber)
logLevel = LOG_STDOUT;
}
warningStreamPrint(logLevel, 0, "The default linear solver fails, the fallback solver with total pivoting is started at time %f. That might raise performance issues, for more information use -lv LOG_LS.", data->localData[0]->timeValue);
linsys->solverData = defaultSolverData->totalpivotData;
success = solveTotalPivot(data, threadData, sysNumber);
linsys->failed = 1;
}else{
linsys->failed = 0;
}
}
linsys->solverData = defaultSolverData;
break;

default:
Expand Down Expand Up @@ -637,14 +626,14 @@ static void setBElement(int row, double value, void *data, threadData_t *threadD
static void setAElementLis(int row, int col, double value, int nth, void *data, threadData_t *threadData)
{
LINEAR_SYSTEM_DATA* linsys = (LINEAR_SYSTEM_DATA*) data;
DATA_LIS* sData = (DATA_LIS*) linsys->solverData;
DATA_LIS* sData = (DATA_LIS*) linsys->solverData[0];
lis_matrix_set_value(LIS_INS_VALUE, row, col, value, sData->A);
}

static void setBElementLis(int row, double value, void *data, threadData_t *threadData)
{
LINEAR_SYSTEM_DATA* linsys = (LINEAR_SYSTEM_DATA*) data;
DATA_LIS* sData = (DATA_LIS*) linsys->solverData;
DATA_LIS* sData = (DATA_LIS*) linsys->solverData[0];
lis_vector_set_value(LIS_INS_VALUE, row, value, sData->b);
}
#endif
Expand All @@ -653,7 +642,7 @@ static void setBElementLis(int row, double value, void *data, threadData_t *thre
static void setAElementUmfpack(int row, int col, double value, int nth, void *data, threadData_t *threadData)
{
LINEAR_SYSTEM_DATA* linSys = (LINEAR_SYSTEM_DATA*) data;
DATA_UMFPACK* sData = (DATA_UMFPACK*) linSys->solverData;
DATA_UMFPACK* sData = (DATA_UMFPACK*) linSys->solverData[0];

infoStreamPrint(LOG_LS_V, 0, " set %d. -> (%d,%d) = %f", nth, row, col, value);
if (row > 0){
Expand All @@ -668,7 +657,7 @@ static void setAElementUmfpack(int row, int col, double value, int nth, void *da
static void setAElementKlu(int row, int col, double value, int nth, void *data, threadData_t *threadData)
{
LINEAR_SYSTEM_DATA* linSys = (LINEAR_SYSTEM_DATA*) data;
DATA_KLU* sData = (DATA_KLU*) linSys->solverData;
DATA_KLU* sData = (DATA_KLU*) linSys->solverData[0];

if (row > 0){
if (sData->Ap[row] == 0){
Expand Down
2 changes: 1 addition & 1 deletion SimulationRuntime/c/simulation_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ typedef struct LINEAR_SYSTEM_DATA
modelica_integer size;
modelica_integer equationIndex; /* index for EQUATION_INFO */

void *solverData;
void *solverData[2]; /* [1] is the totalPivot solver; [0] holds other solvers ; both are used for the default solver */
modelica_real *x; /* solution vector x */
modelica_real *A; /* matrix A */
modelica_real *b; /* vector b */
Expand Down

0 comments on commit 0406ea2

Please sign in to comment.