~ubuntu-branches/ubuntu/lucid/boinc/lucid

« back to all changes in this revision

Viewing changes to sched/validate_util.C

  • Committer: Bazaar Package Importer
  • Author(s): Frank S. Thomas, Frank S. Thomas
  • Date: 2008-05-31 08:02:47 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20080531080247-4ce890lp2rc768cr
Tags: 6.2.7-1
[ Frank S. Thomas ]
* New upstream release.
  - BOINC Manager: Redraw disk usage charts immediately after connecting to
    a (different) client. (closes: 463823)
* debian/copyright:
  - Added the instructions from debian/README.Debian-source about how
    repackaged BOINC tarballs can be reproduced because DevRef now
    recommends to put this here instead of in the afore-mentioned file.
  - Updated for the new release.
* Removed the obsolete debian/README.Debian-source.
* For consistency upstream renamed the core client and the command tool
  ("boinc_client" to "boinc" and "boinc_cmd" to "boinccmd"). Done the same
  in all packages and created symlinks with the old names for the binaries
  and man pages. Also added an entry in debian/boinc-client.NEWS explaining
  this change.
* debian/rules: Do not list Makefile.ins in the clean target individually,
  just remove all that can be found.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
// To view the GNU Lesser General Public License visit
16
16
// http://www.gnu.org/copyleft/lesser.html
17
17
// or write to the Free Software Foundation, Inc.,
18
 
// 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 
20
20
// Code to facilitate writing validators.
21
21
// Can be used as the basis for a validator that accepts everything
23
23
// or that requires strict equality (see sample_bitwise_validator.C)
24
24
// or that uses fuzzy comparison.
25
25
 
 
26
#include <cstring>
26
27
#include "config.h"
27
28
 
28
29
#include "error_numbers.h"
94
95
    return 0;
95
96
}
96
97
 
 
98
struct FILE_REF {
 
99
    char file_name[256];
 
100
    char open_name[256];
 
101
    int parse(XML_PARSER& xp) {
 
102
        char tag[256], path[1024];
 
103
        bool is_tag;
 
104
 
 
105
        strcpy(file_name, "");
 
106
        strcpy(open_name, "");
 
107
        while (!xp.get(tag, sizeof(tag), is_tag)) {
 
108
            if (!is_tag) continue;
 
109
            if (!strcmp(tag, "/file_ref")) {
 
110
                return 0;
 
111
            }
 
112
            if (xp.parse_str(tag, "file_name", file_name, sizeof(file_name))) continue;
 
113
            if (xp.parse_str(tag, "open_name", open_name, sizeof(open_name))) continue;
 
114
        }
 
115
        return ERR_XML_PARSE;
 
116
    }
 
117
};
 
118
 
 
119
// given a path returned by the above, get the corresponding logical name
 
120
//
 
121
int get_logical_name(RESULT const& result, string const& path, string& name) {
 
122
    char phys_name[1024];
 
123
    char tag[256];
 
124
    bool is_tag;
 
125
    MIOFILE mf;
 
126
    int retval;
 
127
 
 
128
    mf.init_buf_read(result.xml_doc_in);
 
129
    XML_PARSER xp(&mf);
 
130
 
 
131
    strcpy(phys_name, path.c_str());
 
132
    char* p = strrchr(phys_name, '/');
 
133
    if (!p) return ERR_NOT_FOUND;
 
134
    strcpy(phys_name, p+1);
 
135
 
 
136
    while (!xp.get(tag, sizeof(tag), is_tag)) {
 
137
        if (!is_tag) continue;
 
138
        if (!strcmp(tag, "result")) continue;
 
139
        if (!strcmp(tag, "file_ref")) {
 
140
            FILE_REF fr;
 
141
            retval = fr.parse(xp);
 
142
            if (retval) continue;
 
143
            if (!strcmp(phys_name, fr.file_name)) {
 
144
                name = fr.open_name;
 
145
                return 0;
 
146
            }
 
147
            continue;
 
148
        }
 
149
        xp.skip_unexpected( tag, false, 0);
 
150
    }
 
151
    return ERR_XML_PARSE;
 
152
}
 
153
 
97
154
#define CREDIT_EPSILON .001
98
155
 
99
156
// If we have N correct results with nonzero claimed credit,
272
329
    return retval;
273
330
}
274
331
 
275
 
const char *BOINC_RCSID_07049e8a0e = "$Id: validate_util.C 12043 2007-02-06 21:50:48Z boincadm $";
 
