Again, using a var instead of a refvar

Again, using a var instead of a refvar

use IO;
use AdvancedIters;

extern proc memcpy(x : [], b, len:int);

// For consistency with the other shootouts, a value is passed to this
// benchmark in the Computer Language Benchmarks Game test suite, even though
// the input set provided is used to determine the problem size.  Store that
// passed value here.
config const n = 0;

config const tableSize = 1 << 16;
config const lineSize = 61;

var tonum : [1..128] int;
tonum[0x41] = 0; // A
tonum[0x43] = 1; // C
tonum[0x54] = 2; // T
tonum[0x47] = 3; // G

var tochar : [0..3] string;
tochar[0] = "A";
tochar[1] = "C";
tochar[2] = "T";
tochar[3] = "G";

class Node {
  var data : uint;
  var count : int;
  var next : Node;
}

class Table {
  var table : [0..tableSize-1] Node;
  var size : int;

  proc this(d : uint) ref {
    const slot :int = (d & (tableSize-1)):int;
    refvar head = table[slot];
    var n = head;
    if n == nil {
      n = new Node(d, 0, nil);
      size += 1;
      head = n;
      return n.count;
    }

    while n != nil {
      if n.data == d then return n.count;
      n = n.next;
    }
    n = new Node(d, 0, head);
    size += 1;
    head = n;
    return n.count;
  }

  iter these() {
    for t in table {
      var n = t;
      while n != nil {
        yield (n.data, n.count);
        n = n.next;
      }
    }
  }

  proc ~Table() {
    for n in table do {
      var cur = n;
      while cur != nil {
        var next = cur.next;
        delete cur;
        cur = next;
      }
    }
  }
}

inline proc hash(str : [] uint(8), beg:int, sizeRange:range(?) ) {
  var data : uint = 0;
  for i in sizeRange {
    data <<= 2;
    data |= tonum[str[beg+i]];
  }
  return data;
}

proc decode(data : uint, size : int) {
  var ret : string;
  var d = data;
  for i in 1..size {
    ret = tochar[(d & 3) : uint(8)] + ret;
    d >>= 2;
  }
  return ret;
}

proc calculate(data : [] uint(8), size : int) {
  var freqs = new Table();

  const ntasks = defaultNumTasks(0);
  var lock : sync bool;
  lock = true;
  const sizeRange = 0..size-1;
  coforall tid in 1..ntasks {
    var curArr = new Table();
    for i in tid .. data.size-size by ntasks {
      curArr[hash(data, i, sizeRange)] += 1;
    }
    lock; // acquire lock
    for (k,v) in curArr do freqs[k] += v;
    lock = true; // free lock
    delete curArr;
  }

  return freqs;
}

proc write_frequencies(data : [] uint(8), size : int) {
  var sum = data.size  - size;
  var freqs = calculate(data, size);

  // sort by frequencies
  var arr : [1..freqs.size] (int, uint);
  for (a, (k,v)) in zip(arr, freqs) do
    a = (v,k);
  QuickSort(arr, reverse=true);

  for (f, s) in arr do
    writef("%s %.3dr\n", decode(s, size), (100.0 * f) / sum);
  delete freqs;
}

proc write_count(data : [] uint(8), str : string) {
  var freqs = calculate(data, str.length);
  var d = hash(str.toBytes(), 1, 0..str.length-1);
  writeln(freqs[d], "\t", decode(d, str.length));
  delete freqs;
}

proc string.toBytes() ref {
   var b : [1..this.length] uint(8);
   memcpy(b, this, this.length);
   return b;
}

inline proc startsWithThree(data : []) {
  return data[1] == 0x3E && data[2] == 0x54 && data[3] == 0x48;
}

proc main() {
  // Open stdin and a binary reader channel
  const inFile = openfd(0);
  const fileLen = inFile.length();
  var myin = inFile.reader(kind=ionative,locking=false);

  // Read line-by-line until we see a line beginning with '>TH'
  var tempdata : [1..lineSize] uint(8);
  var numRead = 0;
  var total = 0;
  while myin.readline(tempdata, numRead) && !startsWithThree(tempdata) { total += numRead; }

  // Read in the rest of the file
  var dataDom = {1..fileLen-total};
  var data : [dataDom] uint(8);
  var idx = 1;
  while myin.readline(data, numRead, idx) { idx += numRead - 1; }

  // Resize our array to the amount actually read
  dataDom = {1..idx};

  // Make everything uppercase
  forall d in data do d ^= 0x20;

  write_frequencies(data, 1);
  writeln();
  write_frequencies(data, 2);
  writeln();
  write_count(data, "GGT");
  write_count(data, "GGTA");
  write_count(data, "GGTATT");
  write_count(data, "GGTATTTTAATT");
  write_count(data, "GGTATTTTAATTTATAGT");
}

use IO;
use AdvancedIters;

extern proc memcpy(x : [], b, len:int);

