8 - largest product in a series

8 - largest product in a series

error: pathspec '008.chpl' did not match any file(s) known to git


14 - longest collatz sequence

14 - longest collatz sequence

/*
 * Longest Collatz sequence
 */

config const maxStart = 1000000,
  printSeq = false;

proc main() {
  var maxCount, startNum: atomic int;

  forall i in 1..maxStart-1 {
    var count = countCollatz(i);
    if count > maxCount.read() {
      maxCount.write(count);
      startNum.write(i);
    }
  }

  const answer = startNum.read();
  if printSeq then
    printCollatz(answer);
  writeln(answer);
}

// Yield each number in the Collatz sequence starting with n and ending with 1.
iter collatz(n) {
  var current = n;

  while (current >= 1) {
    yield current;
    if current == 1 {
      break;
    } else if current % 2 == 0 {
      current = current / 2;
    } else {
      current = 3 * current + 1;
    }
  }
}

// Returns the length of the Collatz sequence starting at n.
proc countCollatz(n) {
  var count = 0;
  for i in collatz(n) {
    count += 1;
  }
  return count;
}

// Print the Collatz sequence.
proc printCollatz(n) {
  var length = 0;
  write(n, ": ");
  for i in collatz(n) {
    length += 1;
    if i == 1 {
      writeln(i);
    } else {
      write(i, " -> ");
    }
  }
  writeln("length: ", length);
}

error: pathspec '014.chpl' did not match any file(s) known to git


Start building out the FFTW module

Start building out the FFTW module

// Wrapper for FFTW version 3.
module FFTW {

	use SysCTypes;

	// Define the various planner flags
	// See Sec. 4.3.2 of FFTW manual "Planner Flags"
	extern const FFTW_ESTIMATE : c_uint;
	extern const FFTW_MEASURE : c_uint;
	extern const FFTW_PATIENT : c_uint;
	extern const FFTW_EXHAUSTIVE : c_uint;
	extern const FFTW_WISDOM_ONLY : c_uint;
	extern const FFTW_DESTROY_INPUT : c_uint;
	extern const FFTW_PRESERVE_INPUT : c_uint;
	extern const FFTW_UNALIGNED : c_uint;

}

error: pathspec 'test/users/npadmana/FFTW.chpl' did not match any file(s) known to git


Snapshot of a first-draft Filerator module

(Sadly it does not work)

config const debug = false;

module FileratorHelp {
  extern type DIRptr;
  extern type direntptr;
  extern proc opendir(name: c_string): DIRptr;
  extern proc readdir(dirp: DIRptr): direntptr;
  extern proc closedir(dirp: DIRptr): c_int;
  extern proc chpl_rt_isDir(pathname: c_string): c_int;

  proc direntptr.d_name(): c_string {
    extern proc chpl_rt_direntptr_getname(d: direntptr): c_string;

    return chpl_rt_direntptr_getname(this);
  }

  /* Not portable (for example to Debian)
  proc direntptr.isDir() {
    extern proc chpl_rt_direntptr_isDir(d: direntptr): bool;

    return chpl_rt_direntptr_isDir(this);
  }
  */

}

iter listdir(path: string, recur = false, dotfiles=false, nosvn=true): string {
  use FileratorHelp;

  var dir: DIRptr;
  var ent: direntptr;
  //  writeln("***Trying ", path);
  dir = opendir(path:c_string);
  if (!is_c_nil(dir)) {
    ent = readdir(dir);
    while (!is_c_nil(ent)) {
      const filename = ent.d_name();
      if (dotfiles || filename.substring(1) != '.') {
        if (!nosvn || filename != '.svn') {
          const fullpath = path + "/" + filename;
          if (!chpl_rt_isDir(fullpath:c_string)) {
            yield fullpath;
          } else {
            //        writeln("^^^ it's a directory!");
            if recur && filename != "." && filename != ".." {
              //
              // feature request: This is a nice place for a yieldall concept
              //
              for filename in listdir(fullpath, recur, dotfiles) do
                yield filename;
            }
          }
        }
      }
      ent = readdir(dir);
    }
    closedir(dir);
  } else {
    extern proc perror(s: c_string);
    perror("error in listdir(): ");
  }
}

iter walkdirs(path: string=".", topdown=true, depth=max(int), dotfiles=false, followlinks=false): string {
  use FileratorHelp;

  if (topdown) then
    yield path;

  if (depth) {
    var dir: DIRptr;
    var ent: direntptr;
    if debug then
      writeln("***Trying ", path);
    dir = opendir(path:c_string);
    if (!is_c_nil(dir)) {
      ent = readdir(dir);
      while (!is_c_nil(ent)) {
        const filename = ent.d_name();
        if (filename != "." && filename != "..") {
          const fullpath = path + "/" + filename;

          if (chpl_rt_isDir(fullpath:c_string)!=0) {
            if debug then
              writeln("***It's a dir!");
            if (dotfiles || filename.substring(1) != '.') {
              //
              // feature request: This is a nice place for a yieldall concept
              //
              for dirname in walkdirs(fullpath, topdown, depth-1, dotfiles, followlinks) do
                yield dirname;
            }
          }
        }
        ent = readdir(dir);
      }
    } else {
      extern proc perror(s: c_string);
      perror("error in walkdirs(): ");
    }
    closedir(dir);
  }

  if (!topdown) then
    yield path;
}

error: pathspec 'test/studies/filerator/Filerator.chpl' did not match any file(s) known to git


5 - smallest multiple

5 - smallest multiple

/*
 * Smallest multiple
 */

config const rangeMax = 20;

const values: [{1..rangeMax}] int;
forall i in 1..rangeMax {
  values[i] = i;
}

proc isMultiple(value: int, numbers: [] int) {
  for num in numbers {
    if value % num != 0 {
      return false;
    }
  }
  return true;
}

// Return least common multiple for list of ints.
proc lcm(numbers: [] int) {
  var maxNum = max reduce numbers,
    value = maxNum;

  while (!isMultiple(value, numbers)) {
    value += maxNum;
  }

  return value;
}

writeln(lcm(values));

error: pathspec '005.chpl' did not match any file(s) known to git


[WIP] Fixed small syntax error

[WIP] Fixed small syntax error

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/matthewsedam/cryptotrade.git/'


Checking in ReadInputFile module for HPL benchmark.  This module contains
the record HPLparams whose fields are initialized by reading the HPL.dat
input file.

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

enum processmaptype {Row=0, Column};
enum factortype {Left=0, Crout, Right};
enum bcasttype {OneRG=0, OneRM, TwoRG, TwoRM, Lng, LnM};
enum swaptype {BinExchange=0, Long, Mix};
enum transtype {Transpose=0, NonTranspose};
enum equiltype {NoEquilibration=0, Equilibration};

record HPLparams {
  var inFileName = "HPL.dat";

  var outFileName: string,
        deviceOut: int;

  var numProbSizes: int;
  var NDom: domain(1);
  var N: [NDom] int;

  var numBlockSizes: int;
  var NBDom: domain(1);
  var NB: [NBDom] int;

  var pMap: processmaptype;
  var numProcessGrids: int;
  var GridDom: domain(1);
  var P: [GridDom] int;
  var Q: [GridDom] int;

  var Thresh: real;

  var numPanelFacts: int;
  var PFactDom: domain(1);
  var PFact: [PFactDom] factortype;

  var numRecurStops: int;
  var NBMinDom: domain(1);
  var NBMin: [NBMinDom] int;

  var numPanels: int;
  var NDivDom: domain(1);
  var NDiv: [NDivDom] int;

  var numRecurPanelFacts: int;
  var RFactDom: domain(1);
  var RFact: [RFactDom] factortype;

  var numBCasts: int;
  var BCastDom: domain(1);
  var BCast: [BCastDom] bcasttype;

  var numDepths: int;
  var DepthDom: domain(1);
  var Depth: [DepthDom] int;

  var Swap: swaptype;
  var swapThresh: int;
  var L1, U: transtype;
  var memAlign: int;

  def initialize() {
     var infile = file(inFileName, path='./', mode='r');

     infile.open();
     infile.readln();
     infile.readln();
     infile.readln(outFileName);
     infile.readln(deviceOut);
     infile.readln(numProbSizes);
     NDom = [1..numProbSizes];
     for n in N do infile.read(n);
     infile.readln();

     infile.readln(numBlockSizes);
     NBDom = [1..numBlockSizes];
     for nb in NB do infile.read(nb);
     infile.readln();

     pMap = infile.readln(int):processmaptype;

     infile.readln(numProcessGrids);
     GridDom = [1..numProcessGrids];
     for p in P do infile.read(p);
     infile.readln();
     for q in Q do infile.read(q);
     infile.readln();

     infile.readln(Thresh);

     infile.readln(numPanelFacts);
     PFactDom = [1..numPanelFacts];
     for pf in PFact do pf = infile.read(int):factortype;
     infile.readln();

     infile.readln(numRecurStops);
     NBMinDom = [1..numRecurStops];
     for nbmin in NBMin do infile.read(nbmin);
     infile.readln();

     infile.readln(numPanels);
     NDivDom = [1..numPanels];
     for nd in NDiv do infile.read(nd);
     infile.readln();

     infile.readln(numRecurPanelFacts);
     RFactDom = [1..numRecurPanelFacts];
     for rf in RFact do rf = infile.read(int):factortype;
     infile.readln();

     infile.readln(numBCasts);
     BCastDom = [1..numBCasts];
     for bc in BCast do bc = infile.read(int):bcasttype;
     infile.readln();

     infile.readln(numDepths);
     DepthDom = [1..numDepths];
     for d in Depth do d = infile.read(int);
     infile.readln();

     Swap = infile.readln(int):swaptype;
     infile.readln(swapThresh);
     L1 = infile.readln(int):transtype;
     U = infile.readln(int): transtype;
     infile.readln(memAlign);
     infile.close();
  }
}

error: pathspec 'test/studies/hpcc/HPL/marybeth/ReadInputFile.chpl' did not match any file(s) known to git


First stab at directory-only walker

First stab at directory-only walker

config const debug = false;

iter walkdirs(path: string=".", topdown=true, depth=max(int), dotfiles=false, followlinks=false): string {
  extern type DIRptr;
  extern type direntptr;
  extern proc opendir(name: c_string): DIRptr;
  extern proc readdir(dirp: DIRptr): direntptr;
  extern proc closedir(dirp: DIRptr): c_int;

  proc direntptr.d_name(): c_string {
    extern proc chpl_rt_direntptr_getname(d: direntptr): c_string;

    return chpl_rt_direntptr_getname(this);
  }

  proc direntptr.isDir() {
    extern proc chpl_rt_direntptr_isDir(d: direntptr): bool;

    return chpl_rt_direntptr_isDir(this);
  }

  if (topdown) then
    yield path;

  if (depth) {
    var dir: DIRptr;
    var ent: direntptr;
    if debug then
      writeln("***Trying ", path);
    dir = opendir(path:c_string);
    if (!is_c_nil(dir)) {
      ent = readdir(dir);
      while (!is_c_nil(ent)) {
        const filename = ent.d_name();
        if (ent.isDir() && filename != "." && filename != "..") {
          if debug then
            writeln("***It's a dir!");
          if (dotfiles || filename.substring(1) != '.') {
            const fullpath = path + "/" + filename;
            //
            // feature request: This is a nice place for a yieldall concept
            //
            for dirname in walkdirs(fullpath, topdown, depth-1, dotfiles, followlinks) do
              yield dirname;
          }
        }
        ent = readdir(dir);
      }
    } else {
      extern proc perror(s: c_string);
      perror("error in walkdirs(): ");
    }
    closedir(dir);
  }

  if (!topdown) then
    yield path;
}

iter sorted(x) {
  use Sort;

  var y = x;
  QuickSort(y);
  for i in y do
    yield i;
}

config const startdir = "subdir";
config const topdown = true;
config const depth = max(int);
config const dotfiles = false;
config const followlinks = false;

config const sort = true;
config const defaults = false;

if defaults then
  if sort then
    for filename in sorted(walkdirs()) do
      writeln(filename);
 else
   for filename in walkdirs() do
     writeln(filename);
else
  if sort then
    for filename in sorted(walkdirs(startdir, topdown, depth, dotfiles, followlinks)) do
      writeln(filename);
 else
   for filename in walkdirs(startdir, topdown, depth, dotfiles, followlinks) do
     writeln(filename);

error: pathspec 'test/studies/filerator/walk.chpl' did not match any file(s) known to git


Add "VisualDebug" (May not be final name.) code to comm routines and to get it started.  This is implemented similar to CommDiagnostics.

