Example : Collect.C

Classes/Techniques Demonstrated :

Collect.C

This example demonstrates use of the HPCxx_Collective class. The example is similar to both the Reduct and the Barrier examples in that a shared array is involved. In this example, however, each thread starts out only with its own small local array and obtains from the Collective gather operation a pointer to a large shared array, produced by the concatenation of the local arrays. In order to control synchronization, the main process also participates in the Collective operation, but the size of its local array is 0 so it does not contribute any elements to the final array.


#include <iostream.h>
#include <hpcxx_rts.h>
#include <hpcxx_invoke.cc>

class MyThread : public HPCxx_Thread {
  HPCxx_Collective<int> &coll;
  HPCxx_Barrier &barrier;
  int *infoAr, *newAr;
  int totalThreads, myId, count, myCollectKey, myBarrierKey;
  
public:
  MyThread(int n, int id, HPCxx_Collective<int> &_coll, 
	   HPCxx_Barrier& _barrier) :
    totalThreads(n), myId(id), coll(_coll), barrier(_barrier),
    HPCxx_Thread()
  {
      myCollectKey=coll.acquireKey();
      myBarrierKey=barrier.getKey();
  }
  
  void run() {
    int size=10;
    int total=0;
    infoAr=new int[10];
    
    cout << "Thread " << myId << " generating array values..." << endl;
 
    for(count=0; count<10; count++) {
      infoAr[count]=(int)(1000*drand48());
    }
    
    cout << "Thread " << myId << " passing to collection..." << endl;

    newAr=coll.gather(myCollectKey, infoAr, size);

    for(count=0; count<totalThreads*10; count++) {
      total+=newAr[count];
    }
    cout << "Thread " << myId << " computed sum " << total 
      << "  Size returned was " << size << endl;
    barrier(myBarrierKey);
  } 
};

int run_threads(int n, HPCxx_Collective<int> coll, HPCxx_Barrier& barrier){
  MyThread *t[100];
  int key0, key1, size=0, total = 0, count;
  int *infoAr, *newAr;

  // give the main process a key to the collection and barrier
  key0=coll.acquireKey();
  key1=barrier.getKey();

  for(int i = 0; i < n; i++){
    t[i] = new MyThread(n, i, coll, barrier);
    t[i]->start();
  }  

  // participate in gather, but local size is 0
  newAr=coll.gather(key0, infoAr, size);

  for(count=0; count< n*10; count++) {
    cout << "newAr[" << count << "] = " << newAr[count] << endl;
    total+=newAr[count];
  }
  cout << "Main process computed sum " << total 
    << "  Size returned was " << size << endl;

  // wait here until all of the threads are finished 
  //   with printing
  barrier(key1);
  return 0;
}


int main(int argc, char **argv)
{
  HPCxx_Group *g;
  int num_threads;

  hpcxx_init(argc, argv, g);

  cout << "enter number of threads: " ;
  cin >> num_threads;
  cout << "using " << num_threads << " threads." << endl << flush;
  g->setNumThreads(num_threads+1);

  HPCxx_Collective<int> coll(g);
  HPCxx_Barrier barrier(*g);
  run_threads(num_threads, coll, barrier);
  cout << "DONE" << endl;
  return hpcxx_exit(g);
}

Benjamin Temko
Last modified: Fri Jun 26 11:06:45 EST 1998