// For consistency with the other shootouts, a value is passed to this
// benchmark in the Computer Language Benchmarks Game test suite, even though
// the input set provided is used to determine the problem size.  Store that
// passed value here.
config const n = 0;

config const tableSize = 1 << 16;
config const lineSize = 61;

var tonum : [1..128] int;
tonum[0x41] = 0; // A
tonum[0x43] = 1; // C
tonum[0x54] = 2; // T
tonum[0x47] = 3; // G

var tochar : [0..3] string;
tochar[0] = "A";
tochar[1] = "C";
tochar[2] = "T";
tochar[3] = "G";

class Node {
  var data : uint;
  var count : int;
  var next : Node;
}

class Table {
  var table : [0..tableSize-1] Node;
  var size : int;

  proc this(d : uint) ref {
    const slot :int = (d & (tableSize-1)):int;
    refvar head = table[slot];
    var n = head;
    if n == nil {
      n = new Node(d, 0, nil);
      size += 1;
      head = n;
      return n.count;
    }

    while n != nil {
      if n.data == d then return n.count;
      n = n.next;
    }
    n = new Node(d, 0, head);
    size += 1;
    head = n;
    return n.count;
  }

  iter these() {
    for t in table {
      var n = t;
      while n != nil {
        yield (n.data, n.count);
        n = n.next;
      }
    }
  }

  proc ~Table() {
    for n in table do {
      var cur = n;
      while cur != nil {
        refvar next = cur.next;
        delete cur;
        cur = next;
      }
    }
  }
}

inline proc hash(str : [] uint(8), beg:int, sizeRange:range(?) ) {
  var data : uint = 0;
  for i in sizeRange {
    data <<= 2;
    data |= tonum[str[beg+i]];
  }
  return data;
}

proc decode(data : uint, size : int) {
  var ret : string;
  var d = data;
  for i in 1..size {
    ret = tochar[(d & 3) : uint(8)] + ret;
    d >>= 2;
  }
  return ret;
}

proc calculate(data : [] uint(8), size : int) {
  var freqs = new Table();

  const ntasks = defaultNumTasks(0);
  var lock : sync bool;
  lock = true;
  const sizeRange = 0..size-1;
  coforall tid in 1..ntasks {
    var curArr = new Table();
    for i in tid .. data.size-size by ntasks {
      curArr[hash(data, i, sizeRange)] += 1;
    }
    lock; // acquire lock
    for (k,v) in curArr do freqs[k] += v;
    lock = true; // free lock
    delete curArr;
  }

  return freqs;
}

proc write_frequencies(data : [] uint(8), size : int) {
  var sum = data.size  - size;
  var freqs = calculate(data, size);

  // sort by frequencies
  var arr : [1..freqs.size] (int, uint);
  for (a, (k,v)) in zip(arr, freqs) do
    a = (v,k);
  QuickSort(arr, reverse=true);

  for (f, s) in arr do
    writef("%s %.3dr\n", decode(s, size), (100.0 * f) / sum);
  delete freqs;
}

proc write_count(data : [] uint(8), str : string) {
  var freqs = calculate(data, str.length);
  var d = hash(str.toBytes(), 1, 0..str.length-1);
  writeln(freqs[d], "\t", decode(d, str.length));
  delete freqs;
}

proc string.toBytes() ref {
   var b : [1..this.length] uint(8);
   memcpy(b, this, this.length);
   return b;
}

inline proc startsWithThree(data : []) {
  return data[1] == 0x3E && data[2] == 0x54 && data[3] == 0x48;
}

proc main() {
  // Open stdin and a binary reader channel
  const inFile = openfd(0);
  const fileLen = inFile.length();
  var myin = inFile.reader(kind=ionative,locking=false);

  // Read line-by-line until we see a line beginning with '>TH'
  var tempdata : [1..lineSize] uint(8);
  var numRead = 0;
  var total = 0;
  while myin.readline(tempdata, numRead) && !startsWithThree(tempdata) { total += numRead; }

  // Read in the rest of the file
  var dataDom = {1..fileLen-total};
  var data : [dataDom] uint(8);
  var idx = 1;
  while myin.readline(data, numRead, idx) { idx += numRead - 1; }

  // Resize our array to the amount actually read
  dataDom = {1..idx};

  // Make everything uppercase
  forall d in data do d ^= 0x20;

  write_frequencies(data, 1);
  writeln();
  write_frequencies(data, 2);
  writeln();
  write_count(data, "GGT");
  write_count(data, "GGTA");
  write_count(data, "GGTATT");
  write_count(data, "GGTATTTTAATT");
  write_count(data, "GGTATTTTAATTTATAGT");
}


Updated comments for norm example a bit.

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

