Added in missing barrier per changes Sung just made to SSCA#2 Kernel4

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

//This code was based on the XMT version of the Graph5000 benchmark submitted by
//John Feo <john.feo@pnl.gov> and Kristi Maschhoff <kristyn@cray.com> in 2010.

// This version incorporates ideas from Kamesh Madduri's implementation
// in terms of using a 1D distribution of the Vertex records, maintaining
// a distributed queue, and sending work to the locale which owns a particular
// vertex. Chapel accomplishes this using the Chapel on statement
// The beauty here is that we are able to preserve the basic simplicity and
// readability of the original XMT implementation.

module Create_Parent_Tree
{
use Graph500_defs;

proc BFS ( root : vertex_id, ParentTree, G )
{

  type Vertex_List = domain (index(vertex_domain) );
  var visited$ : [vertex_domain] sync int = -1;

  var Active_Level: [rcDomain] Level_Set (Vertex_List);
  var Next_Level: [rcDomain] Level_Set (Vertex_List);
  var Active_Remaining: [LocaleSpace] bool = true;

  var Root_vertex : vertex_id = root;

  coforall loc in Locales do on loc {
    rcLocal(Active_Level) = new Level_Set (Vertex_List);
    rcLocal(Active_Level).previous = nil;
    rcLocal(Next_Level) = new Level_Set (Vertex_List);
    rcLocal(Next_Level).previous = rcLocal(Active_Level);
  }

  on G.Vertices(root) {
    rcLocal(Active_Level).Members.add ( root );
    rcLocal(Next_Level).Members.clear ();
    ParentTree[root] = root;
    visited$ (root).writeFF(1);
    rcLocal (Active_Level).previous = nil;
    rcLocal (Next_Level).previous = rcLocal (Active_Level);
  }

  while || reduce Active_Remaining do {

    // barrier
    var count: sync int = numLocales;
    var barrier: single bool;

    coforall loc in Locales do on loc {
      forall u in rcLocal(Active_Level).Members do {

        forall v in G.Neighbors (u) do on v {

          if ( visited$ (v).readXX() < 0 )
          {
            if (visited$ (v).readFE() < 0 )
            {
                visited$ (v).writeEF (1);
                rcLocal(Next_Level).Members.add (v);
                ParentTree (v) = u;
            }
            else
            {
                visited$ (v).writeEF(1);
            }
          }
        }

      }

// barrier needed to insure all updates to Next_Level are complete

      var myc = count;
      if myc==1 {
        barrier=true;
      } else {
        count = myc-1;
        barrier;
      }

      rcLocal(Active_Level) = rcLocal(Next_Level);
      rcLocal(Next_Level) = new Level_Set (Vertex_List);

      rcLocal(Next_Level).previous = rcLocal(Active_Level);

      Active_Remaining[here.id] = rcLocal(Active_Level).Members.numIndices:bool;

    }
  }

}

}

//This code was based on the XMT version of the Graph5000 benchmark submitted by
//John Feo <john.feo@pnl.gov> and Kristi Maschhoff <kristyn@cray.com> in 2010.

// This version incorporates ideas from Kamesh Madduri's implementation
// in terms of using a 1D distribution of the Vertex records, maintaining
// a distributed queue, and sending work to the locale which owns a particular
// vertex. Chapel accomplishes this using the Chapel on statement
// The beauty here is that we are able to preserve the basic simplicity and
// readability of the original XMT implementation.

module Create_Parent_Tree
{
use Graph500_defs;

proc BFS ( root : vertex_id, ParentTree, G )
{

  type Vertex_List = domain (index(vertex_domain) );
  var visited$ : [vertex_domain] sync int = -1;

  var Active_Level: [rcDomain] Level_Set (Vertex_List);
  var Next_Level: [rcDomain] Level_Set (Vertex_List);
  var Active_Remaining: [LocaleSpace] bool = true;

  var Root_vertex : vertex_id = root;

  coforall loc in Locales do on loc {
    rcLocal(Active_Level) = new Level_Set (Vertex_List);
    rcLocal(Active_Level).previous = nil;
    rcLocal(Next_Level) = new Level_Set (Vertex_List);
    rcLocal(Next_Level).previous = rcLocal(Active_Level);
  }

  on G.Vertices(root) {
    rcLocal(Active_Level).Members.add ( root );
    rcLocal(Next_Level).Members.clear ();
    ParentTree[root] = root;
    visited$ (root).writeFF(1);
    rcLocal (Active_Level).previous = nil;
    rcLocal (Next_Level).previous = rcLocal (Active_Level);
  }

  while || reduce Active_Remaining do {

    coforall loc in Locales do on loc {
      forall u in rcLocal(Active_Level).Members do {

        forall v in G.Neighbors (u) do on v {

          if ( visited$ (v).readXX() < 0 )
          {
            if (visited$ (v).readFE() < 0 )
            {
                visited$ (v).writeEF (1);
                rcLocal(Next_Level).Members.add (v);
                ParentTree (v) = u;
            }
            else
            {
                visited$ (v).writeEF(1);
            }
          }
        }

      }

      rcLocal(Active_Level) = rcLocal(Next_Level);
      rcLocal(Next_Level) = new Level_Set (Vertex_List);

      rcLocal(Next_Level).previous = rcLocal(Active_Level);

      Active_Remaining[here.id] = rcLocal(Active_Level).Members.numIndices:bool;

    }
  }

}

}


