Fixed issue with param and config syntax error

// Number of elements to distribute across clusters. We choose 44 million as we're
// using Haswell currently and it has 44 HPC clusters at our disposal. For 'strong'
// scaling, this should likely be changed.
config var nElements = 1 * 1024 * 1024;
// Number of trials to run (and take the average of)
config var nTrials = 10;
// Number of computations per queue operation. This is used to introduce some
// variation that can help reduce contention on the queue (and emulate a more
// realistic workload)
config var nComputations = 0;
// The 'jitter' that causes variations in number of computations per second. In this
// way, the number of computations per operation is 'nComputations ± nJitter'.
config var nJitter = 0;
// Whether or not we are 'weak' scaling, as in we keep the workload the same but distribute
// it as we increase in the number of locales, or 'strong' in that we keep the number
// of elements per locale the same.
config var weak = false;
// Below are flags to determine which queue to test for...
config param isFIFO = false;
config param isMPMC = false;
config param isSync = false;
config param isCCSynch = false;
config param isList = false;
// Whether or not we log communications and per-locale information.
config var logLocaleInfo = false;
config var verboseLog = false;

use IO;
use CommDiagnostics;
use CCQueue;
use DistributedFIFOQueue;
use DistributedQueue;
use SyncList;

use Time;
use Random;

inline proc getQueue(type eltType) : Queue(eltType) {
  if isFIFO {
    return new DistributedFIFOQueue(eltType);
  } else if isMPMC {
    return new DistributedQueue(eltType);
  } else if isSync {
    return new SyncQueue(eltType);
  } else if isCCSynch {
    return new CCQueue(eltType);
  } else if isList {
    return new SyncList(eltType);
  } else {
    halt("Requires one of the flags to be set: '--isFIFO', '--isMPMC', '--isSync', '--isList', or '--isCCSynch'");
  }
}

proc main() {
  // Setup...
  var enqueueFile = open("tmp/enqueue" + numLocales, iomode.cw);
  var dequeueFile = open("tmp/dequeue" + numLocales, iomode.cw);
  var enqueueWriter = enqueueFile.writer();
  var dequeueWriter = dequeueFile.writer();
  var enqueueTrialTime : [1 .. nTrials] real;
  var dequeueTrialTime : [1 .. nTrials] real;

  // Obtain average time for enqueue followed by dequeued...
  for i in 1 .. nTrials {
    // We only use one or the other, but we must declare both.
    // TODO: Have both implement some parent 'Queue' class/interface?
    var queue = getQueue(int);
    var timer = new Timer();
    timer.start();

    if logLocaleInfo {
      resetCommDiagnostics();
      if verboseLog then startVerboseComm();
      startCommDiagnostics();
    }

    coforall loc in Locales do on loc {
      if logLocaleInfo then writeln(here, " has started Enqueue...");
      var iterations = if weak then nElements / numLocales else nElements;

      coforall tid in 0 .. #here.maxTaskPar {
        var x : atomic int;
        var randStr = makeRandomStream(int);
        for j in 1 .. iterations / here.maxTaskPar {
          queue.enqueue(j);
          var nComps = nComputations + (if nJitter then (randStr.getNext() % nJitter) else 0);
          for i in 1 .. nComps {
            // Hopefully compiler doesn't throw away?
            x.write(sin(i) : int);
          }
        }
      }

      if logLocaleInfo then writeln(here, " has finished Enqueue...");

    }

    if logLocaleInfo {
      if verboseLog then stopVerboseComm();
      stopCommDiagnostics();
      writeln(getCommDiagnostics());
    }

    timer.stop();
    enqueueTrialTime[i] = (if weak then nElements else numLocales * nElements) / timer.elapsed();
    writeln(i, "/", nTrials, ": ", (+ reduce enqueueTrialTime) / i);

    // Dequeue portion...
    timer.clear();
    timer.start();

    if logLocaleInfo {
      resetCommDiagnostics();
      if verboseLog then startVerboseComm();
      startCommDiagnostics();
    }
    coforall loc in Locales do on loc {
      if logLocaleInfo then writeln(here, " has started Dequeue...");
      var iterations = if weak then nElements / numLocales else nElements;

      coforall tid in 0 .. #here.maxTaskPar {
        var x : atomic int;
        var randStr = makeRandomStream(int);
        for j in 1 .. iterations / here.maxTaskPar {
          var retval = queue.dequeue();
          var nComps = nComputations + (if nJitter then (randStr.getNext() % nJitter) else 0);
          for i in 1 .. nComps {
            // Hopefully compiler doesn't throw away?
            x.write(sin(i) : int);
          }
        }
      }

      if logLocaleInfo then writeln(here, " has finished Dequeue...");
    }

    if logLocaleInfo {
      if verboseLog then stopVerboseComm();
      stopCommDiagnostics();
      writeln(getCommDiagnostics());
    }

    timer.stop();
    dequeueTrialTime[i] = (if weak then nElements else numLocales * nElements) / timer.elapsed();
    writeln(i, "/", nTrials, ": ", (+ reduce dequeueTrialTime) / i);

    delete queue;
  }
  enqueueWriter.write((+ reduce enqueueTrialTime) / nTrials);
  dequeueWriter.write((+ reduce dequeueTrialTime) / nTrials);
  enqueueWriter.close();
  dequeueWriter.close();
}