/*
 * Copyright 2015 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// VisualDebug.chpl
//
pragma "no use ChapelStandard"
module VisualDebug
{

  use String;

  //
  // Data Generation for the Visual Debug tool  (offline)
  //

  extern proc chpl_vdebug_start ( rootname: c_string);
  extern proc chpl_vdebug_stop ();

  proc startVdebug ( rootname : string ) {
    forall l in Locales do
      on l do chpl_vdebug_start (rootname.c_str());
  }

  proc stopVdebug () {
    forall l in Locales do
      on l do chpl_vdebug_stop();
  }

}

error: pathspec 'modules/standard/VisualDebug.chpl' did not match any file(s) known to git


Fix off-by-one error in bfile fibonacci example.

Running examples/chapel.bfile.fib.py produced the output 89 as the 10th
fibonacci number, which is not correct.  That is the 11th fibonacci number.
The error arose from using 0 to n as the traversal (n+1 numbers), instead of 1
to n (n numbers).  While I was there, I removed the unnecessary traversal
variable i, since for loops can function without storing their iteration if it
isn't used by the body.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/russel/pychapel.git/'


add simple helloworld.chpl

add simple helloworld.chpl

use SearchIndex;

proc main() {

    writeln("initialize search index");

    initPartitions();

    writeln("add document id 10 with terms 2 and 3");

    var terms: [0..1] IndexTerm;
    terms[0].term = 2;
    terms[0].textLocation = 6;
    terms[1].term = 3;
    terms[1].textLocation = 15;
    addDocument(terms, 10);

    // create CHASM instruction buffer
    var buffer = new InstructionBuffer(1024);
    var writer = new InstructionWriter(buffer);

    // write the CHASM code to implement the query
    writeln("querying for term IDs 2");
    writer.write_push_term(2);
    for result in query(new Query(buffer)) {
        writeln(result);
    }

    writeln("querying for term IDs 3");
    buffer.clear();
    writer.write_push_term(3);
    for result in query(new Query(buffer)) {
        writeln(result);
    }

    writeln("querying for term IDs 2 OR 3");
    buffer.clear();
    writer.write_push_term(2);
    writer.write_push_term(3);
    writer.write_or();
    for result in query(new Query(buffer)) {
        writeln(result);
    }

    delete buffer;
}

error: pathspec 'test/helloworld.chpl' did not match any file(s) known to git


copy skeleton (no function blocks) of BitOps.chpl into docs-test.

/*
 * Copyright 2004-2015 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 *  Bit Manipulation Functions
 */
module BitOps {

  /*
    count leading zeros

    :arg x: unsigned integer of size `bits`; `bits` can be: 8, 16, 32, 64

    :returns: the number of 0 bits before the most significant 1 bit in `x` as
              `x.type`
   */
  inline proc clz(x: uint(?bits)): uint(bits) {
  }

  /*
    count leading zeros

    :arg x: integer of size `bits`; `bits` can be: 8, 16, 32, 64

    :returns: the number of 0 bits before the most significant 1 bit in `x` as
              `x.type`
   */
  inline proc clz(x: int(?bits)) {
  }

  /*
    count trailing zeros

    :arg x: unsigned integer of size `bits`; `bits` can be: 8, 16, 32, 64

    :returns: the number of 0 bits after the least significant 1 bit in `x` as
              `x.type`
   */
  inline proc ctz(x: uint(?bits)) {
  }

  /*
    count trailing zeros

    :arg x: integer of size `bits`; `bits` can be: 8, 16, 32, 64

    :returns: the number of 0 bits after the least significant 1 bit in `x` as
              `x.type`
   */
  inline proc ctz(x: int(?bits)) {
  }

  /*
    population count

    :arg x: unsigned integer of size `bits`; `bits` can be: 8, 16, 32, 64

    :returns: the number of 1 bits set in `x` as `x.type`
   */
  inline proc popcount(x: uint(?bits)): uint(bits) {
  }

  /*
    population count

    :arg x: integer of size `bits`; `bits` can be: 8, 16, 32, 64

    :returns: the number of 1 bits set in `x` as `x.type`
   */
  inline proc popcount(x: int(?bits)): int(bits) {
  }

  // Legacy operations
  // -----------------
  // kyleb: a few tests use these, but I'm not sure if there too much value

  // do a bitwise matrix-multiplication of x and y treating
  // them as 8x8 bit matrices and using | as the combinator
  // function.  There should be a similar version using xor
  // as the combinator, but I'm not sure where that would
  // go to be perfectly truthful
  proc bitMatMultOr(x: uint(64), y: uint(64)): uint(64) {
  }

  inline proc bitRotLeft(x, shift) {
  }

  inline proc bitRotRight(x: uint(64), shift) {
  }
}

/**
 * module to hide the extern procedures
 */
module BitOps_internal {
  extern proc chpl_bitops_popcount_32(x: c_uint) : uint(32);
  extern proc chpl_bitops_popcount_64(x: c_ulonglong) : uint(64);

  extern proc chpl_bitops_clz_32(x: c_uint) : uint(32);
  extern proc chpl_bitops_clz_64(x: c_ulonglong) : uint(64);

  extern proc chpl_bitops_ctz_32(x: c_uint) : uint(32);
  extern proc chpl_bitops_ctz_64(x: c_ulonglong) : uint(64);
}

error: pathspec 'doc-test/BitOps.chpl' did not match any file(s) known to git


Missed a file on the last commit...

Missed a file on the last commit...

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

//===> Description ===>
//
// Definitions for an advection/CTU solver on a
// RefinementLevel.
//
//<=== Description <===

use grid_base_defs;
use level_base_defs;
use grid_ctu_defs;

//===> BaseLevel.stepCTU method ===>
//=================================>
def BaseLevel.stepCTU(lev_sol:  LevelSolution,
                      lev_bc:   LevelBC,
                      velocity: dimension*real,
                      dt:       real
                     ){

  //==== Fill ghost cells using boundary condition ====
  lev_bc.ghostFill(lev_sol);

  //==== Now fill ghost cells overlapped by neighbor grids ====
  coforall grid in child_grids {
    grid.copyFromNeighbors(lev_sol.child_sols(grid));
  }

  //==== Take a time step on each grid ====
  coforall grid in child_grids {
    grid.stepCTU(lev_sol.child_sols(grid),
		 velocity,
		 dt);
  }

  //==== Update time ====
  lev_sol.time += dt;

}
//<=================================
//<=== BaseLevel.stepCTU method <===

error: pathspec 'test/studies/amr/lib/level_ctu_defs.chpl' did not match any file(s) known to git


Fixes Issue #48 (#52)

Fixes Issue #48 (#52)

 * GMP now works


Adding capability to sort in reverse

Adding capability to sort in reverse

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

inline proc chpl_sort_cmp(a, b, reverse=false, eq=false) {
  if eq {
    if reverse then return a >= b;
    else return a <= b;
  } else {
    if reverse then return a > b;
    else return a < b;
  }
}

proc HeapSort(Data: [?Dom] ?elType, doublecheck=false, reverse=false) where Dom.rank == 1 {
  const lo = Dom.dim(1).low;
  const hi = Dom.dim(1).high;
  const len = Dom.dim(1).size;

  // heapify
  var start = (len - 2) / 2 + lo;
  while (start >= lo) {
    SiftDown(start, hi);
    start = start - 1;
  }

  // sort, moving max element to end and re-heapifying the rest
  var end = hi;
  while (end > lo) {
    Data(end) <=> Data(lo);
    end = end - 1;
    SiftDown(lo, end);
  }

  proc SiftDown(start, end) {
    var root = start;
    while (root * 2 + 1 - lo <= end) {
      const child = root * 2 + 1 - lo;
      var swap = root;
      if chpl_sort_cmp(Data(swap), Data(child), reverse) then swap = child;
      if (child + 1 <= end) && (chpl_sort_cmp(Data(swap), Data(child + 1), reverse)) then swap = child + 1;
      if swap != root {
        Data(root) <=> Data(swap);
        root = swap;
      } else {
        return;
      }
    }
  }
  if (doublecheck) then VerifySort(Data, "HeapSort", reverse);
}

proc BubbleSort(Data: [?Dom] ?elType, doublecheck=false, reverse=false) where Dom.rank == 1 {
  const lo = Dom.dim(1).low;
  const hi = Dom.dim(1).high;
  var swapped = true;

  while (swapped) {
    swapped = false;
    for i in lo..hi-1 {
      if !chpl_sort_cmp(Data(i), Data(i+1), reverse, true) {
        Data(i) <=> Data(i+1);
        swapped = true;
      }
    }
  }

  if (doublecheck) then VerifySort(Data, "BubbleSort", reverse);
}

proc InsertionSort(Data: [?Dom] ?elType, doublecheck=false, reverse=false) where Dom.rank == 1 {
  const lo = Dom.low;
  for i in Dom {
    const ithVal = Data(i);
    var inserted = false;
    for j in lo..i-1 by -1 {
      if (chpl_sort_cmp(ithVal, Data(j), reverse)) {
        Data(j+1) = Data(j);
      } else {
        Data(j+1) = ithVal;
        inserted = true;
        break;
      }
    }
    if (!inserted) {
      Data(lo) = ithVal;
    }
  }

  if (doublecheck) then VerifySort(Data, "InsertionSort", reverse);
}

proc MergeSort(Data: [?Dom], minlen=16, doublecheck=false, reverse=false) where Dom.rank == 1 {
  _MergeSort(Data, minlen, reverse=reverse);
  if (doublecheck) then VerifySort(Data, "MergeSort", reverse);
}

proc _MergeSort(Data: [?Dom], minlen=16, reverse=false) where Dom.rank == 1 {
  const lo = Dom.dim(1).low;
  const hi = Dom.dim(1).high;

  if hi-lo < minlen {
    InsertionSort(Data, reverse=reverse);
    return;
  }
  const mid = (hi-lo)/2+lo;
  var A1 = Data[lo..mid];
  var A2 = Data[mid+1..hi];
  cobegin {
    { _MergeSort(A1, minlen, reverse=reverse); }
    { _MergeSort(A2, minlen, reverse=reverse); }
  }

  for (a, _a) in zip(Data[lo..hi], _MergeIterator(A1, A2, reverse=reverse)) do a = _a;
}

iter _MergeIterator(A1: [] ?elType, A2: [] elType, reverse=false) {
  var a1 = A1.domain.dim(1).low;
  const a1hi = A1.domain.dim(1).high;
  var a2 = A2.domain.dim(1).low;
  const a2hi = A2.domain.dim(1).high;
  while ((a1 <= a1hi) && (a2 <= a2hi)) {
    while (chpl_sort_cmp(A1(a1) ,A2(a2), reverse, true)) {
      yield A1(a1);
      a1 += 1;
      if a1 > a1hi then break;
    }
    if a1 > a1hi then break;
    while (chpl_sort_cmp(A2(a2), A1(a1), reverse, true)) {
      yield A2(a2);
      a2 += 1;
      if a2 > a2hi then break;
    }
  }
  if a1 == a1hi then yield A1(a1);
  else if a2 == a2hi then yield A2(a2);
  if a1 < a1hi then for a in A1[a1..a1hi] do yield a;
  else if a2 < a2hi then for a in A2[a2..a2hi] do yield a;
}

proc QuickSort(Data: [?Dom] ?elType, minlen=16, doublecheck=false, reverse=false) where Dom.rank == 1 {
  // grab obvious indices
  const lo = Dom.low,
        hi = Dom.high,
        mid = lo + (hi-lo+1)/2;

  // base case -- use insertion sort
  if (hi - lo < minlen) {
    InsertionSort(Data, reverse=reverse);
    return;
  }

  // find pivot using median-of-3 method
  if (chpl_sort_cmp(Data(mid), Data(lo), reverse)) then Data(mid) <=> Data(lo);
  if (chpl_sort_cmp(Data(hi), Data(lo), reverse)) then Data(hi) <=> Data(lo);
  if (chpl_sort_cmp(Data(hi), Data(mid), reverse)) then Data(hi) <=> Data(mid);
  const pivotVal = Data(mid);
  Data(mid) = Data(hi-1);
  Data(hi-1) = pivotVal;
  // end median-of-3 partitioning

  var loptr = lo,
      hiptr = hi-1;
  while (loptr < hiptr) {
    do { loptr += 1; } while (chpl_sort_cmp(Data(loptr), pivotVal, reverse));
    do { hiptr -= 1; } while (chpl_sort_cmp(pivotVal, Data(hiptr), reverse));
    if (loptr < hiptr) {
      Data(loptr) <=> Data(hiptr);
    }
  }

  Data(hi-1) = Data(loptr);
  Data(loptr) = pivotVal;

  //  cobegin {
    QuickSort(Data[..loptr-1], reverse=reverse);  // could use unbounded ranges here
    QuickSort(Data[loptr+1..], reverse=reverse);
    //  }

  if (doublecheck) then VerifySort(Data, "QuickSort", reverse);
}

proc SelectionSort(Data: [?Dom], doublecheck=false, reverse=false) where Dom.rank == 1 {
  const lo = Dom.dim(1).low;
  const hi = Dom.dim(1).high;
  for i in lo..hi-1 {
    var (_, loc) = if reverse then maxloc reduce zip(Data[i..hi], {i..hi})
      else minloc reduce zip(Data[i..hi], {i..hi});
    Data(i) <=> Data(loc);
  }

  if (doublecheck) then VerifySort(Data, "SelectionSort", reverse);
}

inline proc VerifySort(Data: [?Dom] ?elType, str: string, reverse=false) {
  for i in Dom.low..Dom.high-1 do
    if chpl_sort_cmp(Data(i+1), Data(i), reverse) then
      halt(str, " did not sort properly (", i, "): ", Data);
}