/*
 *
 *  Matrix and Vector Norms Example
 *
 *  This example defines a module, Norm for computing matrix and
 *  vector norms, and a second module, TestNorm that tests the
 *  Norm module for 1D and 2D arrays:
 *
 *  The Norm module defines:
 *  - 1-norm, 2-norm, infinity norm and Frobenius norm for vectors
 *  - 1-norm, infinity norm and Frobenius norm for matrices
 *
 *  The normType argument for the first few overloads of norm() is an
 *  enumeration indicating the norm to compute.

 * The norm function may also be called without specifying normType,
 * in which case the default norm for that array rank will be used.
 *
 */

module Norm{

  // normType specifies the type of norm to compute
  enum normType {norm1, norm2, normInf, normFrob};

  // vector norms
  def norm(x: [], p: normType) where x.rank == 1 {
    select (p) {
      when norm1 do return + reduce abs(x);
      when norm2 do return sqrt(+ reduce (abs(x)*abs(x)));
      when normInf do return max reduce abs(x);
      when normFrob do return sqrt(+ reduce (abs(x)*abs(x)));
      otherwise halt("Unexpected norm type");
    }
  }

  // matrix norms
  def norm(x: [?D], p: normType) where x.rank == 2 {
    select (p) {
      when norm1 do
        return max reduce [j in D.dim(2)] (+ reduce abs(x[D.dim(1), j]));

      when norm2 do
        halt("Haven't implemented 2-norm for 2D arrays yet");

      when normInf do
        return max reduce [i in D.dim(1)] (+ reduce abs(x[i, D.dim(2)]));

      when normFrob do return sqrt(+ reduce (abs(x)*abs(x)));

      otherwise halt("Unexpected norm type");
    }
  }

  // this module doesn't implement norms for > 2D arrays, so generate
  // a compile-timem error if the user tries to call one
  def norm(x: [], p: normType) where x.rank > 2 {
    compilerError("Norms not implemented for array ranks > 2D");
  }

  //  default norms
  def norm(x: []) {
    select (x.rank) {
      when 1 do return norm(x, norm2);
      when 2 do return norm(x, normFrob);
      otherwise compilerError("Norms not implemented for array ranks > 2D");
    }
  }
}

module TestNorm {
  use Norm;

  def testNorm(arr: []) {
    var testType = if (arr.rank == 1) then "vector" else "matrix";
    writeln("Test of ", testType, " norms.  Array = ");
    writeln(arr);
    writeln("1-norm = ", norm(arr, norm1));
    if (arr.rank == 1) then
      writeln("2-norm = " , norm(arr, norm2));
    writeln("infinity norm = ", norm(arr, normInf));
    writeln("frobenius norm = ", norm(arr, normFrob));
    writeln("default norm = ", norm(arr));
    writeln();
  }

  def main() {
    const D1 = [1..4];
    var a:[D1] real;
    a = 2.0;
    testNorm(a);

    const D2 = [1..2,1..2];
    var b:[D2] real;
    b = 2.0;
    testNorm(b);

    const D3 = [1..3,1..2];
    var c:[D3] real;
    c = 2.0;
    testNorm(c);

    var d:[D2] int;
    d = 1;
    testNorm(d);

    var e:[D2] complex;
    e = 1.0 + 1.0i;
    testNorm(e);
  }
}

/*
 *
 *  Matrix and Vector Norms Example
 *
 *  Norm module for computing matrix and vector norms:
 *  1-norm, 2-norm, infinity norm and Frobenius norm for vectors
 *  1-norm, infinity norm and Frobenius norm for matrices
 *
 *  normType specifies the type of norm to use
 *  norm function may be called without specifying normType
 *
 *  TestNorm module tests norm function for 1-D and 2-D arrays
 *
 */
module Norm{

  // normType specifies the type of norm to compute
  enum normType {norm1, norm2, normInf, normFrob};

  def norm(x: [], p: normType) where x.rank == 1 {
  // vector norms
    select (p) {
      when norm1 do return + reduce abs(x);
      when norm2 do return sqrt(+ reduce (abs(x)*abs(x)));
      when normInf do return max reduce abs(x);
      when normFrob do return sqrt(+ reduce (abs(x)*abs(x)));
      otherwise halt("Unexpected norm type");
    }
  }

  def norm(x: [?D], p: normType) where x.rank == 2 {
  // matrix norms
    select (p) {
      when norm1 do
        return max reduce [j in D.dim(2)] (+ reduce abs(x[D.dim(1), j]));

      when norm2 do
        halt("Haven't implemented 2-norm for 2D arrays yet");

      when normInf do
        return max reduce [i in D.dim(1)] (+ reduce abs(x[i, D.dim(2)]));

      when normFrob do return sqrt(+ reduce (abs(x)*abs(x)));

      otherwise halt("Unexpected norm type");
    }
  }

  def norm(x: [], p: normType) where x.rank > 2 {
  // norms not implemented for > 2D arrays
    compilerError("Norms not implemented for array ranks > 2D");
  }

  def norm(x: []) {
  //  default norms
    select (x.rank) {
      when 1 do return norm(x, norm2);
      when 2 do return norm(x, normFrob);
      otherwise compilerError("Norms not implemented for array ranks > 2D");
    }
  }
}