// Number of elements to distribute across clusters. We choose 44 million as we're
// using Haswell currently and it has 44 HPC clusters at our disposal. For 'strong'
// scaling, this should likely be changed.
config var nElements = 1 * 1024 * 1024;
// Number of trials to run (and take the average of)
config var nTrials = 10;
// Number of computations per queue operation. This is used to introduce some
// variation that can help reduce contention on the queue (and emulate a more
// realistic workload)
config var nComputations = 0;
// The 'jitter' that causes variations in number of computations per second. In this
// way, the number of computations per operation is 'nComputations ± nJitter'.
config var nJitter = 0;
// Whether or not we are 'weak' scaling, as in we keep the workload the same but distribute
// it as we increase in the number of locales, or 'strong' in that we keep the number
// of elements per locale the same.
config var weak = false;
// Below are flags to determine which queue to test for...
param config var isFIFO = false;
param config var isMPMC = false;
param config var isSync = false;
param config var isCCSynch = false;
param config var isList = false;
// Whether or not we log communications and per-locale information.
config var logLocaleInfo = false;
config var verboseLog = false;

use IO;
use CommDiagnostics;
use CCQueue;
use DistributedFIFOQueue;
use DistributedQueue;
use SyncList;

use Time;
use Random;

inline proc getQueue(type eltType) : Queue(eltType) {
  if isFIFO {
    return new DistributedFIFOQueue(eltType);
  } else if isMPMC {
    return new DistributedQueue(eltType);
  } else if isSync {
    return new SyncQueue(eltType);
  } else if isCCSynch {
    return new CCQueue(eltType);
  } else if isList {
    return new SyncList(eltType);
  } else {
    halt("Requires one of the flags to be set: '--isFIFO', '--isMPMC', '--isSync', '--isList', or '--isCCSynch'");
  }
}

proc main() {
  // Setup...
  var enqueueFile = open("tmp/enqueue" + numLocales, iomode.cw);
  var dequeueFile = open("tmp/dequeue" + numLocales, iomode.cw);
  var enqueueWriter = enqueueFile.writer();
  var dequeueWriter = dequeueFile.writer();
  var enqueueTrialTime : [1 .. nTrials] real;
  var dequeueTrialTime : [1 .. nTrials] real;

  // Obtain average time for enqueue followed by dequeued...
  for i in 1 .. nTrials {
    // We only use one or the other, but we must declare both.
    // TODO: Have both implement some parent 'Queue' class/interface?
    var queue = getQueue(int);
    var timer = new Timer();
    timer.start();

    if logLocaleInfo {
      resetCommDiagnostics();
      if verboseLog then startVerboseComm();
      startCommDiagnostics();
    }

    coforall loc in Locales do on loc {
      if logLocaleInfo then writeln(here, " has started Enqueue...");
      var iterations = if weak then nElements / numLocales else nElements;

      coforall tid in 0 .. #here.maxTaskPar {
        var x : atomic int;
        var randStr = makeRandomStream(int);
        for j in 1 .. iterations / here.maxTaskPar {
          queue.enqueue(j);
          var nComps = nComputations + (if nJitter then (randStr.getNext() % nJitter) else 0);
          for i in 1 .. nComps {
            // Hopefully compiler doesn't throw away?
            x.write(sin(i) : int);
          }
        }
      }

      if logLocaleInfo then writeln(here, " has finished Enqueue...");

    }

    if logLocaleInfo {
      if verboseLog then stopVerboseComm();
      stopCommDiagnostics();
      writeln(getCommDiagnostics());
    }

    timer.stop();
    enqueueTrialTime[i] = (if weak then nElements else numLocales * nElements) / timer.elapsed();
    writeln(i, "/", nTrials, ": ", (+ reduce enqueueTrialTime) / i);

    // Dequeue portion...
    timer.clear();
    timer.start();

    if logLocaleInfo {
      resetCommDiagnostics();
      if verboseLog then startVerboseComm();
      startCommDiagnostics();
    }
    coforall loc in Locales do on loc {
      if logLocaleInfo then writeln(here, " has started Dequeue...");
      var iterations = if weak then nElements / numLocales else nElements;

      coforall tid in 0 .. #here.maxTaskPar {
        var x : atomic int;
        var randStr = makeRandomStream(int);
        for j in 1 .. iterations / here.maxTaskPar {
          var retval = queue.dequeue();
          var nComps = nComputations + (if nJitter then (randStr.getNext() % nJitter) else 0);
          for i in 1 .. nComps {
            // Hopefully compiler doesn't throw away?
            x.write(sin(i) : int);
          }
        }
      }

      if logLocaleInfo then writeln(here, " has finished Dequeue...");
    }

    if logLocaleInfo {
      if verboseLog then stopVerboseComm();
      stopCommDiagnostics();
      writeln(getCommDiagnostics());
    }

    timer.stop();
    dequeueTrialTime[i] = (if weak then nElements else numLocales * nElements) / timer.elapsed();
    writeln(i, "/", nTrials, ": ", (+ reduce dequeueTrialTime) / i);

    delete queue;
  }
  enqueueWriter.write((+ reduce enqueueTrialTime) / nTrials);
  dequeueWriter.write((+ reduce dequeueTrialTime) / nTrials);
  enqueueWriter.close();
  dequeueWriter.close();
}


