Updated with commments added during the HPCC
benchmarks meeting held today.

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

// BLC: Change cast to int into mask against high bit
// BLC: Implement a timer class and insert calls

const POLY = 0x0000000000000007u;  // BLC: should be param, but causes error

config const totMemSize = 1000u;
config const logTableSize = computeLogTableSize(totMemSize);
const tableSize = 1 << logTableSize;

config const verify = true;
config const debug = false;

// BLC: note the prevalence of the n-1 upper bound motif
const tableDom = [0..tableSize:int-1];    // BLC: unfortunate cast
var Table: [tableDom] uint;

const numUpdates = 4*tableSize;
const updateDom = [0..numUpdates:int-1];  // BLC: unfortunate cast

def main() {
  writeln("Main table size = 2**", logTableSize, " = ", tableSize, " words");
  writeln("Number of updates = ", numUpdates);

  randomAccessUpdate();

  if (verify) then verifyResults();
}

// BLC: eliminate Ran array -- replace with per-thread local variable

def randomAccessUpdate() {
  // BLC: would prefer the following line to be Table = tableDom;
  [i in tableDom] Table(i) = i:uint;      // BLC: unfortunate cast

  if debug then writeln("Table is: ", Table);

  // BLC: is it legal to make a config const/var local to a function?
  config const numRandoms = 128;
  var ranDom = [0..numRandoms-1];
  // BLC: Would prefer this initialization to be:
  // var Ran: [i in ranDom] uint = HPCCstarts((numUpdates/numRandoms) * i);
  var Ran: [ranDom] uint;
  // BLC: writing the following line results in the promotion-to-float problem
  // [i in ranDom] Ran(i) = HPCCstarts((numUpdates/numRandoms) * i);
  // BLC: resulting in the following unfortunate cast:
  // BLC: Getting the ambiguity declared is priority #1 for me
  //      -- I've made this mistake too many times now
  [i in ranDom] Ran(i) = HPCCstarts(((numUpdates:int/numRandoms) * i));

  if debug then writeln("Ran is: ", Ran);

  for i in updateDom by numRandoms {
    forall j in ranDom {
      // BLC: This appears everywhere.  Might be nice to make it a macro-ish thing?
      Ran(j) = (Ran(j) << 1) ^ (if Ran(j):int < 0 then POLY else 0u);
      Table((Ran(j) & (tableSize-1)):int) ^= Ran(j); // BLC: unfortunate cast
    }
  }

  if debug then writeln("Table = ", Table);
}

def verifyResults() {
  config const errorTolerance = 0.01;

  var temp = 0x1u;  // BLC: Can we rename this?
  for i in updateDom {
    temp = (temp << 1) ^ (if (temp:int < 0) then POLY else 0u);
    Table((temp & (tableSize-1)):int) ^= temp;  // BLC: unforunate cast
  }

  var numErrors = 0;
  for i in tableDom {
    if (Table(i) != i) then
      numErrors += 1;
  }

  write("Found ", numErrors, " errors in ", tableSize, " locations ");
  if (numErrors <= errorTolerance*tableSize) {
    writeln("(passed)");
  } else {
    writeln("(failed)");
  }
}

// BLC: would really like n to be intent "in" so that it can be
// modified rather than being copied into n2
def HPCCstarts(n:int) {
  param period = 1317624576693539401;

  var n2 = n;
  while (n2 < 0) do
    n2 += period;
  while (n2 > period) do
    n2 -= period;
  if (n2 == 0) then return 0x1u;

  param m2DomSize = 64; // BLC: this is a magic number -- better name?
  var m2Dom = [0..m2DomSize-1];
  var m2: [m2Dom] uint;

  // BLC: isn't this redundantly computing the same array m2 over and
  // over again?
  var temp = 0x1u;  // BLC: is there a better name for this?
  for i in m2Dom {
    m2(i) = temp;
    temp = (temp << 1) ^ (if temp:int < 0 then POLY else 0u);
    temp = (temp << 1) ^ (if temp:int < 0 then POLY else 0u);
  }

  var high = 62;    // BLC: magic number -- name?
  while (n2 >> high) & 1 == 0 do
    high -= 1;

  var ran = 0x2u;
  forall i in 0..high-1 by -1 {
    var temp = 0u;  // BLC: is there a better name for this?
    for j in m2Dom {
      if ((ran >> j:uint) & 1) then temp ^= m2(j); // BLC: unfortunate cast
    }
    ran = temp;
    if ((n2 >> i) & 1) {
      ran = (ran << 1) ^ (if ran:int < 0 then POLY else 0u);
    }
  }
  return ran;
}

