Example #1
0
static int __post_summary_for_contest(unsigned int contestid)
{
  u32 iterhi, iterlo; int rc = -1;
  unsigned int packets, swucount;
  struct timeval ttime;

  TRACE_OUT((+1,"__post_summary_for_contest(%u)\n",contestid));

  if (CliGetContestInfoSummaryData( contestid, &packets, &iterhi, &iterlo,
                                    &ttime, &swucount ) == 0)
  {
    if (packets)
    {
      char ratebuf[15];
      TRACE_OUT((0,"pkts=%u, iter=%u:%u, time=%lu:%lu, swucount=%u\n", packets,
                    iterhi, iterlo, ttime.tv_sec, ttime.tv_usec, swucount ));
      Log("%s: Summary: %u packet%s (%u.%02u stats units)\n%s%c- [%s/s]\n",
          CliGetContestNameFromID(contestid),
          packets, ((packets==1)?(""):("s")),
          swucount/100, swucount%100,
          CliGetTimeString(&ttime,2), ((packets)?(' '):(0)),
          ProblemComputeRate( contestid, ttime.tv_sec, ttime.tv_usec,
                            iterhi, iterlo, 0, 0, ratebuf, sizeof(ratebuf)) );
    }
    rc = 0;
  }

  TRACE_OUT((-1,"__post_summary_for_contest()\n"));
  return rc;
}
Example #2
0
/* 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]) );
      }
    }
Example #3
0
static long __bench_or_test( Client *client, int which, 
                            unsigned int cont_i, unsigned int benchsecs, int in_corenum )
{
  long rc = -1;
  /* FIXME: without -devicenum, test/bench will be run on GPU 0 only */
  int device = hackGetUsedDeviceIndex(client, 0);

  if (selcore_initlev > 0                  /* core table is initialized? */
      && cont_i < CONTEST_COUNT)           /* valid contest id? */
  {
    /* save current state */
    int user_cputype = selcorestatics.user_cputype[cont_i];
    int corenum = selcorestatics.corenum[cont_i];
    int coreidx, corecount = corecount_for_contest( cont_i );
    int fastest = -1;
    int hardcoded = selcoreGetPreselectedCoreForProject(cont_i, device);
    u32 bestrate_hi = 0, bestrate_lo = 0, refrate_hi = 0, refrate_lo = 0;

    rc = 0; /* assume nothing done */
    for (coreidx = 0; coreidx < corecount; coreidx++)
    {
      /* only bench/test cores that won't be automatically substituted */
      if (apply_selcore_substitution_rules(cont_i, coreidx, device) == coreidx)
      {
        if (in_corenum < 0)
            selcorestatics.user_cputype[cont_i] = coreidx; /* as if user set it */
        else
        {
          if( in_corenum < corecount )
          {
            selcorestatics.user_cputype[cont_i] = in_corenum;
            coreidx = corecount;
          }
          else  /* invalid core selection, test them all */
          {
            selcorestatics.user_cputype[cont_i] = coreidx;
            in_corenum = -1;
          }
        }
        selcorestatics.corenum[cont_i] = -1; /* reset to show name */

        if (which == 't') /* selftest */
          rc = SelfTest( client, cont_i );
        else if (which == 's') /* stresstest */
          rc = StressTest( client, cont_i );
        else {
          u32 temprate_hi, temprate_lo;
          rc = TBenchmark( client, cont_i, benchsecs, 0, &temprate_hi, &temprate_lo );
          if (rc > 0 && selcorestatics.corenum[cont_i] == hardcoded) {
            refrate_hi = temprate_hi;
            refrate_lo = temprate_lo;
          }
          if (rc > 0 && (temprate_hi > bestrate_hi || (temprate_hi == bestrate_hi && temprate_lo > bestrate_lo))) {
            bestrate_hi = temprate_hi;
            bestrate_lo = temprate_lo;
            fastest     = selcorestatics.corenum[cont_i];
          }
        }
        #if (CLIENT_OS != OS_WIN32 || !defined(SMC))
        if (rc <= 0) /* failed (<0) or not supported (0) */
          break; /* stop */
        #else
        // HACK! to ignore failed benchmark for x86 rc5 smc core #7 if
        // started from menu and another cruncher is active in background.
        if (rc <= 0) /* failed (<0) or not supported (0) */
        {
          if ( which == 'b' &&  cont_i == RC5 && coreidx == 7 )
            ; /* continue */
          else
            break; /* stop */
        }
        #endif
      }
    } /* for (coreidx = 0; coreidx < corecount; coreidx++) */

    selcorestatics.user_cputype[cont_i] = user_cputype;
    selcorestatics.corenum[cont_i] = corenum;

    /* Summarize the results if multiple cores have been benchmarked (#4108) */
#if (CLIENT_CPU != CPU_CELLBE)
    /* Not applicable for Cell due to PPU/SPU core selection hacks */
    if (in_corenum < 0 && fastest >= 0 && (bestrate_hi != 0 || bestrate_lo != 0)) {
      double percent = 100.0 * ((double)refrate_hi  * 4294967296.0 + (double)refrate_lo) /
                               ((double)bestrate_hi * 4294967296.0 + (double)bestrate_lo);
      char bestrate_str[32], refrate_str[32];

      U64stringify(bestrate_str, sizeof(bestrate_str), bestrate_hi, bestrate_lo, 2, CliGetContestUnitFromID(cont_i));
      U64stringify(refrate_str,  sizeof(refrate_str),  refrate_hi,  refrate_lo,  2, CliGetContestUnitFromID(cont_i));

      Log("%s benchmark summary :\n"
          "Default core : #%d (%s) %s/sec\n"
          "Fastest core : #%d (%s) %s/sec\n",
          CliGetContestNameFromID(cont_i), hardcoded,
          (hardcoded >= 0 ? selcoreGetDisplayName(cont_i, hardcoded) : "undefined"),
          refrate_str,
          fastest, selcoreGetDisplayName(cont_i, fastest), bestrate_str);
          
      if (percent < 100 && hardcoded >= 0 && hardcoded != fastest) {
        if (percent >= 97) {
          Log("Core #%d is marginally faster than the default core.\n"
              "Testing variability might lead to pick one or the other.\n",
              fastest);
        }
        else {
          Log("Core #%d is significantly faster than the default core.\n"
#if (CLIENT_CPU != CPU_CUDA && CLIENT_CPU != CPU_ATI_STREAM && CLIENT_CPU != CPU_OPENCL)
              "Please file a bug report along with the output of\n-cpuinfo.\n"
#else
              "The GPU core selection has been made as a tradeoff between core speed\n"
              "and responsiveness of the graphical desktop.\n"
              "Please file a bug report along with the output of -gpuinfo\n"
              "only if the the faster core selection does not degrade graphics performance.\n"
#endif
              "Changes in cores and selection are frequently made,\n"
              "so be sure to test with the latest client version,\n"
              "typically a pre-release, before filing a bug report.\n",
              fastest);
        }
      }
    }
#endif // CPU_CELLBE

#if (CLIENT_OS == OS_RISCOS) && defined(HAVE_X86_CARD_SUPPORT)
    if (rc > 0 && cont_i == RC5 && 
          GetNumberOfDetectedProcessors() > 1) /* have x86 card */
    {
      Problem *prob = ProblemAlloc(); /* so bench/test gets threadnum+1 */ /* FIXME: not true anymore */
      rc = -1; /* assume alloc failed */
      if (prob)
      {
        Log("RC5: using x86 core.\n" );
        if (which != 's') /* bench */
          rc = TBenchmark( client, cont_i, benchsecs, 0 );
        else
          rc = SelfTest( client, cont_i );
        ProblemFree(prob);
      }
    }
    #endif

  } /* if (cont_i < CONTEST_COUNT) */

  return rc;
}
Example #4
0
// 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);
}
Example #5
0
unsigned int LoadSaveProblems(Client *client,
                              unsigned int load_problem_count,int mode)
{
  /* Some platforms need to stop asynchronously, for example, Win16 which
     gets an ENDSESSION message and has to exit then and there. So also
     win9x when running as a service where windows suspends all threads
     except the window thread. For these (and perhaps other platforms)
     we save our last state so calling with (0,0,0) will save the
     problem states (without hanging). see 'abortive_action' below.
  */
  static Client *previous_client = 0;
  static unsigned int previous_load_problem_count = 0, reentrant_count = 0;
  static int abortive_action = 0;

  unsigned int retval = 0;
  int changed_flag, first_time;

  int allclosed, prob_step,bufupd_pending;
  unsigned int cont_i, prob_for, prob_first, prob_last;
  unsigned int loaded_problems_count[CONTEST_COUNT];
  unsigned int saved_problems_count[CONTEST_COUNT];
  unsigned long totalBlocksDone; /* all contests */

  unsigned int total_problems_loaded, total_problems_saved;
  unsigned int norandom_count, getbuff_errs, empty_problems;

  allclosed = 0;
  norandom_count = getbuff_errs = empty_problems = 0;
  changed_flag = (previous_load_problem_count == 0);
  total_problems_loaded = 0;
  total_problems_saved = 0;
  bufupd_pending = 0;
  totalBlocksDone = 0;

  /* ============================================================= */

  if (abortive_action) /* already aborted once */
  {                    /* no probfill action can happen again */
    return 0;
  }
  if (!client)             /* abnormal end */
  {
    client = previous_client;
    if (!client)
      return 0;
    abortive_action = 1;
    mode = PROBFILL_UNLOADALL;
  }
  previous_client = client;
  if ((++reentrant_count) > 1)
  {
    --reentrant_count;
    return 0;
  }

  /* ============================================================= */

  prob_first = 0;
  prob_step  = 0;
  prob_last  = 0;
  first_time = 0;

  if (load_problem_count == 0) /* only permitted if unloading all */
  {
    if (mode != PROBFILL_UNLOADALL || previous_load_problem_count == 0)
    {
      --reentrant_count;
      return 0;
    }
    load_problem_count = previous_load_problem_count;
  }
  if (previous_load_problem_count == 0) /* must be initial load */
  {            /* [0 ... (load_problem_count - 1)] */
    prob_first = 0;
    prob_last  = (load_problem_count - 1);
    prob_step  = 1;
    first_time = 1;
  }
  else if (mode == PROBFILL_RESIZETABLE)
  {            /* [(previousload_problem_count-1) ... load_problem_count] */
    prob_first = load_problem_count;
    prob_last  = (previous_load_problem_count - 1);
    prob_step  = -1;
  }
  else /* PROBFILL_UNLOADALL, PROBFILL_REFRESH */
  {            /* [(load_problem_count - 1) ... 0] */
    prob_first = 0;
    prob_last  = (load_problem_count - 1);
    prob_step  = -1;
  }

  TRACE_BUFFUPD((+1, "LoadSaveProblems(%d)\n", mode));

  /* ============================================================= */

  for (cont_i = 0; cont_i < CONTEST_COUNT; cont_i++)
  {
    unsigned int blocksdone;
    if (CliGetContestInfoSummaryData( cont_i, &blocksdone, NULL, NULL, NULL, NULL )==0)
      totalBlocksDone += blocksdone;
    loaded_problems_count[cont_i] = 0;
    saved_problems_count[cont_i] = 0;
  }

  /* ============================================================= */

  ClientEventSyncPost(CLIEVENT_PROBLEM_TFILLSTARTED, &load_problem_count,
                                                sizeof(load_problem_count));

  for (prob_for = 0; prob_for <= (prob_last - prob_first); prob_for++)
  {
    Problem *thisprob;
    int load_needed;
    unsigned int prob_i = prob_for + prob_first;
    if ( prob_step < 0 )
      prob_i = prob_last - prob_for;

    thisprob = GetProblemPointerFromIndex( prob_i );
    if (thisprob == 0)
    {
      if (prob_step < 0)
        continue;
      break;
    }

    // -----------------------------------

    load_needed = 0;
    if (__IndividualProblemSave( thisprob, prob_i, client,
        &load_needed, load_problem_count, &cont_i, &bufupd_pending,
        (mode == PROBFILL_UNLOADALL || mode == PROBFILL_RESIZETABLE ),
        abortive_action ))
    {
      changed_flag = 1;
      total_problems_saved++;
      saved_problems_count[cont_i]++;
      totalBlocksDone++;
    }
    if (load_needed)
      empty_problems++;

    TRACE_BUFFUPD((0, "__IndividualProblemSave ==> bufupd_pending = %d\n", bufupd_pending));

    //---------------------------------------

    if (load_needed && mode!=PROBFILL_UNLOADALL && mode!=PROBFILL_RESIZETABLE)
    {
      // Bug #3672 (all clients running at least 2 cores).
      // Take the number of still active crunchers into account to determine
      // whether we can load another problem.

      // Bug #4018: It will not work for initial load: this 'if' will load
      // packet to LAST cruncher while main loop will start FIRST cruncher.
      // So here is a second 'if' for inital load (when mode==0), it will
      // load cruncher from start up to block count. (I wonder can old 'if'
      // be completely replaced with new one.)

      if (client->blockcount > 0)
      {
          if (mode == 0)
          {
              /* Load from beginning to up max. count, skip last crunchers */
              if (totalBlocksDone+total_problems_loaded >= (unsigned long)client->blockcount)
                  load_needed = 0;
          }
          else
          {
              /* Skip first crunchers, load from middle to last */
              if (totalBlocksDone+load_problem_count-empty_problems>=((unsigned long)(client->blockcount)))
                  load_needed = 0;
          }
      }
      if (load_needed)
      {
        load_needed = 0;
        if (__IndividualProblemLoad( thisprob, prob_i, client,
            &load_needed, load_problem_count, &cont_i, &bufupd_pending ))
        {
          empty_problems--;
          total_problems_loaded++;
          loaded_problems_count[cont_i]++;
          changed_flag = 1;
        }
        TRACE_BUFFUPD((0, "__IndividualProblemLoad ==> bufupd_pending = %d\n", bufupd_pending));
        if (load_needed)
        {
          getbuff_errs++;
          if (load_needed == NOLOAD_ALLCONTESTSCLOSED)
          {
            allclosed = 1;
            break; /* the for ... prob_i ... loop */
          }
          else if (load_needed == NOLOAD_NORANDOM)
            norandom_count++;
        }
      }
    } //if (load_needed)
  } //for (prob_i = 0; prob_i < load_problem_count; prob_i++ )

  ClientEventSyncPost(CLIEVENT_PROBLEM_TFILLFINISHED,
     ((previous_load_problem_count==0)?(&total_problems_loaded):(&total_problems_saved)),
     sizeof(total_problems_loaded));

  /* ============================================================= */

  if (mode == PROBFILL_UNLOADALL)
  {
    previous_load_problem_count = 0;
    if (client->nodiskbuffers == 0)
    {
      // close checkpoint file immediately after saving the problems to disk
      CheckpointAction( client, CHECKPOINT_CLOSE, 0 );
    }
    else if (!CheckRestartRequestTrigger()) /* no disk buffers */
    {
      TRACE_BUFFUPD((0, "BufferUpdate: reason = LoadSaveProblem && unload all && membuffers\n"));
      BufferUpdate(client,BUFFERUPDATE_FLUSH,0);
      /* in case the flush fails, empty the membuf table manually */
      for (cont_i = 0; cont_i < CONTEST_COUNT; cont_i++)
      {
        WorkRecord data;
        while (GetBufferCount(client, cont_i, 0, 0)>0)
          GetBufferRecord( client, &data, cont_i, 0 );
        while (GetBufferCount(client, cont_i, 0, 0)>0)
          GetBufferRecord( client, &data, cont_i, 1);
      }
    }
    retval = total_problems_saved;
  }
  else /* if (mode != PROBFILL_UNLOADALL) */
  {
    /*
    =============================================================
    // save the number of active problems, so that we can bail out
    // in an "emergency". Some platforms call us asynchronously when they
    // need to abort [win16/win32 for example]
    -------------------------------------------------------------
    */

    previous_load_problem_count = load_problem_count;

    if (bufupd_pending && client->blockcount >= 0)
    {
      int req = MODEREQ_FLUSH; // always flush while fetching
      if (!CheckExitRequestTriggerNoIO()) //((bufupd_pending & BUFFERUPDATE_FETCH)!=0)
        req |= MODEREQ_FETCH;
      TRACE_BUFFUPD((0, "ModeReqSet(flush=%d, fetch=%d, fquiet=1)\n",
                        (req & MODEREQ_FLUSH) != 0, (req & MODEREQ_FETCH) != 0));
      ModeReqSet( req|MODEREQ_FQUIET ); /* delegate to the client.run loop */
    }

    if (!allclosed && mode != PROBFILL_RESIZETABLE)
    {
      /*
       =============================================================
       if we are running a limited number of blocks then check if we have
       exceeded that number. If we have, but one or more crunchers are
       still at work, bump the limit.
       -------------------------------------------------------------
      */
      if (client->blockcount < 0 || (client->blockcount > 0
                  && totalBlocksDone >= (unsigned long)(client->blockcount)))
      {
        if (empty_problems >= load_problem_count)
        {
          Log( "Shutdown - packet limit exceeded.\n" );
          RaiseExitRequestTrigger();
        }
        // Bug #3672 (all clients running at least 2 cores).
        // The following two lines prevent the client from stopping as
        // instructed by option "-n" when running at least two crunchers
        // simultaneously.
        //else
        //  client->blockcount = ((u32)(totalBlocksDone))+1;
      }
    }

    if (mode == PROBFILL_RESIZETABLE)
      retval = total_problems_saved;
    else if (mode == PROBFILL_GETBUFFERRS)
      retval = getbuff_errs;
    else if (mode == PROBFILL_ANYCHANGED)
      retval = changed_flag;
    else
      retval = total_problems_loaded;
  }

  /* ============================================================= */

  for ( cont_i = 0; cont_i < CONTEST_COUNT; cont_i++) //once for each contest
  {
    int show_totals = 0;
    if (loaded_problems_count[cont_i] || saved_problems_count[cont_i])
      show_totals = 1;

    if (first_time || show_totals)
    {
      unsigned int inout;
      const char *cont_name = CliGetContestNameFromID(cont_i);

      if (loaded_problems_count[cont_i] && load_problem_count > COMBINEMSG_THRESHOLD )
      {
        Log( "%s: Loaded %u packet%s from %s\n",
              cont_name, loaded_problems_count[cont_i],
              ((loaded_problems_count[cont_i]==1)?(""):("s")),
              (client->nodiskbuffers ? "(memory-in)" :
              BufferGetDefaultFilename( cont_i, 0,
                                        client->in_buffer_basename )) );
      }

      if (saved_problems_count[cont_i] && load_problem_count > COMBINEMSG_THRESHOLD
       && (client->nodiskbuffers == 0 || (mode != PROBFILL_UNLOADALL)))
      {
        Log( "%s: Saved %u packet%s to %s\n",
              cont_name, saved_problems_count[cont_i],
              ((saved_problems_count[cont_i]==1)?(""):("s")),
              (mode == PROBFILL_UNLOADALL)?
                (client->nodiskbuffers ? "(memory-in)" :
                BufferGetDefaultFilename( cont_i, 0,
                                          client->in_buffer_basename ) ) :
                (client->nodiskbuffers ? "(memory-out)" :
                BufferGetDefaultFilename( cont_i, 1,
                                          client->out_buffer_basename )) );
      }

      if (show_totals && totalBlocksDone > 0)
      {
        // To suppress "odd" problem completion count summaries (and not be
        // quite so verbose) we only display summaries if the number of
        // completed problems is even divisible by the number of processors.
        // Requires a working GetNumberOfDetectedProcessors() [cpucheck.cpp]
        #if 0
        int cpustmp; unsigned int cpus = 1;
        if ((cpustmp = GetNumberOfDetectedProcessors()) > 1)
          cpus = (unsigned int)cpustmp;
        if (load_problem_count > cpus)
          cpus = load_problem_count;
        if ((totalBlocksDone%cpus) == 0 )
        #endif
        {
          __post_summary_for_contest(cont_i);
        }
      }

      /* -------------------------------------------------------------- */

      for (inout=0;inout<=1;inout++)
      {
        unsigned long stats_count;
        long block_count = GetBufferCount( client, cont_i, inout, &stats_count );

        if (show_totals && block_count >= 0) /* no error */
        {
          char buffer[(3*80)+sizeof(client->in_buffer_basename)];
          int len;

          len = sprintf(buffer, "%s: %ld packet%s ",
                cont_name, block_count, ((block_count == 1)?(""):("s")) );
          if (stats_count)
            len += sprintf( &buffer[len], "(%lu.%02lu stats units) ",
                            stats_count/100,stats_count%100);
          len += sprintf( &buffer[len], "%s in\n%s",
              ((inout!= 0 || mode == PROBFILL_UNLOADALL)?
                 ((block_count==1)?("is"):("are")):
                 ((block_count==1)?("remains"):("remain"))),
              ((inout== 0)?
                  (client->nodiskbuffers ? "(memory-in)" :
                   BufferGetDefaultFilename( cont_i, 0,
                   client->in_buffer_basename ) ) :
                   (client->nodiskbuffers ? "(memory-out)":
                   BufferGetDefaultFilename( cont_i, 1,
                   client->out_buffer_basename ) ))
             );
          if (len < 55) /* fits on a single line, so unwrap */
          {
            char *nl = strrchr( buffer, '\n' );
            if (nl) *nl = ' ';
          }
          if (inout != 0) /* out-buffer */
          {
            /* adjust bufupd_pending if outthresh has been crossed */
            /* we don't check in-buffer here since we need cumulative count */
            if (__check_outbufthresh_limit( client, cont_i, block_count,
                                            stats_count, &bufupd_pending ))
            {
              //Log("5. bufupd_pending |= BUFFERUPDATE_FLUSH;\n");
            }
          }
          else /*in*/ if (stats_count && (mode!=PROBFILL_UNLOADALL))
          {
            timeval tv;
            tv.tv_sec = __get_thresh_secs(client, cont_i, 0, stats_count, 0 );
            if (tv.tv_sec > 0)
            {
              tv.tv_usec = 0;
              len += sprintf(&buffer[len],
                       "\nProjected ideal time to completion: %s",
                       CliGetTimeString( &tv, 2));
            }
          }
          Log( "%s\n", buffer );
        } //if (block_count >= 0)

      } //  for (inout=0;inout<=1;inout++)
    } //if (loaded_problems_count[cont_i] || saved_problems_count[cont_i])
  } //for ( cont_i = 0; cont_i < CONTEST_COUNT; cont_i++)

  /* ============================================================ */

  if (mode == PROBFILL_UNLOADALL)
  {
    previous_load_problem_count = 0;
    previous_client = (Client *)0;
    if (!CheckRestartRequestTrigger())
      Log("Shutdown complete.\n");
  }
  --reentrant_count;

  TRACE_BUFFUPD((-1, "LoadSaveProblems => %d\n", retval));

  return retval;
}