module TestNorm {
  use Norm;

  def testNorm(arr: []) {
    var testType = if (arr.rank == 1) then "vector" else "matrix";
    writeln("Test of ", testType, " norms.  Array = ");
    writeln(arr);
    writeln("1-norm = ", norm(arr, norm1));
    if (arr.rank == 1) then
      writeln("2-norm = " , norm(arr, norm2));
    writeln("infinity norm = ", norm(arr, normInf));
    writeln("frobenius norm = ", norm(arr, normFrob));
    writeln("default norm = ", norm(arr));
    writeln();
  }

  def main() {
    const D1 = [1..4];
    var a:[D1] real;
    a = 2.0;
    testNorm(a);

    const D2 = [1..2,1..2];
    var b:[D2] real;
    b = 2.0;
    testNorm(b);

    const D3 = [1..3,1..2];
    var c:[D3] real;
    c = 2.0;
    testNorm(c);

    var d:[D2] int;
    d = 1;
    testNorm(d);

    var e:[D2] complex;
    e = 1.0 + 1.0i;
    testNorm(e);
  }
}


parallelized bulk_extractor, Thanks to Marcos

use Cdo,
    LinearAlgebra,
    LinearAlgebra.Sparse;

/*
  :arg con: A CDO Connection to Postgres
  :arg edgeTable: The table in PG of edges
  :arg fromField: The field of edgeTable containing the id of the head vertex
  :arg toField: the field of edgeTable containing the id of the tail vertex
  :arg wField: The field of edgeTable containing the weight of the edge
  :arg n: number of distinct vertices. In practice, this may be gives and the number of names
  :arg weights: Boolean on whether to use the weights in the table or a 1 (indicator)
 */

config param batchsize = 10000;

proc wFromPG(con: Connection, edgeTable: string
    , fromField: string, toField: string, wField: string, n: int, weights=true) {
  var q = "SELECT %s, %s, %s FROM %s ORDER BY 1, 2;";
  var cursor = con.cursor();
  cursor.query(q,(fromField, toField, wField, edgeTable));
  const D: domain(2) = {1..n, 1..n};
  var SD: sparse subdomain(D) dmapped CS();
  var W: [SD] real;
  forall row in cursor {
    SD += (row[fromField]: int, row[toField]: int);
    if weights {
      W(row[fromField], row[toField]) = row[wField]: real;
    } else {
      W(row[fromField], row[toField]) = 1;
    }
  }
//  SD.bulkAdd(indices);
//  return W.domain;
  return W;
}

/*

 :arg con: A connection to a Postgres database containing a table with <ftr_id>, <vertex_name> pairs
 :arg nameTable: The name of the Postgres table containing the pairs
 :arg nameField: The name of the field in the nameTable containing the names
 :arg idField: The name of the field in the nameTable containing the feature ids

 :returns: An array of strings in order of feature id
 */
proc vNamesFromPG(con: Connection, nameTable: string
  , nameField: string, idField: string ) {

  var cursor = con.cursor();
  var q1 = "SELECT max(%s) AS n FROM %s";
  cursor.query(q1, (idField, nameTable));
  var n:int= cursor.fetchone()['n']: int;
  var vertexNames: [1..n] string;

  var q2 = "SELECT %s, %s FROM %s ORDER BY 1";
  cursor.query(q2, (idField, nameField, nameTable));
  for row in cursor {
      vertexNames[row[idField]:int ] = row[nameField];
  }
  return vertexNames;
}

/*
 */

 proc persistSparseMatrix(con: Connection, aTable: string, fromField: string, toField: string, weightField: string, A:[?D] real) {
   const q = "INSERT INTO %s (%s, %s, %s) VALUES (%s, %s, %s);";
   var cur = con.cursor();
   var count: int = 0;
   var dom: domain(1, int, false) = {1..0};
   var ts: [dom] (string, string, string, string, int, int, real);
   for ij in A.domain {
     ts.push_back((aTable, fromField, toField, weightField, ij(1), ij(2), A(ij)));
     count += 1;
     if count >= batchsize {
       cur.execute(q, ts);
       count = 0;
       var reset: [dom] (string, string, string, string, int, int, real);
       ts = reset;
     }
   }
   cur.execute(q,ts);
 }

use Cdo,
    LinearAlgebra,
    LinearAlgebra.Sparse;

/*
  :arg con: A CDO Connection to Postgres
  :arg edgeTable: The table in PG of edges
  :arg fromField: The field of edgeTable containing the id of the head vertex
  :arg toField: the field of edgeTable containing the id of the tail vertex
  :arg wField: The field of edgeTable containing the weight of the edge
  :arg n: number of distinct vertices. In practice, this may be gives and the number of names
  :arg weights: Boolean on whether to use the weights in the table or a 1 (indicator)
 */

config param batchsize = 10000;