// BLC: could replace this all by some sort of bpop + bit search
// function?
def computeLogTableSize(memsize) {
  param tableElemSize = 8;  // BLC: magic number == sizeof(uint)

  var elemsInTable = memsize / tableElemSize;
  var logTableSize = 0u;

  while (elemsInTable > 1) {
    elemsInTable /= 2;
    logTableSize += 1;
  }

  return logTableSize;
}

const POLY = 0x0000000000000007u;  // BLC: should be param, but causes error

config const totMemSize = 1000u;
config const logTableSize = computeLogTableSize(totMemSize);
const tableSize = 1 << logTableSize;

config const verify = true;
config const debug = false;

const tableDom = [0..tableSize:int-1];    // BLC: unfortunate cast
var Table: [tableDom] uint;

const numUpdates = 4*tableSize;
const updateDom = [0..numUpdates:int-1];  // BLC: unfortunate cast

def main() {
  writeln("Main table size = 2**", logTableSize, " = ", tableSize, " words");
  writeln("Number of updates = ", numUpdates);

  randomAccessUpdate();

  if (verify) then verifyResults();
}

def randomAccessUpdate() {
  // BLC: would prefer the following line to be Table = tableDom;
  [i in tableDom] Table(i) = i:uint;      // BLC: unfortunate cast

  if debug then writeln("Table is: ", Table);

  // BLC: is it legal to make a config const/var local to a function?
  config const numRandoms = 128;
  var ranDom = [0..numRandoms-1];
  // BLC: Would prefer this initialization to be:
  // var Ran: [i in ranDom] uint = HPCCstarts((numUpdates/numRandoms) * i);
  var Ran: [ranDom] uint;
  // BLC: writing the following line results in the promotion-to-float problem
  // [i in ranDom] Ran(i) = HPCCstarts((numUpdates/numRandoms) * i);
  // BLC: resulting in the following unfortunate cast:
  // BLC: Getting the ambiguity declared is priority #1 for me
  //      -- I've made this mistake too many times now
  [i in ranDom] Ran(i) = HPCCstarts(((numUpdates:int/numRandoms) * i));

  if debug then writeln("Ran is: ", Ran);

  forall i in updateDom by numRandoms {
    forall j in ranDom {
      // This appears everywhere.  Might be nice to make it a macro-ish thing?
      Ran(j) = (Ran(j) << 1) ^ (if Ran(j):int < 0 then POLY else 0u);
      Table((Ran(j) & (tableSize-1)):int) ^= Ran(j); // BLC: unfortunate cast
    }
  }

  if debug then writeln("Table = ", Table);
}

def verifyResults() {
  config const errorTolerance = 0.01;

  var temp = 0x1u;  // BLC: Can we rename this?
  for i in updateDom {
    temp = (temp << 1) ^ (if (temp:int < 0) then POLY else 0u);
    Table((temp & (tableSize-1)):int) ^= temp;  // BLC: unforunate cast
  }

  var numErrors = 0;
  for i in tableDom {
    if (Table(i) != i) then
      numErrors += 1;
  }

  write("Found ", numErrors, " errors in ", tableSize, " locations ");
  if (numErrors <= errorTolerance*tableSize) {
    writeln("(passed)");
  } else {
    writeln("(failed)");
  }
}

// BLC: would really like n to be intent "in" so that it can be
// modified rather than being copied into n2
def HPCCstarts(n:int) {
  param period = 1317624576693539401;

  var n2 = n;
  while (n2 < 0) do
    n2 += period;
  while (n2 > period) do
    n2 -= period;
  if (n2 == 0) then return 0x1u;

  param m2DomSize = 64; // BLC: this is a magic number -- better name?
  var m2Dom = [0..m2DomSize-1];
  var m2: [m2Dom] uint;

  // BLC: isn't this redundantly computing the same array m2 over and
  // over again?
  var temp = 0x1u;  // BLC: is there a better name for this?
  for i in m2Dom {
    m2(i) = temp;
    temp = (temp << 1) ^ (if temp:int < 0 then POLY else 0u);
    temp = (temp << 1) ^ (if temp:int < 0 then POLY else 0u);
  }

  var high = 62;  // BLC: magic number -- name?
  while (n2 >> high) & 1 == 0 do
    high -= 1;

  var ran = 0x2u;
  forall i in 0..high-1 by -1 {
    var temp = 0u;  // BLC: is there a better name for this?
    for j in m2Dom {
      if ((ran >> j:uint) & 1) then temp ^= m2(j); // BLC: unfortunate cast
    }
    ran = temp;
    if ((n2 >> i) & 1) {
      ran = (ran << 1) ^ (if ran:int < 0 then POLY else 0u);
    }
  }
  return ran;
}

def computeLogTableSize(memsize) {
  param tableElemSize = 8;

  var elemsInTable = memsize / tableElemSize;
  var logTableSize = 0u;

  while (elemsInTable > 1) {
    elemsInTable /= 2;
    logTableSize += 1;
  }

  return logTableSize;
}