Updated test to use tuple rather than sequence to initialize array.

git-svn-id: 88467cb1fb04b8a755be7e1ee1026be4190196ef@9738 3a8e244f-b0f2-452b-bcba-4c88e055c3ca

use Random;
use Time;

enum classVals {S, W, A, B, C};

config const probClass = S;
config const seed = 314159265;
config const printTime = false;

const Class: domain(probClass);

const probSizes: [Class] int = ( 2**16, 2**20, 2**23, 2**25, 2**27 ),
      Bmaxs:     [Class] int = ( 2**11, 2**16, 2**19, 2**21, 2**23 ),
      Imaxs:     [Class] int = ( 10, 10, 10, 10, 10 );

config const probSize = probSizes(probClass);
config const Bmax = Bmaxs(probClass);
config const Imax = Imaxs(probClass);

const D: domain(1) = [0..probSize);
const E: domain(1) = [0..Bmax);

// The following should be replaced by two enumerated domain arrays of arrays
const S_testIndexArray: [0..4] int = ( 48427,17148,23627,62548,4431 );
const S_testRankArray: [0..4] int = ( 0,18,346,64917,65463 );
const W_testIndexArray: [0..4] int = ( 357773,934767,875723,898999,404505 );
const W_testRankArray: [0..4] int = ( 1249,11698,1039987,1043896,1048018 );
const A_testIndexArray: [0..4] int = ( 2112377,662041,5336171,3642833,4250760 );
const A_testRankArray: [0..4] int = ( 104,17523,123928,8288932,8388264 );
const B_testIndexArray: [0..4] int = ( 41869,812306,5102857,18232239,26860214 );
const B_testRankArray: [0..4] int = ( 33422937,10244,59149,33135281,99 );
const C_testIndexArray: [0..4] int = ( 44172927,72999161,74326391,129606274,21736814 );
const C_testRankArray: [0..4] int = ( 61147,882988,266290,133997595,133525895 );

var testIndexArray: [0..4] int;
var testRankArray: [0..4] int;

var keyArray: [D] int;
var ranks: [E] int;
var buffer:  [D] int;

var passedVerifications = 0;