proc wFromPG(con: Connection, edgeTable: string
    , fromField: string, toField: string, wField: string, n: int, weights=true) {
  var q = "SELECT %s, %s, %s FROM %s ORDER BY 1, 2;";
  var cursor = con.cursor();
  cursor.query(q,(fromField, toField, wField, edgeTable));
  const D: domain(2) = {1..n, 1..n};
  var SD: sparse subdomain(D) dmapped CS();
  var W: [SD] real;
  var dom1: domain(1, int, false) = {1..0};
  var dom2: domain(1, int, false) = {1..0};
  var indices: [dom1] 2*int;
  var values: [dom2] real;
  for row in cursor {
    indices.push_back((row[fromField]: int, row[toField]: int));
    values.push_back(row[wField]: real);
  }
  SD.bulkAdd(indices);
  forall (ij, w) in zip(indices, values) {
    if weights {
      W((ij(1),ij(2))) = w;
    } else {
      W((ij(1),ij(2))) = 1;
    }
  }
//  SD.bulkAdd(indices);
//  return W.domain;
  return W;
}

/*

 :arg con: A connection to a Postgres database containing a table with <ftr_id>, <vertex_name> pairs
 :arg nameTable: The name of the Postgres table containing the pairs
 :arg nameField: The name of the field in the nameTable containing the names
 :arg idField: The name of the field in the nameTable containing the feature ids

 :returns: An array of strings in order of feature id
 */
proc vNamesFromPG(con: Connection, nameTable: string
  , nameField: string, idField: string ) {

  var cursor = con.cursor();
  var q1 = "SELECT max(%s) AS n FROM %s";
  cursor.query(q1, (idField, nameTable));
  var n:int= cursor.fetchone()['n']: int;
  var vertexNames: [1..n] string;

  var q2 = "SELECT %s, %s FROM %s ORDER BY 1";
  cursor.query(q2, (idField, nameField, nameTable));
  for row in cursor {
      vertexNames[row[idField]:int ] = row[nameField];
  }
  return vertexNames;
}

/*
 */

 proc persistSparseMatrix(con: Connection, aTable: string, fromField: string, toField: string, weightField: string, A:[?D] real) {
   const q = "INSERT INTO %s (%s, %s, %s) VALUES (%s, %s, %s);";
   var cur = con.cursor();
   var count: int = 0;
   var dom: domain(1, int, false) = {1..0};
   var ts: [dom] (string, string, string, string, int, int, real);
   for ij in A.domain {
     ts.push_back((aTable, fromField, toField, weightField, ij(1), ij(2), A(ij)));
     count += 1;
     if count >= batchsize {
       cur.execute(q, ts);
       count = 0;
       var reset: [dom] (string, string, string, string, int, int, real);
       ts = reset;
     }
   }
   cur.execute(q,ts);
 }


Incremented year by a whole lot in getCurrentDate test.

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

use Time;
var year, month, day: int;
(year, month, day) = getCurrentDate();
if year > 2102 then
  writeln("I don't believe that you are still working on Chapel!");
else
  writeln("Chapel is a new parallel programming language.");

use Time;
var year, month, day: int;
(year, month, day) = getCurrentDate();
if year > 2009 then
  writeln("I don't believe that you are still working on Chapel!");
else
  writeln("Chapel is a new parallel programming language.");


More tasks, slightly fewer trials

More tasks, slightly fewer trials

config const iters = 300;
config const trials = 400;
config const n = 80;

var D: domain(real);

for i in 1..trials {
  coforall t in 1..n {
    const b = if t & 1 then -1 else 1;
    var r = 1..iters by b;
    for j in r do
      if !D.member((t+j):real) then
        D += (t+j);
  }
  for j in 2..n+iters do assert(D.member(j));
  D.clear();
}

config const iters = 200;
config const trials = 500;
config const n = 20;

var D: domain(real);

for i in 1..trials {
  coforall t in 1..n {
    const b = if t & 1 then -1 else 1;
    var r = 1..iters by b;
    for j in r do
      if !D.member((t+j):real) then
        D += (t+j);
  }
  for j in 2..n+iters do assert(D.member(j));
  D.clear();
}


Fixed a small change in output that was not meant to be

[Lydia said so.  She was sitting next to me when I made the change]

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

/*
  chpldoc Primer

  This primer covers the use of chpldoc to document source code

*/

// Creating and accessing the documentation:

// To generate the documentation for this and any source file, you may either
// compile using the command 'chpldoc <sourceName.chpl>' for documentation only
// or using the command 'chpl --docs <sourceName.chpl>' to create both
// documentation and an executable.

// The documentation files will be found in a special folder created by the
// chpldoc tool.  If you are compiling a Chapel file that is deeper than your
// current directory, this heirarchy will be reflected within the documentation
// folder.
// (i.e. foo/bar.chpl will generate documentation within docs/foo/)

// Documentation within the code:

/*
  Multiline comments found before a method are associated with that method
  as long as there are no code blocks between them.
*/