proc HeapSort(Data: [?Dom], doublecheck=false) where Dom.rank == 1 {
  const lo = Dom.dim(1).low;
  const hi = Dom.dim(1).high;
  const len = Dom.dim(1).size;

  // heapify
  var start = (len - 2) / 2 + lo;
  while (start >= lo) {
    SiftDown(start, hi);
    start = start - 1;
  }

  // sort, moving max element to end and re-heapifying the rest
  var end = hi;
  while (end > lo) {
    Data(end) <=> Data(lo);
    end = end - 1;
    SiftDown(lo, end);
  }

  proc SiftDown(start, end) {
    var root = start;
    while (root * 2 + 1 - lo <= end) {
      const child = root * 2 + 1 - lo;
      var swap = root;
      if Data(swap) < Data(child) then swap = child;
      if (child + 1 <= end) && (Data(swap) < Data(child + 1)) then swap = child + 1;
      if swap != root {
        Data(root) <=> Data(swap);
        root = swap;
      } else {
        return;
      }
    }
  }
  if (doublecheck) then VerifySort(Data, "HeapSort");
}

proc BubbleSort(Data: [?Dom], doublecheck=false) where Dom.rank == 1 {
  const lo = Dom.dim(1).low;
  const hi = Dom.dim(1).high;
  var swapped = true;
  while (swapped) {
    swapped = false;
    for i in lo..hi-1 {
      if Data(i) > Data(i+1) {
        Data(i) <=> Data(i+1);
        swapped = true;
      }
    }
  }

  if (doublecheck) then VerifySort(Data, "BubbleSort");
}

proc InsertionSort(Data: [?Dom], doublecheck=false) where Dom.rank == 1 {
  const lo = Dom.low;
  for i in Dom {
    const ithVal = Data(i);
    var inserted = false;
    for j in lo..i-1 by -1 {
      if (ithVal < Data(j)) {
        Data(j+1) = Data(j);
      } else {
        Data(j+1) = ithVal;
        inserted = true;
        break;
      }
    }
    if (!inserted) {
      Data(lo) = ithVal;
    }
  }

  if (doublecheck) then VerifySort(Data, "InsertionSort");
}

proc MergeSort(Data: [?Dom], minlen=16, doublecheck=false) where Dom.rank == 1 {
  _MergeSort(Data, minlen);
  if (doublecheck) then VerifySort(Data, "MergeSort");
}

proc _MergeSort(Data: [?Dom], minlen=16) where Dom.rank == 1 {
  const lo = Dom.dim(1).low;
  const hi = Dom.dim(1).high;

  if hi-lo < minlen {
    InsertionSort(Data);
    return;
  }
  const mid = (hi-lo)/2+lo;
  var A1 = Data[lo..mid];
  var A2 = Data[mid+1..hi];
  cobegin {
    { _MergeSort(A1, minlen); }
    { _MergeSort(A2, minlen); }
  }

  for (a, _a) in zip(Data[lo..hi], _MergeIterator(A1, A2)) do a = _a;
}

iter _MergeIterator(A1: [], A2: []) {
  var a1 = A1.domain.dim(1).low;
  const a1hi = A1.domain.dim(1).high;
  var a2 = A2.domain.dim(1).low;
  const a2hi = A2.domain.dim(1).high;
  while ((a1 <= a1hi) && (a2 <= a2hi)) {
    while (A1(a1) <= A2(a2)) {
      yield A1(a1);
      a1 += 1;
      if a1 > a1hi then break;
    }
    if a1 > a1hi then break;
    while (A2(a2) < A1(a1)) {
      yield A2(a2);
      a2 += 1;
      if a2 > a2hi then break;
    }
  }
  if a1 == a1hi then yield A1(a1);
  else if a2 == a2hi then yield A2(a2);
  if a1 < a1hi then for a in A1[a1..a1hi] do yield a;
  else if a2 < a2hi then for a in A2[a2..a2hi] do yield a;
}

proc QuickSort(Data: [?Dom], minlen=16, doublecheck=false) where Dom.rank == 1 {
  // grab obvious indices
  const lo = Dom.low,
        hi = Dom.high,
        mid = lo + (hi-lo+1)/2;

  // base case -- use insertion sort
  if (hi - lo < minlen) {
    InsertionSort(Data);
    return;
  }

  // find pivot using median-of-3 method
  if (Data(mid) < Data(lo)) then Data(mid) <=> Data(lo);
  if (Data(hi) < Data(lo)) then Data(hi) <=> Data(lo);
  if (Data(hi) < Data(mid)) then Data(hi) <=> Data(mid);
  const pivotVal = Data(mid);
  Data(mid) = Data(hi-1);
  Data(hi-1) = pivotVal;
  // end median-of-3 partitioning

  var loptr = lo,
      hiptr = hi-1;
  while (loptr < hiptr) {
    do { loptr += 1; } while (Data(loptr) < pivotVal);
    do { hiptr -= 1; } while (pivotVal < Data(hiptr));
    if (loptr < hiptr) {
      Data(loptr) <=> Data(hiptr);
    }
  }

  Data(hi-1) = Data(loptr);
  Data(loptr) = pivotVal;

  //  cobegin {
    QuickSort(Data[..loptr-1]);  // could use unbounded ranges here
    QuickSort(Data[loptr+1..]);
    //  }

  if (doublecheck) then VerifySort(Data, "QuickSort");
}

proc SelectionSort(Data: [?Dom], doublecheck=false) where Dom.rank == 1 {
  const lo = Dom.dim(1).low;
  const hi = Dom.dim(1).high;
  for i in lo..hi-1 {
    var (_, loc) = minloc reduce zip(Data[i..hi], {i..hi});
    Data(i) <=> Data(loc);
  }

  if (doublecheck) then VerifySort(Data, "SelectionSort");
}

inline proc VerifySort(Data: [?Dom], str: string) {
  for i in Dom.low..Dom.high-1 do
    if (Data(i+1) < Data(i)) then
      halt(str, " did not sort properly (", i, "): ", Data);
}


Madness function tree.  Implemented as an (int, int) associative domain.

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

class FTree {
  type coeff_t = real;
  type idx_t   = 2*int;

  var  indices: domain(idx_t);
  var  nodes  : [indices] coeff_t;

  def this(lvl: int, idx: int) var {
    if !indices.member((lvl, idx)) then
      indices += ((lvl, idx));

    return nodes[(lvl, idx)];
  }
}

def main() {
  var f = FTree();

  for (i, j) in [0..2, 0..2] do
    f[i, j] = i*3+j;

  for (i, j) in [0..2, 0..2] do
    writeln("(",i,", ",j,") = ", f[i, j]);
}

error: pathspec 'test/studies/madness/dinan/mad_chapel/FTree.chpl' did not match any file(s) known to git


factor out chearch tcp service mode

factor out chearch tcp service mode

use BatchIndexer, Logging, Memory, LibEv, IO, Random, SearchIndex, Time;

// ****
// NOTE: this is very much in progress
// ****

// TODO: port to pure chapel
extern proc initialize_socket(port: c_int): c_int;

// trampolines
extern var c_accept_cb: opaque;

extern proc send(sockfd:c_int, buffer: c_string, len: size_t, flags: c_int);

config const port: c_int = 3033;
config const post_load_test: bool = false;
config const load_from_partitions: bool = true;

// TODO: we need to know which client context this is so that we can maintain parsing context
//       is the fd enough?
export proc handle_received_data(fd: c_int, buffer: c_string, read: size_t, buffer_size: size_t) {

  // writeln("from chpl: " + buffer);
  // accumulate string buffer
  var word = buffer;
  var trimmedWord: string = "";
  writeln("word: ", word);

  for i in 1..word.length {
    var ch = word.substring(i);
    if (ch != "\r" && ch != "\n") {
      writeln("ch: ", word.substring(i));
      trimmedWord += word.substring(i);
    }
  }

  //  writeln("trimmedWord: ", trimmedWord);
  if (trimmedWord == "dump") {
    // dumpPartition(partitionForWord("dog"));
  } else {
    writeln("<adding>");
    writeln("</adding>");
  }
  send(fd, buffer, read, 0);
}

proc main() {

  writeln("creating socket...");
  var sd: ev_fd = initialize_socket(port);
  writeln("socket id = ", sd);
  if (sd == -1) {
   writeln("socket error");
   return -1;
  }

  writeln("initializing index");
  initPartitions();

  // POPULATE THE INDEX

  var t: Timer;
  t.start();

  startBatchIndexers();
  waitForBatchIndexers();

  t.stop();
  timing("indexing complete in ",t.elapsed(TimeUnits.microseconds), " microseconds");

  writeln("initializing event loop...");

  // port c_accept_cb, c_read_cb
  var w_accept: ev_io = new ev_io();
  ev_io_init(w_accept, c_accept_cb, sd, EV_READ);
  ev_io_start(EV_DEFAULT, w_accept);

  while (1) {
   ev_loop_fn(EV_DEFAULT, 0);
  }
}

error: pathspec 'chearch_srv.chpl' did not match any file(s) known to git


Added serial version file

Added serial version file

//Author Sparsh Mittal sparsh0mittal@gmail.com
//Research paper reference: Sparsh Mittal, "A Study of Successive Over-relaxation Method
//Parallelization Over Modern HPC Languages", International Journal of High
//Performance Computing and Networking, vol. 7, number  4, pp. 292-298, 2014.

use Time;

config const gridSize: int = 4096;
config const INITIAL_GUESS: real = 0.0;
config const MAXSTEPS: int  = 50000;
config const TOL_VAL: real =0.00001;
config const NUM_CHECK: int =4000;

config const omega: real =  0.376;
config const one_minus_omega: real =  1-omega;

var gridInfo: [1..(gridSize+2),1..(gridSize+2)] real ;

proc MAX_FUNC(a: real, b: real): real {
	if (a > b) {
		return a;
}
	return b;
}

proc ABS_VAL(a: real): real {

	if (a > 0) {
		return a;
}
	return -a;
}

//main starts here
writeln("GridSize ",gridSize, " MaxStep ", MAXSTEPS, " Accuracy ", TOL_VAL );

var maxError: real = 0.0;
var hasConverged: bool = false;

for i in 1..(gridSize+2) {
  for j in 1..(gridSize+2) {
              if (i == 1) {
				gridInfo(i,j) = 1.0;
              } else {
				gridInfo(i,j) = INITIAL_GUESS;
              }
  }
}

var sum: real = 0.0;

var timeMeasure:Timer;

timeMeasure.start();
for k in 1..(MAXSTEPS) {

 maxError = 0.0;
       //RED i even, j even
       for i in 2..(gridSize+1) by 2 {
           for j in 2..(gridSize+1) by 2 {
               sum = (gridInfo(i,j+1) + gridInfo(i+1,j) + gridInfo(i-1,j) + gridInfo(i,j-1)) * 0.25;
       	       maxError = MAX_FUNC(ABS_VAL(omega*(sum-gridInfo(i,j))), maxError);
	       gridInfo(i,j) = one_minus_omega*gridInfo(i,j) + omega*sum;
        }
}

         //RED i odd, j odd
       for i in 3..(gridSize+1) by 2 {
           for j in 3..(gridSize+1) by 2 {
               sum = (gridInfo(i,j+1) + gridInfo(i+1,j) + gridInfo(i-1,j) + gridInfo(i,j-1)) * 0.25;
       	       maxError = MAX_FUNC(ABS_VAL(omega*(sum-gridInfo(i,j))), maxError);
	       gridInfo(i,j) = one_minus_omega*gridInfo(i,j) + omega*sum;
}
}

       //Black  i even, j odd
       for i in 2..(gridSize+1) by 2 {
           for j in 3..(gridSize+1) by 2 {
               sum = (gridInfo(i,j+1) + gridInfo(i+1,j) + gridInfo(i-1,j) + gridInfo(i,j-1)) * 0.25;
       	       maxError = MAX_FUNC(ABS_VAL(omega*(sum-gridInfo(i,j))), maxError);
	       gridInfo(i,j) = one_minus_omega*gridInfo(i,j) + omega*sum;
}
}

         //Black i odd, j even
       for i in 3..(gridSize+1) by 2 {
           for j in 2..(gridSize+1) by 2 {
               sum = (gridInfo(i,j+1) + gridInfo(i+1,j) + gridInfo(i-1,j) + gridInfo(i,j-1)) * 0.25;
       	       maxError = MAX_FUNC(ABS_VAL(omega*(sum-gridInfo(i,j))), maxError);
	       gridInfo(i,j) = one_minus_omega*gridInfo(i,j) + omega*sum;
}
}

      if (k%NUM_CHECK == 0) {
			writeln("Iter ", k, " Error ", maxError);
			if (maxError < TOL_VAL) {
				hasConverged = true;
				break;
   }
   }

}

timeMeasure.stop();
writeln(" Time elapsed ", timeMeasure.elapsed());

if( hasConverged) {
writeln("It converged");
} else {
writeln("It did not converge");
}

error: pathspec 'test/studies/Mittal_IJHPCN_SOR/SOR_Serial.chpl' did not match any file(s) known to git


Adding a possible future version BradsBlock1DPar

