//------------------------------------------------------------ int validate_plural(vector<RESULT>& results, vector<SAH_RESULT>& sah_results, int& canonicalid, double& granted_credit) { // This routine is called for redundant validation (from nontrusted or test case clients) . //------------------------------------------------------------ unsigned int i, j, k; bool found; double max_credit, min_credit, sum; int max_credit_i=-1, min_credit_i=-1, nvalid, retval; // see if there's a pair of results that are strongly similar // Not all results are *neccessarily* checked for overflow. Any // result that may become the canonical reult is checked and thus // a valid overflow indicator is always paased on to the assimilator. found = false; for (i=0; i<sah_results.size()-1; i++) { // scan with [i] to find canonical if (!sah_results[i].have_result) continue; check_overflow_result(results[i]); for (j=i+1; j<sah_results.size(); j++) { // scan with [j] to match [i] if (!sah_results[j].have_result) continue; check_overflow_result(results[j]); validate_stats.nstrong_compare++; if (sah_results[i].strongly_similar(sah_results[j])) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%d (%d signals) and RESULT#%d (%d signals)] ARE strongly similar\n", results[i].id, sah_results[i].num_signals, results[j].id, sah_results[j].num_signals ); found = true; validate_stats.nstrong++; break; } handle_cuda_notvalid(results[i], results[j]); // temporary for cuda debugging log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%d (%d signals) and RESULT#%d (%d signals)] are NOT strongly similar\n", results[i].id, sah_results[i].num_signals, results[j].id, sah_results[j].num_signals ); } // end scan with [j] to match [i] if (found) break; } // end scan with [i] to find canonical if (found) { // At this point results[i] is the canonical result and results[j] // is strongly similar to results[i]. canonicalid = results[i].id; max_credit = 0; min_credit = 0; nvalid = 0; for (k=0; k<sah_results.size(); k++) { // scan with [k] to validate rest of set against canonical if (!sah_results[k].have_result) continue; if (k == i || k == j) { results[k].validate_state = VALIDATE_STATE_VALID; } else { validate_stats.nweak_compare++; if (sah_results[k].weakly_similar(sah_results[i])) { validate_stats.nweak++; log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%d (%d signals) and RESULT#%d (%d signals)] ARE weakly similar\n", results[i].id, sah_results[i].num_signals, results[k].id, sah_results[k].num_signals ); results[k].validate_state = VALIDATE_STATE_VALID; } else { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%d (%d signals) and RESULT#%d (%d signals)] are NOT weakly similar\n", results[i].id, sah_results[i].num_signals, results[k].id, sah_results[k].num_signals ); results[k].validate_state = VALIDATE_STATE_INVALID; handle_cuda_notvalid(results[i], results[k]); // temporary for cuda debugging } } if (results[k].validate_state == VALIDATE_STATE_VALID) { if (results[k].claimed_credit < 0) { results[k].claimed_credit = 0; } if (nvalid == 0) { max_credit = min_credit = results[k].claimed_credit; max_credit_i = min_credit_i = k; } else { if (results[k].claimed_credit >= max_credit) { max_credit = results[k].claimed_credit; max_credit_i = k; } if (results[k].claimed_credit <= min_credit) { min_credit = results[k].claimed_credit; min_credit_i = k; } } nvalid++; } // end validate_state == VALIDATE_STATE_VALID } // end scan with [k] to validate rest of set against canonical // the granted credit is the average of claimed credits // of valid results, discarding the largest and smallest // if (nvalid == 2) { granted_credit = min_credit; } else { // Take care of case where all claimed credits are equal. if (max_credit == min_credit) { granted_credit = min_credit; } else { sum = 0; for (k=0; k<results.size(); k++) { if (!sah_results[k].have_result) continue; if (results[k].validate_state != VALIDATE_STATE_VALID) continue; if (k == max_credit_i) continue; if (k == min_credit_i) continue; sum += results[k].claimed_credit; } granted_credit = sum/(nvalid-2); } } for (k=0; k<results.size(); k++) { if (results[k].validate_state == VALIDATE_STATE_VALID) { results[k].granted_credit = granted_credit; } } } else { // no canonical result found canonicalid = 0; } // end if found return(0); }
// check_pair() is called by BOINC code to validate any results arriving // after the canonical result has been chosen. //------------------------------------------------------------ int check_pair(RESULT& new_result, RESULT& canonical, bool& retry) { //------------------------------------------------------------ int retval; SAH_RESULT sah_new, sah_canonical; DB_RESULT db_result; retry=false; // init log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%d] getting new result file %s\n", new_result.id, new_result.name ); retval = get_result_file((RESULT&)new_result, sah_new); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%d] read/parse of %s FAILED with retval %d\n", new_result.id, new_result.name, retval ); // A directory problem may be transient. if (retval == ERR_OPENDIR) { retry = true; retval = 0; goto return_retval; } else { // a non-transient, non-recoverable error new_result.outcome = RESULT_OUTCOME_VALIDATE_ERROR; new_result.validate_state = VALIDATE_STATE_INVALID; retval = 0; goto return_retval; } } log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%d] getting canonical result file %s\n", canonical.id, canonical.name ); retval = get_result_file((RESULT &)canonical, sah_canonical); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%d] read/parse of %s FAILED with retval %d\n", canonical.id, canonical.name, retval ); // A directory problem may be transient. if (retval == ERR_OPENDIR) { retry = true; retval = 0; goto return_retval; } else { // a non-transient, non-recoverable error - set new_result to error. new_result.outcome = RESULT_OUTCOME_VALIDATE_ERROR; new_result.validate_state = VALIDATE_STATE_INVALID; retval = 0; goto return_retval; } } if (sah_canonical.weakly_similar(sah_new)) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%d (%d signals) and NEW RESULT#%d (%d signals)] ARE weakly similar\n", canonical.id, sah_canonical.num_signals, new_result.id, sah_new.num_signals ); new_result.validate_state = VALIDATE_STATE_VALID; } else { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%d (%d signals) and NEW RESULT#%d (%d signals)] are NOT weakly similar\n", canonical.id, sah_canonical.num_signals, new_result.id, sah_new.num_signals ); new_result.validate_state = VALIDATE_STATE_INVALID; handle_cuda_notvalid(canonical, new_result); // temporary for cuda debugging } if (new_result.validate_state == VALIDATE_STATE_VALID) { log_cuda_result(new_result, canonical.granted_credit); } retval = 0; return_retval: return(retval); }
// check_pair() is called by BOINC code to validate any results arriving // after the canonical result has been chosen. //------------------------------------------------------------ int check_pair(RESULT& new_result, RESULT& canonical, bool& retry) { //------------------------------------------------------------ int retval; SAH_RESULT sah_new, sah_canonical; DB_RESULT db_result; retry=false; // init log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%lld] getting new result file %s\n", new_result.id, new_result.name ); retval = get_result_file((RESULT&)new_result, sah_new); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%lld] read/parse of %s FAILED with retval %d\n", new_result.id, new_result.name, retval ); // Someone is trying to process v7 workunits with v6 if (!sah_new.found_best_autocorr && !(sah_new.is_overflow || canonical.runtime_outlier) && !strcmp(app_name,"setiathome_v7")) { new_result.validate_state = VALIDATE_STATE_INVALID; retval = 0; log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%lld] is from an invalid app_version\n", new_result.id ); goto return_retval; } // A directory problem may be transient. if (retval == ERR_OPENDIR) { retry = true; retval = 0; goto return_retval; } else { // a non-transient, non-recoverable error new_result.outcome = RESULT_OUTCOME_VALIDATE_ERROR; new_result.validate_state = VALIDATE_STATE_INVALID; retval = 0; goto return_retval; } } log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%lld] getting canonical result file %s\n", canonical.id, canonical.name ); retval = get_result_file((RESULT &)canonical, sah_canonical); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%lld] read/parse of %s FAILED with retval %d\n", canonical.id, canonical.name, retval ); // A directory problem may be transient. if (retval == ERR_OPENDIR) { retry = true; retval = 0; goto return_retval; } else { // a non-transient, non-recoverable error - set new_result to error. new_result.outcome = RESULT_OUTCOME_VALIDATE_ERROR; new_result.validate_state = VALIDATE_STATE_INVALID; retval = 0; goto return_retval; } } if (sah_canonical.weakly_similar(sah_new)) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%lld (%d signals) and NEW RESULT#%lld (%d signals)] ARE weakly similar\n", canonical.id, sah_canonical.num_signals, new_result.id, sah_new.num_signals ); new_result.validate_state = VALIDATE_STATE_VALID; } else { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%lld (%d signals) and NEW RESULT#%lld (%lld signals)] are NOT weakly similar\n", canonical.id, sah_canonical.num_signals, new_result.id, sah_new.num_signals ); new_result.validate_state = VALIDATE_STATE_INVALID; handle_cuda_notvalid(canonical, new_result); // temporary for cuda debugging } if (new_result.validate_state == VALIDATE_STATE_VALID) { log_cuda_result(new_result, canonical.granted_credit); } retval = 0; return_retval: return(retval); }