Skip to content

Commit

Permalink
When running the profiler, also output a smaller prof.json in additio…
Browse files Browse the repository at this point in the history
…n to the xml

- The OMEdit transformations browser will now look at the prof.json and display a summary for the profile blocks


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@20267 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Apr 25, 2014
1 parent 67b87e2 commit b9c8d32
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 1 deletion.
8 changes: 8 additions & 0 deletions Makefile.common
Expand Up @@ -182,6 +182,14 @@ fmil:
#TODO: Only copy required headers, add them in omc/fmi subfolder, and do not copy c/txt-files
#cp -rp 3rdParty/FMIL/install/include/* $(builddir_inc)

qjson:
test -d 3rdParty/qjson-0.8.1
mkdir -p 3rdParty/qjson-0.8.1/build/include
(cd 3rdParty/qjson-0.8.1/build && test -f Makefile || CC="$(CC)" CXX="$(CXX)" CFLAGS="$(CFLAGS)" CPPFLAGS="$(CPPFLAGS)" $(CMAKE) -D CMAKE_AR:String="$(AR)" .. -G $(CMAKE_TARGET))
test -f 3rdParty/qjson-0.8.1/build/lib/libqjson$(SHREXT) || $(MAKE) -C 3rdParty/qjson-0.8.1/build
test "(" ! `uname` = Darwin ")" -o "(" ! -f 3rdParty/qjson-0.8.1/build/lib/libqjson$(SHREXT) ")" || install_name_tool -id @rpath/libqjson$(SHREXT) 3rdParty/qjson-0.8.1/build/lib/libqjson$(SHREXT)
cp -a 3rdParty/qjson-0.8.1/build/lib/libqjson*$(SHREXT)* $(builddir_lib)/omc/
cp -a 3rdParty/qjson-0.8.1/src/*.h 3rdParty/qjson-0.8.1/build/include
CMinpack:
test -d 3rdParty/CMinpack
mkdir -p 3rdParty/CMinpack/build
Expand Down
2 changes: 1 addition & 1 deletion Makefile.in
Expand Up @@ -93,7 +93,7 @@ omshell: mkbuilddirs
$(MAKE) -C OMShell/OMShellGUI -f Makefile.unix
omplot: mkbuilddirs boehm-gc-lib
$(MAKE) -C OMPlot/OMPlotGUI -f Makefile.unix
omedit: mkbuilddirs omplot boehm-gc-lib
omedit: mkbuilddirs omplot boehm-gc-lib qjson
$(MAKE) -C OMEdit/OMEditGUI -f Makefile.unix
ifeq (@with_paradiseo@,)
omoptim:
Expand Down
155 changes: 155 additions & 0 deletions SimulationRuntime/c/simulation/modelinfo.c
Expand Up @@ -39,6 +39,7 @@
#include <string.h>
#include <time.h>
#include <assert.h>
#include <stdint.h>

/* UNDEF to debug the gnuplot file
#define NO_PIPE
Expand All @@ -60,6 +61,56 @@ static void indent(FILE *fout, int n) {
while(n--) fputc(' ', fout);
}

static void convertProfileData(const char *prefix, int numFnsAndBlocks)
{
size_t len = strlen(prefix);
int i;
uint32_t step;
double time[2];
uint32_t iarr[numFnsAndBlocks];
double darr[numFnsAndBlocks];
char inBinary[len + 11];
char outCsv[len + 10];
FILE *fin;
FILE *fout;
int fail = 0;
memcpy(inBinary,prefix,len);
memcpy(outCsv,prefix,len);
strcpy(inBinary + len, "_prof.data");
strcpy(outCsv + len, "_prof.csv");
fin = fopen(inBinary, "rb");
if (!fin) {
throwStreamPrint(NULL, "Failed to open %s for reading", inBinary);
}
fout = fopen(outCsv, "wb");
if (!fout) {
fclose(fin);
throwStreamPrint(NULL, "Failed to open %s for writing", outCsv);
}
do {
fail |= 1 != fread(&step, sizeof(uint32_t), 1, fin);
fail |= 2 != fread(time, sizeof(double), 2, fin);
fail |= numFnsAndBlocks != fread(iarr, sizeof(uint32_t), numFnsAndBlocks, fin);
fail |= numFnsAndBlocks != fread(darr, sizeof(double), numFnsAndBlocks, fin);
if (fail) {
break;
}
fprintf(fout, "%d,%g,%g", step, time[0], time[1]);
for (i=0; i<numFnsAndBlocks; i++) {
fprintf(fout, ",%d", iarr[i]);
}
for (i=0; i<numFnsAndBlocks; i++) {
fprintf(fout, ",%g", darr[i]);
}
fputc('\n', fout);
} while (!feof(fin));
fclose(fin);
fclose(fout);
if (fail && !feof(fin)) {
throwStreamPrint(NULL, "Failed to read all data from %s", inBinary);
}
}

static void printPlotCommand(FILE *plt, const char *plotFormat, const char *title, const char *prefix, int numFnsAndBlocks, int i, int id, const char *idPrefix) {
const char *format = "plot \"%s_prof.data\" binary format=\"%%*uint32%%2double%%*%duint32%%%ddouble\" using 1:($%d>1e-9 ? $%d : 1e-30) w l lw %d\n";
const char *formatCount = "plot \"%s_prof.data\" binary format=\"%%*uint32%%*2double%%%duint32%%*%ddouble\" using %d w l lw %d\n";
Expand Down Expand Up @@ -448,3 +499,107 @@ int printModelInfo(DATA *data, const char *filename, const char *plotfile, const
}
return 0;
}

#define ERROR_WRITE() throwStreamPrint(NULL, "Failed to write to opened file")

void escapeJSON(FILE *file, const char *data)
{
while (*data) {
switch (*data) {
case '\"': if (fputs("\\\"",file)<0) ERROR_WRITE();break;
case '\\': if (fputs("\\\\",file)<0) ERROR_WRITE();break;
case '\n': if (fputs("\\n",file)<0) ERROR_WRITE();break;
case '\b': if (fputs("\\b",file)<0) ERROR_WRITE();break;
case '\f': if (fputs("\\f",file)<0) ERROR_WRITE();break;
case '\r': if (fputs("\\r",file)<0) ERROR_WRITE();break;
case '\t': if (fputs("\\t",file)<0) ERROR_WRITE();break;
default:
if (*data < ' ') { /* Escape other control characters */
if (fprintf(file, "\\u%04x",*data)<0) ERROR_WRITE();
} else {
if (putc(*data,file)<0) ERROR_WRITE();
}
}
data++;
}
}

