// Internal function that loads 'wrdata' with a new workrecord // from the next open contest with available blocks. // Return value: // if (return_single_count) is non-zero, returns number of packets // left for the same project work was found for, otherwise it // returns the *total* number of packets available for *all* // contests for the thread in question. // // Note that 'return_single_count' IS ALL IT TAKES TO DISABLE ROTATION. static long __loadapacket( Client *client, WorkRecord *wrdata /*where to load*/, int /*ign_closed*/, unsigned int prob_i /* for which 'thread' */, int return_single_count /* see above */ ) { unsigned int proj_i; long bufcount, totalcount = -1; for (proj_i = 0; proj_i < PROJECT_COUNT; proj_i++ ) { unsigned int selproject = client->project_order_map[proj_i]; if (ProjectGetFlags(selproject) == PROJECT_UNSUPPORTED) continue; if (client->project_state[selproject] & PROJECTSTATE_USER_DISABLED) continue; if (!IsProblemLoadPermitted( (long)prob_i, selproject )) { continue; /* problem.cpp - result depends on #defs, threadsafety etc */ } bufcount = -1; if (!wrdata) /* already loaded a packet */ bufcount = GetBufferCount( client, selproject, 0, NULL ); else /* haven't got a packet yet */ { bufcount = GetBufferRecord( client, wrdata, selproject, 0 ); if (bufcount >= 0) /* no error */ wrdata = 0; /* don't load again */ } if (bufcount >= 0) /* no error */ { if (totalcount < 0) totalcount = 0; totalcount += bufcount; if (return_single_count) break; } } return totalcount; }
/* this is called from Problem::LoadState() */ int selcoreGetSelectedCoreForContest( Client *client, unsigned int contestid ) { TRACE_OUT((0, "selcoreGetSelectedCoreForContest project=%d\n", contestid)); int corename_printed = 0; static long detected_type = -123; const char *contname = CliGetContestNameFromID(contestid); /* FIXME: without -devicenum, core always selected for GPU 0 */ int device = hackGetUsedDeviceIndex(client, 0); if (!contname) /* no such contest */ return -1; if (!IsProblemLoadPermitted(-1 /*any thread*/, contestid)) return -1; /* no cores available */ if (selcore_initlev <= 0) /* ACK! selcoreInitialize() */ return -1; /* hasn't been called */ if (corecount_for_contest(contestid) == 1) /* only one core? */ return 0; if (selcorestatics.corenum[contestid] >= 0) /* already selected one? */ return selcorestatics.corenum[contestid]; TRACE_OUT((+1, "selcoreGetSelectedCoreForContest project=%d\n", contestid)); if (detected_type == -123) /* haven't autodetected yet? */ { int quietly = 1; unsigned int cont_i; for (cont_i = 0; quietly && cont_i < CONTEST_COUNT; cont_i++) { if (corecount_for_contest(cont_i) < 2) ; /* nothing */ else if (selcorestatics.user_cputype[cont_i] < 0) quietly = 0; } detected_type = GetProcessorType(quietly, device); if (detected_type < 0) detected_type = -1; } selcorestatics.corenum[contestid] = selcorestatics.user_cputype[contestid]; if (selcorestatics.corenum[contestid] < 0) selcorestatics.corenum[contestid] = selcoreGetPreselectedCoreForProject(contestid, device); TRACE_OUT((0, "cpu/arch preselection done: %d\n", selcorestatics.corenum[contestid])); if (selcorestatics.corenum[contestid] < 0) selcorestatics.corenum[contestid] = selcorestatics.user_cputype[contestid]; if (selcorestatics.corenum[contestid] < 0) /* ok, bench it then */ { TRACE_OUT((0, "do benchmark\n")); int corecount = (int)corecount_for_contest(contestid); selcorestatics.corenum[contestid] = 0; if (corecount > 0) { int whichcrunch, saidmsg = 0, fastestcrunch = -1; u32 fasttime_hi = 0, fasttime_lo = 0; for (whichcrunch = 0; whichcrunch < corecount; whichcrunch++) { /* test only if not substituted */ if (whichcrunch == apply_selcore_substitution_rules(contestid, whichcrunch, device)) { u32 rate_hi, rate_lo; selcorestatics.corenum[contestid] = whichcrunch; if (!saidmsg) { LogScreen("%s: Running micro-bench to select fastest core...\n", contname); saidmsg = 1; } if (CheckExitRequestTriggerNoIO()) break; if (TBenchmark( client, contestid, 2, TBENCHMARK_QUIET | TBENCHMARK_IGNBRK, &rate_hi, &rate_lo ) > 0) { #ifdef DEBUG LogScreen("%s Core %d: %d:%d keys/sec\n", contname,whichcrunch,rate_hi,rate_lo); #endif if (fastestcrunch < 0 || (rate_hi > fasttime_hi || (rate_hi == fasttime_hi && rate_lo > fasttime_lo))) { fasttime_hi = rate_hi; fasttime_lo = rate_lo; fastestcrunch = whichcrunch; } } } } if (fastestcrunch < 0) /* all failed */ fastestcrunch = 0; /* don't bench again */ selcorestatics.corenum[contestid] = fastestcrunch; } } if (selcorestatics.corenum[contestid] >= 0) /* didn't fail */ { /* ** substitution according to real selcoreSelectCore() rules ** Returns original if no substitution occurred. */ int override = apply_selcore_substitution_rules(contestid, selcorestatics.corenum[contestid], device); if (!corename_printed) { if (override != selcorestatics.corenum[contestid]) { Log("%s: selected core #%d (%s)\n" " is not supported by this client/OS/architecture.\n" " Using core #%d (%s) instead.\n", contname, selcorestatics.corenum[contestid], selcoreGetDisplayName(contestid, selcorestatics.corenum[contestid]), override, selcoreGetDisplayName(contestid, override) ); } else { Log("%s: using core #%d (%s).\n", contname, selcorestatics.corenum[contestid], selcoreGetDisplayName(contestid, selcorestatics.corenum[contestid]) ); } }
// returns 0 if not supported, <0 on failed or break static long SelfTestInternal( Client *client, unsigned int contest, int stress ) { int threadpos, threadcount = 1; long successes = 0L; const char *contname; int userbreak = 0; unsigned long runtime_sec, runtime_usec; if (CheckExitRequestTrigger()) return 0; if (contest >= CONTEST_COUNT) { Log("test::error. invalid contest %u\n", contest ); return 0; } if (!IsProblemLoadPermitted(-1, contest)) /* also checks HAVE_xxx_CORES */ return 0; contname = CliGetContestNameFromID( contest ); for ( threadpos = 0; !userbreak && successes >= 0L && threadpos < threadcount; threadpos++ ) { char lastmsg[100]; unsigned int testnum; ClientEventSyncPost( CLIEVENT_SELFTEST_STARTED, &contest, sizeof(contest) ); successes = 0L; lastmsg[0] = '\0'; runtime_sec = runtime_usec = 0; for ( testnum = 0 ; !userbreak && testnum < TEST_CASE_COUNT ; testnum++ ) { const u32 (*test_cases)[TEST_CASE_COUNT][TEST_CASE_DATA] = NULL; u32 expectedsolution_hi, expectedsolution_mid, expectedsolution_lo; ContestWork contestwork; Problem *thisprob; memset(&contestwork, 0, sizeof(contestwork)); expectedsolution_lo = expectedsolution_mid = expectedsolution_hi = 0; /* shaddup compiler */ #if defined(HAVE_RC5_72_CORES) if (contest == RC5_72) { test_cases = (const u32 (*)[TEST_CASE_COUNT][TEST_CASE_DATA])rc5_72_test_cases; expectedsolution_hi = (*test_cases)[testnum][0]; expectedsolution_mid = (*test_cases)[testnum][1]; expectedsolution_lo = (*test_cases)[testnum][2]; contestwork.bigcrypto.key.hi = expectedsolution_hi; contestwork.bigcrypto.key.mid = expectedsolution_mid; contestwork.bigcrypto.key.lo = expectedsolution_lo & 0xFFFF0000L; if (testnum>1 && testnum<=7) { contestwork.bigcrypto.key.lo -= 0x00010000; if ((expectedsolution_lo & 0xFFFF0000L) == 0) { contestwork.bigcrypto.key.mid--; if (!~contestwork.bigcrypto.key.mid) contestwork.bigcrypto.key.hi--; } } } #endif #if defined(HAVE_OGR_CORES) if (contest == OGR_NG) { test_cases = (const u32 (*)[TEST_CASE_COUNT][TEST_CASE_DATA])ogr_test_cases; expectedsolution_lo = (*test_cases)[testnum][0]; } #endif #if defined(HAVE_OGR_PASS2) if (contest == OGR_P2) { test_cases = (const u32 (*)[TEST_CASE_COUNT][TEST_CASE_DATA])ogrp2_test_cases; expectedsolution_lo = (*test_cases)[testnum][0]; } #endif //if (0) //{ // PROJECT_NOT_HANDLED(contest); //} switch (contest) { #if defined(HAVE_CRYPTO_V2) case RC5_72: { contestwork.bigcrypto.iv.lo = ( (*test_cases)[testnum][3] ); contestwork.bigcrypto.iv.hi = ( (*test_cases)[testnum][4] ); contestwork.bigcrypto.plain.lo = ( (*test_cases)[testnum][5] ); contestwork.bigcrypto.plain.hi = ( (*test_cases)[testnum][6] ); contestwork.bigcrypto.cypher.lo = ( (*test_cases)[testnum][7] ); contestwork.bigcrypto.cypher.hi = ( (*test_cases)[testnum][8] ); contestwork.bigcrypto.keysdone.lo = ( 0 ); contestwork.bigcrypto.keysdone.hi = ( 0 ); contestwork.bigcrypto.iterations.lo = ( 0x00020000L ); // 17 bits instead of 16 contestwork.bigcrypto.iterations.hi = ( 0 ); contestwork.bigcrypto.randomsubspace = ( 0xFFFF ); // not defined (invalid) break; } #endif #if defined(HAVE_OGR_PASS2) case OGR_P2: { int tcd; contestwork.ogr_p2.workstub.stub.marks = (u16)((*test_cases)[testnum][1]); contestwork.ogr_p2.minpos = (u32)((*test_cases)[testnum][2]); contestwork.ogr_p2.workstub.stub.length = 0; for (tcd = 0; tcd < TEST_CASE_DATA-3; tcd++) { contestwork.ogr_p2.workstub.stub.diffs[tcd] = (u16)((*test_cases)[testnum][3+tcd]); if (contestwork.ogr_p2.workstub.stub.diffs[tcd] == 0) break; contestwork.ogr_p2.workstub.stub.length++; } contestwork.ogr_p2.workstub.worklength = 0; contestwork.ogr_p2.nodes.lo = contestwork.ogr_p2.nodes.hi = 0; break; } #endif #if defined(HAVE_OGR_CORES) case OGR_NG: { int tcd; contestwork.ogr_ng.workstub.stub.marks = (u16)((*test_cases)[testnum][1]); contestwork.ogr_ng.workstub.stub.length = 0; for (tcd = 0; tcd < TEST_CASE_DATA-2; tcd++) { contestwork.ogr_ng.workstub.stub.diffs[tcd] = (u16)((*test_cases)[testnum][2+tcd]); if (contestwork.ogr_ng.workstub.stub.diffs[tcd] == 0) break; contestwork.ogr_ng.workstub.stub.length++; } contestwork.ogr_ng.workstub.worklength = 0; contestwork.ogr_ng.nodes.lo = contestwork.ogr_ng.nodes.hi = 0; contestwork.ogr_ng.workstub.collapsed = 0; break; } #endif default: PROJECT_NOT_HANDLED(contest); userbreak = 1; break; } /* switch */ if (userbreak) break; thisprob = ProblemAlloc(); if (thisprob) { u32 tslice = 0x4000; u32 sec = 0; int non_preemptive_env = 0; int resultcode; #if (CLIENT_OS == OS_NETWARE) non_preemptive_env = (!nwCliIsPreemptiveEnv()); if (non_preemptive_env) tslice = 2048; #elif (CLIENT_OS == OS_WIN16 || CLIENT_OS == OS_WIN32) || (CLIENT_OS == OS_WIN64) /* or win32s */ non_preemptive_env = (winGetVersion() < 400); if (non_preemptive_env) tslice = 2048; #elif (CLIENT_OS == OS_RISCOS) non_preemptive_env = riscos_check_taskwindow(); if (non_preemptive_env) tslice = 32768; #endif #if defined(HAVE_OGR_CORES) if (contest == OGR_NG && stress) tslice = 1; #endif if (ProblemLoadState( thisprob, &contestwork, contest, tslice, 0, 0, 0, 0, client ) == 0) { ClientEventSyncPost( CLIEVENT_SELFTEST_TESTBEGIN, (void *)thisprob, -1 ); do { if (non_preemptive_env) { #if (CLIENT_OS == OS_WIN16) || (CLIENT_OS == OS_WIN32) || (CLIENT_OS == OS_WIN64) /* or win32s */ w32Yield(); /* pump waiting messages */ #elif (CLIENT_OS == OS_RISCOS) riscos_upcall_6(); #elif (CLIENT_OS == OS_NETWARE) ThreadSwitchLowPriority(); #endif } if (CheckExitRequestTrigger()) { userbreak = 1; break; } if (contest == OGR_P2 || contest == OGR_NG) { /* show /some/ activity (the time changes) */ if (thisprob->pub_data.runtime_sec >= sec) { LogScreen("\r%s: Test %02d working...", contname, testnum + 1 ); sec = thisprob->pub_data.runtime_sec + 1; } } } while ( ProblemRun(thisprob) == RESULT_WORKING ); resultcode = RESULT_WORKING; if (!userbreak) { const char *resulttext = NULL; resultcode = ProblemRetrieveState( thisprob, &contestwork, NULL, 1, 0 ); runtime_sec += thisprob->pub_data.runtime_sec; runtime_usec += thisprob->pub_data.runtime_usec; if (runtime_usec >= 1000000ul) { runtime_sec++; runtime_usec-=1000000ul; } switch (contest) { #ifdef HAVE_CRYPTO_V2 case RC5_72: { int expected_cmc_count = (int)(*test_cases)[testnum][9]; // may be <= 0 if no solution, but perhaps some cmc key(s) int logMode; resulttext = NULL; /* assume success by default */ if ( expected_cmc_count == 0 && /* expect no solution and no cmc */ ( resultcode != RESULT_NOTHING || contestwork.bigcrypto.check.count != 0 ) ) { contestwork.bigcrypto.key.lo = contestwork.bigcrypto.key.mid = contestwork.bigcrypto.key.hi = 0; resulttext = "FAILED0"; } else if ( expected_cmc_count < 0 && /* expect no solution but cmc */ ( resultcode != RESULT_NOTHING || contestwork.bigcrypto.check.count != (u32)(-expected_cmc_count)) ) { //contestwork.bigcrypto.key.lo = //contestwork.bigcrypto.key.mid = contestwork.bigcrypto.key.hi = 0; resulttext = "FAILED1"; } else if ( expected_cmc_count > 0 && resultcode != RESULT_FOUND ) /* no solution */ { contestwork.bigcrypto.key.lo = contestwork.bigcrypto.key.mid = contestwork.bigcrypto.key.hi = 0; resulttext = "FAILED2"; } else if ( expected_cmc_count > 0 && ( contestwork.bigcrypto.key.hi != expectedsolution_hi || contestwork.bigcrypto.key.mid != expectedsolution_mid || contestwork.bigcrypto.key.lo != expectedsolution_lo ) ) { /* wrong solution */ resulttext = "FAILED3"; } else if ( expected_cmc_count > 0 && contestwork.bigcrypto.check.count != (u32)expected_cmc_count ) { resulttext = "FAILED4"; } else if ( expected_cmc_count != 0 && ( contestwork.bigcrypto.check.hi != expectedsolution_hi || contestwork.bigcrypto.check.mid != expectedsolution_mid || contestwork.bigcrypto.check.lo != expectedsolution_lo ) ) { /* wrong partial solution */ resulttext = "FAILED5"; } else if ( expected_cmc_count <= 0 ) /* correct 'no' solution */ { expectedsolution_lo = contestwork.bigcrypto.key.lo; } else /* correct solution */ { // fallthru to success } if (resulttext == NULL) { resulttext = "passed"; successes++; logMode = LOGAS_LOGSCREEN; } else { resultcode = -1; logMode = LOGAS_LOG; } LogTo( logMode, "\r%s: Test %02d %s: %02X:%08X:%08X-%02X:%08X:%08X\n", contname, testnum + 1, resulttext, contestwork.bigcrypto.key.hi, contestwork.bigcrypto.key.mid, contestwork.bigcrypto.key.lo, expectedsolution_hi, expectedsolution_mid, expectedsolution_lo ); break; } #endif #ifdef HAVE_OGR_PASS2 case OGR_P2: { if (expectedsolution_lo & 0x80000000) // no solution { expectedsolution_lo = ~expectedsolution_lo; if (resultcode != RESULT_NOTHING || contestwork.ogr_p2.nodes.lo != expectedsolution_lo) { resulttext = "FAILED"; resultcode = -1; } else { resulttext = "passed"; successes++; } } else if (resultcode != RESULT_FOUND || contestwork.ogr_p2.nodes.lo != expectedsolution_lo) { resulttext = "FAILED"; resultcode = -1; } else { resulttext = "passed"; successes++; } LogScreen( "\r%s: Test %02d %s: %s %08X-%08X\n", contname, testnum + 1, resulttext, ogr_stubstr(&contestwork.ogr_p2.workstub.stub), contestwork.ogr_p2.nodes.lo, expectedsolution_lo ); break; } #endif #ifdef HAVE_OGR_CORES case OGR_NG: { int logTo; resulttext = NULL; // assume success if (expectedsolution_lo & 0x80000000) // no solution { expectedsolution_lo = ~expectedsolution_lo; if (resultcode != RESULT_NOTHING || contestwork.ogr_ng.nodes.lo != expectedsolution_lo) { resulttext = "FAILED1"; } } else if (resultcode != RESULT_FOUND || contestwork.ogr_ng.nodes.lo != expectedsolution_lo) { resulttext = "FAILED2"; } if (resulttext == NULL) { resulttext = "passed "; successes++; logTo = LOGAS_LOGSCREEN; /* same as LogScreen() */ } else { resultcode = -1; logTo = LOGAS_LOG; /* same as Log() */ } LogTo( logTo, "\r%s: Test %02d %s: %s %08X-%08X\n", contname, testnum + 1, resulttext, ogrng_stubstr(&contestwork.ogr_ng.workstub), contestwork.ogr_ng.nodes.lo, expectedsolution_lo ); break; } #endif default: { PROJECT_NOT_HANDLED(contest); break; } } /* switch */ } /* if (!userbreak) */ ClientEventSyncPost( CLIEVENT_SELFTEST_TESTEND, &resultcode, sizeof(resultcode) ); } /* if load state ok */ else { Log( "\r%s: Test %02d load failed\n", contname, testnum + 1); } ProblemFree(thisprob); } /* if ProblemAlloc() */ #ifdef HAVE_OGR_CORES if (contest == OGR_NG) { // Release cached limits once they are no longer required. We assume the // tests are sorted by number of marks. if (testnum == TEST_CASE_COUNT - 1 || (*test_cases)[testnum][1] != (*test_cases)[testnum+1][1]) { ogr_cleanup_cache(); } } #endif } /* for ( testnum = 0 ; testnum < TEST_CASE_COUNT ; testnum++ ) */ if (userbreak) successes = -1L; else { if (successes > 0L) { Log( "%s: %ld/%ld Tests Passed (%lu.%06lu seconds)\n", contname, successes, (long) TEST_CASE_COUNT, runtime_sec, runtime_usec ); } if (successes != ((long)TEST_CASE_COUNT)) { Log( "%s: WARNING WARNING WARNING: %ld Tests FAILED!!!\n", contname, (((long)TEST_CASE_COUNT) - successes) ); successes = -1L; } } ClientEventSyncPost( CLIEVENT_SELFTEST_FINISHED, &successes, sizeof(successes) ); } /* for ( threadpos = 0; threadpos < threadcount; threadpos++ ) */ return (successes); }