Forgot to update this file

Forgot to update this file

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

/*
 * The Computer Language Benchmarks Game
 * http://shootout.alioth.debian.org/
 *
 * Original C contributed by Sebastien Loisel
 * Conversion to Chapel by Albert Sidelnik
 * Updated by Lydia Duncan
 */

config const n = 500 : int(64);

/* Return: 1.0 / (i + j) * (i + j +1) / 2 + i + 1; */
inline proc eval_A(i,j) : real
{
  /*
   * 1.0 / (i + j) * (i + j +1) / 2 + i + 1;
   * n * (n+1) is even number. Therefore, just (>> 1) for (/2)
   */
  const d = (((i + j) * (i + j + 1)) >> 1) + i + 1;
  return 1.0 / d;
}

proc eval_A_times_u(U : [] real, inRange, Au : [] real)
{
  forall i in 0..#inRange do {
    Au(i) = + reduce [j in 0..#inRange] (U(j) * eval_A(i,j));
  }
}

proc eval_At_times_u(U : [] real, inRange, Au : [] real)
{
  forall i in 0..#inRange do {
    Au(i) = + reduce [j in 0..#inRange] (U(j) * eval_A(j,i));
  }
}

proc eval_AtA_times_u(u,AtAu,v : [] real, inRange)
{
     eval_A_times_u(u, inRange, v);
     eval_At_times_u(v, inRange, AtAu);
}

proc main() {
  var tmp, U, V : [0..#n] real;

  U = 1.0;

  for 1..10 do {
    eval_AtA_times_u(U,V,tmp,n);
    eval_AtA_times_u(V,U,tmp,n);
  }

  const vv = + reduce [v in V] (v * v);
  const vBv = + reduce [(u,v) in zip(U,V)] (u * v);

  const res = sqrt(vBv/vv);
  writeln(res, new iostyle(precision=10));
}

/*
 * The Computer Language Benchmarks Game
 * http://shootout.alioth.debian.org/
 *
 * Original C contributed by Sebastien Loisel
 * Conversion to Chapel by Albert Sidelnik
 * Updated by Lydia Duncan
 */

config const NUM = 500 : int(64);

/* Return: 1.0 / (i + j) * (i + j +1) / 2 + i + 1; */
inline proc eval_A(i,j) : real
{
  /*
   * 1.0 / (i + j) * (i + j +1) / 2 + i + 1;
   * n * (n+1) is even number. Therefore, just (>> 1) for (/2)
   */
  const d = (((i + j) * (i + j + 1)) >> 1) + i + 1;
  return 1.0 / d;
}

proc eval_A_times_u(U : [] real, inRange, Au : [] real)
{
  forall i in 0..#inRange do {
    Au(i) = + reduce [j in 0..#inRange] (U(j) * eval_A(i,j));
  }
}

proc eval_At_times_u(U : [] real, inRange, Au : [] real)
{
  forall i in 0..#inRange do {
    Au(i) = + reduce [j in 0..#inRange] (U(j) * eval_A(j,i));
  }
}

proc eval_AtA_times_u(u,AtAu,v : [] real, inRange)
{
     eval_A_times_u(u, inRange, v);
     eval_At_times_u(v, inRange, AtAu);
}

proc spectral_game(N) : real
{
  var tmp, U, V : [0..#N] real;

  U = 1.0;

  for 1..10 do {
    eval_AtA_times_u(U,V,tmp,N);
    eval_AtA_times_u(V,U,tmp,N);
  }

  const vv = + reduce [v in V] (v * v);
  const vBv = + reduce [(u,v) in zip(U,V)] (u * v);

  return sqrt(vBv/vv);
}

proc main() {
  writeln(spectral_game(NUM), new iostyle(precision=10));
}


Made .future test use += on syncs as intended.

This is only an issue because += has alternative semantics on domains.

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

use Time;

var j: sync int;
var count: sync int = 0;
var done = false;

var a,b: [1..3] int;
a = 0;

for i in 1..3 {
  j = i;
  var k = i;
  begin {
    a(i) = j;
    b(i) = k;
    count += 1;
  }
}

while !done {
  if (readXX(count) == 3) {
    writeln(a);
    writeln(b);
    done = true;
  }
}

use Time;

var j: sync int;
var count: sync int = 0;
var done = false;

var a,b: [1..3] int;
a = 0;

for i in 1..3 {
  j = i;
  var k = i;
  begin {
    a(i) = j;
    b(i) = k;
    count = count + 1;
  }
}

while !done {
  if (readXX(count) == 3) {
    writeln(a);
    writeln(b);
    done = true;
  }
}