static void printJSONFunctions(FILE *fout, DATA *data) {
int i;
for(i = 0; i < data->modelData.modelDataXml.nFunctions; i++) {
const struct FUNCTION_INFO func = modelInfoXmlGetFunction(&data->modelData.modelDataXml, i);
rt_clear(i + SIM_TIMER_FIRST_FUNCTION);
fputs(i == 0 ? "\n" : ",\n", fout);
fprintf(fout, "{\"name\":\"");
escapeJSON(fout, func.name);
fprintf(fout, "\",\"ncall\":%d,\"time\":%.9f,\"maxTime\":%.9f}",
(int) rt_ncall_total(i + SIM_TIMER_FIRST_FUNCTION),
rt_total(i + SIM_TIMER_FIRST_FUNCTION),
rt_max_accumulated(i + SIM_TIMER_FIRST_FUNCTION));
}
}

static void printJSONProfileBlocks(FILE *fout, DATA *data) {
int i;
for(i = data->modelData.modelDataXml.nFunctions; i < data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++) {
const struct EQUATION_INFO eq = modelInfoXmlGetEquationIndexByProfileBlock(&data->modelData.modelDataXml, i-data->modelData.modelDataXml.nFunctions);
rt_clear(i + SIM_TIMER_FIRST_FUNCTION);
fputs(i == data->modelData.modelDataXml.nFunctions ? "\n" : ",\n", fout);
fprintf(fout, "{\"id\":%d,\"ncall\":%d,\"time\":%.9f,\"maxTime\":%.9f}",
(int) eq.id,
(int) rt_ncall_total(i + SIM_TIMER_FIRST_FUNCTION),
rt_total(i + SIM_TIMER_FIRST_FUNCTION),
rt_max_accumulated(i + SIM_TIMER_FIRST_FUNCTION));
}
}

