Skip to content

Commit

Permalink
Adding API function diffSimulationResults, similar to cmpSimulationRe…
Browse files Browse the repository at this point in the history
…sults

- Outputs a list of csv-files with the compared values (which might be interpolated)


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@17660 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Oct 13, 2013
1 parent 8acb9a9 commit 0c8e945
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 51 deletions.
17 changes: 17 additions & 0 deletions Compiler/FrontEnd/ModelicaBuiltin.mo
Expand Up @@ -2331,6 +2331,23 @@ external "builtin";
annotation(preferredView="text");
end compareSimulationResults;

public function diffSimulationResults "compares simulation results."
input String actualFile;
input String expectedFile;
input String diffPrefix;
input Real relTol := 0.01;
input Real absTol := 0.0001;
input String[:] vars := fill("",0);
input Boolean keepEqualResults := false;
output Boolean success /* On success, resultFiles is empty. But it might be empty on failure anyway (for example if an input file does not exist) */;
output String[:] resultFiles;
external "builtin";
annotation(Documentation(info="<html>
<p>Takes two result files and compares them. By default, all selected variables that are not equal in the two files are output to diffPrefix.varName.csv.</p>
<p>The output is the generated filesnames</p>
</html>"),preferredView="text");
end diffSimulationResults;

public function checkTaskGraph "Checks if the given taskgraph has the same structure as the reference taskgraph and if all attributes are set correctly."
input String filename;
input String reffilename;
Expand Down
20 changes: 20 additions & 0 deletions Compiler/Script/CevalScript.mo
Expand Up @@ -2428,6 +2428,26 @@ algorithm
case (cache,env,"compareSimulationResults",_,st,_)
then (cache,Values.STRING("Error in compareSimulationResults"),st);

case (cache,env,"diffSimulationResults",{Values.STRING(filename),Values.STRING(filename_1),Values.STRING(filename2),Values.REAL(x1),Values.REAL(x2),Values.ARRAY(valueLst=cvars),Values.BOOL(b)},st,_)
equation
pwd = System.pwd();
pd = System.pathDelimiter();
filename = Util.if_(System.substring(filename,1,1) ==& "/",filename,stringAppendList({pwd,pd,filename}));
filename_1 = Util.testsuiteFriendlyPath(filename_1);
filename_1 = Util.if_(System.substring(filename_1,1,1) ==& "/",filename_1,stringAppendList({pwd,pd,filename_1}));
filename2 = Util.if_(System.substring(filename2,1,1) ==& "/",filename2,stringAppendList({pwd,pd,filename2}));
vars_1 = List.map(cvars, ValuesUtil.valString);
(b,strings) = SimulationResults.diffSimulationResults(Config.getRunningTestsuite(),filename,filename_1,filename2,x1,x2,vars_1,b);
cvars = List.map(strings,ValuesUtil.makeString);
v = ValuesUtil.makeArray(cvars);
then
(cache,Values.TUPLE({Values.BOOL(b),v}),st);

case (cache,env,"diffSimulationResults",_,st,_)
equation
v = ValuesUtil.makeArray({});
then (cache,Values.TUPLE({Values.BOOL(false),v}),st);

case (cache,env,"checkTaskGraph",{Values.STRING(filename),Values.STRING(filename_1)},st,_)
equation
pwd = System.pwd();
Expand Down
14 changes: 14 additions & 0 deletions Compiler/Util/SimulationResults.mo
Expand Up @@ -88,5 +88,19 @@ public function cmpSimulationResults
end cmpSimulationResults;


public function diffSimulationResults
input Boolean runningTestsuite;
input String filename;
input String reffilename;
input String prefix;
input Real refTol;
input Real absTol;
input list<String> vars;
input Boolean keepEqualResults;
output Boolean success;
output list<String> res;
external "C" res=SimulationResults_diffSimulationResults(runningTestsuite,filename,reffilename,prefix,refTol,absTol,vars,keepEqualResults,success) annotation(Library = "omcruntime");
end diffSimulationResults;

end SimulationResults;

114 changes: 69 additions & 45 deletions Compiler/runtime/SimulationResultsCmp.c
Expand Up @@ -38,7 +38,7 @@
#include "systemimpl.h"

/* Size of the buffer for warnings and other messages */
#define WARNINGBUFFSIZE 2000
#define WARNINGBUFFSIZE 4096

typedef struct {
double *data;
Expand Down Expand Up @@ -237,7 +237,7 @@ static char AlmostEqualRelativeAndAbs(double A, double B)
return 0;
}

static unsigned int cmpData(char* varname, DataField *time, DataField *reftime, DataField *data, DataField *refdata, double reltol, double abstol, DiffDataField *ddf, char **cmpdiffvars, unsigned int vardiffindx)
static unsigned int cmpData(int isResultCmp, char* varname, DataField *time, DataField *reftime, DataField *data, DataField *refdata, double reltol, double abstol, DiffDataField *ddf, char **cmpdiffvars, unsigned int vardiffindx, int keepEqualResults, void **diffLst, char *prefix)
{
unsigned int i,j,k,j_event;
double t,tr,d,dr,err,d_left,d_right,dr_left,dr_right,t_event;
Expand All @@ -246,6 +246,16 @@ static unsigned int cmpData(char* varname, DataField *time, DataField *reftime,
char isdifferent = 0;
char refevent = 0;
double average=0;
FILE *fout = NULL;
char *fname = NULL;
if (!isResultCmp) {
fname = (char*) malloc(15 + strlen(varname));
sprintf(fname, "%s.%s.csv", prefix, varname);
fout = fopen(fname,"w");
if (fout) {
fprintf(fout, "time,reference,actual,err,relerr,\"%s\"\n",varname);
}
}
for (i=0;i<refdata->n;i++){
average += absdouble(refdata->data[i]);
}
Expand Down Expand Up @@ -504,6 +514,9 @@ static unsigned int cmpData(char* varname, DataField *time, DataField *reftime,
#ifdef DEBUGOUTPUT
fprintf(stderr, "delta:%.6g reltol:%.6g\n",err,average);
#endif
if (fout) {
fprintf(fout, "%.6g,%.6g,%.6g,%.6g,%.6g\n",tr,d,dr,err,AlmostEqualRelativeAndAbs(d,0) ? err/average : absdouble(err/d));
}
if ( err > average){
if (j+1<reftime->n) {
if (reftime->data[j+1] == tr) {
Expand All @@ -517,25 +530,39 @@ static unsigned int cmpData(char* varname, DataField *time, DataField *reftime,
}

isdifferent = 1;
if (ddf->n >= ddf->n_max) {
DiffData *diffdatafild;
ddf->n_max = ddf->n_max ? ddf->n_max*2 : 1024;
ddf->data = (DiffData*) realloc(ddf->data, sizeof(DiffData)*(ddf->n_max));
/* TODO: Check for errors? */
if (isResultCmp) { /* If we produce the full diff, this data has already been output */
if (ddf->n >= ddf->n_max) {
DiffData *newData;
ddf->n_max = ddf->n_max ? ddf->n_max*2 : 1024;
newData = (DiffData*) realloc(ddf->data, sizeof(DiffData)*(ddf->n_max));
if (!newData) continue; /* realloc failed... pretty bad, but let's continue */
ddf->data = newData;
}
ddf->data[ddf->n].name = varname;
ddf->data[ddf->n].data = d;
ddf->data[ddf->n].dataref = dr;
ddf->data[ddf->n].time = t;
ddf->data[ddf->n].timeref = tr;
ddf->data[ddf->n].interpolate = interpolate?'1':'0';
ddf->n +=1;
}
ddf->data[ddf->n].name = varname;
ddf->data[ddf->n].data = d;
ddf->data[ddf->n].dataref = dr;
ddf->data[ddf->n].time = t;
ddf->data[ddf->n].timeref = tr;
ddf->data[ddf->n].interpolate = interpolate?'1':'0';
ddf->n +=1;
}
}
if (isdifferent)
{
if (isdifferent) {
cmpdiffvars[vardiffindx] = varname;
vardiffindx++;
if (!isResultCmp) {
*diffLst = mk_cons(mk_scon(fname),*diffLst);
}
}
if (fout) {
fclose(fout);
}
if (!isdifferent && 0==keepEqualResults && 0==isResultCmp) {
SystemImpl__removeFile(fname);
}
if (fname) {
free(fname);
}
return vardiffindx;
}
Expand Down Expand Up @@ -577,7 +604,8 @@ static const char* getTimeVarName(void *vars) {
return res;
}

void* SimulationResultsCmp_compareResults(int runningTestsuite, const char *filename, const char *reffilename, const char *resultfilename, double reltol, double abstol, void *vars)
/* Common, huge function, for both result comparison and result diff */
void* SimulationResultsCmp_compareResults(int isResultCmp, int runningTestsuite, const char *filename, const char *reffilename, const char *resultfilename, double reltol, double abstol, void *vars, int keepEqualResults, int *success)
{
char **cmpvars=NULL;
char **cmpdiffvars=NULL;
Expand Down Expand Up @@ -642,14 +670,12 @@ void* SimulationResultsCmp_compareResults(int runningTestsuite, const char *file
timeVarName = getTimeVarName(allvars);
timeVarNameRef = getTimeVarName(allvarsref);
time = getData(timeVarName,filename,size,&simresglob_c);
if (time.n==0)
{
if (time.n==0) {
return mk_cons(mk_scon("Error get time!"),mk_nil());
}
/* fprintf(stderr, "get reftime\n"); */
timeref = getData(timeVarNameRef,reffilename,size_ref,&simresglob_ref);
if (timeref.n==0)
{
if (timeref.n==0) {
return mk_cons(mk_scon("Error get ref time!"),mk_nil());
}
/* check if time is larger or less reftime */
Expand All @@ -659,11 +685,10 @@ void* SimulationResultsCmp_compareResults(int runningTestsuite, const char *file
#ifdef DEBUGOUTPUT
fprintf(stderr, "max time value=%.6g ref max time value: %.6g\n",time.data[time.n-1],timeref.data[timeref.n-1]);
#endif
res = mk_cons(mk_scon("Warning: Resultfile and Reference have different end time points!\n"),res);
snprintf(buf,WARNINGBUFFSIZE,"Reffile[%d]=%f\n",timeref.n,timeref.data[timeref.n-1]);
res = mk_cons(mk_scon(buf),res);
snprintf(buf,WARNINGBUFFSIZE,"File[%d]=%f\n",time.n,time.data[time.n-1]);
res = mk_cons(mk_scon(buf),res);
snprintf(buf,WARNINGBUFFSIZE,"Resultfile and Reference have different end time points!\n"
"Reffile[%d]=%f\n"
"File[%d]=%f\n",timeref.n,timeref.data[timeref.n-1],time.n,time.data[time.n-1]);
c_add_message(-1, ErrorType_scripting, ErrorLevel_warning, buf, NULL, 0);
}
var1=NULL;
var2=NULL;
Expand Down Expand Up @@ -701,8 +726,6 @@ void* SimulationResultsCmp_compareResults(int runningTestsuite, const char *file
msg[1] = var;
c_add_message(-1, ErrorType_scripting, ErrorLevel_warning, gettext("Get data of variable %s from file %s failed!\n"), msg, 2);
ngetfailedvars++;
snprintf(buf,WARNINGBUFFSIZE,"Get data of variable %s from file %s failed!\n",var,msg[0]);
res = mk_cons(mk_scon(buf),res);
continue;
}
}
Expand All @@ -719,35 +742,36 @@ void* SimulationResultsCmp_compareResults(int runningTestsuite, const char *file
msg[1] = var;
c_add_message(-1, ErrorType_scripting, ErrorLevel_warning, gettext("Get data of variable %s from file %s failed!\n"), msg, 2);
ngetfailedvars++;
snprintf(buf,WARNINGBUFFSIZE,"Get data of variable %s from file %s failed!\n",var,msg[0]);
res = mk_cons(mk_scon(buf),res);
continue;
}
}
/* compare */
vardiffindx = cmpData(var,&time,&timeref,&data,&dataref,reltol,abstol,&ddf,cmpdiffvars,vardiffindx);
vardiffindx = cmpData(isResultCmp,var,&time,&timeref,&data,&dataref,reltol,abstol,&ddf,cmpdiffvars,vardiffindx,keepEqualResults,&res,resultfilename);
/* free */
if (dataref.data) free(dataref.data);
if (data.data) free(data.data);
}

if (writeLogFile(resultfilename,&ddf,filename,reffilename,reltol,abstol))
{
c_add_message(-1, ErrorType_scripting, ErrorLevel_warning, gettext("Cannot write to the difference (.csv) file!\n"), msg, 0);
}
if (isResultCmp) {
if (writeLogFile(resultfilename,&ddf,filename,reffilename,reltol,abstol)) {
c_add_message(-1, ErrorType_scripting, ErrorLevel_warning, gettext("Cannot write to the difference (.csv) file!\n"), msg, 0);
}

if ((ddf.n > 0) || (ngetfailedvars > 0)){
/* fprintf(stderr, "diff: %d\n",ddf.n); */
/* for (i=0;i<vardiffindx;i++)
fprintf(stderr, "diffVar: %s\n",cmpdiffvars[i]); */
for (i=0;i<vardiffindx;i++){
res = (void*)mk_cons(mk_scon(cmpdiffvars[i]),res);
if ((ddf.n > 0) || (ngetfailedvars > 0)){
/* fprintf(stderr, "diff: %d\n",ddf.n); */
/* for (i=0;i<vardiffindx;i++)
fprintf(stderr, "diffVar: %s\n",cmpdiffvars[i]); */
for (i=0;i<vardiffindx;i++){
res = (void*)mk_cons(mk_scon(cmpdiffvars[i]),res);
}
res = mk_cons(mk_scon("Files not Equal!"),res);
c_add_message(-1, ErrorType_scripting, ErrorLevel_warning, gettext("Files not Equal\n"), msg, 0);
} else {
res = mk_cons(mk_scon("Files Equal!"),res);
}
res = mk_cons(mk_scon("Files not Equal!"),res);
c_add_message(-1, ErrorType_scripting, ErrorLevel_warning, gettext("Files not Equal\n"), msg, 0);
} else {
*success = 0==vardiffindx;
}
else
res = mk_cons(mk_scon("Files Equal!"),res);

if (var1) free(var1);
if (var2) free(var2);
Expand Down
Expand Up @@ -32,8 +32,6 @@
#include <stdlib.h>


extern "C" {

#include "meta_modelica.h"
#include "rml_compatibility.h"
#define ADD_METARECORD_DEFINITIONS static
Expand Down Expand Up @@ -67,12 +65,15 @@ double SimulationResults_val(const char *filename, const char *varname, double t

void* SimulationResults_cmpSimulationResults(int runningTestsuite, const char *filename,const char *reffilename,const char *logfilename, double refTol, double absTol, void *vars)
{
return SimulationResultsCmp_compareResults(runningTestsuite,filename,reffilename,logfilename,refTol,absTol,vars);
return SimulationResultsCmp_compareResults(1,runningTestsuite,filename,reffilename,logfilename,refTol,absTol,vars,0,NULL);
}

void SimulationResults_close()
void* SimulationResults_diffSimulationResults(int runningTestsuite, const char *filename,const char *reffilename,const char *logfilename, double refTol, double absTol, void *vars, int keepEqualResults, int *success)
{
SimulationResultsImpl__close(&simresglob);
return SimulationResultsCmp_compareResults(0,runningTestsuite,filename,reffilename,logfilename,refTol,absTol,vars,keepEqualResults,success);
}

void SimulationResults_close()
{
SimulationResultsImpl__close(&simresglob);
}
11 changes: 10 additions & 1 deletion Compiler/runtime/SimulationResults_rml.c
Expand Up @@ -86,8 +86,17 @@ RML_END_LABEL

RML_BEGIN_LABEL(SimulationResults__cmpSimulationResults)
{
rmlA0 = SimulationResultsCmp_compareResults(RML_UNTAGFIXNUM(rmlA0),RML_STRINGDATA(rmlA1),RML_STRINGDATA(rmlA2),RML_STRINGDATA(rmlA3),rml_prim_get_real(rmlA4),rml_prim_get_real(rmlA5),rmlA6);
rmlA0 = SimulationResultsCmp_compareResults(1,RML_UNTAGFIXNUM(rmlA0),RML_STRINGDATA(rmlA1),RML_STRINGDATA(rmlA2),RML_STRINGDATA(rmlA3),rml_prim_get_real(rmlA4),rml_prim_get_real(rmlA5),rmlA6,0,NULL);
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL


RML_BEGIN_LABEL(SimulationResults__diffSimulationResults)
{
int res;
rmlA1 = SimulationResultsCmp_compareResults(0,RML_UNTAGFIXNUM(rmlA0),RML_STRINGDATA(rmlA1),RML_STRINGDATA(rmlA2),RML_STRINGDATA(rmlA3),rml_prim_get_real(rmlA4),rml_prim_get_real(rmlA5),rmlA6,RML_UNTAGFIXNUM(rmlA7),&res);
rmlA0 = mk_icon(res);
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

0 comments on commit 0c8e945

Please sign in to comment.