proc commented(val: int): string {
  var totalNum = val + 4;
  var str = "hello agent " + totalNum;
  return str;
}

/*
  The method can be a stub and still output its comment
*/
proc stub(val): bool {
  /* Comments within the method body are ignored */
}

// Single line comments are also ignored.  However, this does not prevent
// the display of the method itself.
proc uncommented() {
  /*
    Longer comments within the method body are also ignored
  */
}

/*
  If the source code defines a module, it can also have a comment associated
  with it
*/
module Defined {

  /*
    And classes can display their comments, too
  */
  class Foo {
    /*
      Including the comments associated with their fields
    */
    var a: int;

    /*
      And class specific methods
    */
    proc getA(): int {
      return a;
    }
  }

  /*
    If a class inherits from another class, those fields, methods, and their
    comments are output in both the super and the subclass
  */
  class Bar : Foo {

    proc setA(newVal: int) {
      a = newVal;
    }
  }
}

/*
  chpldoc Primer

  This primer covers the use of chpldoc to document source code

*/

// Creating and accessing the documentation:

// To generate the documentation for this and any source file, you may either
// compile using the command 'chpldoc <sourceName.chpl>' for documentation only
// or using the command 'chpl --docs <sourceName.chpl>' to create both
// documentation and an executable.

// The documentation files will be found in a special folder created by the
// chpldoc tool.  If you are compiling a Chapel file that is deeper than your
// current directory, this heirarchy will be reflected within the documentation
// folder.
// (i.e. foo/bar.chpl will generate documentation within docs/foo/)

// Documentation within the code:

/*
  Multiline comments found before a method are **associated** with that method
  as long as there are no code blocks between them.
*/

proc commented(val: int): string {
  var totalNum = val + 4;
  var str = "hello agent " + totalNum;
  return str;
}

/*
  The method can be a stub and still output its comment
*/
proc stub(val): bool {
  /* Comments within the method body are ignored */
}

// Single line comments are also ignored.  However, this does not prevent
// the display of the method itself.
proc uncommented() {
  /*
    Longer comments within the method body are also ignored
  */
}

/*
  If the source code defines a module, it can also have a comment associated
  with it
*/
module Defined {

  /*
    And classes can display their comments, too
  */
  class Foo {
    /*
      Including the comments associated with their fields
    */
    var a: int;

    /*
      And class specific methods
    */
    proc getA(): int {
      return a;
    }
  }

  /*
    If a class inherits from another class, those fields, methods, and their
    comments are output in both the super and the subclass
  */
  class Bar : Foo {

    proc setA(newVal: int) {
      a = newVal;
    }
  }
}


More dead variable elimination and some simplification
to tangled control flow in sprnvc().

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

use Random;

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

config const probClass = S;

//const Class: domain(classVals) = [S..O];
const Class: domain(1) = [S..O];
const probSizes:   [Class] int = (/ 1400, 7000, 14000, 75000, 150000, 150000, 1400 /),
      nonZeroes:   [Class] int = (/ 7, 8, 11, 13, 15, 21, 7 /),
      shifts:      [Class] int = (/ 10, 12, 20, 60, 110, 500, 10 /),
      numIters:    [Class] int = (/ 15, 15, 15, 75, 75, 100, 15 /),
      verifyZetas: [Class] real = (/ 8.5971775078648, 10.362595087124,
                                    17.130235054029, 22.712745482631,
                                    28.973605592845, 52.5145321058, 0.0 /);

config const n = probSizes(probClass),
             rcond = 0.1,
             nonzer = nonZeroes(probClass),
             shift = shifts(probClass);

type elemType = real(64);

def main() {
  writeln("Chapel sparsity pattern is:");
  for res in makea() {
    writeln(res);
  }
}

iterator makea() {
  const nonzerMax = 16;
  var v: [1..nonzerMax] real,    // BLC: insert domains? or grow as necessary?
      iv: [1..nonzerMax] int;

  var size = 1.0;
  const ratio = rcond ** (1.0 / n);

  var randStr = RandomStream(314159265);

  for iouter in 1..n {
    var nzv = nonzer;

    sprnvc(n, nzv, v, iv, randStr);
    vecset(v, iv, nzv, iouter, 0.50);

    // BLC: replace with zippered loop over iv or iv(1..nzv)?
    for ivelt in 1..nzv {
      const jcol = iv(ivelt),
            scale = size * v(ivelt);

      // BLC: replace with zippered loop over iv or iv(1..nzv)?
      for ivelt1 in 1..nzv {
        const irow = iv(ivelt1);

        yield ((irow, jcol), v(ivelt1)*scale);
      }
    }
    size *= ratio;
  }

  for i in 1..n {
    yield ((i, i), rcond - shift);
  }
}