This is a variation on the current BradsBlock1DPar.chpl
that (a) takes it in a few directions that can't currently
be expected to work (such as using on clauses and parallelism
within the leader iterator), and (b) is incomplete -- for
some of the iterators, I put comments indicating what they
would do rather than writing the code, since it's still
pretty speculative (and the comments are probably clearer
for discussion).

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

// TODO: Have the global class leader/follower iterators defer to the
// local class leader/followers once we're within a locale?

// TODO: Make these into an official distribution?

// TODO: Would using nested classes allow me to avoid so much
// passing around of globIndexType and locIndexType?

config param debugBradsBlock1D = false;

// TODO: This would need to be moved somewhere more standard
enum IteratorType { leader, follower };

//
// The distribution class
//
class Block1DDist {
  //
  // The distribution's index type and domain's global index type
  //
  type glbIdxType = int(64);

  //
  // The bounding box that defines the block distribution
  //
  const boundingBox: domain(1, glbIdxType);

  //
  // a domain and array describing the set of target locales to which
  // the indices are mapped
  //
  const targetLocDom: domain(1);
  const targetLocs: [targetLocDom] locale;
  //
  // NOTE: originally I wrote this as:
  //
  //   const targetLocs = Locales;
  //   const targetLocDom = targetLocs.domain;
  //
  // but this had two interesting problems:
  //
  // (1) the capture of the targetLocs array only makes a copy of the
  //     array, not of its domain, so if someone were to resize the
  //     LocaleSpace domain outside of the class, this would inadvertantly
  //     get resized as well.  We really want to make a copy of both the
  //     domain and array (which I now do in the constructor).
  //
  // (2) Initializing targetLocs with Locales prevents us from assigning
  //     anything other than a numLocales-ary array of locales to it
  //     which is stricter than I wanted -- I only wanted to restrict
  //     us to a 1D array of locales.  In our current model, this would
  //     require us to have some sort of [domain(1)] locale declaration
  //     to make it work.  Or we could think about whether a model in
  //     which only the array's static type information is inferred
  //     for a field?

  //
  // an array of local distribution class descriptors -- set up in
  // initialize() below
  //
  // TODO: would like this to be const and initialize in-place,
  // removing the initialize method; would want to be able to use
  // an on-clause at the expression list to make this work.
  // Otherwise, would have to move the allocation into a function
  // just to get it at the statement level.
  //
  // WANTED:
  //
  /*
  const locDist: [loc in targetLocDom] LocBlock1DDist(glbIdxType)
                   = on targetLocs(loc) do
                       new LocBlock1DDist(glbIdxType, targetLocDom.order(loc), this);
  */
  //
  // but this doesn't work yet because an array forall initializer
  // apparently can't refer to a local member domain.
  //
  const locDist: [targetLocDom] LocBlock1DDist(glbIdxType);
  //
  // WORKAROUND: Initialize in the constructor instead
  //

  def Block1DDist(type glbIdxType = int(64), bbox: domain(1, glbIdxType),
                  targetLocales: [?targetLocalesDomain] locale) {
    boundingBox = bbox;
    targetLocDom = targetLocalesDomain;
    targetLocs = targetLocales;
    //
    // WANT TO DO:
    /*
    for locid in targetLocDom do
      on targetLocs(locid) do
        locDist(locid) = new LocBlock1DDist(glbIdxType, locid, this);
    */
    //
    // BUT results in a _heapAlloc(type int(64)) call.
    // WORKAROUND:
    helpConstruct();
  }
  //
  // WORKAROUND CONTINUED:
  //
  def helpConstruct() {
    for locid in targetLocDom do
      on targetLocs(locid) do
        locDist(locid) = new LocBlock1DDist(glbIdxType, locid, this);
  }
  //
  // END WORKAROUND
  //

  def writeThis(x:Writer) {
    x.writeln("BradsBlock1DPar");
    x.writeln("---------------");
    x.writeln("distributes: ", boundingBox);
    x.writeln("across locales: ", targetLocs);
    x.writeln("indexed via: ", targetLocDom);
    x.writeln("resulting in: ");
    for locid in targetLocDom do
      x.writeln("  [", locid, "] ", locDist(locid));
  }

  //
  // Create a new domain over this distribution with the given index
  // set (inds) and the given global and local index type (idxType,
  // locIdxType)
  //
  def newDomain(inds, type idxType = glbIdxType, type locIdxType = idxType) {
    // Note that I'm fixing the global and local index types to be the
    // same, but making this a generic function would fix this
    return new Block1DDom(idxType, locIdxType, this, inds);
  }

  //
  // compute what chunk of inds is owned by a given locale -- assumes
  // it's being called on the locale in question
  //
  def getChunk(inds, locid) {
    // use domain slicing to get the intersection between what the
    // locale owns and the domain's index set

    // TODO: Should this be able to be written as myChunk[inds] ???
    return locDist(locid).myChunk(inds.dim(1));
  }

  //
  // Determine which locale owns a particular index
  //
  def ind2locInd(ind: glbIdxType) {
    const ind0 = ind - boundingBox.low;
    const loc0 = (ind0 * targetLocs.numElements) / boundingBox.numIndices;
    const locInd = loc0: index(targetLocs.domain) + targetLocs.domain.low;
    return locInd;
  }

  def ind2loc(ind: glbIdxType) {
    return targetLocs(ind2locInd(ind));
  }
}

//
// A per-locale local distribution class
//
class LocBlock1DDist {
  //
  // The distribution's index type and domain's global index type
  //
  type glbIdxType;

  //
  // This stores the piece of the global bounding box owned by
  // the locale.  Note that my original guess that we'd want
  // to use lclIdxType here is wrong since we're talking about
  // the section of the global index space owned by the locale.
  //
  const myChunk: domain(1, glbIdxType);
  const locid: int;
  const loc: locale;

  //
  // Compute what chunk of index(1) is owned by the current locale
  // Arguments:
  //
  def LocBlock1DDist(type glbIdxType,
                     _locid: int, // the locale index from the target domain
                     dist: Block1DDist(glbIdxType) // reference to glob dist
                     ) {
    locid = _locid;
    loc = dist.targetLocs(locid);
    const lo = dist.boundingBox.low;
    const hi = dist.boundingBox.high;
    const numelems = hi - lo + 1;
    const numlocs = dist.targetLocDom.numIndices;
    const locid0 = dist.targetLocDom.order(locid); // 0-based locale ID
    const blo = if (locid == 0) then min(glbIdxType)
                else procToData((numelems: real * locid) / numlocs, lo);
    const bhi = if (locid == numlocs - 1) then max(glbIdxType)
                else procToData((numelems: real * (locid+1)) / numlocs, lo) - 1;
    myChunk = [blo..bhi];
    if debugBradsBlock1D then
      writeln("locale ", locid, " owns ", myChunk);
  }

  //
  // a helper function for mapping processors to indices
  //
  def procToData(x, lo)
    return (lo + (x: lo.type) + (x:real != x:int:real));

  def writeThis(x:Writer) {
    x.write("locale ", loc.id, " owns chunk: ", myChunk);
  }
}

//
// The global domain class
//
class Block1DDom {
  //
  // The index types of the global and local domain portions
  //
  type glbIdxType;
  type lclIdxType;

  //
  // a pointer to the parent distribution
  //
  const dist: Block1DDist(glbIdxType);

  //
  // a domain describing the complete domain
  //
  const whole: domain(1, glbIdxType);

  //
  // an array of local domain class descriptors -- set up in
  // initialize() below
  //
  //
  // TODO: would like this to be const and initialize in-place,
  // removing the initialize method; would want to be able to use
  // an on-clause at the expression list to make this work.
  // Otherwise, would have to move the allocation into a function
  // just to get it at the statement level.
  //
  var locDoms: [dist.targetLocDom] LocBlock1DDom(glbIdxType, lclIdxType);

  def initialize() {
    for locid in dist.targetLocDom do
      on dist.targetLocs(locid) do
        locDoms(locid) = new LocBlock1DDom(glbIdxType, lclIdxType, this,
                                           dist.getChunk(whole, locid));
    if debugBradsBlock1D then
      [loc in dist.targetLocDom] writeln(loc, " owns ", locDoms(loc));
  }

  //
  // the iterator for the domain -- currently sequential
  //
  def these() {
    for blk in locDoms do
      // TODO: Would want to do something like:
      // on blk do
      // But can't currently have yields in on clauses
        for ind in blk do
          yield ind;
  }

  //
  // this is the parallel iterator for the global domain, following
  // a variation on Steve and David's proposals -- I've split the
  // single iterator into two iterators, distinguished by where
  // clauses on their parameter values.  This permits each to only
  // take the parameters it cares about; permits the leader to be
  // defined in an inlineable way; and permits the follower for an
  // array iterator to be a var iterator
  //
  // I've named these methods newThese() for the time being
  // to avoid conflicting with the above which is currently targeted
  // by the compiler.  My current assumption is that we would want to
  // overload these() to serve this purpose in the final language
  // definition.
  //
  def newThese(param iterator: IteratorType)
        where iterator == IteratorType.leader {
    //
    // TODO: And really want to split the inter- and intra-locale
    // parallelism into two separate stages for communication
    // optimization and the like.  Not sure that even this current
    // approach that uses both global and local iterators achieves
    // this.
    //
    // TODO: Abstract this subtraction of low into a function?
    // Note relationship between this operation and the
    // order/position functions -- any chance for creating similar
    // support? (esp. given how frequent this seems likely to be?)
    //
    coforall locDom in locDoms do
      on locDom do
        forall i in locDom do
          yield i;
  }

  def newThese(param iterator: IteratorType, followThis)
        where iterator == IteratorType.follower {
    //
    // TODO: Abstract this addition of low into a function?
    // Note relationship between this operation and the
    // order/position functions -- any chance for creating similar
    // support? (esp. given how frequent this seems likely to be?)
    //
    // TODO: As noted above, I still have concerns about whether
    // this strategy will help do things like efficient communication
    // on a locale- rather than core basis.
    //
    for i in followThis {
      yield i + whole.low;
    }
  }

  //
  // the print method for the domain
  //
  def writeThis(x:Writer) {
    x.write(whole);
  }

  //
  // how to allocate a new array over this domain
  //
  def newArray(type elemType) {
    return new Block1DArr(glbIdxType, lclIdxType, elemType, this);
  }

  //
  // queries for the number of indices, low, and high bounds
  //
  def numIndices {
    return whole.numIndices;
  }

  def low {
    return whole.low;
  }

  def high {
    return whole.high;
  }
}

//
// the local domain class
//
class LocBlock1DDom {
  //
  // The index types of the global and local domain portions
  //
  type glbIdxType;
  type lclIdxType;

  //
  // a reference to the parent global domain class
  //
  const wholeDom: Block1DDom(glbIdxType, lclIdxType);

  //
  // a local domain describing the indices owned by this locale
  //
  var myBlock: domain(1, lclIdxType);

  //
  // iterator over this locale's indices
  //
  def these() {
    // May want to do something like:
    // on this do
    // But can't currently have yields in on clauses
    for ind in myBlock do
      yield ind;
  }

  //
  // this is the parallel iterator for the local domain, see global
  // domain parallel iterators for general notes on the approach
  //
  def newThese(param iterator: IteratorType)
        where iterator == IteratorType.leader {
    const numChunks = here.numCores();
    coforall (core, blk) in (numChunks, BlockSchedule(myBlock, numChunks)) do
      yield blk - wholeDom.whole.low;
  }

  def newThese(param iterator: IteratorType, followThis0)
        where iterator == IteratorType.follower {
    const followThis = followThis0 + wholeDom.whole.high;
    forall i in followThis do
      yield i;
  }

  //
  // how to write out this locale's indices
  //
  def writeThis(x:Writer) {
    x.write(myBlock);
  }

  //
  // queries for this locale's number of indices, low, and high bounds
  //
  def numIndices {
    return myBlock.numIndices;
  }

  def low {
    return myBlock.low;
  }

  def high {
    return myBlock.high;
  }
}

//
// the global array class
//
class Block1DArr {
  //
  // The index types of the global and local domain portions
  //
  type glbIdxType;
  type lclIdxType;

  //
  // the array's element type
  //
  type elemType;

  //
  // the global domain descriptor for this array
  //
  var dom: Block1DDom(glbIdxType, lclIdxType);

  //
  // an array of local array classes
  //
  // TODO: would like this to be const and initialize in-place,
  // removing the initialize method; would want to be able to use
  // an on-clause at the expression list to make this work.
  // Otherwise, would have to move the allocation into a function
  // just to get it at the statement level.
  //
  var locArr: [dom.dist.targetLocDom] LocBlock1DArr(glbIdxType, lclIdxType, elemType);

  def initialize() {
    for locid in dom.dist.targetLocDom do
      on dom.dist.targetLocs(locid) do
        locArr(locid) = new LocBlock1DArr(glbIdxType, lclIdxType, elemType, dom.locDoms(locid));
  }

  //
  // the global accessor for the array
  //
  def this(i: glbIdxType) var {
    return locArr(dom.dist.ind2locInd(i))(i);
  }