Make more general

Make more general

use FFTW;

proc printcmp(x, y) {
	var err = max reduce abs(x-y);
	writeln(err);
}

/* Read in the data and set up the domains appropriately */
param ndim : int = 1;
var dims : ndim*int(32);
var D : domain(ndim);
// Define ranges here
var rD,cD,reD,imD : domain(ndim,int,true);
var A,B,goodA,goodB : [D] fftw_complex;
{
	var f = open("arr1d.dat",iomode.r).reader(kind=iokind.little);
	for ii in 1..ndim {
		f.read(dims(ii));
	}
	D = 0.. #dims(ndim);
	for (r,c) in goodA {
		f.read(r);
		c = 0;
	}
	for (r,c) in goodB {
		f.read(r); f.read(c);
	}
	f.close();
}
// Set up domains based on dimension size
var first : ndim*int;
if (ndim==1) {
	// Domains for real FFT
	rD = 0.. #(2*(dims(ndim)/2 + 1)); // Padding to do in place transforms
	cD = 0.. #(dims(ndim)/2 + 1);
	// Define domains to extract the real and imaginary parts
	reD = rD[0..(2*(dims(ndim)/2)+1) by 2]; // Padding to do in place transforms
	imD = rD[1..(2*(dims(ndim)/2) + 1) by 2]; // Padding to do in place transforms
	first=(0,);
}

// FFTW does not normalize inverse transform, set up norm
var norm = * reduce dims;

// FFT testing here
var fwd = plan_dft_1d(dims, A[first],B[first],FFTW_FORWARD,FFTW_ESTIMATE);
var rev = plan_dft_1d(dims, B[first],A[first],FFTW_BACKWARD,FFTW_ESTIMATE);
// Test forward and reverse transform
A = goodA;
execute(fwd);
printcmp(B,goodB);
execute(rev);
A /= norm;
printcmp(A,goodA);
destroy_plan(fwd);
destroy_plan(rev);

// Test in-place transforms
fwd = plan_dft_1d(dims,A[first],A[first],FFTW_FORWARD,FFTW_ESTIMATE);
rev = plan_dft_1d(dims,A[first],A[first],FFTW_BACKWARD,FFTW_ESTIMATE);
A = goodA;
// Test forward and reverse transform
A = goodA;
execute(fwd);
printcmp(A,goodB);
execute(rev);
A /= norm; // FFTW does an unnormalized transform
printcmp(A,goodA);
destroy_plan(fwd);
destroy_plan(rev);

// Testing r2c and c2r
var rA : [rD] real(64);
var cB : [cD] fftw_complex;
fwd = plan_dft_r2c_1d(dims,rA[first],cB[first],FFTW_ESTIMATE);
rev = plan_dft_c2r_1d(dims,cB[first],rA[first],FFTW_ESTIMATE);
rA[D] = re(goodA);
execute(fwd);
printcmp(cB,goodB[cD]);
execute(rev);
rA /= norm;
printcmp(rA[D],re(goodA));
destroy_plan(fwd);
destroy_plan(rev);
// In place transform
fwd = plan_dft_r2c_1d(dims,rA[first],rA[first],FFTW_ESTIMATE);
rev = plan_dft_c2r_1d(dims,rA[first],rA[first],FFTW_ESTIMATE);
rA[D] = re(goodA);
execute(fwd);
printcmp(rA[reD],re(goodB[cD]));
printcmp(rA[imD],im(goodB[cD]));
execute(rev);
rA /= norm;
printcmp(rA[D],re(goodA));
destroy_plan(fwd);
destroy_plan(rev);

use FFTW;

proc printcmp(x, y) {
	var err = max reduce abs(x-y);
	writeln(err);
}