def sprnvc(n, nz, v, iv, randStr) {
  const zeta = randStr.getFirst();

  const nn1 = log2(n);

  var indices: domain(int);

  for nzv in 1..nz {
    var vecelt: real, i: int;
    do {
      vecelt = randStr.getNext();
      i = (randStr.getNext() * nn1):int + 1;
    } while (i > n || indices.member?(i));
    indices += i;
    v(nzv) = vecelt;
    iv(nzv) = i;
  }
}

def vecset(v, iv, inout nzv, i, val) {
  var set = false;
  for k in 1..nzv {
    if (iv(k) == i) {
      v(k) = val;
      set = true;
    }
  }
  if (!set) {
    nzv += 1;
    v(nzv) = val;
    iv(nzv) = i;
  }
}

use Random;

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

config const probClass = S;

//const Class: domain(classVals) = [S..O];
const Class: domain(1) = [S..O];
const probSizes:   [Class] int = (/ 1400, 7000, 14000, 75000, 150000, 150000, 1400 /),
      nonZeroes:   [Class] int = (/ 7, 8, 11, 13, 15, 21, 7 /),
      shifts:      [Class] int = (/ 10, 12, 20, 60, 110, 500, 10 /),
      numIters:    [Class] int = (/ 15, 15, 15, 75, 75, 100, 15 /),
      verifyZetas: [Class] real = (/ 8.5971775078648, 10.362595087124,
                                    17.130235054029, 22.712745482631,
                                    28.973605592845, 52.5145321058, 0.0 /);

config const n = probSizes(probClass),
             rcond = 0.1,
             nonzer = nonZeroes(probClass),
             shift = shifts(probClass);

type elemType = real(64);

def main() {
  writeln("Chapel sparsity pattern is:");
  for res in makea() {
    writeln(res);
  }
}

iterator makea() {
  const nonzerMax = 16,
        naMax = 150000;
  var v: [1..nonzerMax] real,    // BLC: insert domains? or grow as necessary?
      iv: [1..nonzerMax] int;

  var size = 1.0;
  const ratio = rcond ** (1.0 / n);

  var randStr = RandomStream(314159265);

  for iouter in 1..n {
    var nzv = nonzer;

    sprnvc(n, nzv, v, iv, randStr);
    vecset(n, v, iv, nzv, iouter, 0.50);

    // BLC: replace with zippered loop over iv or iv(1..nzv)?
    for ivelt in 1..nzv {
      const jcol = iv(ivelt),
            scale = size * v(ivelt);

      // BLC: replace with zippered loop over iv or iv(1..nzv)?
      for ivelt1 in 1..nzv {
        const irow = iv(ivelt1);

        yield ((irow, jcol), v(ivelt1)*scale);
      }
    }
    size *= ratio;
  }

  for i in 1..n {
    yield ((i, i), rcond - shift);
  }
}

def sprnvc(n, nz, v, iv, randStr) {
  const zeta = randStr.getFirst();

  const nn1 = log2(n);

  var indSpace: domain(int);

  var nzv = 0;

  while (nzv < nz) {
    do {
      const vecelt = randStr.getNext(),
            i = (randStr.getNext() * nn1):int + 1;
      if (i <= n && !indSpace.member?(i)) {
        indSpace += i;
        nzv += 1;
        v(nzv) = vecelt;
        iv(nzv) = i;
      }
    } while (!(i <= n));
  }
}

def vecset(n, v, iv, inout nzv, i, val) {
  var set = false;
  for k in 1..nzv {
    if (iv(k) == i) {
      v(k) = val;
      set = true;
    }
  }
  if (!set) {
    nzv += 1;
    v(nzv) = val;
    iv(nzv) = i;
  }
}


Fix a race condition in is_mt.  To determine when all threads had finished,
a sync var was incremented before each thread was spawned and decremented when
each thread terminated, and checked for 0.  If all running threads finished
before the total number of threads needed were started, the count fell to 0 and
not all work was done before doing verifications.

Instead of bumping the counter each iteration, initialize the counter to
nThreads and only decrement it. Thanks for the tip, Brad.

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

use Random;
use Time;

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

config param probClass = S;
config const printTime = false;
config const nThreads = 4;

param seed = 314159265;

const Class: domain(classVals);

const TotalKeys:  [Class] int = ( 2**16, 2**20, 2**23, 2**25, 2**27 ),
      MaxKey:     [Class] int = ( 2**11, 2**16, 2**19, 2**21, 2**23 ),
      TotalIters: [Class] int = ( 10, 10, 10, 10, 10 );

const totalKeys = TotalKeys(probClass);
const maxKey = MaxKey(probClass);
const maxIterations = TotalIters(probClass);

const D: domain(1) = [0..totalKeys);
const E: domain(2) = [0..maxKey-1, 0..nThreads-1];

// 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 partialVerifyVals: [0..4] int;

var keyArray, buffer: [D] int;
var keyBuff1: [E] int;

