X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=lttv%2Flttv%2Fsync%2Fevent_analysis_eval.c;h=d5c3be290c2fc1016e689ce12e004bdec6a569b2;hb=ab6edc6a1a55aefe52cfd9e610b5f21ee2029544;hp=0872eb6dd8aa7c7762e7606e87963009320de1eb;hpb=277e5b535febfb81a5e9485b0d008e148b6979ac;p=lttv.git diff --git a/lttv/lttv/sync/event_analysis_eval.c b/lttv/lttv/sync/event_analysis_eval.c index 0872eb6d..d5c3be29 100644 --- a/lttv/lttv/sync/event_analysis_eval.c +++ b/lttv/lttv/sync/event_analysis_eval.c @@ -35,7 +35,6 @@ #include "lookup3.h" #include "sync_chain.h" -#include "event_analysis_chull.h" #include "event_analysis_eval.h" @@ -46,15 +45,6 @@ struct WriteHistogramInfo FILE* graphsStream; }; -#ifdef HAVE_LIBGLPK -struct LPAddRowInfo -{ - glp_prob* lp; - int boundType; - GArray* iArray, * jArray, * aArray; -}; -#endif - // Functions common to all analysis modules static void initAnalysisEval(SyncState* const syncState); static void destroyAnalysisEval(SyncState* const syncState); @@ -65,16 +55,8 @@ static void analyzeExchangeEval(SyncState* const syncState, Exchange* const exchange); static void analyzeBroadcastEval(SyncState* const syncState, Broadcast* const broadcast); -static GArray* finalizeAnalysisEval(SyncState* const syncState); +static AllFactors* finalizeAnalysisEval(SyncState* const syncState); static void printAnalysisStatsEval(SyncState* const syncState); -static void writeAnalysisTraceTimeBackPlotsEval(SyncState* const syncState, - const unsigned int i, const unsigned int j); -static void writeAnalysisTraceTimeForePlotsEval(SyncState* const syncState, - const unsigned int i, const unsigned int j); -static void writeAnalysisTraceTraceBackPlotsEval(SyncState* const syncState, - const unsigned int i, const unsigned int j); -static void writeAnalysisTraceTraceForePlotsEval(SyncState* const syncState, - const unsigned int i, const unsigned int j); // Functions specific to this module static guint ghfRttKeyHash(gconstpointer key); @@ -109,19 +91,6 @@ static void writeHistogram(FILE* graphsStream, const struct RttKey* rttKey, static void updateBounds(Bounds** const bounds, Event* const e1, Event* const e2); -static void finalizeAnalysisEvalLP(SyncState* const syncState); -// The next group of functions is only needed when computing synchronization -// accuracy. -#ifdef HAVE_LIBGLPK -static glp_prob* lpCreateProblem(GQueue* const lowerHull, GQueue* const - upperHull); -static void gfLPAddRow(gpointer data, gpointer user_data); -static Factors* calculateFactors(glp_prob* const lp, const int direction); -static void calculateCompleteFactors(glp_prob* const lp, FactorsCHull* - factors); -static FactorsCHull** createAllFactors(const unsigned int traceNb); -#endif - // initialized in registerAnalysisEval() double binBase; @@ -135,12 +104,7 @@ static AnalysisModule analysisModuleEval= { .analyzeBroadcast= &analyzeBroadcastEval, .finalizeAnalysis= &finalizeAnalysisEval, .printAnalysisStats= &printAnalysisStatsEval, - .graphFunctions= { - .writeTraceTimeBackPlots= &writeAnalysisTraceTimeBackPlotsEval, - .writeTraceTimeForePlots= &writeAnalysisTraceTimeForePlotsEval, - .writeTraceTraceBackPlots= &writeAnalysisTraceTraceBackPlotsEval, - .writeTraceTraceForePlots= &writeAnalysisTraceTraceForePlotsEval, - } + .graphFunctions= {} }; static ModuleOption optionEvalRttFile= { @@ -205,7 +169,8 @@ static void initAnalysisEval(SyncState* const syncState) if (syncState->stats) { analysisData->stats= calloc(1, sizeof(AnalysisStatsEval)); - analysisData->stats->broadcastDiffSum= 0.; + analysisData->stats->broadcastRangeMin= INFINITY; + analysisData->stats->broadcastRangeMax= -INFINITY; analysisData->stats->messageStats= malloc(syncState->traceNb * sizeof(MessageStats*)); @@ -218,11 +183,6 @@ static void initAnalysisEval(SyncState* const syncState) analysisData->stats->exchangeRtt= g_hash_table_new_full(&ghfRttKeyHash, &gefRttKeyEqual, &gdnDestroyRttKey, &gdnDestroyDouble); - -#ifdef HAVE_LIBGLPK - analysisData->stats->chFactorsArray= NULL; - analysisData->stats->lpFactorsArray= NULL; -#endif } if (syncState->graphsStream) @@ -245,25 +205,6 @@ static void initAnalysisEval(SyncState* const syncState) graphs->bounds[i][j].max= 0; } } - -#ifdef HAVE_LIBGLPK - graphs->lps= NULL; - graphs->lpFactorsArray= NULL; -#endif - } - - if (syncState->stats || syncState->graphsStream) - { - GList* result; - - analysisData->chullSS= malloc(sizeof(SyncState)); - memcpy(analysisData->chullSS, syncState, sizeof(SyncState)); - analysisData->chullSS->stats= false; - analysisData->chullSS->analysisData= NULL; - result= g_queue_find_custom(&analysisModules, "chull", - &gcfCompareAnalysis); - analysisData->chullSS->analysisModule= (AnalysisModule*) result->data; - analysisData->chullSS->analysisModule->initAnalysis(analysisData->chullSS); } } @@ -551,11 +492,6 @@ static void destroyAnalysisEval(SyncState* const syncState) g_hash_table_destroy(stats->exchangeRtt); -#ifdef HAVE_LIBGLPK - freeAllFactors(syncState->traceNb, stats->chFactorsArray); - freeAllFactors(syncState->traceNb, stats->lpFactorsArray); -#endif - free(stats); } @@ -574,36 +510,9 @@ static void destroyAnalysisEval(SyncState* const syncState) } free(graphs->bounds); -#ifdef HAVE_LIBGLPK - for (i= 0; i < syncState->traceNb; i++) - { - unsigned int j; - - for (j= 0; j < i; j++) - { - // There seems to be a memory leak in glpk, valgrind reports a - // loss (reachable) even if the problem is deleted - glp_delete_prob(graphs->lps[i][j]); - } - free(graphs->lps[i]); - } - free(graphs->lps); - - if (!syncState->stats) - { - freeAllFactors(syncState->traceNb, graphs->lpFactorsArray); - } -#endif - free(graphs); } - if (syncState->stats || syncState->graphsStream) - { - analysisData->chullSS->analysisModule->destroyAnalysis(analysisData->chullSS); - free(analysisData->chullSS); - } - free(syncState->analysisData); syncState->analysisData= NULL; } @@ -704,12 +613,6 @@ static void analyzeMessageEval(SyncState* const syncState, Message* const updateBounds(analysisData->graphs->bounds, message->inE, message->outE); } - - if (syncState->stats || syncState->graphsStream) - { - analysisData->chullSS->analysisModule->analyzeMessage(analysisData->chullSS, - message); - } } @@ -823,7 +726,40 @@ static void analyzeBroadcastEval(SyncState* const syncState, Broadcast* const g_queue_get_length(broadcast->events), 2.); if (y > 0) { - analysisData->stats->broadcastDiffSum+= sqrt(y); + analysisData->stats->broadcastStdevSum+= sqrt(y); + } + + if (syncState->traceNb == 2 && g_queue_get_length(broadcast->events) + == 2) + { + Event* e0, * e1; + double dd; + + e0= g_queue_peek_head(broadcast->events); + e1= g_queue_peek_tail(broadcast->events); + if (e0->traceNum > e1->traceNum) + { + Event* tmp; + + tmp= e0; + e0= e1; + e1= tmp; + } + + dd= wallTimeSub(&e1->wallTime, &e0->wallTime); + + analysisData->stats->broadcastPairNb++; + if (dd < analysisData->stats->broadcastRangeMin) + { + analysisData->stats->broadcastRangeMin= dd; + } + if (dd > analysisData->stats->broadcastRangeMax) + { + analysisData->stats->broadcastRangeMax= dd; + } + + analysisData->stats->broadcastSum+= dd; + analysisData->stats->broadcastSumSquares+= pow(dd, 2); } } @@ -857,19 +793,17 @@ static void analyzeBroadcastEval(SyncState* const syncState, Broadcast* const /* * Finalize the factor calculations. Since this module does not really - * calculate factors, identity factors are returned. Instead, histograms are + * calculate factors, absent factors are returned. Instead, histograms are * written out and histogram structures are freed. * * Args: * syncState container for synchronization data. * * Returns: - * Factors[traceNb] identity factors for each trace + * AllFactors* synchronization factors for each trace pair */ -static GArray* finalizeAnalysisEval(SyncState* const syncState) +static AllFactors* finalizeAnalysisEval(SyncState* const syncState) { - GArray* factors; - unsigned int i; AnalysisDataEval* analysisData= syncState->analysisData; if (syncState->graphsStream && analysisData->graphs->histograms) @@ -881,21 +815,7 @@ static GArray* finalizeAnalysisEval(SyncState* const syncState) analysisData->graphs->histograms= NULL; } - finalizeAnalysisEvalLP(syncState); - - factors= g_array_sized_new(FALSE, FALSE, sizeof(Factors), - syncState->traceNb); - g_array_set_size(factors, syncState->traceNb); - for (i= 0; i < syncState->traceNb; i++) - { - Factors* e; - - e= &g_array_index(factors, Factors, i); - e->drift= 1.; - e->offset= 0.; - } - - return factors; + return createAllFactors(syncState->traceNb); } @@ -923,11 +843,27 @@ static void printAnalysisStatsEval(SyncState* const syncState) printf("Synchronization evaluation analysis stats:\n"); if (analysisData->stats->broadcastNb) { - printf("\tsum of broadcast differential delays: %g\n", - analysisData->stats->broadcastDiffSum); - printf("\taverage broadcast differential delay: %g\n", - analysisData->stats->broadcastDiffSum / + printf("\tBroadcast differential delay:\n"); + printf("\t\tsum of standard deviations: %g\n", + analysisData->stats->broadcastStdevSum); + printf("\t\taverage standard deviation: %g\n", + analysisData->stats->broadcastStdevSum / analysisData->stats->broadcastNb); + + if (syncState->traceNb == 2) + { + printf("\t\tdifferential delay range: [ %g .. %g ]\n", + analysisData->stats->broadcastRangeMin, + analysisData->stats->broadcastRangeMax); + printf("\t\tdifferential delay average: %g\n", + analysisData->stats->broadcastSum / + analysisData->stats->broadcastPairNb); + printf("\t\tdifferential delay standard deviation: %g\n", + sqrt(analysisData->stats->broadcastSumSquares / + analysisData->stats->broadcastPairNb - + pow(analysisData->stats->broadcastSum / + analysisData->stats->broadcastPairNb, 2))); + } } printf("\tIndividual evaluation:\n" @@ -951,13 +887,13 @@ static void printAnalysisStatsEval(SyncState* const syncState) &analysisData->stats->messageStats[loopValues[k].t1][loopValues[k].t2]; printf("\t\t%3d - %-3d ", loopValues[k].t1, loopValues[k].t2); - printf("%u (%u%%)%n", messageStats->inversionNb, (unsigned - int) ceil((double) messageStats->inversionNb / - messageStats->total * 100), &charNb); + printf("%u (%.2f%%)%n", messageStats->inversionNb, (double) + messageStats->inversionNb / messageStats->total * 100, + &charNb); printf("%*s", 17 - charNb > 0 ? 17 - charNb + 1: 1, " "); - printf("%u (%u%%)%n", messageStats->tooFastNb, (unsigned int) - ceil((double) messageStats->tooFastNb / - messageStats->total * 100), &charNb); + printf("%u (%.2f%%)%n", messageStats->tooFastNb, (double) + messageStats->tooFastNb / messageStats->total * 100, + &charNb); printf("%*s%-10u %u\n", 17 - charNb > 0 ? 17 - charNb + 1: 1, " ", messageStats->noRTTInfoNb, messageStats->total); @@ -970,11 +906,11 @@ static void printAnalysisStatsEval(SyncState* const syncState) } printf("\t\t total "); - printf("%u (%u%%)%n", totInversion, (unsigned int) ceil((double) - totInversion / totTotal * 100), &charNb); + printf("%u (%.2f%%)%n", totInversion, (double) totInversion / totTotal * + 100, &charNb); printf("%*s", 17 - charNb > 0 ? 17 - charNb + 1: 1, " "); - printf("%u (%u%%)%n", totTooFast, (unsigned int) ceil((double) totTooFast - / totTotal * 100), &charNb); + printf("%u (%.2f%%)%n", totTooFast, (double) totTooFast / totTotal * 100, + &charNb); printf("%*s%-10u %u\n", 17 - charNb > 0 ? 17 - charNb + 1: 1, " ", totNoInfo, totTotal); @@ -982,45 +918,6 @@ static void printAnalysisStatsEval(SyncState* const syncState) "\t\tHost pair RTT from exchanges RTTs from file (ms)\n"); g_hash_table_foreach(analysisData->stats->exchangeRtt, &ghfPrintExchangeRtt, analysisData->rttInfo); - -#ifdef HAVE_LIBGLPK - printf("\tConvex hull factors comparisons:\n" - "\t\tTrace pair Factors type Differences (lp - chull)\n" - "\t\t a0 a1\n" - "\t\t Min Max Min Max\n"); - - for (i= 0; i < syncState->traceNb; i++) - { - for (j= 0; j < i; j++) - { - FactorsCHull* chFactors= &analysisData->stats->chFactorsArray[i][j]; - FactorsCHull* lpFactors= &analysisData->stats->lpFactorsArray[i][j]; - - printf("\t\t%3d - %-3d ", i, j); - if (lpFactors->type == chFactors->type) - { - if (lpFactors->type == MIDDLE) - { - printf("%-13s %-10.4g %-10.4g %-10.4g %.4g\n", - approxNames[lpFactors->type], - lpFactors->min->offset - chFactors->min->offset, - lpFactors->max->offset - chFactors->max->offset, - lpFactors->min->drift - chFactors->min->drift, - lpFactors->max->drift - chFactors->max->drift); - } - else if (lpFactors->type == ABSENT) - { - printf("%s\n", approxNames[lpFactors->type]); - } - } - else - { - printf("Different! %s and %s\n", approxNames[lpFactors->type], - approxNames[chFactors->type]); - } - } - } -#endif } @@ -1495,515 +1392,3 @@ static void updateBounds(Bounds** const bounds, Event* const e1, Event* const tpBounds->max= messageTime; } } - - -#ifdef HAVE_LIBGLPK -/* - * Create the linear programming problem containing the constraints defined by - * two half-hulls. The objective function and optimization directions are not - * written. - * - * Args: - * syncState: container for synchronization data - * i: first trace number - * j: second trace number, garanteed to be larger than i - * Returns: - * A new glp_prob*, this problem must be freed by the caller with - * glp_delete_prob() - */ -static glp_prob* lpCreateProblem(GQueue* const lowerHull, GQueue* const - upperHull) -{ - unsigned int it; - const int zero= 0; - const double zeroD= 0.; - glp_prob* lp= glp_create_prob(); - unsigned int hullPointNb= g_queue_get_length(lowerHull) + - g_queue_get_length(upperHull); - GArray* iArray= g_array_sized_new(FALSE, FALSE, sizeof(int), hullPointNb + - 1); - GArray* jArray= g_array_sized_new(FALSE, FALSE, sizeof(int), hullPointNb + - 1); - GArray* aArray= g_array_sized_new(FALSE, FALSE, sizeof(double), - hullPointNb + 1); - struct { - GQueue* hull; - struct LPAddRowInfo rowInfo; - } loopValues[2]= { - {lowerHull, {lp, GLP_UP, iArray, jArray, aArray}}, - {upperHull, {lp, GLP_LO, iArray, jArray, aArray}}, - }; - - // Create the LP problem - glp_term_out(GLP_OFF); - if (hullPointNb > 0) - { - glp_add_rows(lp, hullPointNb); - } - glp_add_cols(lp, 2); - - glp_set_col_name(lp, 1, "a0"); - glp_set_col_bnds(lp, 1, GLP_FR, 0., 0.); - glp_set_col_name(lp, 2, "a1"); - glp_set_col_bnds(lp, 2, GLP_LO, 0., 0.); - - // Add row constraints - g_array_append_val(iArray, zero); - g_array_append_val(jArray, zero); - g_array_append_val(aArray, zeroD); - - for (it= 0; it < sizeof(loopValues) / sizeof(*loopValues); it++) - { - g_queue_foreach(loopValues[it].hull, &gfLPAddRow, - &loopValues[it].rowInfo); - } - - g_assert_cmpuint(iArray->len, ==, jArray->len); - g_assert_cmpuint(jArray->len, ==, aArray->len); - g_assert_cmpuint(aArray->len - 1, ==, hullPointNb * 2); - - glp_load_matrix(lp, aArray->len - 1, &g_array_index(iArray, int, 0), - &g_array_index(jArray, int, 0), &g_array_index(aArray, double, 0)); - - glp_scale_prob(lp, GLP_SF_AUTO); - - g_array_free(iArray, TRUE); - g_array_free(jArray, TRUE); - g_array_free(aArray, TRUE); - - return lp; -} - - -/* - * A GFunc for g_queue_foreach(). Add constraints and bounds for one row. - * - * Args: - * data Point*, synchronization point for which to add an LP row - * (a constraint) - * user_data LPAddRowInfo* - */ -static void gfLPAddRow(gpointer data, gpointer user_data) -{ - Point* p= data; - struct LPAddRowInfo* rowInfo= user_data; - int indexes[2]; - double constraints[2]; - - indexes[0]= g_array_index(rowInfo->iArray, int, rowInfo->iArray->len - 1) + 1; - indexes[1]= indexes[0]; - - if (rowInfo->boundType == GLP_UP) - { - glp_set_row_bnds(rowInfo->lp, indexes[0], GLP_UP, 0., p->y); - } - else if (rowInfo->boundType == GLP_LO) - { - glp_set_row_bnds(rowInfo->lp, indexes[0], GLP_LO, p->y, 0.); - } - else - { - g_assert_not_reached(); - } - - g_array_append_vals(rowInfo->iArray, indexes, 2); - indexes[0]= 1; - indexes[1]= 2; - g_array_append_vals(rowInfo->jArray, indexes, 2); - constraints[0]= 1.; - constraints[1]= p->x; - g_array_append_vals(rowInfo->aArray, constraints, 2); -} - - -/* - * Calculate min or max correction factors (as possible) using an LP problem. - * - * Args: - * lp: A linear programming problem with constraints and bounds - * initialized. - * direction: The type of factors desired. Use GLP_MAX for max - * approximation factors (a1, the drift or slope is the - * largest) and GLP_MIN in the other case. - * - * Returns: - * If the calculation was successful, a new Factors struct. Otherwise, NULL. - * The calculation will fail if the hull assumptions are not respected. - */ -static Factors* calculateFactors(glp_prob* const lp, const int direction) -{ - int retval, status; - Factors* factors; - - glp_set_obj_coef(lp, 1, 0.); - glp_set_obj_coef(lp, 2, 1.); - - glp_set_obj_dir(lp, direction); - retval= glp_simplex(lp, NULL); - status= glp_get_status(lp); - - if (retval == 0 && status == GLP_OPT) - { - factors= malloc(sizeof(Factors)); - factors->offset= glp_get_col_prim(lp, 1); - factors->drift= glp_get_col_prim(lp, 2); - } - else - { - factors= NULL; - } - - return factors; -} - - -/* - * Calculate min, max and approx correction factors (as possible) using an LP - * problem. - * - * Args: - * lp: A linear programming problem with constraints and bounds - * initialized. - * - * Returns: - * Please note that the approximation type may be MIDDLE, INCOMPLETE or - * ABSENT. Unlike in analysis_chull, ABSENT is also used when the hulls do - * not respect assumptions. - */ -static void calculateCompleteFactors(glp_prob* const lp, FactorsCHull* factors) -{ - factors->min= calculateFactors(lp, GLP_MIN); - factors->max= calculateFactors(lp, GLP_MAX); - - if (factors->min && factors->max) - { - factors->type= MIDDLE; - calculateFactorsMiddle(factors); - } - else if (factors->min || factors->max) - { - factors->type= INCOMPLETE; - factors->approx= NULL; - } - else - { - factors->type= ABSENT; - factors->approx= NULL; - } -} - - -/* - * Create and initialize an array like AnalysisStatsCHull.allFactors - * - * Args: - * traceNb: number of traces - * - * Returns: - * A new array, which can be freed with freeAllFactors() - */ -static FactorsCHull** createAllFactors(const unsigned int traceNb) -{ - FactorsCHull** factorsArray; - unsigned int i; - - factorsArray= malloc(traceNb * sizeof(FactorsCHull*)); - for (i= 0; i < traceNb; i++) - { - factorsArray[i]= calloc((i + 1), sizeof(FactorsCHull)); - - factorsArray[i][i].type= EXACT; - factorsArray[i][i].approx= malloc(sizeof(Factors)); - factorsArray[i][i].approx->drift= 1.; - factorsArray[i][i].approx->offset= 0.; - } - - return factorsArray; -} -#endif - - -/* - * Compute synchronization factors using a linear programming approach. - * Compute the factors using analysis_chull. Compare the two. - * - * When the solver library, glpk, is not available at build time, only compute - * the factors using analysis_chull. This is to make sure that module runs its - * finalize function so that its graph functions can be called later. - * - * Args: - * syncState: container for synchronization data - */ -static void finalizeAnalysisEvalLP(SyncState* const syncState) -{ - AnalysisDataEval* analysisData= syncState->analysisData; -#ifdef HAVE_LIBGLPK - unsigned int i, j; - AnalysisDataCHull* chAnalysisData= analysisData->chullSS->analysisData; - FactorsCHull** lpFactorsArray; - - if (!syncState->stats && !syncState->graphsStream) - { - return; - } - - /* Because of matching_distributor, this analysis may be called twice. - * Only run it once */ - if ((syncState->graphsStream && analysisData->graphs->lps != NULL) || - (syncState->stats && analysisData->stats->chFactorsArray != NULL)) - { - return; - } - - lpFactorsArray= createAllFactors(syncState->traceNb); - - if (syncState->stats) - { - analysisData->stats->chFactorsArray= - calculateAllFactors(analysisData->chullSS); - analysisData->stats->lpFactorsArray= lpFactorsArray; - } - - if (syncState->graphsStream) - { - analysisData->graphs->lps= malloc(syncState->traceNb * - sizeof(glp_prob**)); - for (i= 0; i < syncState->traceNb; i++) - { - analysisData->graphs->lps[i]= malloc(i * sizeof(glp_prob*)); - } - analysisData->graphs->lpFactorsArray= lpFactorsArray; - } - - for (i= 0; i < syncState->traceNb; i++) - { - for (j= 0; j < i; j++) - { - glp_prob* lp; - - // Create the LP problem - lp= lpCreateProblem(chAnalysisData->hullArray[i][j], - chAnalysisData->hullArray[j][i]); - - // Use the LP problem to find the correction factors for this pair of - // traces - calculateCompleteFactors(lp, &lpFactorsArray[i][j]); - - if (syncState->graphsStream) - { - analysisData->graphs->lps[i][j]= lp; - } - else - { - glp_delete_prob(lp); - } - } - } -#endif - - g_array_free(analysisData->chullSS->analysisModule->finalizeAnalysis(analysisData->chullSS), - TRUE); -} - - -/* - * Compute synchronization accuracy information using a linear programming - * approach. Write the neccessary data files and plot lines in the gnuplot - * script. - * - * When the solver library, glpk, is not available at build time nothing is - * actually produced. - * - * Args: - * syncState: container for synchronization data - * i: first trace number - * j: second trace number, garanteed to be larger than i - */ -static void writeAnalysisTraceTimeBackPlotsEval(SyncState* const syncState, - const unsigned int i, const unsigned int j) -{ -#ifdef HAVE_LIBGLPK - unsigned int it; - AnalysisDataEval* analysisData= syncState->analysisData; - AnalysisGraphsEval* graphs= analysisData->graphs; - GQueue*** hullArray= ((AnalysisDataCHull*) - analysisData->chullSS->analysisData)->hullArray; - FactorsCHull* lpFactors= &graphs->lpFactorsArray[j][i]; - glp_prob* lp= graphs->lps[j][i]; - - if (lpFactors->type == MIDDLE) - { - int retval; - char* cwd; - char fileName[40]; - FILE* fp; - double* xValues; - unsigned int xBegin, xEnd; - double interval; - const unsigned int graphPointNb= 1000; - - // Open the data file - snprintf(fileName, 40, "analysis_eval_accuracy-%03u_and_%03u.data", i, j); - fileName[sizeof(fileName) - 1]= '\0'; - - cwd= changeToGraphsDir(syncState->graphsDir); - - if ((fp= fopen(fileName, "w")) == NULL) - { - g_error(strerror(errno)); - } - fprintf(fp, "#%-24s %-25s %-25s %-25s\n", "x", "middle", "min", "max"); - - retval= chdir(cwd); - if (retval == -1) - { - g_error(strerror(errno)); - } - free(cwd); - - // Build the list of absisca values for the points in the accuracy graph - g_assert_cmpuint(graphPointNb, >=, 4); - xValues= malloc(graphPointNb * sizeof(double)); - xValues[0]= graphs->bounds[j][i].min; - xValues[graphPointNb - 1]= graphs->bounds[j][i].max; - xValues[1]= MIN(((Point*) g_queue_peek_head(hullArray[i][j]))->x, - ((Point*) g_queue_peek_head(hullArray[j][i]))->x); - xValues[graphPointNb - 2]= MAX(((Point*) - g_queue_peek_tail(hullArray[i][j]))->x, ((Point*) - g_queue_peek_tail(hullArray[j][i]))->x); - - if (xValues[0] == xValues[1]) - { - xBegin= 0; - } - else - { - xBegin= 1; - } - if (xValues[graphPointNb - 2] == xValues[graphPointNb - 1]) - { - xEnd= graphPointNb - 1; - } - else - { - xEnd= graphPointNb - 2; - } - interval= (xValues[xEnd] - xValues[xBegin]) / (graphPointNb - 1); - - for (it= xBegin; it <= xEnd; it++) - { - xValues[it]= xValues[xBegin] + interval * (it - xBegin); - } - - /* For each absisca value and each optimisation direction, solve the LP - * and write a line in the data file */ - for (it= 0; it < graphPointNb; it++) - { - unsigned int it2; - int directions[]= {GLP_MIN, GLP_MAX}; - - glp_set_obj_coef(lp, 1, 1.); - glp_set_obj_coef(lp, 2, xValues[it]); - - fprintf(fp, "%25.9f %25.9f", xValues[it], lpFactors->approx->offset - + lpFactors->approx->drift * xValues[it]); - for (it2= 0; it2 < sizeof(directions) / sizeof(*directions); it2++) - { - int status; - - glp_set_obj_dir(lp, directions[it2]); - retval= glp_simplex(lp, NULL); - status= glp_get_status(lp); - - g_assert(retval == 0 && status == GLP_OPT); - fprintf(fp, " %25.9f", glp_get_obj_val(lp)); - } - fprintf(fp, "\n"); - } - - free(xValues); - fclose(fp); - - fprintf(syncState->graphsStream, - "\t\"analysis_eval_accuracy-%1$03u_and_%2$03u.data\" " - "using 1:(($3 - $2) / clock_freq_%2$u):(($4 - $2) / clock_freq_%2$u) " - "title \"Synchronization accuracy\" " - "with filledcurves linewidth 2 linetype 1 " - "linecolor rgb \"black\" fill solid 0.25 noborder, \\\n", i, - j); - } -#endif -} - - -/* - * Write the analysis-specific graph lines in the gnuplot script. - * - * When the solver library, glpk, is not available at build time nothing is - * actually produced. - * - * Args: - * syncState: container for synchronization data - * i: first trace number - * j: second trace number, garanteed to be larger than i - */ -static void writeAnalysisTraceTimeForePlotsEval(SyncState* const syncState, - const unsigned int i, const unsigned int j) -{ -#ifdef HAVE_LIBGLPK - if (((AnalysisDataEval*) - syncState->analysisData)->graphs->lpFactorsArray[j][i].type == - MIDDLE) - { - fprintf(syncState->graphsStream, - "\t\"analysis_eval_accuracy-%1$03u_and_%2$03u.data\" " - "using 1:(($3 - $2) / clock_freq_%2$u) notitle " - "with lines linewidth 2 linetype 1 " - "linecolor rgb \"gray60\", \\\n" - "\t\"analysis_eval_accuracy-%1$03u_and_%2$03u.data\" " - "using 1:(($4 - $2) / clock_freq_%2$u) notitle " - "with lines linewidth 2 linetype 1 " - "linecolor rgb \"gray60\", \\\n", i, j); - } -#endif -} - - -/* - * Write the analysis-specific graph lines in the gnuplot script. - * - * Args: - * syncState: container for synchronization data - * i: first trace number - * j: second trace number, garanteed to be larger than i - */ -static void writeAnalysisTraceTraceBackPlotsEval(SyncState* const syncState, - const unsigned int i, const unsigned int j) -{ -#ifdef HAVE_LIBGLPK - fprintf(syncState->graphsStream, - "\t\"analysis_eval_accuracy-%1$03u_and_%2$03u.data\" " - "using 1:3:4 " - "title \"Synchronization accuracy\" " - "with filledcurves linewidth 2 linetype 1 " - "linecolor rgb \"black\" fill solid 0.25 noborder, \\\n", i, j); -#endif -} - - -/* - * Write the analysis-specific graph lines in the gnuplot script. - * - * Args: - * syncState: container for synchronization data - * i: first trace number - * j: second trace number, garanteed to be larger than i - */ -static void writeAnalysisTraceTraceForePlotsEval(SyncState* const syncState, - const unsigned int i, const unsigned int j) -{ - AnalysisDataEval* analysisData= syncState->analysisData; - - analysisData->chullSS->analysisModule->graphFunctions.writeTraceTraceForePlots(analysisData->chullSS, - i, j); -}