def main() {
  var time = Timer();
  var randomStream = RandomStream(seed);
  var tempreals: [1..4] real;
  var max = Bmax / 4;

  setupPartialVerify();

  writeln(" NAS Parallel Benchmarks (Chapel) - IS Benchmark\n");
  writeln(" Size:  ", probSize, "  (class ", probClass, ")");
  writeln(" Iterations:   ", Imax, "\n");

  // Generate Keys
  [i in D] {
    randomStream.fillRandom(tempreals);
    keyArray(i) = (max * (+ reduce tempreals)):int;
  }

  // Do one interation for free (i.e., untimed) to guarantee initialization of
  // all data and code pages and respective tables
  rank(1);

  if (probClass != S) then writeln("   iteration");

  time.start();
  [i in 1..Imax] {
    if (probClass != S) then writeln("        ", i);
    rank(i);
  }
  time.stop();
  fullVerify();

  writeln("\n\n IS Benchmark Completed");
  writeln(" Class           = ", probClass);
  writeln(" Size            = ", probSize);
  writeln(" Iterations      = ", Imax);
  if printTime {
    writeln(" Time in seconds = ", time.elapsed(seconds));
    writeln(" Mop/s total     = ",
            (Imax*probSize)/time.elapsed(seconds)/1000000);
  }
  if (passedVerifications == (Imax+1) * 5 + 1) then
    writeln(" Verification    = SUCCESSFUL");
  else
    writeln(" Verification    = FAILED ", passedVerifications);
}

def setupPartialVerify() {
  // Would like to use an array over an enumerated domain of arrays instead
  select probClass {
    when S do {
      testIndexArray = S_testIndexArray;
      testRankArray  = S_testRankArray;
    }
    when W do {
      testIndexArray = W_testIndexArray;
      testRankArray  = W_testRankArray;
    }
    when A do {
      testIndexArray = A_testIndexArray;
      testRankArray  = A_testRankArray;
    }
    when B do {
      testIndexArray = B_testIndexArray;
      testRankArray  = B_testRankArray;
    }
    when C do {
      testIndexArray = C_testIndexArray;
      testRankArray  = C_testRankArray;
    }
  }
}

def rank(iteration: int) {
  keyArray(iteration) = iteration;
  keyArray(iteration+Imax) = Bmax - iteration;
  ranks = 0;
  [i in D] ranks(keyArray(i)) += 1;
  [i in 0..Bmax-2] ranks(i+1) += ranks(i);

  partialVerification(iteration);
}