var passedVerifications = 0;

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

  setupPartialVerify();

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

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

  // Do one iteration 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();
  for i in 1..maxIterations {
    if (probClass != S) then writeln("        ", i);
    rank(i);
  }
  time.stop();
  fullVerify();

  writeln("\n\n IS Benchmark Completed");
  writeln(" Class           = ", probClass);
  writeln(" Size            = ", totalKeys);
  writeln(" Iterations      = ", maxIterations);
  if printTime {
    writeln(" Time in seconds = ", time.elapsed(seconds));
    writeln(" Mop/s total     = ",
            (maxIterations*totalKeys)/time.elapsed(seconds)/1000000);
  }
  if (passedVerifications == (maxIterations+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) {
  var done: single bool;
  var blkSize = totalKeys / nThreads;
  var threadCnt: sync int = nThreads;

  keyArray(iteration) = iteration;
  keyArray(iteration+maxIterations) = maxKey - iteration;

  partialVerifyVals = keyArray(testIndexArray);
  keyBuff1 = 0;

  for thread in 0..nThreads-1 {
    var low = thread * blkSize;
    var high = if thread == nThreads-1 then D.high else (thread+1)*blkSize - 1;
    var DOM: domain(1) = [low..high];
    begin {
      keyBuff1([i in DOM] keyArray(i), thread) += 1;
      var threadCntL = threadCnt;
      threadCntL -= 1;
      threadCnt = threadCntL;
      if threadCntL == 0 then done = true;
    }
  }
  if done {
    var slice: domain(2) = [0..maxKey-1, 0..0];
    if nThreads > 1 then
      [i in 0..maxKey-1] keyBuff1(i, 0) = + reduce keyBuff1(i, [0..nThreads-1]);

    keyBuff1(slice) = + scan keyBuff1(slice);
    partialVerification(iteration);
  }
}

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

def fullVerify() {
  var failures = 0;
  buffer = keyArray;
  [i in D] {
    atomic {
      keyBuff1(buffer(i), 0) -= 1;
      keyArray(keyBuff1(buffer(i), 0)) = 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 param probClass = S;
config const printTime = false;
config const nThreads = 4;

param seed = 314159265;

const Class: domain(classVals);

const TotalKeys:  [Class] int = ( 2**16, 2**20, 2**23, 2**25, 2**27 ),
      MaxKey:     [Class] int = ( 2**11, 2**16, 2**19, 2**21, 2**23 ),
      TotalIters: [Class] int = ( 10, 10, 10, 10, 10 );

const totalKeys = TotalKeys(probClass);
const maxKey = MaxKey(probClass);
const maxIterations = TotalIters(probClass);

const D: domain(1) = [0..totalKeys);
const E: domain(2) = [0..maxKey-1, 0..nThreads-1];

// 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 partialVerifyVals: [0..4] int;

var keyArray, buffer: [D] int;
var keyBuff1: [E] int;

var passedVerifications = 0;

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

  setupPartialVerify();

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

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

  // Do one iteration 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();
  for i in 1..maxIterations {
    if (probClass != S) then writeln("        ", i);
    rank(i);
  }
  time.stop();
  fullVerify();

  writeln("\n\n IS Benchmark Completed");
  writeln(" Class           = ", probClass);
  writeln(" Size            = ", totalKeys);
  writeln(" Iterations      = ", maxIterations);
  if printTime {
    writeln(" Time in seconds = ", time.elapsed(seconds));
    writeln(" Mop/s total     = ",
            (maxIterations*totalKeys)/time.elapsed(seconds)/1000000);
  }
  if (passedVerifications == (maxIterations+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) {
  var done: single bool;
  var blkSize = totalKeys / nThreads;
  var threadCnt: sync int = 0;
  keyArray(iteration) = iteration;
  keyArray(iteration+maxIterations) = maxKey - iteration;

  partialVerifyVals = keyArray(testIndexArray);
  keyBuff1 = 0;

  for thread in 0..nThreads-1 {
    var low = thread * blkSize;
    var high = if thread == nThreads-1 then D.high else (thread+1)*blkSize - 1;
    var DOM: domain(1) = [low..high];
    threadCnt += 1;
    begin {
      keyBuff1([i in DOM] keyArray(i), thread) += 1;
      var threadCntL = threadCnt;
      threadCntL -= 1;
      threadCnt = threadCntL;
      if threadCntL == 0 then done = true;
    }
  }
  if done {
    var slice: domain(2) = [0..maxKey-1, 0..0];
    if nThreads > 1 then
      [i in 0..maxKey-1] keyBuff1(i, 0) = + reduce keyBuff1(i, [0..nThreads-1]);

    keyBuff1(slice) = + scan keyBuff1(slice);
    partialVerification(iteration);
  }
}

def subRank(iteration: int, myThread: int, DOM) {
  keyBuff1([i in DOM] keyArray(i), myThread) += 1;
}

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

def fullVerify() {
  var failures = 0;
  buffer = keyArray;
  [i in D] {
    atomic {
      keyBuff1(buffer(i), 0) -= 1;
      keyArray(keyBuff1(buffer(i), 0)) = 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;
}