#include <stdio.h>
#include <mpi.h>
#include <binarysearch.hpp>

template<class SystemInfo>
void csm1MPI(int* c, int* pl, int* pcl, double* key, int nc, int numproc, int cpp, double totups, SystemInfo *iclass, int myid, int arrswitch)
{
  double r;
  int i, k;
  for(k=0; k<cpp; k++)
  {
    i = k*numproc + myid; //For each system associated with each processor
    if(i<nc)
    {
      r = (iclass[(1-arrswitch)*cpp + k]->randc())*totups; //Generate a random number from 0 to the total of upsilon
      c[i] = binsearch(key, r, nc + 1); //Use this random number to select a system to clone
      pl[i] = c[i] % numproc; //Determine associated processor
      pcl[pl[i]] += 1; //Record communication between processors
    }
  }
}

template<class SystemInfo>
void csm2MPI(int* c, int* pl, int* pcl, double* key, int nc, int numproc, int cpp, double totups, SystemInfo* iclass, int myid, int arrswitch)
{
  double r, rc;
  int i, k;
  if(myid==0)
  {
    rc = (iclass[(1-arrswitch)*cpp]->randc())*totups/double(nc);
  }
  MPI_Bcast(&rc, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  for(k=0; k<cpp; k++)
  {
    i = k*numproc + myid; //For each clone associated with each processor
    if (i<nc)
    {
      r = rc+(double(i)*totups/double(nc)); //Place markers at regular intervals
      c[i] = binsearch(key, r, nc + 1); //Use these markers to select systems to clone
      pl[i] = c[i] % numproc; //Determine associated processor
      pcl[pl[i]] += 1; //Record communication between processors
    }
  }
}