/* Read in the data and set up the domains appropriately */
param ndim : int = 1;
var dims : ndim*int(32);
var D : domain(ndim);
// Define ranges here
var rD,cD,reD,imD : domain(ndim,int,true);
var A,B,goodA,goodB : [D] fftw_complex;
{
	var f = open("arr1d.dat",iomode.r).reader(kind=iokind.little);
	for ii in 1..ndim {
		f.read(dims(ii));
	}
	D = 0.. #dims(1);
	for (r,c) in goodA {
		f.read(r);
		c = 0;
	}
	for (r,c) in goodB {
		f.read(r); f.read(c);
	}
	f.close();
}
// Set up domains based on dimension size
var first : ndim*int;
if (ndim==1) {
	// Domains for real FFT
	rD = 0.. #(2*(dims(1)/2 + 1)); // Padding to do in place transforms
	cD = 0.. #(dims(1)/2 + 1);
	// Define domains to extract the real and imaginary parts
	reD = rD[0..(2*(dims(1)/2)+1) by 2]; // Padding to do in place transforms
	imD = rD[1..(2*(dims(1)/2) + 1) by 2]; // Padding to do in place transforms
	first=(0,);
}

// FFTW does not normalize inverse transform, set up norm
var norm = * reduce dims;

// FFT testing here
var fwd = plan_dft_1d(dims, A[first],B[first],FFTW_FORWARD,FFTW_ESTIMATE);
var rev = plan_dft_1d(dims, B[first],A[first],FFTW_BACKWARD,FFTW_ESTIMATE);
// Test forward and reverse transform
A = goodA;
execute(fwd);
printcmp(B,goodB);
execute(rev);
A /= norm;
printcmp(A,goodA);
destroy_plan(fwd);
destroy_plan(rev);

// Test in-place transforms
fwd = plan_dft_1d(dims,A[first],A[first],FFTW_FORWARD,FFTW_ESTIMATE);
rev = plan_dft_1d(dims,A[first],A[first],FFTW_BACKWARD,FFTW_ESTIMATE);
A = goodA;
// Test forward and reverse transform
A = goodA;
execute(fwd);
printcmp(A,goodB);
execute(rev);
A /= norm; // FFTW does an unnormalized transform
printcmp(A,goodA);
destroy_plan(fwd);
destroy_plan(rev);

// Testing r2c and c2r
var rA : [rD] real(64);
var cB : [cD] fftw_complex;
fwd = plan_dft_r2c_1d(dims,rA[first],cB[first],FFTW_ESTIMATE);
rev = plan_dft_c2r_1d(dims,cB[first],rA[first],FFTW_ESTIMATE);
rA[D] = re(goodA);
execute(fwd);
printcmp(cB,goodB[cD]);
execute(rev);
rA /= norm;
printcmp(rA[D],re(goodA));
destroy_plan(fwd);
destroy_plan(rev);
// In place transform
fwd = plan_dft_r2c_1d(dims,rA[first],rA[first],FFTW_ESTIMATE);
rev = plan_dft_c2r_1d(dims,rA[first],rA[first],FFTW_ESTIMATE);
rA[D] = re(goodA);
execute(fwd);
printcmp(rA[reD],re(goodB[cD]));
printcmp(rA[imD],im(goodB[cD]));
execute(rev);
rA /= norm;
printcmp(rA[D],re(goodA));
destroy_plan(fwd);
destroy_plan(rev);


Revise ref counting implementation, to catch more failures in sharedRefCount2.chpl

We need to get the compiler to bind the assignment operator defined for Handle
to get the expected failure.  Right now, the compiler only binds the version that
does not have ref intent on either operand.

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

// refCountedType.chpl
//
// Implementation of a reference counted type for use in other tests.
//

// The implementation of a reference-counted type.
// Invariants:
//  - The contents of the reference count in the implementation is always
//    equal to the number of handles pointing to it.
class Impl
{
  var count: int; // The reference count
  var value: real; // the payload.

  proc retain() { count += 1; }
  proc release() : int { count -= 1; return count; }
}

// A handle to the reference-counted type,.
// Copying a handle creates a new reference to the implementation, so the
// reference count therein must be increased.
// Deleting a handle removes a reference from the implementation, so the
// reference count therein must be decremented.
// When the reference count goes to zero, the implementation is deleted.
record Handle
{
  var _impl : Impl;
//  ctor Handle() { _impl = nil; } // Future
//  ctor Handle(val: real) { _impl = new Impl(1, val); }
  proc Handle(val: real) { _impl = new Impl(1, val); }
// Copy-constructors are not yet implemented.  See chpl__initCopy() below.
//  ctor Handle(ref h: Handle) { _impl = h._impl; _impl.retain(); }
  proc ~Handle() { if _impl != nil && _impl.release() == 0 { delete _impl; _impl = nil; } }

// Accessor
  proc value return _impl.value;
}