332
double stddev_credit(WORKUNIT& wu, std::vector<RESULT>& results) {
 
333
    double credit_low_bound = 0, credit_high_bound = 0;
 
334
    double penalize_credit_high_bound = 0;
 
335
    double credit_avg = 0;
 
336
    double credit = 0;
 
337
    double old = 0;
 
338
    double std_dev = 0;
 
339
    double temp = 0;
 
340
    int nvalid = 0;
 
341
    unsigned int i;
 
342
 
 
343
    //calculate average
 
344
    for (i=0; i<results.size(); i++) {
 
345
        RESULT& result = results[i];
 
346
        if (result.validate_state != VALIDATE_STATE_VALID) continue;
 
347
        credit = credit + result.claimed_credit;
 
348
        nvalid++;
 
349
    }
 
350
    
 
351
    
 
352
    if (nvalid == 0 ) {
 
353
        return CREDIT_EPSILON;
 
354
    }
 
355
    
 
356
    credit_avg = credit/nvalid;
 
357
 
 
358
    nvalid = 0;
 
359
    //calculate stddev difference
 
360
    for (i=0; i<results.size(); i++) {
 
361
        RESULT& result = results[i];
 
362
        if (result.validate_state != VALIDATE_STATE_VALID) continue;
 
363
        std_dev = pow(credit_avg - result.claimed_credit,2) + std_dev;
 
364
        nvalid++;
 
365
    }
 
366
    
 
367
    std_dev = std_dev/ (double) nvalid;
 
368
    std_dev = sqrt(std_dev);
 
369
 
 
370
    credit_low_bound = credit_avg-std_dev;
 
371
    if ( credit_low_bound > credit_avg*.85 ) {
 
372
        credit_low_bound = credit_avg*.85;
 
373
    }
 
374
    credit_low_bound = credit_low_bound - 2.5;
 
375
    if ( credit_low_bound < 1) credit_low_bound = 1;
 
376
    
 
377
    credit_high_bound = credit_avg+std_dev;
 
378
    if ( credit_high_bound < credit_avg*1.15 ) {
 
379
        credit_high_bound = credit_avg*1.15;
 
380
    }
 
381
    credit_high_bound = credit_high_bound + 5;
 
382
    
 
383
    
 
384
    nvalid=0;
 
385
    credit = 0;
 
386
    for (i=0; i<results.size(); i++) {
 
387
        RESULT& result = results[i];
 
388
        if (result.validate_state != VALIDATE_STATE_VALID) continue;
 
389
        if ( result.claimed_credit < credit_high_bound && result.claimed_credit > credit_low_bound ) {
 
390
                credit = credit + result.claimed_credit;
 
391
                nvalid++;
 
392
        } else {
 
393
                log_messages.printf(MSG_NORMAL,"[RESULT#%d %s] CREDIT_CALC_SD Discarding invalid credit %.1lf, avg %.1lf, low %.1lf, high %.1lf \n",result.id, result.name, result.claimed_credit, credit_avg, credit_low_bound, credit_high_bound);
 
394
        }
 
395
    }
 
396
    
 
397
    double grant_credit;
 
398
    switch(nvalid) {
 
399
    case 0:
 
400
        grant_credit = median_mean_credit(wu, results);
 
401
        old = grant_credit;
 
402
        break;
 
403
    default:
 
404
            grant_credit = credit/nvalid;
 
405
            old = median_mean_credit(wu, results);
 
406
    }
 
407
    
 
408
    // Log what happened
 
409
    if ( old > grant_credit ) {
 
410
        log_messages.printf(MSG_DEBUG,"CREDIT_CALC_VAL New Method grant: %.1lf  Old Method grant: %.1lf  Less awarded\n", grant_credit, old);
 
411
    } else if ( old == grant_credit ) {
 
412
        log_messages.printf(MSG_DEBUG,"CREDIT_CALC_VAL New Method grant: %.1lf  Old Method grant: %.1lf  Same awarded\n", grant_credit, old);
 
413
    } else {
 
414
        log_messages.printf(MSG_DEBUG,"CREDIT_CALC_VAL New Method grant: %.1lf  Old Method grant: %.1lf  More awarded\n", grant_credit, old);
 
415
    }
 
416
    
 
417
    
 
418
    // penalize hosts that are claiming too much
 
419
    penalize_credit_high_bound = grant_credit+1.5*std_dev;
 
420
    if ( penalize_credit_high_bound < grant_credit*1.65 ) {
 
421
        penalize_credit_high_bound = grant_credit*1.65;
 
422
    }
 
423
    penalize_credit_high_bound = penalize_credit_high_bound + 20;
 
424
 
 
425
    for (i=0; i<results.size(); i++) {
 
426
        RESULT& result = results[i]; 
 
427
        if (result.validate_state != VALIDATE_STATE_VALID) continue;
 
428
        if ( result.claimed_credit > penalize_credit_high_bound ) {
 
429
                result.granted_credit = grant_credit * 0.5;
 
430
                    log_messages.printf(MSG_NORMAL,"[RESULT#%d %s] CREDIT_CALC_PENALTY Penalizing host for too high credit %.1lf, grant %.1lf, penalize %.1lf, stddev %.1lf, avg %.1lf, low %.1lf, high %.1lf \n",result.id, result.name, result.claimed_credit, grant_credit, penalize_credit_high_bound, std_dev, credit_avg, credit_low_bound, credit_high_bound);           
 
431
        }
 
432
    }
 
433
 
 
434
    return grant_credit;
 
435
}
 