  //
  // the iterator over the array's elements, currently sequential
  //
  def these() var {
    for loc in dom.dist.targetLocDom {
      // TODO: May want to do something like:
      // on this do
      // But can't currently have yields in on clauses
      for elem in locArr(loc) {
        yield elem;
      }
    }
  }

  //
  // this is the parallel iterator for the global array, see th
  // example for general notes on the approach
  //

  def newThese(param iterator: IteratorType)
        where iterator == IteratorType.leader {
    coforall loc in locArr do
      on locArr do
        forall i in locArr.locDom do
          yield i;
  }

  def newThese(param iterator: IteratorType, followThis) var
        where iterator == IteratorType.follower {

    // TODO: Determine which locale we're running on, find the
    // appropriate local array descriptor, and defer this to its
    // follower iterator
  }

  //
  // how to print out the whole array, sequentially
  //
  def writeThis(x: Writer) {
    var first = true;
    for loc in dom.dist.targetLocDom {
      // May want to do something like the following:
      //      on loc {
      // but it causes deadlock -- see writeThisUsingOn.chpl
        if (locArr(loc).numElements >= 1) {
          if (first) {
            first = false;
          } else {
            x.write(" ");
          }
          x.write(locArr(loc));
        }
        //    }
      stdout.flush();
    }
  }

  //
  // a query for the number of elements in the array
  //
  def numElements {
    return dom.numIndices;
  }
}

//
// the local array class
//
class LocBlock1DArr {
  //
  // The index types of the global and local domain portions
  //
  type glbIdxType;
  type lclIdxType;

  //
  // the element type
  //
  type elemType;

  //
  // a reference to the local domain class for this array and locale
  //
  const locDom: LocBlock1DDom(glbIdxType, lclIdxType);

  //
  // the block of local array data
  //
  var myElems: [locDom.myBlock] elemType;

  //
  // the accessor for the local array -- assumes the index is local
  //
  def this(i: lclIdxType) var {
    return myElems(i);
  }

  //
  // iterator over the elements owned by this locale
  //
  def these() var {
    for elem in myElems {
      yield elem;
    }
  }

  //
  // this is the parallel iterator for the local array, see global
  // domain parallel iterators for general notes on the approach
  //
  def newThese(param iterator: IteratorType)
        where iterator == IteratorType.leader {
    // TODO: Break into per-core chunks as we did in the local domain
    // class
  }

  def newThese(param iterator: IteratorType, followThis)
        where iterator == IteratorType.follower {
    //
    // TODO: I view this one as having at least two cases: (1) the
    // followThis block is owned completely locally (an aligned
    // zippered iteration) -- great!  Let's blast through it quickly.
    // (2) we don't own some or all of the elements in question.  Need
    // to bring them over locally, either all at once, an element at a
    // time, or some clever midpoint that pipelines communication and
    // computation (using a double buffer e.g.)
    //
  }

  //
  // prints out this locale's piece of the array
  //
  def writeThis(x: Writer) {
    // May want to do something like the following:
    //      on loc {
    // but it causes deadlock -- see writeThisUsingOn.chpl
    x.write(myElems);
  }

  //
  // query for the number of local array elements
  //
  def numElements {
    return myElems.numElements;
  }
}

error: pathspec 'test/studies/hpcc/common/bradc/BradsBlock1DPar-ideal.chpl' did not match any file(s) known to git


13 - large sum

13 - large sum

error: pathspec '013.chpl' did not match any file(s) known to git


Added a Barrier which stores finished status of each task on the locale it came
from.

This Barrier keeps track of a number of expected tasks; the last locale to finish
then updates a status variable on every other locale to reflect that they can now
move on.  (By default, it also resets itself to be reusable, although this setting
can be toggled.)  Presently, its performance is not very good; certainly in all
test cases I have run it performs substantially worse than its more standard
ancestor (test/parallel/taskPar/sungeun/barrier/Barrier.chpl).

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

// This Barrier is intended to store the finished status of each task locally
// on each locale (instead of on one locale that the other tasks have to keep
// an eye on).  It's currently limited to a single task per locale, but this
// could be fairly simply modified by making tasksFinished a [PrivateSpace] atomic
// int instead, counting down from an initial value of tasksPerLocale.
//
// However, in its present state, this Barrier performs very poorly by comparison
// to its ancestor in test/parallel/taskPar/sungeun/barrier.  We hypothesize that
// in a situation where the different tasks hit the barrier at very different times,
// this barrier might have better performance; however, this hypothesis hasn't
// been tested rigorously.
//
// Its performance is notably better if the flag disableBlockLazyRAD=true.

use BlockDist;

// use this instead of a PrivateDist for performance reasons (PrivateDists are expensive!)
const PrivateSpace = {LocaleSpace} dmapped Block(boundingBox={LocaleSpace});

record Barrier {
  param reusable = true;
  var n: int;
  var count: atomic int;
  var tasksFinished: [PrivateSpace] atomic bool; // to store finished? status locally
                                                 // on each locale

  proc Barrier() {
    reset(numLocales);
  }

  inline proc reset(_n: int) {
    on this {
      n = _n;
      count.write(n);
      for loc in tasksFinished {
        loc.write(false);
      }
    }
  }

  inline proc barrier() {
    const myc = count.fetchSub(1);
    if myc <= 1 {
      if tasksFinished[here.id].read() {
        halt("too many callers to barrier()");
      }
      for loc in tasksFinished { // I'm the last one to finish, notify everyone!
        loc.write(true);
      }
      if reusable { // cleanup for reuse
        count.waitFor(n-1);
        count.add(1);
        for loc in tasksFinished {
          loc.clear();
        }
      }
    } else {
      tasksFinished[here.id].waitFor(true);
      if reusable { // cleanup for reuse
        count.add(1);
        tasksFinished[here.id].waitFor(false);
      }
    }
  }

  inline proc notify() {
    const myc = count.fetchSub(1);
    if myc <= 1 {
      if tasksFinished[here.id].read() {
        halt("too many callers to notify()");
      }
      for loc in tasksFinished {
        loc.write(true);
      }
    }
 }

  inline proc wait() {
    tasksFinished[here.id].waitFor(true);
    if reusable {
      var sum = count.fetchAdd(1);
      if sum == n-1 then tasksFinished.clear();
      else tasksFinished[here.id].waitFor(false);
    }
  }

  inline proc try() {
    return tasksFinished[here.id];
  }
}

error: pathspec 'test/parallel/taskPar/rachels/Barrier.chpl' did not match any file(s) known to git


Trying to commit a copy of this for Tom.

For some reason he seems unable to svn cp this file ('bad gateway' error)

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

use ChapelBase;
use ChapelIO;
use ChapelArray;
use DefaultRectangular;
use DefaultAssociative;

/*
   This code keeps track of tasks, their state, and where they
   spawned from.

   The taks information is used to generate a task report (optionally
   displayed when the user Ctrl+C's out of the program).

   The type chpl_taskID_t is a primitve type defined in the include
   files for each tasking layer.

*/

enum taskState { pending, active, suspended };

//
// This represents a currently running task.  The state, lineno, and
// filename members should be obvious; tl_info is information belonging
// to the tasking layer.
//
// If we included the parent in this, the print method could topologically
// sort the tasks and indent to show the parent/child relationships, which
// might be very nice.
//
record chpldev_Task {
  var state     : taskState;
  var lineno    : uint(32);
  var filename  : string;
  var tl_info   : uint(64);
}

var chpldev_taskTableD : domain(chpl_taskID_t, parSafe=false);
var chpldev_taskTable : [chpldev_taskTableD] chpldev_Task;

pragma "export" proc chpldev_taskTable_add(taskID   : chpl_taskID_t,
                                          lineno   : uint(32),
                                          filename : string,
                                          tl_info  : uint(64))
{
  if(!chpldev_taskTableD.member(taskID)) {
    chpldev_taskTableD.add(taskID);
  }
  chpldev_taskTable[taskID] = new chpldev_Task(taskState.pending,
                                               lineno, filename, tl_info);
}

pragma "export" proc chpldev_taskTable_remove(taskID : chpl_taskID_t)
{
  chpldev_taskTableD.remove(taskID);
}

pragma "export" proc chpldev_taskTable_set_active(taskID : chpl_taskID_t)
{
  chpldev_taskTable[taskID].state = taskState.active;
}

pragma "export" proc chpldev_taskTable_set_suspended(taskID : chpl_taskID_t)
{
  chpldev_taskTable[taskID].state = taskState.suspended;
}

pragma "export" proc chpldev_taskTable_get_tl_info(taskID : chpl_taskID_t)
{
  return chpldev_taskTable[taskID].tl_info;
}

pragma "export" proc chpldev_taskTable_print()
{
  for taskID in chpldev_taskTableD {
    stderr.writeln("- ", chpldev_taskTable[taskID].filename,
                   ":",  chpldev_taskTable[taskID].lineno,
                   " is ", chpldev_taskTable[taskID].state);
  }
}

error: pathspec 'modules/internal/ChapelRT.chpl' did not match any file(s) known to git


add perf test

add perf test

use Random, Time;

type Word = uint(32); // ARMv7 has a wordsize of 32-bit

inline proc genHashKey(h: Word): Word {
  const hashConst1: Word = 0x85ebca6b;
  const hashConst2: Word = 0xc2b2ae35;

  var k: Word = h;
  k ^= k >> 16;
  k *= hashConst1;
  k ^= k >> 13;
  k *= hashConst2;
  k ^= k >> 16;
  return k;
}

proc exercise(arr: [?D] Word, iterations: int, seed: int){

  var randStreamSeeded: RandomStream = new RandomStream(seed);

  var t: Timer;
  t.start();

  for i in [1..iterations] {
    var nextRand: Word = randStreamSeeded.getNext(): Word;
    var hash = genHashKey(nextRand) % D.size + D.low;
    arr[hash] += 1;
  }

  t.stop();
  writeln("completed in ",t.elapsed(TimeUnits.microseconds), " microseconds");
}

var x = 4096;

for i in {1..16} {
  x *= 2;
  var arr: [0..x-1] Word;
  writeln("x = ", x);
  for z in {1..4} {
    exercise(arr, 1024*1024 * 16, 17);
  }
}

error: pathspec 'test/hash_perf.chpl' did not match any file(s) known to git


Update main.chpl

Update main.chpl


9 - special pythagorean triplet

9 - special pythagorean triplet

/*
 * Special Pythagorean triplet
 */

config const sum = 1000;
config const printTriplet = false;

proc main() {
  // Setup 3 dimensional domain for iterating over the entire 3 D space of
  // 1..sum for each a, b, c.
  const denseD = {1..sum, 1..sum, 1..sum};

  // This will find all triplets (three dimensions for a, b, c) that are
  // pythagorean triplets, and test if their sum is 1000. Use atomics to store
  // answer, since a and b will appear twice and we could have a race
  // condition.
  //
  // There is probably some optimizations that could be done here to reduce the
  // number of iterations.
  var resultA, resultB, resultC: atomic int;
  forall (a, b, c) in denseD {
    if exactSum(a, b, c) && isPythagoreanTriplet(a, b, c) {
      resultA.write(a);
      resultB.write(b);
      resultC.write(c);
    }
  }

  const a = resultA.read(),
    b = resultB.read(),
    c = resultC.read();

  if printTriplet {
    writef("%di = %di + %di + %di\n", sum, a, b, c);
    writef("%di^2 = %di^2 + %di^2\n", c, a, b);
  }
  writeln(a * b * c);
}

// Returns true when c ** 2 = a ** 2 + b ** 2, false otherwise.
proc isPythagoreanTriplet(a, b, c) {
  return c ** 2 == a ** 2 + b ** 2;
}

// Returns true when the sum of a, b, and c is exactly sum.
proc exactSum(a, b, c) {
  return a + b + c == sum;
}

error: pathspec '009.chpl' did not match any file(s) known to git


Finished Electrum Test

Finished Electrum Test

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/matthewsedam/cryptotrade.git/'


Added an example of Chapel's parallel tasking features
It needs comments added, but this programs shows how to use begin, cobegin, coforall, and sync statements, as well as sync variables.

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

use Time;

var seed: sync uint = getCurrentTime() : uint;

var notThereYet = true;

begin
  while notThereYet {
    writeln ("Are we there yet?");
    var delay = RandomNumber() * 4.0;
    sleep (delay : uint);
  }

begin {
  sleep (10);
  notThereYet = false;
  writeln ("Shut up!");
}

writeln ("Want to play rock, paper, scissors?");

enum choices {rock, paper, scissors};
var choice: [1..2] sync choices,
    refereeReady: [1..2] sync bool;
var notTired: sync bool = true;

cobegin {
  player(1);
  player(2);
  referee();
}

def player(num) {
  sync {
    begin {
      var delay = RandomNumber() * 10.0 + 1.0;
      sleep (delay : uint);
      if notTired {
        notTired = false;
        writeln ("Player ", num, ": I'm tired of playing!");
      }
      else {
        notTired = false;
        writeln ("Player ", num, ": Me too!");
      }
    }
    while notTired.readFF() {
      var rockPaperScissors = chooseBetweenRockPaperScissors();
      if refereeReady(num) && notTired.readFF() then
        writeln ("Player ", num, ": ", rockPaperScissors);
      choice(num) = rockPaperScissors;
    }
  }
  writeln ("Player ", num, ": Yeah, me too!");
}