// Copy-constructor implementation
// This should really be named chpl__autoCopy in the current vernacular, but
// that is really moot under the assumption that both will be replaced by a
// proper copy-constructor.
// The argument should have ref intent, which is also a minor point.
pragma "init copy fn"
proc chpl__initCopy(h: Handle)
{
  if h._impl == nil then halt("Illegal copy of unintialized Handle.");

  h._impl.retain();
  return h;
  // The returned value is copied bit-by-bit into the storage allocated to hold
  // it in the caller, but without calling the copy-constructor (which, of
  // course, would cause infinite recursion.
  // The caller is responsible for calling ~Handle() on the value thus
  // initialized, or memory will be leaked.
}

// The incorrectly-implemented POD optimization causes the chpl__initCopy routine to
// fail to be called.

// Assignment
// proc =(ref lhs: Handle, ref rhs:Handle)
// This signature does not work.  We get:
// sharedRefCount.chpl:8: In function 'foo':
// sharedRefCount.chpl:14: error: non-lvalue actual is passed to 'ref' formal 'rhs' of = [functionResolution.cpp:2543]
// which means that there is no ref promotion...
// proc =(ref lhs: Handle, rhs:Handle)
// That's where we want to go, but we're not there yet.  Again, since there is
// no ref promotion, we don't bind the lhs either, and end up using the
// catch-all implementation on line 242 of ChapelBase.chpl.
// We have to bind to this version, or we don't get the desired
// reference-counting behavior
proc =(lhs: Handle, rhs:Handle)
{
  // The rhs gains a new reference.
  if rhs._impl == nil then halt("Illegal read of uninitialized Handle.");
  rhs._impl.retain();

  // The lhs loses a reference.
  if lhs._impl != nil && lhs._impl.release() == 0 { delete lhs._impl; lhs._impl = nil; }

  // The handle now copies a reference to its implementation from the RHS.
  // The implementation is of class type, so this is a pointer copy.
  lhs._impl = rhs._impl;
}

// refCountedType.chpl
//
// Implementation of a reference counted type for use in other tests.
//

// The implementation of a reference-counted type.
// Invariants:
//  - The contents of the reference count in the implementation is always
//    equal to the number of handles pointing to it.
class Impl
{
  var count: int; // The reference count
  var value: real; // the payload.

  proc retain() { count += 1; }
  proc release() : int { count -= 1; return count; }
}

// A handle to the reference-counted type,.
// Copying a handle creates a new reference to the implementation, so the
// reference count therein must be increased.
// Deleting a handle removes a reference from the implementation, so the
// reference count therein must be decremented.
// When the reference count goes to zero, the implementation is deleted.
record Handle
{
  var _impl : Impl;
//  ctor Handle() { _impl = nil; } // Future
//  ctor Handle(val: real) { _impl = new Impl(1, val); }
  proc Handle(val: real) { _impl = new Impl(1, val); }
// Copy-constructors are not yet implemented.  See chpl__initCopy() below.
//  ctor Handle(ref h: Handle) { _impl = h._impl; _impl.retain(); }
  proc ~Handle() { if _impl != nil && _impl.release() == 0 { delete _impl; _impl = nil; } }

// Accessor
  proc value return _impl.value;
}

// Copy-constructor implementation
// This should really be named chpl__autoCopy in the current vernacular, but
// that is really moot under the assumption that both will be replaced by a
// proper copy-constructor.
// The argument should have ref intent, which is also a minor point.
pragma "init copy fn"
proc chpl__initCopy(h: Handle)
{
  if h._impl == nil then halt("Illegal copy of unintialized Handle.");

  h._impl.retain();
  return h;
  // The returned value is copied bit-by-bit into the storage allocated to hold
  // it in the caller, but without calling the copy-constructor (which, of
  // course, would cause infinite recursion.
  // The caller is responsible for calling ~Handle() on the value thus
  // initialized, or memory will be leaked.
}

// Assignment
   // proc =(ref lhs: Handle, ref rhs:Handle)
      // This signature does not work.  We get
         //sharedRefCount.chpl:8: In function 'foo':
// sharedRefCount.chpl:14: error: non-lvalue actual is passed to 'ref' formal 'rhs' of = [functionResolution.cpp:2543]
// which means that there is no ref promotion...
proc =(ref lhs: Handle, rhs:Handle)
{
  // The rhs gains a new reference.
  if rhs._impl == nil then halt("Illegal read of uninitialized Handle.");
  rhs._impl.retain();

  // The lhs loses a reference.
  if lhs._impl != nil && lhs._impl.release() == 0 { delete lhs._impl; lhs._impl = nil; }

  // The handle now copies a reference to its implementation from the RHS.
  // The implementation is of class type, so this is a pointer copy.
  lhs._impl = rhs._impl;
}