int printModelInfoJSON(DATA *data, const char *filename, const char *outputFilename)
{
char buf[256];
FILE *fout = fopen(filename, "wb");
time_t t;
if (!fout) {
throwStreamPrint(NULL, "Failed to open file %s for writing", filename);
}
convertProfileData(data->modelData.modelFilePrefix, data->modelData.modelDataXml.nFunctions+data->modelData.modelDataXml.nProfileBlocks);
if(time(&t) < 0)
{
fclose(fout);
throwStreamPrint(LOG_UTIL, 0, "time() failed: %s", strerror(errno));
}
if(!strftime(buf, 250, "%Y-%m-%d %H:%M:%S", localtime(&t)))
{
fclose(fout);
throwStreamPrint(LOG_UTIL, 0, "strftime() failed");
}
fprintf(fout, "{\n\"name\":\"");
escapeJSON(fout, data->modelData.modelName);
fprintf(fout, "\",\n\"prefix\":\"");
escapeJSON(fout, data->modelData.modelFilePrefix);
fprintf(fout, "\",\n\"date\":\"");
escapeJSON(fout, buf);
fprintf(fout, "\",\n\"method\":\"");
escapeJSON(fout, data->simulationInfo.solverMethod);
fprintf(fout, "\",\n\"outputFormat\":\"");
escapeJSON(fout, data->simulationInfo.outputFormat);
fprintf(fout, "\",\n\"outputFilename\":\"");
escapeJSON(fout, outputFilename);
fprintf(fout, "\",\n\"outputFilesize\":%ld",(long) fileSize(outputFilename));
fprintf(fout, ",\n\"overheadTime\":%g",rt_accumulated(SIM_TIMER_OVERHEAD));
fprintf(fout, ",\n\"preinitTime\":%g",rt_accumulated(SIM_TIMER_PREINIT));
fprintf(fout, ",\n\"initTime\":%g",rt_accumulated(SIM_TIMER_INIT));
fprintf(fout, ",\n\"eventTime\":%g",rt_accumulated(SIM_TIMER_EVENT));
fprintf(fout, ",\n\"outputTime\":%g",rt_accumulated(SIM_TIMER_OUTPUT));
fprintf(fout, ",\n\"linearizeTime\":%g",rt_accumulated(SIM_TIMER_LINEARIZE));
fprintf(fout, ",\n\"totalTime\":%g",rt_accumulated(SIM_TIMER_TOTAL));
fprintf(fout, ",\n\"totalStepsTime\":%g",rt_total(SIM_TIMER_STEP));
fprintf(fout, ",\n\"numStep\":%d", (int) rt_ncall_total(SIM_TIMER_STEP));
fprintf(fout, ",\n\"maxTime\":%.9g", rt_max_accumulated(SIM_TIMER_STEP));
fprintf(fout, ",\n\"functions\":[");
printJSONFunctions(fout,data);
fprintf(fout, "\n],\n\"profileBlocks\":[");
printJSONProfileBlocks(fout,data);
fprintf(fout, "\n]\n");
fprintf(fout, "}");
return 0;
}
1 change: 1 addition & 0 deletions SimulationRuntime/c/simulation/modelinfo.h
Expand Up @@ -36,6 +36,7 @@ extern "C" {
#endif

int printModelInfo(DATA *data, const char *modelinfo, const char *plotinfo, const char *plotFormat, const char *method, const char *outputFormat, const char *outputFilename);
int printModelInfoJSON(DATA *data, const char *filename, const char *outputFilename);

#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions SimulationRuntime/c/simulation/simulation_runtime.cpp
Expand Up @@ -569,12 +569,14 @@ int startNonInteractiveSimulation(int argc, char**argv, DATA* data)

if(0 == retVal && measure_time_flag)
{
const string jsonInfo = string(data->modelData.modelFilePrefix) + "_prof.json";
const string modelInfo = string(data->modelData.modelFilePrefix) + "_prof.xml";
const string plotFile = string(data->modelData.modelFilePrefix) + "_prof.plt";
rt_accumulate(SIM_TIMER_TOTAL);
const char* plotFormat = omc_flagValue[FLAG_MEASURETIMEPLOTFORMAT];
retVal = printModelInfo(data, modelInfo.c_str(), plotFile.c_str(), plotFormat ? plotFormat : "svg",
data->simulationInfo.solverMethod, data->simulationInfo.outputFormat, result_file_cstr.c_str()) && retVal;
retVal = printModelInfoJSON(data, jsonInfo.c_str(), result_file_cstr.c_str()) && retVal;
}

return retVal;
Expand Down

0 comments on commit b9c8d32

Please sign in to comment.