436
 
 
437
double two_credit(WORKUNIT& wu, std::vector<RESULT>& results) {
 
438
        int i;
 
439
        double credit = 0;
 
440
        double credit_avg = 0;
 
441
        double last_credit = 0;
 
442
        int nvalid = 0;
 
443
        double grant_credit;
 
444
        
 
445
    //calculate average
 
446
    for (i=0; i<results.size(); i++) {
 
447
        RESULT& result = results[i];
 
448
        if (result.validate_state != VALIDATE_STATE_VALID) continue;
 
449
        credit = credit + result.claimed_credit;
 
450
        last_credit = result.claimed_credit;
 
451
        nvalid++;
 
452
    }
 
453
    
 
454
    
 
455
    if (nvalid == 0 ) {
 
456
        return CREDIT_EPSILON;
 
457
    }
 
458
    
 
459
    credit_avg = credit/nvalid;
 
460
    
 
461
    // If more then 2 valid results, compute via stddev method
 
462
    if ( nvalid > 2 ) return stddev_credit(wu, results);
 
463
        log_messages.printf(MSG_DEBUG,"[WORKUNIT#%d %s] Only 2 results \n",wu.id, wu.name);             
 
464
    
 
465
    // If only 2, then check to see if range is reasonable
 
466
    if ( fabs(last_credit - credit_avg) < 0.15*credit_avg ) return credit_avg;
 
467
        log_messages.printf(MSG_DEBUG,"[WORKUNIT#%d %s] Average is more than 15 percent from each value \n",wu.id, wu.name); 
 
468
        
 
469
        // log data on large variance in runtime
 
470
        float cpu_time = 0.0;
 
471
    for (i=0; i<results.size(); i++) {
 
472
        RESULT& result = results[i];
 
473
        if (result.validate_state != VALIDATE_STATE_VALID) continue;
 
474
        if (result.cpu_time < 30 ) continue;
 
475
        if (cpu_time == 0 ) {
 
476
            cpu_time = result.cpu_time*1.0;
 
477
        } else {
 
478
            if ( cpu_time/result.cpu_time > 2 || cpu_time/result.cpu_time < 0.5 ) {
 
479
                    log_messages.printf(MSG_DEBUG,"[WORKUNIT#%d %s] Large difference in runtime \n",wu.id, wu.name); 
 
480
            }
 
481
        }
 
482
    }
 
483
        
 
484
 
 
485
    //find result with smallest deviation from historical credit and award that value
 
486
    DB_HOST host;
 
487
    double deviation = -1;
 
488
    grant_credit = credit_avg; // default award in case nobody matches the cases
 
489
    for (i=0; i<results.size(); i++) {
 
490
        RESULT& result = results[i];
 
491
        if (result.validate_state != VALIDATE_STATE_VALID) continue;
 
492
        host.lookup_id(result.hostid);
 
493
                log_messages.printf(MSG_DEBUG,"[RESULT#%d %s] Claimed Credit = %.2lf  Historical Credit = %.2lf \n",result.id, result.name, result.claimed_credit, result.cpu_time*host.credit_per_cpu_sec);            
 
494
        if ( (deviation < 0 || deviation > fabs(result.claimed_credit - result.cpu_time*host.credit_per_cpu_sec)) && result.cpu_time > 30 ) {
 
495
                deviation = fabs(result.claimed_credit - result.cpu_time*host.credit_per_cpu_sec);
 
496
                    log_messages.printf(MSG_NORMAL,"[RESULT#%d %s] Credit deviation = %.2lf \n",result.id, result.name, deviation);             
 
497
                grant_credit = result.claimed_credit;
 
498
        }
 
499
    }
 
500
        log_messages.printf(MSG_DEBUG,"[WORKUNIT#%d %s] Credit granted = %.2lf \n",wu.id, wu.name, grant_credit);               
 
501
    return grant_credit;
 
502
}
 
503
 
 
504
const char *BOINC_RCSID_07049e8a0e = "$Id: validate_util.C 14870 2008-03-07 21:13:01Z davea $";