def partialVerification(iteration: int) {
  for i in 0..4 {
    var k = keyArray(testIndexArray(i));
    select probClass {
      when S do {
        if (i <= 2) {
          if (ranks(k-1) != testRankArray(i)+iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i)-iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
      when W do {
        if (i < 2) {
          if (ranks(k-1) != testRankArray(i) + (iteration-2)) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i) - iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
      when A do {
        if (i <= 2) {
          if (ranks(k-1) != testRankArray(i) + (iteration-1)) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i) - (iteration-1)) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
      when B do {
        if (i == 1 || i == 2 || i == 4) {
          if (ranks(k-1) != testRankArray(i) + iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i) - iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
      when C do {
        if (i <= 2) {
          if (ranks(k-1) != testRankArray(i) + iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i) - iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
    }
  }
}

def fullVerify() {
  var failures = 0;
  [i in D] buffer(i) = keyArray(i);
  [i in D] {
    ranks(buffer(i)) -= 1;
    keyArray(ranks(buffer(i))) = buffer(i);
  }

  [i in 0..D.numIndices-2]
    if (keyArray(i) > keyArray(i+1)) then failures += 1;

  if (failures != 0) then
    halt("Full verification: number of keys out of sort ", failures);
  else
    passedVerifications += 1;
}

use Random;
use Time;

enum classVals {S, W, A, B, C};

config const probClass = S;
config const seed = 314159265;
config const printTime = false;

const Class: domain(probClass);

const probSizes: [Class] int = _seq( 2**16, 2**20, 2**23, 2**25, 2**27 ),
      Bmaxs:     [Class] int = _seq( 2**11, 2**16, 2**19, 2**21, 2**23 ),
      Imaxs:     [Class] int = _seq( 10, 10, 10, 10, 10 );

config const probSize = probSizes(probClass);
config const Bmax = Bmaxs(probClass);
config const Imax = Imaxs(probClass);

const D: domain(1) = [0..probSize);
const E: domain(1) = [0..Bmax);

// The following should be replaced by two enumerated domain arrays of arrays
const S_testIndexArray: [0..4] int = _seq( 48427,17148,23627,62548,4431 );
const S_testRankArray: [0..4] int = _seq( 0,18,346,64917,65463 );
const W_testIndexArray: [0..4] int = _seq( 357773,934767,875723,898999,404505 );
const W_testRankArray: [0..4] int = _seq( 1249,11698,1039987,1043896,1048018 );
const A_testIndexArray: [0..4] int = _seq( 2112377,662041,5336171,3642833,4250760 );
const A_testRankArray: [0..4] int = _seq( 104,17523,123928,8288932,8388264 );
const B_testIndexArray: [0..4] int = _seq( 41869,812306,5102857,18232239,26860214 );
const B_testRankArray: [0..4] int = _seq( 33422937,10244,59149,33135281,99 );
const C_testIndexArray: [0..4] int = _seq( 44172927,72999161,74326391,129606274,21736814 );
const C_testRankArray: [0..4] int = _seq( 61147,882988,266290,133997595,133525895 );

var testIndexArray: [0..4] int;
var testRankArray: [0..4] int;

var keyArray: [D] int;
var ranks: [E] int;
var buffer:  [D] int;

var passedVerifications = 0;

def main() {
  var time = Timer();
  var randomStream = RandomStream(seed);
  var tempreals: [1..4] real;
  var max = Bmax / 4;

  setupPartialVerify();

  writeln(" NAS Parallel Benchmarks (Chapel) - IS Benchmark\n");
  writeln(" Size:  ", probSize, "  (class ", probClass, ")");
  writeln(" Iterations:   ", Imax, "\n");

  // Generate Keys
  [i in D] {
    randomStream.fillRandom(tempreals);
    keyArray(i) = (max * (+ reduce tempreals)):int;
  }

  // Do one interation for free (i.e., untimed) to guarantee initialization of
  // all data and code pages and respective tables
  rank(1);

  if (probClass != S) then writeln("   iteration");

  time.start();
  [i in 1..Imax] {
    if (probClass != S) then writeln("        ", i);
    rank(i);
  }
  time.stop();
  fullVerify();

  writeln("\n\n IS Benchmark Completed");
  writeln(" Class           = ", probClass);
  writeln(" Size            = ", probSize);
  writeln(" Iterations      = ", Imax);
  if printTime {
    writeln(" Time in seconds = ", time.elapsed(seconds));
    writeln(" Mop/s total     = ",
            (Imax*probSize)/time.elapsed(seconds)/1000000);
  }
  if (passedVerifications == (Imax+1) * 5 + 1) then
    writeln(" Verification    = SUCCESSFUL");
  else
    writeln(" Verification    = FAILED ", passedVerifications);
}

def setupPartialVerify() {
  // Would like to use an array over an enumerated domain of arrays instead
  select probClass {
    when S do {
      testIndexArray = S_testIndexArray;
      testRankArray  = S_testRankArray;
    }
    when W do {
      testIndexArray = W_testIndexArray;
      testRankArray  = W_testRankArray;
    }
    when A do {
      testIndexArray = A_testIndexArray;
      testRankArray  = A_testRankArray;
    }
    when B do {
      testIndexArray = B_testIndexArray;
      testRankArray  = B_testRankArray;
    }
    when C do {
      testIndexArray = C_testIndexArray;
      testRankArray  = C_testRankArray;
    }
  }
}

def rank(iteration: int) {
  keyArray(iteration) = iteration;
  keyArray(iteration+Imax) = Bmax - iteration;
  ranks = 0;
  [i in D] ranks(keyArray(i)) += 1;
  [i in 0..Bmax-2] ranks(i+1) += ranks(i);

  partialVerification(iteration);
}

def partialVerification(iteration: int) {
  for i in 0..4 {
    var k = keyArray(testIndexArray(i));
    select probClass {
      when S do {
        if (i <= 2) {
          if (ranks(k-1) != testRankArray(i)+iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i)-iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
      when W do {
        if (i < 2) {
          if (ranks(k-1) != testRankArray(i) + (iteration-2)) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i) - iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
      when A do {
        if (i <= 2) {
          if (ranks(k-1) != testRankArray(i) + (iteration-1)) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i) - (iteration-1)) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
      when B do {
        if (i == 1 || i == 2 || i == 4) {
          if (ranks(k-1) != testRankArray(i) + iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i) - iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
      when C do {
        if (i <= 2) {
          if (ranks(k-1) != testRankArray(i) + iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        } else {
          if (ranks(k-1) != testRankArray(i) - iteration) {
            writeln("Failed partial verification: iteration ",
                 iteration, ", test key ", i);
          } else {
            passedVerifications += 1;
          }
        }
      }
    }
  }
}

def fullVerify() {
  var failures = 0;
  [i in D] buffer(i) = keyArray(i);
  [i in D] {
    ranks(buffer(i)) -= 1;
    keyArray(ranks(buffer(i))) = buffer(i);
  }

  [i in 0..D.numIndices-2]
    if (keyArray(i) > keyArray(i+1)) then failures += 1;

  if (failures != 0) then
    halt("Full verification: number of keys out of sort ", failures);
  else
    passedVerifications += 1;
}