def referee () {
  cobegin {
    begin {
      var delay = RandomNumber() * 10.0 + 1.0;
      sleep (delay : uint);
      if notTired {
        notTired = false;
        writeln ("Referee: I'm tired of playing!");
      }
      else {
        notTired = false;
        writeln ("Referee: Me too!");
      }
    }
    while notTired.readFF() {
      var delay = RandomNumber() * 2;
      sleep ((delay + 1.0) : uint);
      coforall i in 1..2 do
        refereeReady(i) = true;
      var player1 = choice(1),
          player2 = choice(2);
      if player1 == player2 then
        declareWinner("tied");
      else if player1 == choices.rock then
        if player2 == choices.paper then
          declareWinner("Player 2 wins!");
        else declareWinner("Player 1 wins!");
      else if player1 == choices.paper then
        if player2 == choices.scissors then
          declareWinner("Player 2 wins!");
        else declareWinner("Player 1 wins!");
      else if player1 == choices.scissors then
        if player2 == choices.rock then
          declareWinner("Player 2 wins!");
        else declareWinner("Player 1 wins!");
    }
  }
  writeln ("Referee: Yes, me too!");
}

def RandomNumber() {
  const multiplier: int(64) = 16807,
        modulus: int(64) = 2147483647;
  // The following calculation must be done in at least 46-bit arithmetic!
  var newSeed = (seed * multiplier % modulus) : uint;
  seed = newSeed;
  return (newSeed-1) / (modulus-1) : real;
}

def chooseBetweenRockPaperScissors() {
  var random = RandomNumber();
  var choice = (random * 3.0) : uint + 1;
  return choice : choices;
}

def declareWinner (w) {
  if notTired.readFF() then
    writeln ("Referee: ", w);
}

error: pathspec 'test/release/examples/parallelTaskingFeatures.chpl' did not match any file(s) known to git


4 - largest palindrome product

4 - largest palindrome product

/*
 * Largest palindrome product
 */

config const width = 3;

// Setup a domain, which will allow us to iterate from 999 down to 100 in two
// dimension, i.e. 999, 999; 999, 998; 999, 997; ... ; 998, 999; ... ; etc.
const min = 10 ** (width - 1),
  max = (10 ** width) - 1,
  D = {min..max by -1, min..max by -1};

// Returns whether or not the number is a palindrome.
proc isPalindrome(num) {
  var strNum = num: string;
  for i in 1..(strNum.length / 2) {
    if strNum.substring(i) != strNum.substring(strNum.length - i + 1) {
      return false;
    }
  }
  return true;
}

var maxResult = (0, -1, -1);
for (i, j) in D {
  var result = i * j;
  if result > maxResult(1) && isPalindrome(result) {
    maxResult = (result, i, j);
  }
}

writef("%di = %di * %di\n", maxResult(1), maxResult(2), maxResult(3));

error: pathspec '004.chpl' did not match any file(s) known to git


3 - largest prime factor

3 - largest prime factor

/*
 * Largest prime factor
 */

config const num = 600851475143;

// Calculate the largest prime factor of num and return the result. This uses
// the simple trial division.
proc largestPrimeFactor(num) {
  var biggestPF = 1,
    d = 2,
    n = num;
  while (d * d <= n) {
    while (n % d == 0) {
      biggestPF = d;
      n /= d;
    }
    d += 1;
  }

  if n > 1 {
    biggestPF = n;
  }

  return biggestPF;
}

writeln(largestPrimeFactor(num));

error: pathspec '003.chpl' did not match any file(s) known to git


Somehow this file slipped out of my last checkin.

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

function foo() {
  writeln("in foo!");
}

foo();

error: pathspec 'test/trivial/bradc/functions/noargs.chpl' did not match any file(s) known to git


Jacobi example

Jacobi example

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

// Implementation of Jacobi transform

var n: int = 5;
var Full: domain(2) = [1..n,1..n];
var Inner: subdomain(Full) = [2..n-1,2..n-1];
var A: [Full] float, B: [Full] float;
var threshold: float = 0.1;

fun main() {
  initialize();
  while (true) {
    if (stencil(A,B) < threshold) {
      writeln(B);
      break;
    }
    if (stencil(B,A)  < threshold) {
      writeln(A);
      break;
    }
  }
}

// Put the stencil of X in Y
// Return the max difference between the new and old stencils
fun stencil(X,Y) {
  forall i,j in Inner {
    Y(i,j) = (X(i+1,j) + X(i-1,j) + X(i,j+1) + X(i,j-1)) / 4;
  }
  return max reduce [i in Inner] abs(X(i) - Y(i));
}

// Initialize everything but the south boundary to 0.0
// Initialize the south boundary to 1.0
fun initialize() {
  forall i in [n..n,1..n] {
    A(i) = 1.0;
    B(i) = 1.0;
  }
}

error: pathspec 'test/studies/jacobi/bocchino/jacobi.chpl' did not match any file(s) known to git


error: pathspec 'helloworld.chpl' did not match any file(s) known to git


Finished ConfigFile

Finished ConfigFile

 * Finished ConfigFile
 * Added appropriate functions for accessing properties as the
   Java class did not need these as it was derived from the
   Java class Properties
 * This is *mostly* manually tested


custom Chapel test framework added (cw-2)

// Codewars test module for Chapel
// Code based on Python, PHP and JS cw-2 modules

module Test {

  use Math;

  // Basic Test Method
  proc expect(passed: bool, msg: string = "Value was not what was expected",
              allow_raise: bool = false) throws {
    if passed {
      writeln("\n<PASSED::>Test Passed");
    } else {
      writeln("\n<FAILED::>" + msg);
      if allow_raise {throw new Error(msg);}
    }
  }

  // Assertion Methods
  proc assertEquals(actual: ?t_act, expected: ?t_exp, msg: string = "",
                    allow_raise: bool = true) : void {
    var message: string = msg;
    var equals_msg: string = actual + " should equal " + expected;
    if message == "" {
      message = equals_msg;
    } else {
      message += ": " + equals_msg;
    }
    expect(actual == expected, message, allow_raise);
  }

  proc assertNotEquals(actual: ?t_act, expected: ?t_exp, msg: string = "",
                       allow_raise: bool = true) : void {
    var message: string = msg;
    var equals_msg: string = actual + " should equal " + expected;
    if message == "" {
      message = equals_msg;
    } else {
      message += ": " + equals_msg;
    }
    expect(actual != expected, message, allow_raise);
  }

  proc assertFuzzyEquals(actual : real, expected: real, msg: string = "",
                         allow_raise: bool = true) : void {
    var in_range: bool = false;
    const max_err: real = 1e-9;

    if expected == 0 {
      in_range = abs(actual) <= max_err;
    } else {
      in_range = abs((actual - expected) / expected) <= max_err;
    }

    var message: string = msg;
    var equals_msg: string = "%.9r".format(actual) + " should equal "
                           + "%.9r".format(expected);
    if message == "" {
      message = equals_msg;
    } else {
      message += ": " + equals_msg;
    }
    expect(in_range, message, allow_raise);
  }

  proc expectError(msg, function) {
    var passed: bool = false;
    try {
      function();
    } catch {
      passed = true;
    }
    expect(passed, msg);
  }

  proc expectNoError(msg, function) {
    var passed: bool = true;
    try {
      function();
    } catch {
      passed = false;
    }
    expect(passed, msg);
  }

  proc _format(msg) {
    return msg.replace("\n", "<:LF:>");
  }

  // Describes the tests to be executed.
  proc describe(msg) {
    write("<DESCRIBE::>" + _format(msg));
  }

  // "It" blocks
  proc it(msg) {
    write("<IT::>" + _format(msg));
  }
}

use Test;

error: pathspec 'frameworks/chapel/cw-2.chpl' did not match any file(s) known to git


7 - 10001st prime

7 - 10001st prime

/*
 * 10001st prime
 */

config const n = 10001;
config const printPrimes = false;

// This is a fairly optimized version of calculating if a number is prime or
// not.
// See: http://stackoverflow.com/a/15285588
proc isPrime(number) {
  if number == 2 || number == 3 {
    return true;
  } else if number < 2 || number % 2 == 0 {
    return false;
  } else if number < 9 {
    return true;
  } else if number % 3 == 0 {
    return false;
  }

  var r = (number ** 0.5): int,
    f = 5;
  while (f <= r) {
    if number % f == 0 {
      return false;
    } else if number % (f + 2) == 0 {
      return false;
    }
    f += 6;
  }
  return true;
}

// Returns the first <count> prime numbers beginning with 2, the first prime.
// This was more for fun than to be useful.
iter primes(count) {
  if count >= 1 {
    yield 2;
  }
  var current = 3;
  for i in 2..count {
    yield current;

    do {
      current += 2;
    } while !isPrime(current);
  }
}

proc getPrime(count) {
  var result = -1;
  for (value, i) in zip(primes(count), 1..count) {
    if printPrimes {
      writef("%di: %di\n", i, value);
    }
    if i == count {
      result = value;
    }
  }
  return result;
}

writeln(getPrime(n));

error: pathspec '007.chpl' did not match any file(s) known to git


16 - power digit sum

16 - power digit sum

/*
 * Power digit sum
 */

// requires CHPL_GMP=gmp or system
use GMP;

config const exp = 1000;

proc main() {
  writeln(sumDigits(power(2, exp)));
}

// Returns base ** exp using BigInts to avoid integer overflow.
proc power(base, exp) {
  var result = new BigInt();
  result.pow_ui(new BigInt(base), exp: c_ulong);
  return result;
}

// Returns sum of individual digits of n. n is serialized as string, then each
// character is cast to an int, and added together.
proc sumDigits(n) {
  var nStr = n: string,
    result = 0;
  for i in 1..nStr.length {
    result += nStr.substring(i): int;
  }
  return result;
}

error: pathspec '016.chpl' did not match any file(s) known to git


A much cleaner version of fock-1 with coforall being used to launch consumers
and cobegin being used to launch producers and consumers, all in parallel. The
producer is driven by an iterator that yields blocks of indices in the fock
iteration space.

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

config const natom = 5;
const n = (natom/2)*10 + ((natom+1)/2)*5;
const bas_info : [(i,j) in [1..natom, 1..2]] int =
  5*(i/2) + 10*((i-1)/2) + if (j==1) then 1 else 10/(i%2+1);

type elemType = real(64);
const matD : domain(2) distributed(Block) = [1..n, 1..n];
const dmat : [(i,j) in matD] elemType = 1.0/(i+j);
var jmat2, kmat2, jmat2T, kmat2T : [matD] elemType;
var oneAtATime: sync bool = true;

class blockIndices {
  const ilo, ihi, jlo, jhi, klo, khi, llo, lhi : int;
}

config const numLocs = 100;
var task : sync blockIndices;

def buildjk() {
  cobegin {
    coforall loc in 1..numLocs do
      consumer();

    producer();
  }

  cobegin {
    [(i,j) in matD] jmat2T(i,j) = jmat2(j,i);
    [(i,j) in matD] kmat2T(i,j) = kmat2(j,i);
  }

  cobegin {
    jmat2 = (jmat2 + jmat2T) * 2;
    kmat2 += kmat2T;
  }

  writeln("\n1st row of coulomb matrix:-\n", jmat2(1..1,1..n));
  writeln("\n1st col of coulomb matrix:-\n", jmat2(1..n,1..1));
  writeln("\n1st row of exchange matrix:-\n", kmat2(1..1,1..n));
  writeln("\n1st col of exchange matrix:-\n", kmat2(1..n,1..1));
}

def consumer() {
  var bI, copyofbI : blockIndices;
  bI = task;
  while (bI.ilo != 0) {
    copyofbI = bI;
    cobegin {
      buildjk_atom4(copyofbI);
      bI = task;
    }
  }
}

def producer() {
  forall bI in genBlocks() do
    task = bI;
}

def genBlocks() {
  forall iat in 1..natom {
    forall jat in 1..iat {
      forall kat in 1..iat {
        const lattop = if (kat==iat) then jat else kat;
        forall lat in 1..lattop {
          yield blockIndices(bas_info(iat,1), bas_info(iat,2), bas_info(jat,1),
                             bas_info(jat,2), bas_info(kat,1), bas_info(kat,2),
                             bas_info(lat,1), bas_info(lat,2));
        }
      }
    }
  }
  forall loc in 1..numLocs do
    yield blockIndices(0,0,0,0,0,0,0,0);
}

def buildjk_atom4(bI) {
  const (ilo,ihi,jlo,jhi,klo,khi,llo,lhi) =
    (bI.ilo,bI.ihi,bI.jlo,bI.jhi,bI.klo,bI.khi,bI.llo,bI.lhi);

  const (ijD,ikD,ilD,jkD,jlD,klD) = ([ilo..ihi,jlo..jhi],[ilo..ihi,klo..khi],
    [ilo..ihi,llo..lhi],[jlo..jhi,klo..khi],[jlo..jhi,llo..lhi],
    [klo..khi,llo..lhi]);

  const dij = dmat(ijD);
  const dik = dmat(ikD);
  const dil = dmat(ilD);
  const djk = dmat(jkD);
  const djl = dmat(jlD);
  const dkl = dmat(klD);

  var jij : [ijD] elemType;
  var jkl : [klD] elemType;
  var kik : [ikD] elemType;
  var kil : [ilD] elemType;
  var kjk : [jkD] elemType;
  var kjl : [jlD] elemType;

  var jtop, ktop, ltop : int;
  var facij, facijkl, gijkl: elemType;

  for i in ilo..ihi {
    if (ilo==jlo) then jtop = i; else jtop = jhi;
    for j in jlo..jtop {
      if (i==j) then facij = 0.5; else facij = 1.0;
      if (ilo==klo && jlo==llo) then ktop = i; else ktop = khi;
      for k in klo..ktop {
        ltop = lhi;
        if (klo==llo) then ltop = k;
        if (ilo==klo && jlo==llo && k==i) then ltop = j;
        for l in llo..ltop {
          facijkl = facij;
          if (k==l) then facijkl *= 0.5;
          if (i==k && j==l) then facijkl *= 0.5;
          gijkl = g(i,j,k,l)*facijkl;
          jij(i,j) += dkl(k,l)*gijkl;
          jkl(k,l) += dij(i,j)*gijkl;
          kik(i,k) += djl(j,l)*gijkl;
          kil(i,l) += djk(j,k)*gijkl;
          kjk(j,k) += dil(i,l)*gijkl;
          kjl(j,l) += dik(i,k)*gijkl;
        }
      }
    }
  }

  var tmp = oneAtATime;
  atomic jmat2(ijD) += jij;
  atomic jmat2(klD) += jkl;
  atomic kmat2(ikD) += kik;
  atomic kmat2(ilD) += kil;
  atomic kmat2(jkD) += kjk;
  atomic kmat2(jlD) += kjl;
  oneAtATime = tmp;
}

def g(i,j,k,l) {
  return 1.0/(i*j + k*l);
}

def main() {
  buildjk();
}

error: pathspec 'test/users/shetag/fock/fock-1-latest.chpl' did not match any file(s) known to git


initial commit of version using miniMD's modified BlockDist

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

// 9-point stencil using a modified version of BlockDist that can
// handle fluff (ghosts/overlap/etc.) and periodic boundaries
// Note: disable the RAD optimization when compiling: -sdefaultDoRADOpt=false
//
// Compiling: chpl stencil9-mod.chpl -M ../../release/examples/benchmarks/miniMD/stencil/helpers/StencilDist.chpl <other>

use StencilDist;

config const n = 10;

config const epsilon = 0.01;

config const printArrays = false;

const LocDom = {1..n  , 1..n  },
         Dom = LocDom dmapped Block(LocDom, fluff=(1,1));

var A, B: [Dom] real;

A[  n/4+1,   n/4+1] =  1.0;
A[3*n/4+1, 3*n/4+1] =  1.0;
A[  n/4+1, 3*n/4+1] = -1.0;
A[3*n/4+1,   n/4+1] = -1.0;

A.updateFluff();

if printArrays then
  writeln("Initial A:\n", A, "\n");

var numIters = 0;

do {
  numIters += 1;

  forall (i,j) in Dom do
    B[i,j] = 0.25   * A[i,j]
           + 0.125  * (A[i+1,j  ] + A[i-1,j  ] + A[i  ,j-1] + A[i  ,j+1])
           + 0.0625 * (A[i-1,j-1] + A[i-1,j+1] + A[i+1,j-1] + A[i+1,j+1]);

  const delta = max reduce fabs(B - A);

  if printArrays then
    writeln("delta: ", delta);

  B <=> A;

  A.updateFluff();

 } while (delta > epsilon);

if printArrays then
  writeln("Final A:\n", A);

writeln("# iterations: ", numIters);

error: pathspec 'test/studies/stencil9/stencil9-mod.chpl' did not match any file(s) known to git


Update chpl example file with 'with' keyword and octal ints.

/***********************************************************************
 * Chapel implementation of "99 bottles of beer"
 *
 * by Brad Chamberlain and Steve Deitz
 * 07/13/2006 in Knoxville airport while waiting for flight home from
 *            HPLS workshop
 * compiles and runs with chpl compiler version 1.7.0
 * for more information, contact: chapel_info@cray.com
 *
 *
 * Notes:
 * o as in all good parallel computations, boundary conditions
 *   constitute the vast bulk of complexity in this code (invite Brad to
 *   tell you about his zany boundary condition simplification scheme)
 * o uses type inference for variables, arguments
 * o relies on integer->string coercions
 * o uses named argument passing (for documentation purposes only)
 ***********************************************************************/

// allow executable command-line specification of number of bottles
// (e.g., ./a.out -snumBottles=999999)
config const numBottles = 99;
const numVerses = numBottles+1;

// a domain to describe the space of lyrics
var LyricsSpace: domain(1) = {1..numVerses};

// array of lyrics
var Lyrics: [LyricsSpace] string;

// parallel computation of lyrics array
[verse in LyricsSpace] Lyrics(verse) = computeLyric(verse);

// as in any good parallel language, I/O to stdout is serialized.
// (Note that I/O to a file could be parallelized using a parallel
// prefix computation on the verse strings' lengths with file seeking)
writeln(Lyrics);

// HELPER FUNCTIONS:

proc computeLyric(verseNum) {
  var bottleNum = numBottles - (verseNum - 1);
  var nextBottle = (bottleNum + numVerses - 1)%numVerses;
  return "\n" // disguise space used to separate elements in array I/O
    + describeBottles(bottleNum, startOfVerse=true) + " on the wall, "
    + describeBottles(bottleNum) + ".\n"
    + computeAction(bottleNum)
    + describeBottles(nextBottle) + " on the wall.\n";
}

proc describeBottles(bottleNum, startOfVerse:bool = false) {
  // NOTE: bool should not be necessary here (^^^^); working around bug
  var bottleDescription = if (bottleNum) then bottleNum:string
    else (if startOfVerse then "N"
            else "n")
           + "o more";
  return bottleDescription
    + " bottle" + (if (bottleNum == 1) then "" else "s")
    + " of beer";
}

proc computeAction(bottleNum) {
  return if (bottleNum == 0) then "Go to the store and buy some more, "
    else "Take one down and pass it around, ";
}

// Modules...
module M1 {
  var x = 10;
}

module M2 {
  use M1;
  proc main() {
    writeln("M2 -> M1 -> x " + x);
  }
}

// Classes, records, unions...
const PI: real = 3.14159;

record Point {
  var x, y: real;
}
var p: Point;
writeln("Distance from origin: " + sqrt(p.x ** 2 + p.y ** 2));
p = new Point(1.0, 2.0);
writeln("Distance from origin: " + sqrt(p.x ** 2 + p.y ** 2));

class Circle {
  var p: Point;
  var r: real;
}
var c = new Circle(r=2.0);
proc Circle.area()
  return PI * r ** 2;
writeln("Area of circle: " + c.area());

class Oval: Circle {
  var r2: real;
}
proc Oval.area()
  return PI * r * r2;

delete c;
c = nil;
c = new Oval(r=1.0, r2=2.0);
writeln("Area of oval: " + c.area());

// This is a valid decimal integer:
var x = 0000000000012;

union U {
  var i: int;
  var r: real;
}

// chapel ranges are awesome.
var r1 = 1..10,            // 1 2 3 4 5 6 7 8 9 10
  r2 = 10..1,              // no values in this range
  r3 = 1..10 by -1,        // 10 9 8 7 6 5 4 3 2 1
  r4 = 1..10 by 2,         // 1 3 5 7 9
  r5 = 1..10 by 2 align 0, // 2 4 6 8 10
  r6 = 1..10 by 2 align 2, // 2 4 6 8 10
  r7 = 1..10 # 3,          // 1 2 3
  r8 = 1..10 # -2,         // 9 10
  r9 = 1..100 # 10 by 2,   // 1 3 5 7 9
  ra = 1..100 by 2 # 10,   // 1 3 5 7 9 11 13 15 17 19
  rb = 1.. # 100 by 10;    // 1 11 21 31 41 51 61 71 81 91

// create a variable with default initialization
var myVarWithoutInit: real = noinit;
myVarWithoutInit = 1.0;

// Chapel has <~> operator for read and write I/O operations.
class IntPair {
  var x: int;
  var y: int;
  proc readWriteThis(f) {
    f <~> x <~> new ioLiteral(",") <~> y <~> new ioNewline();
  }
}
var ip = new IntPair(17,2);
write(ip);

var targetDom: {1..10},
  target: [targetDom] int;
coforall i in targetDom with (ref target) {
  targetDom[i] = i ** 3;
}

var wideOpen = 0o777,
  mememe = 0o600,
  clique_y = 0O660,
  zeroOct = 0o0,
  minPosOct = 0O1;


Test LockFreeHash

Test LockFreeHash

use LockFreeHash;

proc storeItemTest(lfh: LockFreeHash, key: KeyType, value: ValueType) {
  writeln("attempting to store value: ", value, " with key ", key);
  lfh.setItem(key, value);
  writeln("attempting to get value with key ", key);
  var rItem = lfh.getItem(key);
  write("value == rItem\t", value == rItem);
}

proc main() {
  var lfh = new LockFreeHash(2);
  var item1: uint(32) = 32;
  var item2: uint(32) = 48;
  var item3: uint(32) = 64;
  storeItemTest(lfh, genHashKey32("hello1"), item1);
  storeItemTest(lfh, genHashKey32("hello2"), item2);
  storeItemTest(lfh, genHashKey32("hello3"), item3);
}

error: pathspec 'chapel/test/lockfreehashtest.chpl' did not match any file(s) known to git


First stab at a directory-specific walker

config const debug = false;

iter walkdirs(path: string=".", topdown=true, depth=max(int), dotfiles=false, followlinks=false): string {
  extern type DIRptr;
  extern type direntptr;
  extern proc opendir(name: c_string): DIRptr;
  extern proc readdir(dirp: DIRptr): direntptr;
  extern proc closedir(dirp: DIRptr): c_int;

  proc direntptr.d_name(): c_string {
    extern proc chpl_rt_direntptr_getname(d: direntptr): c_string;

    return chpl_rt_direntptr_getname(this);
  }

  proc direntptr.isDir() {
    extern proc chpl_rt_direntptr_isDir(d: direntptr): bool;

    return chpl_rt_direntptr_isDir(this);
  }

  if (topdown) then
    yield path;

  if (depth) {
    var dir: DIRptr;
    var ent: direntptr;
    if debug then
      writeln("***Trying ", path);
    dir = opendir(path:c_string);
    if (!is_c_nil(dir)) {
      ent = readdir(dir);
      while (!is_c_nil(ent)) {
        const filename = ent.d_name();
        if (ent.isDir() && filename != "." && filename != "..") {
          if debug then
            writeln("***It's a dir!");
          if (dotfiles || filename.substring(1) != '.') {
            const fullpath = path + "/" + filename;
            //
            // feature request: This is a nice place for a yieldall concept
            //
            for dirname in walkdirs(fullpath, topdown, depth-1, dotfiles, followlinks) do
              yield dirname;
          }
        }
        ent = readdir(dir);
      }
    } else {
      extern proc perror(s: c_string);
      perror("error in walkdirs(): ");
    }
    closedir(dir);
  }

  if (!topdown) then
    yield path;
}

iter sorted(x) {
  use Sort;

  var y = x;
  QuickSort(y);
  for i in y do
    yield i;
}

config const startdir = "subdir";
config const topdown = true;
config const depth = max(int);
config const dotfiles = false;
config const followlinks = false;

config const sort = true;
config const defaults = false;

if defaults then
  if sort then
    for filename in sorted(walkdirs()) do
      writeln(filename);
 else
   for filename in walkdirs() do
     writeln(filename);
else
  if sort then
    for filename in sorted(walkdirs(startdir, topdown, depth, dotfiles, followlinks)) do
      writeln(filename);
 else
   for filename in walkdirs(startdir, topdown, depth, dotfiles, followlinks) do
     writeln(filename);

error: pathspec 'test/studies/filerator/walk.chpl' did not match any file(s) known to git


okay, it works but needs to be cleaned up

use NumSuch, LinearAlgebra.Sparse, Norm;

/* Create some fake data */

/* Create the actual function w */
const EPSILON: real = 0.05,
      ETA: real = 0.005;
var n = 10,
    d = 50,
    w: [1..n] real;

// Create X, the data, using sparse data since that's how I roll
var D = CSRDomain(d,n),
    X = CSRMatrix(D, real);

for i in 1..d {
  for j in 1..n {
    D += (i,j);
    var r = rand(-1,1);
    X[i,j] = r;
  }
}

// Create y = f(X) = Xw
for i in 1..n do w[i] = rand(2,9);
const y = X.dot(w);
writeln("Actual y: ", y);
writeln("Actual w: ", w);
/* Run Procedure */

var theta = SGD(X=X, y=y, method="linear");
writeln("final theta: ", theta);

proc SGD(X:[] real, y:[] real, method:string = "linear") {
  if method=="linear" {
    return linearSGD(X=X, y=y);
  } else {
    halt("NO! You can't do that!!");
  }
}

proc linearSGD(X:[] real, y:[] real, epsilon:real=0.05, eta:real=0.05) {
  var rows = seq(1, X.domain.dim(1).size),
      ncols = X.domain.dim(2).size,
      theta:[1..ncols] real,
      loss: real = 1000,
      itr: int = 1;

  var yAvg = (+reduce y) / y.size;
  for i in 1..theta.size do theta[i] = yAvg;
  writeln("theta 0: ", theta);
  do {
    shuffle(rows);
    for r in rows {
        var x:[1..ncols] real;
        for j in X.domain.dimIter(2,r) {
          x[j] = X[r,j];
        }
        theta = theta - ETA * linearSGDdf(x=x,theta=theta, y=y[r]);
    }
    var yHat = X.dot(theta),
        err = yHat - y;
    loss = norm(err);
    //writeln("* iteration %n  loss = %n".format(itr, loss));
    itr += 1;
  } while loss >= epsilon && itr < 100;
  writeln("Loss after %n iterations: %n".format(itr, loss));
  return theta;
}

/*
 Calculates the derivative of (theta * x - y)^2
 */
proc linearSGDdf(x:[] real, theta:[] real, y: real) {
  var z: [1..theta.size] real;
  //var wx = theta.dot(x) - y;
  //writeln("wx: ", wx);
  for i in 1..theta.size {
    z[i] = 2*x[i] * (theta.dot(x) - y);
  }
  return z;
}

/*
var s = seq(1,d);
// The parameter to fit
var theta: [1..n] real;
for i in 1..theta.size do theta[i] = (+ reduce y)/theta.size;
writeln("theta: ", theta);
//for r in s {
//for k in 1.. 10 {  // Should be repeat until
var k = 1;
var delta: real = 101;
do {  // Should be repeat until
  shuffle(s);
  for r in s {
    //writeln("r is now: %n".format(r));
    var x: [1..n] real;
    for j in X.domain.dimIter(2,r) {
      x[j] = X[r,j];
    }
    theta = theta - ETA * df(theta, x, y[r]);
  }
  var yh = X.dot(theta);
  var d = yh-y;
  delta = norm(d);
  writeln("iteration %n  delta = %n".format(k, delta));
  k += 1;
//} while delta > 100;
} while delta > EPSILON;

proc df(theta:[] real, x:[] real, y:real) {
  var z: [1..theta.size] real;
  for i in 1..theta.size {
    var wx = theta.dot(x);
    z[i] = 2*x[i] * (theta.dot(x) - y);
  }
  return z;
}
*/

error: pathspec 'examples/linearGradientDescent.chpl' did not match any file(s) known to git


I revisited my Sudoku test and came up with a much simpler implementation of
sudoku-simple.  The new implementation builds a table of which values are
possible at each square and iterates on this table to fill in the board.  It's
38% the length of the original sudoku-simple.chpl: 73 lines compared to 192.

sudoku-simpler solves easy.dat and hard.dat correctly, but for some reason it
doesn't get as far on evil.dat and outlaw.dat as sudoku-simple.  Not really
sure why this is yet since the approaches ought to be equivalent.  The original
implementor of sudoku-simple must have done some evil hacks or something.

PS- The LOC comparison isn't totally fair since sudoku-simple has several
workarounds: continue, array slicing, etc...

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

config const inputfile = "easy.dat";

// Attempt to solve the given Sudoku board.  Note: the simple solver
// isn't able to completely solve really hard puzzles.
def solveBoard(inout board: [] int) {
  var elimBoard: [1..9, 1..9, 1..9] bool = true;
  var nUpdates = 0;

  // For each spot that's filled in, mark it as unavailable in the list for
  // each other spot in its row, column, and block
  for (i, j) in board.domain do
    if (board[i, j] > 0) {
      elimBoard[i, 1..9, board[i, j]] = false;
      elimBoard[1..9, j, board[i, j]] = false;
      elimBoard[(i-1)/3*3+1..(i-1)/3*3+3, (j-1)/3*3+1..(j-1)/3*3+3, board[i, j]] = false;
      //writeln("(", i, ", ", j, "): irange = [", (i-1)/3*3+1, "..", (i-1)/3*3+3, "]  jrange = [",
      //  (j-1)/3*3+1, "..", (j-1)/3*3+3, "]");
    }

  do {
    nUpdates = 0;

    // Find spaces where there's only one possible entry and fill them in
    for (i, j) in board.domain {
      const NONE = 0, MULTIPLE = -1;
      var   idx  = NONE;

      if board[i, j] > 0 then continue;

      for k in 1..9 do
        if elimBoard[i, j, k] then
          idx = if idx == NONE then k else MULTIPLE;

      if idx > 0 {
        board[i, j] = idx;
        elimBoard[i, 1..9, board[i, j]] = false;
        elimBoard[1..9, j, board[i, j]] = false;
        elimBoard[(i-1)/3*3+1..(i-1)/3*3+3, (j-1)/3*3+1..(j-1)/3*3+3, board[i, j]] = false;
        nUpdates   += 1;
      }
    }

    writeln(" - Udates this round: ", nUpdates);
  } while (nUpdates > 0);
}

def main() {
  var board: [1..9, 1..9] int;
  var boardData = new file(inputfile, path='./', mode=FileAccessMode.read);

  // Read the board from the input file
  boardData.open();

  writeln("Reading board from: ", inputfile, "\n");
  for element in board do boardData.read(element);

  boardData.close();
  writeln(board, "\n");

  solveBoard(board);

  // Count up the remaining blanks
  var nSpots = 0;
  [num in board] if num == 0 then nSpots += 1;

  if nSpots == 0 then
    writeln("\nPuzzle solved:\n\n", board);
  else
    writeln("\nI was able to fill in all but ", nSpots,
        " spaces, good luck with the rest!\n\n", board);
}

error: pathspec 'test/studies/sudoku/dinan/sudoku-simpler.chpl' did not match any file(s) known to git


Added parallel version file

Added parallel version file

//Author Sparsh Mittal sparsh0mittal@gmail.com
//Research paper reference: Sparsh Mittal, "A Study of Successive Over-relaxation Method
//Parallelization Over Modern HPC Languages", International Journal of High
//Performance Computing and Networking, vol. 7, number  4, pp. 292-298, 2014.

 use Time;

config const gridSize: int = 4096;
config const INITIAL_GUESS: real = 0.0;
config const MAXSTEPS: int  = 50000;
config const TOL_VAL: real =0.00001;
config const NUM_CHECK: int =4000;

config const omega: real =  0.376;
config const one_minus_omega: real =  1-omega;

config const numberOfSlaves: int = 2;
config const factorValue: int = gridSize / numberOfSlaves;

var gridInfo: [1..(gridSize+2),1..(gridSize+2)] real ;
var gridInfoOld: [1..(gridSize+2),1..(gridSize+2)] real ;

proc MAX_FUNC(a: real, b: real): real {

	if (a > b) {
		return a;
}
	return b;

}

proc ABS_VAL(a: real): real {

	if (a > 0) {
		return a;
}
	return -a;
}

proc sorSolverSlaveRed(myNumberOne: int) {

	var sum: real = 0;

        var myNumber: int = myNumberOne-1;

	var iStart: int = (myNumber * factorValue) + 2;
	var iEnd: int = ((myNumber + 1) * factorValue)+1;

        //writeln(" factorValue ", factorValue);
        //writeln(" For slave ", myNumber , " iStart ", iStart, " iEnd ", iEnd);

       //RED i even, j even
       for i in (iStart)..(iEnd) by 2 {
           for j in 2..(gridSize+1) by 2 {

              //writeln("RedEven ", i, " ", j);

               sum = (gridInfo(i,j+1) + gridInfo(i+1,j) + gridInfo(i-1,j) + gridInfo(i,j-1)) * 0.25;
	       gridInfo(i,j) = one_minus_omega*gridInfo(i,j) + omega*sum;
         }
        }

         //RED i odd, j odd
       for i in (iStart+1)..(iEnd) by 2 {

           for j in 3..(gridSize+1) by 2 {

              // writeln("RedOdd ", i, " ", j);

               sum = (gridInfo(i,j+1) + gridInfo(i+1,j) + gridInfo(i-1,j) + gridInfo(i,j-1)) * 0.25;
	       gridInfo(i,j) = one_minus_omega*gridInfo(i,j) + omega*sum;
          }
         }

}

proc sorSolverSlaveBlack(myNumberOne: int) {

       var myNumber: int = myNumberOne-1;
   var sum: real = 0;

  var iStart: int = (myNumber * factorValue) + 2;
  var iEnd: int = ((myNumber + 1) * factorValue)+1;

       //Black  i even, j odd
       for i in (iStart)..(iEnd) by 2 {
           for j in 3..(gridSize+1) by 2 {

               //writeln("BlackEven ", i, " ", j);

               sum = (gridInfo(i,j+1) + gridInfo(i+1,j) + gridInfo(i-1,j) + gridInfo(i,j-1)) * 0.25;
	       gridInfo(i,j) = one_minus_omega*gridInfo(i,j) + omega*sum;
}
}

         //Black i odd, j even
       for i in (iStart+1)..(iEnd) by 2 {
           for j in 2..(gridSize+1) by 2 {

               //writeln("BlackOdd ", i, " ", j);

               sum = (gridInfo(i,j+1) + gridInfo(i+1,j) + gridInfo(i-1,j) + gridInfo(i,j-1)) * 0.25;
	       gridInfo(i,j) = one_minus_omega*gridInfo(i,j) + omega*sum;
}
}

}

//main starts here
writeln("GridSize ",gridSize, " MaxStep ", MAXSTEPS, " Accuracy ", TOL_VAL );

var maxError: real = 0.0;
var hasConverged: bool = false;

for i in 1..(gridSize+2) {
  for j in 1..(gridSize+2) {
              if (i == 1) {
				gridInfo(i,j) = 1.0;
              } else {
				gridInfo(i,j) = INITIAL_GUESS;
              }
  }
}

var sum: real = 0.0;

var timeMeasure:Timer;

timeMeasure.start();
for k in 1..(MAXSTEPS) {

 maxError = 0.0;
        if (k%NUM_CHECK == 0) {
          for i in 2..(gridSize+1)  {
           for j in 2..(gridSize+1) {

	       gridInfoOld(i,j) = gridInfo(i,j);
              }
             }
       }

       sync {
            for p in 1..numberOfSlaves {
             begin sorSolverSlaveRed(p);
             }
      }

       sync {
            for p in 1..numberOfSlaves {
             begin sorSolverSlaveBlack(p);
          }
         }

      if (k%NUM_CHECK == 0) {

      for i in 2..(gridSize+1)  {
           for j in 2..(gridSize+1) {

	  maxError = MAX_FUNC (ABS_VAL (gridInfoOld(i,j) - gridInfo(i,j)), maxError);
         }
         }
			writeln("Iter ", k, " Error ", maxError);
			if (maxError < TOL_VAL) {
				hasConverged = true;
				break;
   }
   }

}

timeMeasure.stop();
writeln(" Time elapsed ", timeMeasure.elapsed());

if( hasConverged) {
writeln("It converged");
} else {
writeln("It did not converge");
}

error: pathspec 'test/studies/Mittal_IJHPCN_SOR/SOR_Parallel.chpl' did not match any file(s) known to git


Not too much different from example1.chpl.  Changes include:
 - removal of the 3rd array to store the delta
 - removed the explicit max reduction the delta array
 - "main" world is now the smaller domain so that it does not
   print the extra border values in the final writeln

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

// Example of the Jacobi algorithm in Chapel

param M = 4;
param N = 4;
config const THRESHOLD = 0.00001;
// config const THRESHOLD: = 0.00001; // generates "0.0 = 0.0001"
// param MAXDELTAPOSSIBLE:float = 1.0;// error:value not known at compile time?
// param THRESHOLD:float = 0.00001;   // error:value not known at compile time?

// would like to use subdomains for D, northOfD, southOfD, westOfD, eastOfD
var outerD: domain(2) = [0..M+1, 0..N+1];
var D: domain(2) = [1..M, 1..N];
var northOfD: domain(2) = [0..0,     1..N];  // 0..0
var southOfD: domain(2) = [M+1..M+1, 1..N];
var westOfD : domain(2) = [1..M, 0..0];
var eastOfD : domain(2) = [1..M, N+1..N+1];  // N+1..N+1

var World:[D] float;
var Temp:[outerD] float;

// starting conditions
[e in D] Temp(e) = 0.0;
[e in northOfD] Temp(e) = 0.25;
[e in southOfD] Temp(e) = 1.09;
[e in westOfD]  Temp(e) = 0.59;
[e in eastOfD]  Temp(e) = 0.63;

var moving: bool;
do {
  moving = false;
  forall i,j in D do {                       // calc new World
    World(i,j) = (Temp(i-1,j) + Temp(i+1,j) + Temp(i,j-1) + Temp(i,j+1)) / 4.0;
    moving |= abs( World(i,j) - Temp(i,j)) > THRESHOLD;
  }
  [e in D] Temp(e) = World(e);               // copy back World->Temp
 } while (moving);

writeln( World);

error: pathspec 'test/studies/jacobi/waynew/example2.chpl' did not match any file(s) known to git