Esempio n. 1
0
//********************************************************************
//
// Chang Robert's algorithm function
//
// This function performs Chang and Robert's algrithom
//
// Return Value
// ------------
// void                         
//
//
// Reference Parameters
// --------------------
// rank                     INT				            MPI processor rank number
// id                       INT*                        MPI processor random id
// size                     INT                         MPI processor numbers
// right                    INT                         The right neighbor of processor
// left                     INT                         The left neighbor of processor
// state_status             INT                         Define the participation of a processor
// count                    INT                         Count how many phase the processor has been through
// election                 INT*                        The election message array
// elected                  INT*                        The elected message array
// requests                 MPI_REQUEST                 The MPI requests in unblocking message
// status                   MPI_STATUS                  The MPI status
// flag                     INT                         The MPI flags used in MPI_Test
//
// Local Variables
// ---------------
// NONE
//*******************************************************************
void chang_robert(int rank, int size, int* id, int right, int left, int* count, int* flag, int* election, int* elected, int* state_status, MPI_Request requests, MPI_Status status)
{
	MPI_Irecv(election, 2, MPI_INT, left, 100, MPI_COMM_WORLD, &requests);
    
	MPI_Test(&requests, &flag[left], &status);
	while (!flag[left])
		MPI_Test(&requests, &flag[left], &status);

	if (election[1] == -1)
	{
		*count++;

		if (election[0] > *id)
		{
			printf("Phase: %d, Rank:  %d, Identifier: %d, Status: Passive\n", *count+1, rank, *id);
			fflush(stdout);

			if (*state_status == NONPARTICIPANT)
				*state_status = PARTICIPANT;
			MPI_Send(election, 2, MPI_INT, right, 100, MPI_COMM_WORLD);
		}
		else if (election[0] < *id)
		{
			printf("Phase: %d, Rank:  %d, Identifier: %d, Status: Active\n", *count+1, rank, *id);
			fflush(stdout);

			if (*state_status == NONPARTICIPANT)
			{
				*state_status = PARTICIPANT; 
				election[0] = *id;
				MPI_Send(election, 2, MPI_INT, right, 100, MPI_COMM_WORLD);
			}	
		}
		else
		{
            printf("Phase: %d, Rank:  %d, Identifier: %d, Status: Active\n", *count+1, rank, *id);
            fflush(stdout);

			*state_status = NONPARTICIPANT;
			election[1] = rank;
			MPI_Send(election, 2, MPI_INT, right, 100, MPI_COMM_WORLD);	
			fflush(stdout);
		}
	}
	else
	{
		elected[0] = election[0];
		elected[1] = election[1];
		election = NULL;

		if (elected[0] != *id)
		{
			*state_status = NONPARTICIPANT;
			MPI_Send(elected, 2, MPI_INT, right, 100, MPI_COMM_WORLD);
		}
        
		else if(elected[0] == *id)
        {
			printf("I am the Leader and my Rank is: %d and my Identifier is: %d\n", rank, *id);
            fflush(stdout);
        }

	}
}
 void peano::applications::faxen::repositories::FaxenBatchJobRepositoryStatePacked::receive(int source, int tag) {
    MPI_Request* sendRequestHandle = new MPI_Request();
    MPI_Status   status;
    int          flag = 0;
    int          result;
    
    clock_t      timeOutWarning   = -1;
    clock_t      timeOutShutdown  = -1;
    bool         triggeredTimeoutWarning = false;
    
    result = MPI_Irecv(
       this, 1, Datatype, source, tag,
       tarch::parallel::Node::getInstance().getCommunicator(), sendRequestHandle
    );
    if ( result != MPI_SUCCESS ) {
       std::ostringstream msg;
       msg << "failed to start to receive peano::applications::faxen::repositories::FaxenBatchJobRepositoryStatePacked from node "
       << source << ": " << tarch::parallel::MPIReturnValueToString(result);
       _log.error( "receive(int)", msg.str() );
    }
    
    result = MPI_Test( sendRequestHandle, &flag, &status );
    while (!flag) {
       if (timeOutWarning==-1)   timeOutWarning   = tarch::parallel::Node::getInstance().getDeadlockWarningTimeStamp();
       if (timeOutShutdown==-1)  timeOutShutdown  = tarch::parallel::Node::getInstance().getDeadlockTimeOutTimeStamp();
       result = MPI_Test( sendRequestHandle, &flag, &status );
       if (result!=MPI_SUCCESS) {
          std::ostringstream msg;
          msg << "testing for finished receive task for peano::applications::faxen::repositories::FaxenBatchJobRepositoryStatePacked failed: "
          << tarch::parallel::MPIReturnValueToString(result);
          _log.error("receive(int)", msg.str() );
       }
       
       // deadlock aspect
       if (
          tarch::parallel::Node::getInstance().isTimeOutWarningEnabled() &&
          (clock()>timeOutWarning) &&
          (!triggeredTimeoutWarning)
       ) {
          tarch::parallel::Node::getInstance().writeTimeOutWarning(
          "peano::applications::faxen::repositories::FaxenBatchJobRepositoryStatePacked",
          "receive(int)", source
          );
          triggeredTimeoutWarning = true;
       }
       if (
          tarch::parallel::Node::getInstance().isTimeOutDeadlockEnabled() &&
          (clock()>timeOutShutdown)
       ) {
          tarch::parallel::Node::getInstance().triggerDeadlockTimeOut(
          "peano::applications::faxen::repositories::FaxenBatchJobRepositoryStatePacked",
          "receive(int)", source
          );
       }
       tarch::parallel::Node::getInstance().receiveDanglingMessages();
    }
    
    delete sendRequestHandle;
    
    _senderRank = status.MPI_SOURCE;
    #ifdef Debug
    _log.debug("receive(int,int)", "received " + toString() ); 
    #endif
    
 }
Esempio n. 3
0
 inline bool test_impl(request_impl* r){
     int f = 0; MPI_Test(&r->mpi_request, &f, MPI_STATUS_IGNORE); return f;
 }
Esempio n. 4
0
static PetscErrorCode PetscCommBuildTwoSided_Ibarrier(MPI_Comm comm,PetscMPIInt count,MPI_Datatype dtype,PetscMPIInt nto,const PetscMPIInt *toranks,const void *todata,PetscMPIInt *nfrom,PetscMPIInt **fromranks,void *fromdata)
{
  PetscErrorCode ierr;
  PetscMPIInt    nrecvs,tag,done,i;
  MPI_Aint       lb,unitbytes;
  char           *tdata;
  MPI_Request    *sendreqs,barrier;
  PetscSegBuffer segrank,segdata;
  PetscBool      barrier_started;

  PetscFunctionBegin;
  ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
  ierr = MPI_Type_get_extent(dtype,&lb,&unitbytes);CHKERRQ(ierr);
  if (lb != 0) SETERRQ1(comm,PETSC_ERR_SUP,"Datatype with nonzero lower bound %ld\n",(long)lb);
  tdata = (char*)todata;
  ierr  = PetscMalloc1(nto,&sendreqs);CHKERRQ(ierr);
  for (i=0; i<nto; i++) {
    ierr = MPI_Issend((void*)(tdata+count*unitbytes*i),count,dtype,toranks[i],tag,comm,sendreqs+i);CHKERRQ(ierr);
  }
  ierr = PetscSegBufferCreate(sizeof(PetscMPIInt),4,&segrank);CHKERRQ(ierr);
  ierr = PetscSegBufferCreate(unitbytes,4*count,&segdata);CHKERRQ(ierr);

  nrecvs  = 0;
  barrier = MPI_REQUEST_NULL;
  /* MPICH-3.2 sometimes does not create a request in some "optimized" cases.  This is arguably a standard violation,
   * but we need to work around it. */
  barrier_started = PETSC_FALSE;
  for (done=0; !done; ) {
    PetscMPIInt flag;
    MPI_Status  status;
    ierr = MPI_Iprobe(MPI_ANY_SOURCE,tag,comm,&flag,&status);CHKERRQ(ierr);
    if (flag) {                 /* incoming message */
      PetscMPIInt *recvrank;
      void        *buf;
      ierr      = PetscSegBufferGet(segrank,1,&recvrank);CHKERRQ(ierr);
      ierr      = PetscSegBufferGet(segdata,count,&buf);CHKERRQ(ierr);
      *recvrank = status.MPI_SOURCE;
      ierr      = MPI_Recv(buf,count,dtype,status.MPI_SOURCE,tag,comm,MPI_STATUS_IGNORE);CHKERRQ(ierr);
      nrecvs++;
    }
    if (!barrier_started) {
      PetscMPIInt sent,nsends;
      ierr = PetscMPIIntCast(nto,&nsends);CHKERRQ(ierr);
      ierr = MPI_Testall(nsends,sendreqs,&sent,MPI_STATUSES_IGNORE);CHKERRQ(ierr);
      if (sent) {
#if defined(PETSC_HAVE_MPI_IBARRIER)
        ierr = MPI_Ibarrier(comm,&barrier);CHKERRQ(ierr);
#elif defined(PETSC_HAVE_MPIX_IBARRIER)
        ierr = MPIX_Ibarrier(comm,&barrier);CHKERRQ(ierr);
#endif
        barrier_started = PETSC_TRUE;
        ierr = PetscFree(sendreqs);CHKERRQ(ierr);
      }
    } else {
      ierr = MPI_Test(&barrier,&done,MPI_STATUS_IGNORE);CHKERRQ(ierr);
    }
  }
  *nfrom = nrecvs;
  ierr   = PetscSegBufferExtractAlloc(segrank,fromranks);CHKERRQ(ierr);
  ierr   = PetscSegBufferDestroy(&segrank);CHKERRQ(ierr);
  ierr   = PetscSegBufferExtractAlloc(segdata,fromdata);CHKERRQ(ierr);
  ierr   = PetscSegBufferDestroy(&segdata);CHKERRQ(ierr);
  ierr   = PetscCommDestroy(&comm);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Esempio n. 5
0
static int ADIOI_GEN_irc_poll_fn(void *extra_state, MPI_Status *status)
{
    ADIOI_NBC_Request *nbc_req;
    ADIOI_GEN_IreadStridedColl_vars *rsc_vars = NULL;
    ADIOI_Icalc_others_req_vars     *cor_vars = NULL;
    ADIOI_Iread_and_exch_vars       *rae_vars = NULL;
    ADIOI_R_Iexchange_data_vars     *red_vars = NULL;
    int errcode = MPI_SUCCESS;
    int flag;

    nbc_req = (ADIOI_NBC_Request *)extra_state;

    switch (nbc_req->data.rd.state) {
        case ADIOI_IRC_STATE_GEN_IREADSTRIDEDCOLL:
            rsc_vars = nbc_req->data.rd.rsc_vars;
            errcode = MPI_Testall(2, rsc_vars->req_offset, &flag,
                                  MPI_STATUSES_IGNORE);
            if (errcode == MPI_SUCCESS && flag) {
                ADIOI_GEN_IreadStridedColl_inter(nbc_req, &errcode);
            }
            break;

        case ADIOI_IRC_STATE_GEN_IREADSTRIDEDCOLL_INDIO:
            rsc_vars = nbc_req->data.rd.rsc_vars;
            errcode = MPI_Test(&rsc_vars->req_ind_io, &flag, MPI_STATUS_IGNORE);
            if (errcode == MPI_SUCCESS && flag) {
                /* call the last function */
                ADIOI_GEN_IreadStridedColl_fini(nbc_req, &errcode);
            }
            break;

        case ADIOI_IRC_STATE_ICALC_OTHERS_REQ:
            cor_vars = nbc_req->cor_vars;
            errcode = MPI_Test(&cor_vars->req1, &flag, MPI_STATUS_IGNORE);
            if (errcode == MPI_SUCCESS && flag) {
                ADIOI_Icalc_others_req_main(nbc_req, &errcode);
            }
            break;

        case ADIOI_IRC_STATE_ICALC_OTHERS_REQ_MAIN:
            cor_vars = nbc_req->cor_vars;
            if (cor_vars->num_req2) {
                errcode = MPI_Testall(cor_vars->num_req2, cor_vars->req2,
                                      &flag, MPI_STATUSES_IGNORE);
                if (errcode == MPI_SUCCESS && flag) {
                    ADIOI_Icalc_others_req_fini(nbc_req, &errcode);
                }
            } else {
                ADIOI_Icalc_others_req_fini(nbc_req, &errcode);
            }
            break;

        case ADIOI_IRC_STATE_IREAD_AND_EXCH:
            rae_vars = nbc_req->data.rd.rae_vars;
            errcode = MPI_Test(&rae_vars->req1, &flag, MPI_STATUS_IGNORE);
            if (errcode == MPI_SUCCESS && flag) {
                rae_vars->m = 0;
                ADIOI_Iread_and_exch_l1_begin(nbc_req, &errcode);
            }
            break;

        case ADIOI_IRC_STATE_IREAD_AND_EXCH_L1_BEGIN:
            rae_vars = nbc_req->data.rd.rae_vars;
            errcode = MPI_Test(&rae_vars->req2, &flag, MPI_STATUS_IGNORE);
            if (errcode == MPI_SUCCESS && flag) {
                ADIOI_R_Iexchange_data(nbc_req, &errcode);
            }
            break;

        case ADIOI_IRC_STATE_R_IEXCHANGE_DATA:
            red_vars = nbc_req->data.rd.red_vars;
            errcode = MPI_Test(&red_vars->req1, &flag, MPI_STATUS_IGNORE);
            if (errcode == MPI_SUCCESS && flag) {
                ADIOI_R_Iexchange_data_recv(nbc_req, &errcode);
            }
            break;

        case ADIOI_IRC_STATE_R_IEXCHANGE_DATA_RECV:
            red_vars = nbc_req->data.rd.red_vars;
            errcode = MPI_Testall(red_vars->nprocs_recv, red_vars->req2, &flag,
                                  MPI_STATUSES_IGNORE);
            if (errcode == MPI_SUCCESS && flag) {
                ADIOI_R_Iexchange_data_fill(nbc_req, &errcode);
            }
            break;

        case ADIOI_IRC_STATE_R_IEXCHANGE_DATA_FILL:
            red_vars = nbc_req->data.rd.red_vars;
            errcode = MPI_Testall(red_vars->nprocs_send,
                                  red_vars->req2 + red_vars->nprocs_recv,
                                  &flag, MPI_STATUSES_IGNORE);
            if (errcode == MPI_SUCCESS && flag) {
                ADIOI_R_Iexchange_data_fini(nbc_req, &errcode);
            }
            break;

        default:
            break;
    }

    /* --BEGIN ERROR HANDLING-- */
    if (errcode != MPI_SUCCESS) {
        errcode = MPIO_Err_create_code(MPI_SUCCESS,
                MPIR_ERR_RECOVERABLE,
                "ADIOI_GEN_irc_poll_fn", __LINE__,
                MPI_ERR_IO, "**mpi_grequest_complete",
                0);
    }
    /* --END ERROR HANDLING-- */

    return errcode;
}
Esempio n. 6
0
double
do_compute_and_probe(double seconds, MPI_Request* request)
{
    double t1 = 0.0, t2 = 0.0;
    double test_time = 0.0;
    int num_tests = 0;
    double target_seconds_for_compute = 0.0;
    int flag = 0;
    MPI_Status status;

    if (options.num_probes) {
        target_seconds_for_compute = (double) seconds/options.num_probes;
        if (DEBUG) fprintf(stderr, "setting target seconds to %f\n", (target_seconds_for_compute * 1e6 ));
    } 
    else {
        target_seconds_for_compute = seconds;
        if (DEBUG) fprintf(stderr, "setting target seconds to %f\n", (target_seconds_for_compute * 1e6 ));
    }

#ifdef _ENABLE_CUDA_KERNEL_
    if (options.target == gpu) {
        if (options.num_probes) {
            /* Do the dummy compute on GPU only */
            do_compute_gpu(target_seconds_for_compute);
            num_tests = 0;
            while (num_tests < options.num_probes) {
                t1 = MPI_Wtime();
                MPI_Test(request, &flag, &status);
                t2 = MPI_Wtime();
                test_time += (t2-t1);
                num_tests++;
            }
        }
        else {
            do_compute_gpu(target_seconds_for_compute);
        }
    }
    else if (options.target == both) {
        if (options.num_probes) {
            /* Do the dummy compute on GPU and CPU*/
            do_compute_gpu(target_seconds_for_compute);
            num_tests = 0;
            while (num_tests < options.num_probes) {
                t1 = MPI_Wtime();
                MPI_Test(request, &flag, &status);
                t2 = MPI_Wtime();
                test_time += (t2-t1);
                num_tests++;
                do_compute_cpu(target_seconds_for_compute);
            }
        } 
        else {
            do_compute_gpu(target_seconds_for_compute);
            do_compute_cpu(target_seconds_for_compute);
        }        
    }
    else
#endif
    if (options.target == cpu) {
        if (options.num_probes) {
            num_tests = 0;
            while (num_tests < options.num_probes) {
                do_compute_cpu(target_seconds_for_compute);
                t1 = MPI_Wtime();
                MPI_Test(request, &flag, &status);
                t2 = MPI_Wtime();
                test_time += (t2-t1);
                num_tests++;
            }
        }
        else {
            do_compute_cpu(target_seconds_for_compute);
        }
    }

#ifdef _ENABLE_CUDA_KERNEL_
    if (options.target == gpu || options.target == both) {
        cudaDeviceSynchronize();    
        cudaStreamDestroy(stream);
    }
#endif
    
    return test_time;
}
 void tarch::parallel::messages::NodePoolAnswerMessagePacked::send(int destination, int tag, bool exchangeOnlyAttributesMarkedWithParallelise) {
    MPI_Request* sendRequestHandle = new MPI_Request();
    MPI_Status   status;
    int          flag = 0;
    int          result;
    
    clock_t      timeOutWarning   = -1;
    clock_t      timeOutShutdown  = -1;
    bool         triggeredTimeoutWarning = false;
    
    #ifdef Asserts
    _senderRank = -1;
    #endif
    
    if (exchangeOnlyAttributesMarkedWithParallelise) {
       result = MPI_Isend(
          this, 1, Datatype, destination,
          tag, tarch::parallel::Node::getInstance().getCommunicator(),
          sendRequestHandle
       );
       
    }
    else {
       result = MPI_Isend(
          this, 1, FullDatatype, destination,
          tag, tarch::parallel::Node::getInstance().getCommunicator(),
          sendRequestHandle
       );
       
    }
    if  (result!=MPI_SUCCESS) {
       std::ostringstream msg;
       msg << "was not able to send message tarch::parallel::messages::NodePoolAnswerMessagePacked "
       << toString()
       << " to node " << destination
       << ": " << tarch::parallel::MPIReturnValueToString(result);
       _log.error( "send(int)",msg.str() );
    }
    result = MPI_Test( sendRequestHandle, &flag, &status );
    while (!flag) {
       if (timeOutWarning==-1)   timeOutWarning   = tarch::parallel::Node::getInstance().getDeadlockWarningTimeStamp();
       if (timeOutShutdown==-1)  timeOutShutdown  = tarch::parallel::Node::getInstance().getDeadlockTimeOutTimeStamp();
       result = MPI_Test( sendRequestHandle, &flag, &status );
       if (result!=MPI_SUCCESS) {
          std::ostringstream msg;
          msg << "testing for finished send task for tarch::parallel::messages::NodePoolAnswerMessagePacked "
          << toString()
          << " sent to node " << destination
          << " failed: " << tarch::parallel::MPIReturnValueToString(result);
          _log.error("send(int)", msg.str() );
       }
       
       // deadlock aspect
       if (
          tarch::parallel::Node::getInstance().isTimeOutWarningEnabled() &&
          (clock()>timeOutWarning) &&
          (!triggeredTimeoutWarning)
       ) {
          tarch::parallel::Node::getInstance().writeTimeOutWarning(
          "tarch::parallel::messages::NodePoolAnswerMessagePacked",
          "send(int)", destination,tag,1
          );
          triggeredTimeoutWarning = true;
       }
       if (
          tarch::parallel::Node::getInstance().isTimeOutDeadlockEnabled() &&
          (clock()>timeOutShutdown)
       ) {
          tarch::parallel::Node::getInstance().triggerDeadlockTimeOut(
          "tarch::parallel::messages::NodePoolAnswerMessagePacked",
          "send(int)", destination,tag,1
          );
       }
       tarch::parallel::Node::getInstance().receiveDanglingMessages();
    }
    
    delete sendRequestHandle;
    #ifdef Debug
    _log.debug("send(int,int)", "sent " + toString() );
    #endif
    
 }
Esempio n. 8
0
/* slave 进程 */
void worker()
{
    printf("\tProcessor %d at %s begin work..\n", myid, processor_name);

    MPI_Status status;
    MPI_Request handle;

    int recv_flag = 0;
    int count = 0;
    int upload = 0;

    // 非阻塞接收主进程消息
    MPI_Irecv(selectedGenes, n, MPI_GENETYPE, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &handle);

    while(1)
    {
        // 独立繁衍count代
        count = generations;
        while(count--)
        {
            select();
            crossover();
            mutate();
            evaluate();
            prefer();
            // 若满足终止条件,则向主进程发送最优路径,并结束进程
            if(population[CARDINALITY].fitness <= optimal+margin)
            {
                printf("\tProcessor %d at %s Terminated\n", myid, processor_name);
                MPI_Send(&population[CARDINALITY], 1, MPI_GENETYPE, 0, DONE_TAG, MPI_COMM_WORLD);
                printf("\tProcessor %d at %s exit\n", myid, processor_name);
                return;
            }
            // 探测是否收到主进程的消息
            MPI_Test(&handle, &recv_flag, &status);
            // 若收到主进程的消息
            if(recv_flag)
            {
                printf("\tProcessor %d at %s recv %d\n", myid, processor_name, status.MPI_TAG);

                // 状态重置
                recv_flag = 0;
                // 若接收到DONE_TAG则结束进程
                if(status.MPI_TAG == DONE_TAG)
                {
                    printf("\tProcessor %d at %s exit\n", myid, processor_name);
                    return;
                }
                // 否则,将接收到的优良个体替换种群中最差的个体
                qsort(population, CARDINALITY, sizeof(GeneType), compare);
                for(int i=1; i <= n; i++)
                    assign(&population[CARDINALITY-i], &selectedGenes[i-1]);
                if(selectedGenes[0].fitness < population[CARDINALITY].fitness)
                    assign(&population[CARDINALITY], &selectedGenes[0]);

                // 非阻塞接收主进程消息
                MPI_Irecv(selectedGenes, n, MPI_GENETYPE, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &handle);
            }
        }
        // 繁衍count代后,若没有终止则向主进程发送最优个体
        select_N_best(n);
        MPI_Send(selectedGenes, n, MPI_GENETYPE, 0, PUT_BETTER_TAG, MPI_COMM_WORLD);
        printf("\tProcessor %d at %s upload %d\n", myid, processor_name, upload++);
    }
}
int main (int argc, char *argv[]){
	MPI_Init	(&argc,&argv);
    	MPI_Comm_size	(MPI_COMM_WORLD,&numtasks);
    	MPI_Comm_rank	(MPI_COMM_WORLD,&rank);
	STEPS	= 50;
	NX	= 800;
	NY	= 400;
	NZ	= 30;
	x_partition_count = 2;
	y_partition_count = 1;
	z_partition_count = 1;
	
	for(i=1; i<argc; ++i) {
		if(!strcmp(argv[i], "s"))
			STEPS = atoi(argv[i+1]);
		else if(!strcmp(argv[i], "x"))
			NX = atoi(argv[i+1]);
		else if(!strcmp(argv[i],"y"))
			NY = atoi(argv[i+1]);
		else if(!strcmp(argv[i],"z"))
			NZ = atoi(argv[i+1]);
		else if(!strcmp(argv[i],"px"))
			x_partition_count = atoi(argv[i+1]);
		else if(!strcmp(argv[i],"py"))
			y_partition_count = atoi(argv[i+1]);
		else if(!strcmp(argv[i],"pz"))
			z_partition_count = atoi(argv[i+1]);
	}
	
	rank_mass = total_mass/(double)numtasks;
	
	if(rank == 0) {
		printf("\n\n==================================\n==========SESSION START===========\n==================================\n"
	        	"Program size (x/y/z/steps): %d x %d x %d x %d\n"
				"Partition grid (x/y/z): %d x %d x %d\n", 
					NX, NY, NZ, STEPS, x_partition_count, y_partition_count, z_partition_count);
		fp = fopen("log.txt", "a");
		fprintf(fp,"%dx%dx%dx%d\n%dx%dx%d\n%d processes\n\n",
				NX, NY, NZ, STEPS, x_partition_count, y_partition_count, z_partition_count,
					x_partition_count * y_partition_count * z_partition_count);
		if(!(NX && NY && NZ && x_partition_count && y_partition_count && z_partition_count)){
			puts("Elements/Grid zero, cannot continue\n"\
				"Use -x  <number> to input x elements count\n"\
				"Use -y  <number> to input y elements count\n"\
				"Use -z  <number> to input z elements count\n"\
				"Use -s  <number> to input step count\n"\
				"Use -px <number> to input x-dimension partition count\n"\
				"Use -py <number> to input y-dimension partition count\n"\
				"Use -pz <number> to input z-dimension partition count\n"\
				);
			//getchar();
			return;
		}
	}
	
	#pragma omp parallel
	{
		if((rank==0) && (omp_get_thread_num() == 0)) 
			printf("Internal element processing threads (OpenMP parallelization): %d\n", omp_get_num_threads());
	}
	MPI_Barrier(MPI_COMM_WORLD); //for printf to apper in order
	// ================================START Data partition assignment================================
	
	x_length = NX/x_partition_count;		//Divide elements uniformly among partitions
	x_rank	 = rank % x_partition_count;		//rank, as is "partition rank"
	x_start	 = x_rank * x_length ;			//min
	x_end	 = (x_rank+1) * x_length - 1;

	y_length = NY/y_partition_count;
	y_rank	 = (rank  / x_partition_count ) % y_partition_count; //rank, as is "partition rank"
	y_start	 = y_rank * y_length;			//min
	y_end	 = (y_rank+1) * y_length - 1;
		
	z_length = NZ/z_partition_count;	
	z_rank	 = rank / (x_partition_count*y_partition_count);
	z_start	 = z_rank * z_length;			//min
	z_end	 = (z_rank+1) * z_length - 1;
	
	printf("Rank %d range: x(%d-%d) of %d, y(%d-%d) of %d, z(%d-%d) of %d\n",
					rank, x_start, x_end, NX, y_start, y_end, NY, z_start, z_end, NZ);
	//================================END Data partition assignment================================

	
	//=====================================START Initialization====================================
	duration_sendrecv   = 0.0;
	duration_internal   = 0.0;
	duration_busywait   = 0.0;
	duration_external   = 0.0;
	duration_mass_reduce= 0.0;
	duration_waitsend   = 0.0;
	//Each of the arrays needs to have a size of (x+4)*(y +4)* z elements.
	//The size must be identical for all so that MPI datatype column will work correctly.
	//The +4 is the Halo zone for receives.
	u[0]	= (struct element*) malloc((x_length+4)*(y_length+4)*z_length*sizeof(struct element));
	u[1]	= (struct element*) malloc((x_length+4)*(y_length+4)*z_length*sizeof(struct element));
	for (iz=0; iz<z_length; ++iz)
		for (iy=0; iy<y_length+4; ++iy)
			for (ix=0; ix<x_length+4; ++ix){
				(u[0]+c(ix,iy,iz))->mass 	= total_mass/numtasks/NX/NY/NZ;
				(u[0]+c(ix,iy,iz))->xy_value 	= (double)(rand() % 100);
				(u[0]+c(ix,iy,iz))->z_value 	=  a*pow((u[0]+c(ix,iy,iz))->xy_value,10.0);
				(u[1]+c(ix,iy,iz))->mass 	= total_mass/numtasks/NX/NY/NZ;
				(u[1]+c(ix,iy,iz))->xy_value 	= 0.0;
			}
	//iz: Track which of the u arrays is the "old"
	iu = 0;
	//sprintf(filename,"atm%ds%d.txt", rank, it);
	//prtdat(filename);
	//printf("Rank %d saving in %s\n", rank, filename);
	// for printf to apper in order
	MPI_Barrier(MPI_COMM_WORLD);
	
	// DATATYPE: Notice how column size(1st arg) depends on partition size
	// an element consists of 3 doubles
	MPI_Type_vector (2,  3*x_length, 3*(x_length+4), MPI_DOUBLE, &xmargindata); 
	MPI_Type_commit (&xmargindata);
	MPI_Type_vector (y_length, 6, 3*(x_length+4), MPI_DOUBLE, &ymargindata);
	MPI_Type_commit (&ymargindata);
	sizes[2]		= 3*(x_length+4);
	sizes[1]		= y_length+4;
	sizes[0]		= z_length;
	subsizes_right_left[2]	= 3*2;
	subsizes_right_left[1]	= y_length;
	subsizes_right_left[0]	= z_length;
	starts_right_left[0]	= 0;
	starts_right_left[1]	= 0;
	starts_right_left[2]	= 0;
	MPI_Type_create_subarray(3, sizes, subsizes_right_left, starts_right_left, MPI_ORDER_C, MPI_DOUBLE, &right_left_type);
	MPI_Type_commit (&right_left_type);
	subsizes_down_up[2]	= 3*x_length;
	subsizes_down_up[1]	= 2;
	subsizes_down_up[0]	= z_length;
	MPI_Type_create_subarray(3, sizes, subsizes_down_up, starts_right_left, MPI_ORDER_C, MPI_DOUBLE, &down_up_type);
	MPI_Type_commit (&down_up_type);
	
	printf("Rank %d has finished initialisation\n", rank);
	//==============================================END Initialization==============================================

	//Main Computation
	for (it = 1; it <= STEPS; ++it)	{
		if(rank == 0) printf("Step %d\n", it);
		time_start_sendrecv = MPI_Wtime();
		
		//printf("Rank %d starts iteration %d\n",rank,it);
	/*	if(STEPS==1) printf("Rank %d neighbours: U %d  D %d  L %d  R %d\n",rank,
		((rank+x_partition_count) % (x_partition_count*y_partition_count) 
			+ (x_partition_count*y_partition_count)*(rank/x_partition_count/y_partition_count)),
				((rank-x_partition_count+x_partition_count*y_partition_count) % (x_partition_count*y_partition_count) 
					+ (x_partition_count*y_partition_count)*(rank/x_partition_count/y_partition_count)),
						(rank+(rank % x_partition_count ? 0 : x_partition_count)-1),
							(rank+((rank+1) % x_partition_count ? 0 : -x_partition_count)+1));*/
		
		MPI_Isend(u[iu]+c(2, y_length, 0), 1, down_up_type,\
			(rank+x_partition_count) % (x_partition_count*y_partition_count) + 
				(x_partition_count*y_partition_count)*(rank/x_partition_count/y_partition_count), 
					DTUTAG, MPI_COMM_WORLD, req_send + 0);
		MPI_Irecv(u[iu]+c(2, y_length+2, 0), 1, down_up_type,\
			(rank+x_partition_count) % (x_partition_count*y_partition_count) +
				(x_partition_count*y_partition_count)*(rank/x_partition_count/y_partition_count), 
					UTDTAG, MPI_COMM_WORLD, req_recv + 0);

		MPI_Isend(u[iu]+c(2,2,0), 1, down_up_type,\
			(rank-x_partition_count+x_partition_count*y_partition_count) % (x_partition_count*y_partition_count) + 
				(x_partition_count*y_partition_count)*(rank/x_partition_count/y_partition_count), 
					UTDTAG, MPI_COMM_WORLD, req_send + 1);
		MPI_Irecv(u[iu]+c(2,0,0), 1, down_up_type,\
			(rank-x_partition_count+x_partition_count*y_partition_count) % (x_partition_count*y_partition_count) +
				(x_partition_count*y_partition_count)*(rank/x_partition_count/y_partition_count), 
					DTUTAG, MPI_COMM_WORLD, req_recv+1);

		// use % due to spatial wraparound
		MPI_Isend(u[iu]+c(2,2,0), 1, right_left_type,\
			rank+(rank % x_partition_count ? 0 : x_partition_count)-1, RTLTAG, MPI_COMM_WORLD, req_send+2); 
		MPI_Irecv(u[iu]+c(0,2,0), 1, right_left_type,\
			rank+(rank % x_partition_count ? 0 : x_partition_count)-1, LTRTAG, MPI_COMM_WORLD, req_recv+2);

		MPI_Isend(u[iu]+c(x_length,2,0), 1, right_left_type,\
			rank+((rank+1) % x_partition_count ? 0 : -x_partition_count)+1, LTRTAG, MPI_COMM_WORLD, req_send+3);
		MPI_Irecv(u[iu]+c(x_length+2,2,0), 1, right_left_type,\
			rank+((rank+1) % x_partition_count ? 0 : -x_partition_count)+1, RTLTAG, MPI_COMM_WORLD, req_recv+3);
		//printf("Rank %d has finished nonblocking sendrecvs\n", rank);
		duration_sendrecv += MPI_Wtime() - time_start_sendrecv;
			
		//begin update of internal elements
		time_start_internal = MPI_Wtime();
		#pragma omp parallel
		{
			#pragma omp for
				for(iz=0; iz<z_length; ++iz){ //full z range
					//printf("Iteration %d is assigned to thread %d\n", iz, omp_get_thread_num());
					//disregard both the data waiting to be received (width 2 perimeter) and the ones 
					//who need them to be calculated (another 2 width perimeter)(central elements)
					for(iy=4; iy<y_length; ++iy) 
						for(ix=4; ix<x_length; ++ix)
							update(ix, iy, iz, u[iu], u[1-iu]);
				}
		}
		duration_internal += MPI_Wtime() - time_start_internal;
		// printf("Rank %d has finished internal elements\n", rank);
		// finished update of internal elements
	
		time_start_busywait = MPI_Wtime();
		done_count = 0;                  
		memset(done, 0, 4*sizeof(int)); 
		while(done_count<4){
			for(i=0; i<4; ++i)
				if(!done[i]){
					MPI_Test(req_recv+i, done+i, MPI_STATUS_IGNORE);
					if(done[i]){
						switch(i){
						case 0:
							for(iz=0; iz<z_length; ++iz) //full z range
								for(iy=y_length; iy<y_length+2; ++iy)
									for(ix=2; ix<x_length+2; ++ix)
										update(ix,iy,iz,u[iu],u[1-iu]);//update top row except corners
							break;
						case 1:
							for(iz=0; iz<z_length; ++iz) //full z range
								for(iy=2; iy<4; ++iy)
									for(ix=2; ix<x_length+2; ++ix)
										update(ix,iy,iz,u[iu],u[1-iu]);//update bottom row except corners
							break;
						case 2:
							for(iz=0; iz<z_length; ++iz) //full z range
								for(ix=2; ix<4; ++ix)
									for(iy=2; iy<y_length+2; ++iy)
										update(ix,iy,iz,u[iu],u[1-iu]);//update left column except corners
							break;
						case 3:
							for(iz=0;iz<z_length;iz++) //full z range
								for(ix=x_length;ix<x_length+2;ix++)
									for(iy=2;iy<y_length+2;iy++)
										update(ix,iy,iz,u[iu],u[1-iu]);//update right column except corners
						}
						++done_count;
					}//end if(done[i])
				}//end if(!done[i]).
		}//end while(done_count<4)
		//printf("Rank %d has finished busywait phase\n", rank);
		duration_busywait += MPI_Wtime() - time_start_busywait;

		time_start_external = MPI_Wtime();
		for(iz=0; iz<z_length; ++iz) //full z range
			for(iy=2*y_length-2; iy<2*y_length+2; ++iy)
				for(ix=2*x_length-2; ix<2*x_length+2; ++ix)
					update(ix%x_length+2,iy%y_length+2,iz,u[iu],u[1-iu]);//update the four corners
		duration_external += MPI_Wtime() - time_start_external;

		time_start_mass_reduce = MPI_Wtime();
		if(it % reduce_frequency == 0){
			MPI_Reduce(&rank_mass, &mass_reduced, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
			if(rank == 0)
				printf("Step %d: Rank %d reduced total mass of %f\n", it, rank, mass_reduced);
		}
		duration_mass_reduce += MPI_Wtime() - time_start_mass_reduce;
			
		time_start_waitsend = MPI_Wtime();
		for(i=0; i<4; ++i)
			MPI_Wait(req_send+i, MPI_STATUS_IGNORE);//Wait for the sends
		//MPI_Barrier(MPI_COMM_WORLD);
		//printf("rank %d finished MPI_Waits at step %d\n", rank, it);	
		//Revert arrays
		iu = 1-iu;
		duration_waitsend += MPI_Wtime() - time_start_waitsend;
		
		//sprintf(filename,"atm%ds%d.txt", rank, it);
		//prtdat(filename);
				
	}//end STEPS iteration
	
	MPI_Reduce(&duration_sendrecv   ,&total_sendrecv   ,1, MPI_DOUBLE,MPI_SUM, 0, MPI_COMM_WORLD);
	MPI_Reduce(&duration_busywait   ,&total_busywait   ,1, MPI_DOUBLE,MPI_SUM, 0, MPI_COMM_WORLD);
	MPI_Reduce(&duration_internal   ,&total_internal   ,1, MPI_DOUBLE,MPI_SUM, 0, MPI_COMM_WORLD);
	MPI_Reduce(&duration_external   ,&total_external   ,1, MPI_DOUBLE,MPI_SUM, 0, MPI_COMM_WORLD);
	MPI_Reduce(&duration_mass_reduce,&total_mass_reduce,1, MPI_DOUBLE,MPI_SUM, 0, MPI_COMM_WORLD);
	MPI_Reduce(&duration_waitsend   ,&total_waitsend   ,1, MPI_DOUBLE,MPI_SUM, 0, MPI_COMM_WORLD);
	total_accounted_for = total_sendrecv + total_internal + total_external + total_busywait + total_mass_reduce + total_waitsend;
	
	if(!rank) printf("Time elapsed: %f seconds\n", total_accounted_for);
	if(!rank) printf("Durations:\nSend/Recv    = %f\nInternal    = %f\nBusywait    = %f\nExternal    = %f\nReduce mass = %f\nWait sends    = %f\n\n"
		"Respective percentages (based on accounted for):\nSend/Recv    = %f\nInternal    = %f\nBusywait    = %f\nExternal    = %f\nReduce mass = %f\nWait sends    = %f\n\n",
		total_sendrecv,total_internal,total_busywait,total_external,total_mass_reduce,total_waitsend,
		100.0 * total_sendrecv   /total_accounted_for,
		100.0 * total_internal   /total_accounted_for,
		100.0 * total_busywait   /total_accounted_for,
		100.0 * total_external   /total_accounted_for,
		100.0 * total_mass_reduce/total_accounted_for,
		100.0 * total_waitsend   /total_accounted_for);
	if(rank==0)	{
		fprintf(fp,"Total/Sendrecv/internal/busywait/external/mass reduce/waitsend durations:\n%f\t%f\t%f\t%f\t%f\t%f\t%f\n\n\n",
				total_accounted_for, total_sendrecv, total_internal, total_busywait, total_external, total_mass_reduce, total_waitsend);
		fclose(fp);
	}

	if(!rank) printf("\n\n==================================\n===========SESSION END============\n==================================\n\n\n");
    MPI_Finalize();
	return 0;
}
Esempio n. 10
0
int main(int argc, char **argv)
{
    int errs = 0;
    int found, completed;
    int rank, size;
    int *sendbuf = NULL, *recvbuf = NULL;
    int count, i;
    MPI_Message msg;
    MPI_Request rreq;
    MPI_Status s1, s2;
    MPI_Datatype vectype;

    MTest_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    if (size < 2) {
        printf("this test requires at least 2 processes\n");
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

    /* all processes besides ranks 0 & 1 aren't used by this test */
    if (rank >= 2) {
        goto epilogue;
    }

    sendbuf = (int *) malloc(LARGE_SZ * sizeof(int));
    recvbuf = (int *) malloc(LARGE_SZ * sizeof(int));
    if (sendbuf == NULL || recvbuf == NULL) {
        printf("Error in memory allocation\n");
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

    /* test 0: simple send & mprobe+mrecv */
    if (rank == 0) {
        sendbuf[0] = 0xdeadbeef;
        sendbuf[1] = 0xfeedface;
        MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
    } else {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 5);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg != MPI_MESSAGE_NULL);

        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 2);

        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
        check(recvbuf[0] == 0xdeadbeef);
        check(recvbuf[1] == 0xfeedface);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 5);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
    }

    /* test 1: simple send & mprobe+imrecv */
    if (rank == 0) {
        sendbuf[0] = 0xdeadbeef;
        sendbuf[1] = 0xfeedface;
        MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
    } else {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 5);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg != MPI_MESSAGE_NULL);

        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 2);

        rreq = MPI_REQUEST_NULL;
        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
        check(rreq != MPI_REQUEST_NULL);
        MPI_Wait(&rreq, &s2);
        check(recvbuf[0] == 0xdeadbeef);
        check(recvbuf[1] == 0xfeedface);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 5);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
    }

    /* test 2: simple send & improbe+mrecv */
    if (rank == 0) {
        sendbuf[0] = 0xdeadbeef;
        sendbuf[1] = 0xfeedface;
        MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
    } else {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        do {
            check(msg == MPI_MESSAGE_NULL);
            MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
        } while (!found);
        check(msg != MPI_MESSAGE_NULL);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 5);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);

        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 2);

        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
        check(recvbuf[0] == 0xdeadbeef);
        check(recvbuf[1] == 0xfeedface);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 5);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
    }

    /* test 3: simple send & improbe+imrecv */
    if (rank == 0) {
        sendbuf[0] = 0xdeadbeef;
        sendbuf[1] = 0xfeedface;
        MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
    } else {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        do {
            check(msg == MPI_MESSAGE_NULL);
            MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
        } while (!found);
        check(msg != MPI_MESSAGE_NULL);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 5);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);

        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 2);

        rreq = MPI_REQUEST_NULL;
        MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
        check(rreq != MPI_REQUEST_NULL);
        MPI_Wait(&rreq, &s2);
        check(recvbuf[0] == 0xdeadbeef);
        check(recvbuf[1] == 0xfeedface);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 5);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
    }

    /* test 4: mprobe+mrecv with MPI_PROC_NULL */
    {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == MPI_PROC_NULL);
        check(s1.MPI_TAG == MPI_ANY_TAG);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg == MPI_MESSAGE_NO_PROC);

        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 0);

        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
        /* recvbuf should remain unmodified */
        check(recvbuf[0] == 0x01234567);
        check(recvbuf[1] == 0x89abcdef);
        /* should get back "proc null status" */
        check(s2.MPI_SOURCE == MPI_PROC_NULL);
        check(s2.MPI_TAG == MPI_ANY_TAG);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
        count = -1;
        MPI_Get_count(&s2, MPI_INT, &count);
        check(count == 0);
    }

    /* test 5: mprobe+imrecv with MPI_PROC_NULL */
    {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == MPI_PROC_NULL);
        check(s1.MPI_TAG == MPI_ANY_TAG);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg == MPI_MESSAGE_NO_PROC);
        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 0);

        rreq = MPI_REQUEST_NULL;
        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
        check(rreq != MPI_REQUEST_NULL);
        completed = 0;
        MPI_Test(&rreq, &completed, &s2);       /* single test should always succeed */
        check(completed);
        /* recvbuf should remain unmodified */
        check(recvbuf[0] == 0x01234567);
        check(recvbuf[1] == 0x89abcdef);
        /* should get back "proc null status" */
        check(s2.MPI_SOURCE == MPI_PROC_NULL);
        check(s2.MPI_TAG == MPI_ANY_TAG);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
        count = -1;
        MPI_Get_count(&s2, MPI_INT, &count);
        check(count == 0);
    }

    /* test 6: improbe+mrecv with MPI_PROC_NULL */
    {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        found = 0;
        MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
        check(found);
        check(msg == MPI_MESSAGE_NO_PROC);
        check(s1.MPI_SOURCE == MPI_PROC_NULL);
        check(s1.MPI_TAG == MPI_ANY_TAG);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 0);

        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
        /* recvbuf should remain unmodified */
        check(recvbuf[0] == 0x01234567);
        check(recvbuf[1] == 0x89abcdef);
        /* should get back "proc null status" */
        check(s2.MPI_SOURCE == MPI_PROC_NULL);
        check(s2.MPI_TAG == MPI_ANY_TAG);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
        count = -1;
        MPI_Get_count(&s2, MPI_INT, &count);
        check(count == 0);
    }

    /* test 7: improbe+imrecv */
    {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
        check(found);
        check(msg == MPI_MESSAGE_NO_PROC);
        check(s1.MPI_SOURCE == MPI_PROC_NULL);
        check(s1.MPI_TAG == MPI_ANY_TAG);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 0);

        rreq = MPI_REQUEST_NULL;
        MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
        check(rreq != MPI_REQUEST_NULL);
        completed = 0;
        MPI_Test(&rreq, &completed, &s2);       /* single test should always succeed */
        check(completed);
        /* recvbuf should remain unmodified */
        check(recvbuf[0] == 0x01234567);
        check(recvbuf[1] == 0x89abcdef);
        /* should get back "proc null status" */
        check(s2.MPI_SOURCE == MPI_PROC_NULL);
        check(s2.MPI_TAG == MPI_ANY_TAG);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
        count = -1;
        MPI_Get_count(&s2, MPI_INT, &count);
        check(count == 0);
    }

    /* test 8: simple ssend & mprobe+mrecv */
    if (rank == 0) {
        sendbuf[0] = 0xdeadbeef;
        sendbuf[1] = 0xfeedface;
        MPI_Ssend(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
    } else {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 5);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg != MPI_MESSAGE_NULL);

        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 2);

        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
        check(recvbuf[0] == 0xdeadbeef);
        check(recvbuf[1] == 0xfeedface);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 5);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
    }

    /* test 9: mprobe+mrecv LARGE */
    if (rank == 0) {
        for (i = 0; i < LARGE_SZ; i++)
            sendbuf[i] = i;
        MPI_Send(sendbuf, LARGE_SZ, MPI_INT, 1, 5, MPI_COMM_WORLD);
    } else {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 5);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg != MPI_MESSAGE_NULL);

        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == LARGE_SZ);

        memset(recvbuf, 0xFF, LARGE_SZ * sizeof(int));
        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
        for (i = 0; i < LARGE_SZ; i++)
            check(recvbuf[i] == i);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 5);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
    }

    /* test 10: mprobe+mrecv noncontiguous datatype */
    MPI_Type_vector(2, 1, 4, MPI_INT, &vectype);
    MPI_Type_commit(&vectype);
    if (rank == 0) {
        memset(sendbuf, 0, 8 * sizeof(int));
        sendbuf[0] = 0xdeadbeef;
        sendbuf[4] = 0xfeedface;
        MPI_Send(sendbuf, 1, vectype, 1, 5, MPI_COMM_WORLD);
    } else {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 5);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg != MPI_MESSAGE_NULL);

        count = -1;
        MPI_Get_count(&s1, vectype, &count);
        check(count == 1);

        memset(recvbuf, 0, 8 * sizeof(int));
        MPI_Mrecv(recvbuf, 1, vectype, &msg, &s2);
        check(recvbuf[0] == 0xdeadbeef);
        for (i = 1; i < 4; i++)
            check(recvbuf[i] == 0);
        check(recvbuf[4] = 0xfeedface);
        for (i = 5; i < 8; i++)
            check(recvbuf[i] == 0);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 5);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
    }
    MPI_Type_free(&vectype);

    /* test 11: mprobe+mrecv noncontiguous datatype LARGE */
    MPI_Type_vector(LARGE_DIM, LARGE_DIM - 1, LARGE_DIM, MPI_INT, &vectype);
    MPI_Type_commit(&vectype);
    if (rank == 0) {
        for (i = 0; i < LARGE_SZ; i++)
            sendbuf[i] = i;
        MPI_Send(sendbuf, 1, vectype, 1, 5, MPI_COMM_WORLD);
    } else {
        int idx = 0;

        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 5);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg != MPI_MESSAGE_NULL);

        count = -1;
        MPI_Get_count(&s1, vectype, &count);
        check(count == 1);

        memset(recvbuf, 0, LARGE_SZ * sizeof(int));
        MPI_Mrecv(recvbuf, 1, vectype, &msg, &s2);
        for (i = 0; i < LARGE_DIM; i++) {
            int j;
            for (j = 0; j < LARGE_DIM - 1; j++) {
                check(recvbuf[idx] == idx);
                ++idx;
            }
            check(recvbuf[idx++] == 0);
        }
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 5);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
    }
    MPI_Type_free(&vectype);

    /* test 12: order test */
    if (rank == 0) {
        MPI_Request lrequest[2];
        sendbuf[0] = 0xdeadbeef;
        sendbuf[1] = 0xfeedface;
        sendbuf[2] = 0xdeadbeef;
        sendbuf[3] = 0xfeedface;
        sendbuf[4] = 0xdeadbeef;
        sendbuf[5] = 0xfeedface;
        MPI_Isend(&sendbuf[0], 4, MPI_INT, 1, 6, MPI_COMM_WORLD, &lrequest[0]);
        MPI_Isend(&sendbuf[4], 2, MPI_INT, 1, 6, MPI_COMM_WORLD, &lrequest[1]);
        MPI_Waitall(2, &lrequest[0], MPI_STATUSES_IGNORE);
    } else {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(0, 6, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 6);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg != MPI_MESSAGE_NULL);

        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 4);

        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Recv(recvbuf, 2, MPI_INT, 0, 6, MPI_COMM_WORLD, &s2);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 6);
        check(recvbuf[0] == 0xdeadbeef);
        check(recvbuf[1] == 0xfeedface);

        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        recvbuf[2] = 0x01234567;
        recvbuf[3] = 0x89abcdef;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
        check(recvbuf[0] == 0xdeadbeef);
        check(recvbuf[1] == 0xfeedface);
        check(recvbuf[2] == 0xdeadbeef);
        check(recvbuf[3] == 0xfeedface);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 6);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
    }

    /* test 13: simple send & mprobe+mrecv with zero count */
    if (rank == 0) {
        MPI_Send(sendbuf, 0, MPI_INT, 1, 13, MPI_COMM_WORLD);
    } else {
        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(0, 13, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 13);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg != MPI_MESSAGE_NULL);

        count = -1;
        MPI_Get_count(&s1, MPI_INT, &count);
        check(count == 0);

        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Mrecv(recvbuf, 0, MPI_INT, &msg, &s2);
        /* recvbuf should remain unmodified */
        check(recvbuf[0] == 0x01234567);
        check(recvbuf[1] == 0x89abcdef);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 13);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
        count = -1;
        MPI_Get_count(&s2, MPI_INT, &count);
        check(count == 0);
    }

    /* test 14: simple send & mprobe+mrecv with zero-size datatype */
    if (rank == 0) {
        MPI_Send(sendbuf, 0, MPI_BYTE, 1, 14, MPI_COMM_WORLD);
    } else {
        MPI_Datatype zero_dtype;

        MPI_Type_contiguous(0, MPI_INT, &zero_dtype);
        MPI_Type_commit(&zero_dtype);

        memset(&s1, 0xab, sizeof(MPI_Status));
        memset(&s2, 0xab, sizeof(MPI_Status));
        /* the error field should remain unmodified */
        s1.MPI_ERROR = MPI_ERR_DIMS;
        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;

        msg = MPI_MESSAGE_NULL;
        MPI_Mprobe(0, 14, MPI_COMM_WORLD, &msg, &s1);
        check(s1.MPI_SOURCE == 0);
        check(s1.MPI_TAG == 14);
        check(s1.MPI_ERROR == MPI_ERR_DIMS);
        check(msg != MPI_MESSAGE_NULL);

        count = -1;
        MPI_Get_count(&s1, zero_dtype, &count);
        check(count == 0);

        recvbuf[0] = 0x01234567;
        recvbuf[1] = 0x89abcdef;
        MPI_Mrecv(recvbuf, 1, zero_dtype, &msg, &s2);
        /* recvbuf should remain unmodified */
        check(recvbuf[0] == 0x01234567);
        check(recvbuf[1] == 0x89abcdef);
        check(s2.MPI_SOURCE == 0);
        check(s2.MPI_TAG == 14);
        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
        check(msg == MPI_MESSAGE_NULL);
        count = -1;
        MPI_Get_count(&s2, zero_dtype, &count);
        check(count == 0);

        MPI_Type_free(&zero_dtype);
    }

    free(sendbuf);
    free(recvbuf);

    /* TODO MPI_ANY_SOURCE and MPI_ANY_TAG should be tested as well */
    /* TODO a full range of message sizes should be tested too */
    /* TODO threaded tests are also needed, but they should go in a separate
     * program */

    /* simple test to ensure that c2f/f2c routines are present (initially missed
     * in MPICH impl) */
    {
        MPI_Fint f_handle = 0xdeadbeef;
        f_handle = MPI_Message_c2f(MPI_MESSAGE_NULL);
        msg = MPI_Message_f2c(f_handle);
        check(f_handle != 0xdeadbeef);
        check(msg == MPI_MESSAGE_NULL);

        /* PMPI_ versions should also exists */
        f_handle = 0xdeadbeef;
        f_handle = PMPI_Message_c2f(MPI_MESSAGE_NULL);
        msg = PMPI_Message_f2c(f_handle);
        check(f_handle != 0xdeadbeef);
        check(msg == MPI_MESSAGE_NULL);
    }

  epilogue:
    MTest_Finalize(errs);

    return MTestReturnValue(errs);
}
Esempio n. 11
0
int master_main(const char *host, int port, const char *addr) {
	time_t idle_stoptime;
	struct link *master = NULL;
	int num_workers, i;
	struct mpi_queue_job **workers;

	struct itable *active_jobs = itable_create(0);
	struct itable *waiting_jobs = itable_create(0);
	struct list   *complete_jobs = list_create();

	MPI_Comm_size(MPI_COMM_WORLD, &num_workers);

	workers = malloc(num_workers * sizeof(*workers));
	memset(workers, 0, num_workers * sizeof(*workers));	
	
	idle_stoptime = time(0) + idle_timeout;

	while(!abort_flag) {
		char line[MPI_QUEUE_LINE_MAX];

		if(time(0) > idle_stoptime) {
			if(master) {
				printf("mpi master: gave up after waiting %ds to receive a task.\n", idle_timeout);
			} else {
				printf("mpi master: gave up after waiting %ds to connect to %s port %d.\n", idle_timeout, host, port);
			}
			break;
		}


		if(!master) {
			char working_dir[MPI_QUEUE_LINE_MAX];
			master = link_connect(addr, port, idle_stoptime);
			if(!master) {
				sleep(5);
				continue;
			}

			link_tune(master, LINK_TUNE_INTERACTIVE);
			
			link_readline(master, line, sizeof(line), time(0) + active_timeout);

			memset(working_dir, 0, MPI_QUEUE_LINE_MAX);
			if(sscanf(line, "workdir %s", working_dir) == 1) {
				MPI_Bcast(working_dir, MPI_QUEUE_LINE_MAX, MPI_CHAR, 0, MPI_COMM_WORLD);
			} else {
				link_close(master);
				master = NULL;
				continue;
			}
		}
		
		if(link_readline(master, line, sizeof(line), time(0) + short_timeout)) {
			struct mpi_queue_operation *op;
			int jobid, mode;
			INT64_T length;
			char path[MPI_QUEUE_LINE_MAX];
			op = NULL;
			
			debug(D_MPI, "received: %s\n", line);

			if(!strcmp(line, "get results")) {
				struct mpi_queue_job *job;
				debug(D_MPI, "results requested: %d available\n", list_size(complete_jobs));
				link_putfstring(master, "num results %d\n", time(0) + active_timeout, list_size(complete_jobs));
				while(list_size(complete_jobs)) {
					job = list_pop_head(complete_jobs);
					link_putfstring(master, "result %d %d %d %lld\n", time(0) + active_timeout, job->jobid, job->status, job->result, job->output_length);
					if(job->output_length) {
						link_write(master, job->output, job->output_length, time(0)+active_timeout);
					}
					mpi_queue_job_delete(job);
				}

			} else if(sscanf(line, "work %d %lld", &jobid, &length)) {
				op = malloc(sizeof(*op));
				memset(op, 0, sizeof(*op));
				op->type = MPI_QUEUE_OP_WORK;
				op->buffer_length = length+1;
				op->buffer = malloc(length+1);
				op->buffer[op->buffer_length] = 0;
				link_read(master, op->buffer, length, time(0) + active_timeout);
				op->result = -1;
				
			} else if(sscanf(line, "stat %d %s", &jobid, path) == 2) {
				op = malloc(sizeof(*op));
				memset(op, 0, sizeof(*op));
				op->type = MPI_QUEUE_OP_STAT;
				sprintf(op->args, "%s", path);
				op->result = -1;
				
			} else if(sscanf(line, "unlink %d %s", &jobid, path) == 2) {
				op = malloc(sizeof(*op));
				memset(op, 0, sizeof(*op));
				op->type = MPI_QUEUE_OP_UNLINK;
				sprintf(op->args, "%s", path);
				op->result = -1;
				
			} else if(sscanf(line, "mkdir %d %s %o", &jobid, path, &mode) == 3) {
				op = malloc(sizeof(*op));
				memset(op, 0, sizeof(*op));
				op->type = MPI_QUEUE_OP_MKDIR;
				sprintf(op->args, "%s %o", path, mode);
				op->result = -1;
				
			} else if(sscanf(line, "close %d", &jobid) == 1) {
				op = malloc(sizeof(*op));
				memset(op, 0, sizeof(*op));
				op->type = MPI_QUEUE_OP_CLOSE;
				op->result = -1;
				
//			} else if(sscanf(line, "symlink %d %s %s", &jobid, path, filename) == 3) {
//			} else if(sscanf(line, "put %d %s %lld %o", &jobid, filename, &length, &mode) == 4) {
//			} else if(sscanf(line, "rget %d %s", &jobid, filename) == 2) {
//			} else if(sscanf(line, "get %d %s", &jobid, filename) == 2) {
//			} else if(sscanf(line, "thirdget %d %d %s %[^\n]", &jobid, &mode, filename, path) == 4) {
//			} else if(sscanf(line, "thirdput %d %d %s %[^\n]", &jobid, &mode, filename, path) == 4) {
			} else if(!strcmp(line, "exit")) {
				break;
			} else {
				abort_flag = 1;
				continue;
			}
			if(op) {
				struct mpi_queue_job *job;
					job = itable_lookup(active_jobs, jobid);
				if(!job) {
					job = itable_lookup(waiting_jobs, jobid);
				}
				if(!job) {
					job = malloc(sizeof(*job));
					memset(job, 0, sizeof(*job));
					job->jobid = jobid;
					job->operations = list_create();
					job->status = MPI_QUEUE_JOB_WAITING;
					job->worker_rank = -1;
					itable_insert(waiting_jobs, jobid, job);
				}
				list_push_tail(job->operations, op);
			}
			idle_stoptime = time(0) + idle_timeout;
		} else {
			link_close(master);
			master = 0;
			sleep(5);
		}
		
		int num_waiting_jobs = itable_size(waiting_jobs);
		int num_unvisited_jobs = itable_size(active_jobs);
		for(i = 1; i < num_workers && (num_unvisited_jobs > 0 || num_waiting_jobs > 0); i++) {
			struct mpi_queue_job *job;
			struct mpi_queue_operation *op;
			int flag = 0;
			UINT64_T jobid;

			if(!workers[i]) {
				if(num_waiting_jobs) {
					itable_firstkey(waiting_jobs);
					itable_nextkey(waiting_jobs, &jobid, (void **)&job);
					itable_remove(waiting_jobs, jobid);
					itable_insert(active_jobs, jobid, job);
					workers[i] = job;
					num_waiting_jobs--;
					job->worker_rank = i;
					job->status = MPI_QUEUE_JOB_READY;
				} else {
					continue;
				}
			} else {
				num_unvisited_jobs--;
				if(workers[i]->status == MPI_QUEUE_JOB_BUSY) {
					MPI_Test(&workers[i]->request, &flag, &workers[i]->mpi_status);
					if(flag) {
						op = list_pop_head(workers[i]->operations);
						if(op->output_length) {
							op->output_buffer = malloc(op->output_length);
							MPI_Recv(op->output_buffer, op->output_length, MPI_BYTE, workers[i]->worker_rank, 0, MPI_COMM_WORLD, &workers[i]->mpi_status);
						}
						
						workers[i]->status = MPI_QUEUE_JOB_READY;

						if(op->type == MPI_QUEUE_OP_WORK || op->result < 0) {
							if(workers[i]->output)
								free(workers[i]->output);
							workers[i]->output = op->output_buffer;
							op->output_buffer = NULL;
							workers[i]->output_length = op->output_length;
							workers[i]->result = op->result;
							if(op->result < 0) {
								workers[i]->status = MPI_QUEUE_JOB_FAILED | op->type;
								op->type = MPI_QUEUE_OP_CLOSE;
								list_push_head(workers[i]->operations, op);
								op = NULL;
							}
						}
						if(op) {
							if(op->buffer)
								free(op->buffer);
							if(op->output_buffer)
								free(op->output_buffer);
							free(op);
						}
					}
				}
			}
			
			if( workers[i]->status != MPI_QUEUE_JOB_BUSY && list_size(workers[i]->operations)) {
				op = list_peek_head(workers[i]->operations);
				
				if(op->type == MPI_QUEUE_OP_CLOSE) {
					itable_remove(active_jobs, workers[i]->jobid);
					list_push_tail(complete_jobs, workers[i]);
					if(!(workers[i]->status & MPI_QUEUE_JOB_FAILED))
						workers[i]->status = MPI_QUEUE_JOB_COMPLETE;
					workers[i] = NULL;
					i--;
					continue;
				}
				
				MPI_Send(op, sizeof(*op), MPI_BYTE, workers[i]->worker_rank, 0, MPI_COMM_WORLD);
				if(op->buffer_length) {
					MPI_Send(op->buffer, op->buffer_length, MPI_BYTE, workers[i]->worker_rank, 0, MPI_COMM_WORLD);
					free(op->buffer);
					op->buffer_length = 0;
					op->buffer = NULL;
				}
				MPI_Irecv(op, sizeof(*op), MPI_BYTE, workers[i]->worker_rank, 0, MPI_COMM_WORLD, &workers[i]->request);
				workers[i]->status = MPI_QUEUE_JOB_BUSY;
			}
		}
	}


	/** Clean up waiting & complete jobs, send Exit commands to each worker */
	if(!master) {
		// If the master link hasn't been set up yet
		// the workers will be waiting for the working directory
		char line[MPI_QUEUE_LINE_MAX];
		memset(line, 0, MPI_QUEUE_LINE_MAX);
		MPI_Bcast(line, MPI_QUEUE_LINE_MAX, MPI_CHAR, 0, MPI_COMM_WORLD);
	} else {
		link_close(master);
	}

	for(i = 1; i < num_workers; i++) {
		struct mpi_queue_operation *op, close;
		memset(&close, 0, sizeof(close));
		close.type = MPI_QUEUE_OP_EXIT;
		
		if(workers[i]) {
			if(workers[i]->status == MPI_QUEUE_JOB_BUSY) {
				MPI_Wait(&workers[i]->request, &workers[i]->mpi_status);
				op = list_peek_head(workers[i]->operations);
				
				if(op->output_length) {
					op->output_buffer = malloc(op->output_length);
					MPI_Recv(op->output_buffer, op->output_length, MPI_BYTE, workers[i]->worker_rank, 0, MPI_COMM_WORLD, &workers[i]->mpi_status);
				}
			}
			itable_remove(active_jobs, workers[i]->jobid);
			list_push_tail(complete_jobs, workers[i]);
		}
		MPI_Send(&close, sizeof(close), MPI_BYTE, i, 0, MPI_COMM_WORLD);
	}

	itable_firstkey(waiting_jobs);
	while(itable_size(waiting_jobs)) {
		struct mpi_queue_job *job;
		UINT64_T jobid;

		itable_nextkey(waiting_jobs, &jobid, (void **)&job);
		itable_remove(waiting_jobs, jobid);
		list_push_tail(complete_jobs, job);
	}

	while(list_size(complete_jobs)) {
		mpi_queue_job_delete(list_pop_head(complete_jobs));
	}

	MPI_Finalize();
	return abort_flag;
}
Esempio n. 12
0
void do_master_stuff(int argc, char ** argv, struct mw_api_spec *f)
{

  DEBUG_PRINT(("master starting"));

  int number_of_slaves;

  MPI_Comm_size(MPI_COMM_WORLD, &number_of_slaves);
  
  LinkedList * work_list;

  double start, end, start_create, end_create, start_results, end_results;

  start = MPI_Wtime();

  DEBUG_PRINT(("creating work list..."));
  start_create = MPI_Wtime();
  work_list = listFromArray(f->create(argc, argv));
  end_create = MPI_Wtime();
  DEBUG_PRINT(("created work in %f seconds!", end_create - start_create));

  int slave=1, num_work_units=0;

  num_work_units = list_length(work_list);

  mw_result_t * received_results =  malloc(f->res_sz * num_work_units);
  if (received_results == NULL)
  {
    fprintf(stderr, "ERROR: insufficient memory to allocate received_results\n");
    exit(0);
  }

  int num_results_received = 0;

  // make array keeping track of pointers for work that's active
  LinkedList* assignment_ptrs[number_of_slaves-2];

  // make array of binary indicators for inactive workers
  // initially all workers are active and 0
  //unsigned int inactive_workers[number_of_slaves-2];

  // create array of start times
  double assignment_time[number_of_slaves-2];

  int are_you_down[number_of_slaves-2];

  // current pointer
  LinkedList
    * next_work_node = work_list,
    * list_end = NULL;

  // have supervisor so starting at 2
  for(slave=2; slave<number_of_slaves; ++slave)
  {
    are_you_down[slave-2] = 0; //slaves are all working in the beginning
    DEBUG_PRINT(("assigning work to slave"));

    if(next_work_node == NULL)
    {
      DEBUG_PRINT(("reached the end of the work, breaking!"));
      break;
    }

    mw_work_t * work_unit = next_work_node->data;

    send_to_slave(work_unit, f->work_sz, MPI_CHAR, slave, WORK_TAG, MPI_COMM_WORLD);

    // save next_work_node to assigned work
    assignment_ptrs[slave-2] = next_work_node;
    assert(assignment_ptrs[slave-2] != NULL);
    
    // save start time
    assignment_time[slave-2] = MPI_Wtime();

    // update next_work_node
    if(next_work_node->next == NULL)
    {
      list_end = next_work_node;
    }
    next_work_node=next_work_node->next;

    DEBUG_PRINT(("work sent to slave"));
  }

  // send time array to supervisor
  DEBUG_PRINT(("Sending supervisor first time update"));
  MPI_Send(assignment_time, number_of_slaves-2, MPI_DOUBLE, 1, SUPERVISOR_TAG, MPI_COMM_WORLD);

  // failure id
  int failure_id;

  MPI_Status status_fail, status_res;
  MPI_Request request_fail, request_res;
  int flag_fail = 0, flag_res = 0;

  // receive failure from supervisor as non-blocking recv
  MPI_Irecv(&failure_id, 1, MPI_INT, 1, FAIL_TAG, MPI_COMM_WORLD, &request_fail);

  // receive result from workers as non-blocking recv
  MPI_Irecv(&received_results[num_results_received], f->res_sz, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &request_res);

  // send units of work while haven't received all results
  while(num_results_received < num_work_units)
  {
    // check for flag_fail again
    MPI_Test(&request_fail, &flag_fail, &status_fail);

    // check for flag_res again
    MPI_Test(&request_res, &flag_res, &status_res);
    
    // send work if have failures or got results
    if (flag_fail)
    {
      // change inactive workers array
      //inactive_workers[status_fail.MPI_SOURCE-2] = 1;
      DEBUG_PRINT(("received failure from supervisor, process %d", failure_id));

      // get work_unit that needs to be reassigned
      LinkedList * work_unit = assignment_ptrs[failure_id];

      if(work_unit != NULL)
      {
        DEBUG_PRINT(("Moving assignment at %p to end of the queue", work_unit));
        move_node_to_end(work_unit);
        if(next_work_node == NULL)
        {
          next_work_node = work_unit;
        }
        assert(next_work_node != NULL);
      }
      if(assignment_time[failure_id] == 0.0)
      {
        DEBUG_PRINT(("Failure on idle process %d. WTF??", failure_id));
      }
      if(are_you_down[failure_id] == 1)
      {
        DEBUG_PRINT(("Failure on a process which is already failed. WTF??"));
      }
      are_you_down[failure_id] = 1; //this slave is considered dead :(
      assignment_ptrs[failure_id] = NULL;
      assignment_time[failure_id] = 0.0;
      MPI_Send(assignment_time, number_of_slaves-2, MPI_DOUBLE, 1, SUPERVISOR_TAG, MPI_COMM_WORLD);
      flag_fail = 0;
      // continue to receive failures from supervisor as non-blocking recv
      MPI_Irecv(&failure_id, 1, MPI_INT, 1, FAIL_TAG, MPI_COMM_WORLD, &request_fail);
    }
    
    int idle_process = -1, i;
    for(i=0; i<number_of_slaves-2; ++i)
    {
      if(assignment_time[i] == 0.0 && !are_you_down[i])
      {
        idle_process = i;
        break;
      }
    }

    if(next_work_node != NULL && idle_process > -1)
    {
      send_to_slave(next_work_node->data, f->work_sz, MPI_CHAR, idle_process+2, WORK_TAG, MPI_COMM_WORLD);
      assignment_ptrs[idle_process] = next_work_node;
      assignment_time[idle_process] = MPI_Wtime();
      MPI_Send(assignment_time, number_of_slaves-2, MPI_DOUBLE, 1, SUPERVISOR_TAG, MPI_COMM_WORLD);
      DEBUG_PRINT(("Gave an assignment to previously idle process %d, assignment at %p", idle_process, next_work_node));
      if(next_work_node->next == NULL)
      {
        list_end = next_work_node;
      }
      next_work_node = next_work_node->next;
    }

    if (flag_res)
    {
      int worker_number = status_res.MPI_SOURCE-2;
      if(!are_you_down[worker_number]) //If this slave is marked dead, just ignore him
      {
        // update number of results received
        num_results_received++;

        if(next_work_node == NULL && list_end != NULL && list_end->next != NULL)
        {
          DEBUG_PRINT(("Found more work to do, now an idle process can get an assignment"));
          next_work_node = list_end->next;
          list_end = NULL;
        }
        if(next_work_node != NULL)
        {
          // get work_unit
          mw_work_t* work_unit = next_work_node->data;

          // send new unit of work
          send_to_slave(work_unit, f->work_sz, MPI_CHAR, status_res.MPI_SOURCE, WORK_TAG, MPI_COMM_WORLD);        

          // update pointer
          if(next_work_node->next == NULL)
          {
            list_end = next_work_node;
          }

          // update work index for new_pid
          assignment_ptrs[status_res.MPI_SOURCE-2] = next_work_node;
          assert(assignment_ptrs[status_res.MPI_SOURCE-2] != NULL);
          assignment_time[status_res.MPI_SOURCE-2] = MPI_Wtime();
          // send updated array of times to supervisor
          MPI_Send(assignment_time, number_of_slaves-2, MPI_DOUBLE, 1, SUPERVISOR_TAG, MPI_COMM_WORLD);
          DEBUG_PRINT(("SENT TIME TO SUP"));
          next_work_node = next_work_node->next;
          if(next_work_node == NULL)
          {
            DEBUG_PRINT(("Reached the end of the work list, should get idle processors after this"));
          }
        }
        else
        {
          DEBUG_PRINT(("Worker %d is now idle, I ain't got shit for him to do", worker_number));
          assignment_time[worker_number] = 0.0;
          assignment_ptrs[worker_number] = NULL;
          assert(!are_you_down[worker_number]);
          MPI_Send(assignment_time, number_of_slaves-2, MPI_DOUBLE, 1, SUPERVISOR_TAG, MPI_COMM_WORLD);
        }
      }
      // continue to receive results from workers as non-blocking recv
      MPI_Irecv(&received_results[num_results_received], f->res_sz, MPI_CHAR, MPI_ANY_SOURCE, WORK_TAG, MPI_COMM_WORLD, &request_res);      
    }
  }

  // send kill signal to other processes, including supervisor
  for(slave=1; slave<number_of_slaves; ++slave)
  {
    DEBUG_PRINT(("Murdering slave"));
    kill_slave(slave);
  }

  start_results = MPI_Wtime();
  int err_code = f->result(num_results_received, received_results);
  end_results = MPI_Wtime();

  end = MPI_Wtime();
  
  DEBUG_PRINT(("all %f s\n", end-start));
  DEBUG_PRINT(("create %f s\n", end_create-start_create));
  DEBUG_PRINT(("process %f s\n", end_results-start_results));
}
Esempio n. 13
0
int main(int argc, char *argv[])
{
  int rank, numprocs, i;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  //Tests: 
  //A: 0(isend -> wait) with 1(recv)
  int A = 1;
  //B: 0(send) with 1(irecv -> wait)
  int B = 1;
  //C: 0(N * isend -> N * wait) with 1(N * recv)
  int C = 1;
  //D: 0(N * isend -> N * waitany) with 1(N * recv)
  int D = 1;
  //E: 0(N*send) with 1(N*irecv, N*wait)
  int E = 1;
  //F: 0(N*send) with 1(N*irecv, N*waitany)
  int F = 1;
  //G: 0(N* isend -> waitall) with 1(N*recv)
  int G = 1;
  //H: 0(N*send) with 1(N*irecv, waitall)
  int H = 1;
  //I: 0(2*N*send, 2*N*Irecv, Waitall) with
  //   1(N*irecv, waitall, N*isend, N*waitany) with 
  //   2(N*irecv, N*waitany, N*isend, waitall)
  int I = 1;
  //J: 0(N*isend, N*test, N*wait) with (N*irecv, N*test, N*wait)
  int J = 1;

  int N = 13;

  int tag = 12345;
/////////////////////////////////////////
////////////////// RANK 0
///////////////////////////////////
  if (rank == 0) {
    MPI_Request request;
    MPI_Status status;
    MPI_Request req[2 * N];
    MPI_Status sta[2 * N];
    int *r = (int *) malloc(sizeof(int) * DATATOSENT);
    if (A) {
      TRACE_smpi_set_category("A");
      MPI_Isend(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD, &request);
      MPI_Wait(&request, &status);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (B) {
      TRACE_smpi_set_category("B");
      MPI_Send(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (C) {
      TRACE_smpi_set_category("C");
      for (i = 0; i < N; i++) {
        MPI_Isend(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD, &req[i]);
      }
      for (i = 0; i < N; i++) {
        MPI_Wait(&req[i], &sta[i]);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (D) {
      TRACE_smpi_set_category("D");
      for (i = 0; i < N; i++) {
        MPI_Isend(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD, &req[i]);
      }
      for (i = 0; i < N; i++) {
        int completed;
        MPI_Waitany(N, req, &completed, sta);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (E) {
      TRACE_smpi_set_category("E");
      for (i = 0; i < N; i++) {
        MPI_Send(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (F) {
      TRACE_smpi_set_category("F");
      for (i = 0; i < N; i++) {
        MPI_Send(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (G) {
      TRACE_smpi_set_category("G");
      for (i = 0; i < N; i++) {
        MPI_Isend(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD, &req[i]);
      }
      MPI_Waitall(N, req, sta);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (H) {
      TRACE_smpi_set_category("H");
      for (i = 0; i < N; i++) {
        MPI_Send(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (I) {
      TRACE_smpi_set_category("I");
      for (i = 0; i < 2 * N; i++) {
        if (i < N) {
          MPI_Send(r, DATATOSENT, MPI_INT, 2, tag, MPI_COMM_WORLD);
        } else {
          MPI_Send(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD);
        }
      }
      MPI_Barrier(MPI_COMM_WORLD);
      for (i = 0; i < 2 * N; i++) {
        if (i < N) {
          MPI_Irecv(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD,
                    &req[i]);
        } else {
          MPI_Irecv(r, DATATOSENT, MPI_INT, 2, tag, MPI_COMM_WORLD,
                    &req[i]);
        }
      }
      MPI_Waitall(2 * N, req, sta);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (J) {
      TRACE_smpi_set_category("J");
      for (i = 0; i < N; i++) {
        MPI_Isend(r, DATATOSENT, MPI_INT, 1, tag, MPI_COMM_WORLD, &req[i]);
      }
      for (i = 0; i < N; i++) {
        int flag;
        MPI_Test(&req[i], &flag, &sta[i]);
      }
      for (i = 0; i < N; i++) {
        MPI_Wait(&req[i], &sta[i]);
      }
    }
    free(r);
/////////////////////////////////////////
////////////////// RANK 1
///////////////////////////////////
  } else if (rank == 1) {
    MPI_Request request;
    MPI_Status status;
    MPI_Request req[N];
    MPI_Status sta[N];
    int *r = (int *) malloc(sizeof(int) * DATATOSENT);

    if (A) {
      TRACE_smpi_set_category("A");
      MPI_Recv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (B) {
      TRACE_smpi_set_category("B");
      MPI_Irecv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &request);
      MPI_Wait(&request, &status);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (C) {
      TRACE_smpi_set_category("C");
      for (i = 0; i < N; i++) {
        MPI_Recv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &sta[i]);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (D) {
      TRACE_smpi_set_category("D");
      for (i = 0; i < N; i++) {
        MPI_Recv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &sta[i]);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (E) {
      TRACE_smpi_set_category("E");
      for (i = 0; i < N; i++) {
        MPI_Irecv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &req[i]);
      }
      for (i = 0; i < N; i++) {
        MPI_Wait(&req[i], &sta[i]);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (F) {
      TRACE_smpi_set_category("F");
      for (i = 0; i < N; i++) {
        MPI_Irecv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &req[i]);
      }
      for (i = 0; i < N; i++) {
        int completed;
        MPI_Waitany(N, req, &completed, sta);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (G) {
      TRACE_smpi_set_category("G");
      for (i = 0; i < N; i++) {
        MPI_Recv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &sta[i]);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (H) {
      TRACE_smpi_set_category("H");
      for (i = 0; i < N; i++) {
        MPI_Irecv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &req[i]);
      }
      MPI_Waitall(N, req, sta);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (I) {
      TRACE_smpi_set_category("I");
      for (i = 0; i < N; i++) {
        MPI_Irecv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &req[i]);
      }
      MPI_Waitall(N, req, sta);

      MPI_Barrier(MPI_COMM_WORLD);
      for (i = 0; i < N; i++) {
        MPI_Isend(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &req[i]);
      }
      MPI_Waitall(N, req, sta);
//      for (i = 0; i < N; i++){
//        MPI_Wait (&req[i], &sta[i]);
//      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    if (J) {
      TRACE_smpi_set_category("J");
      for (i = 0; i < N; i++) {
        MPI_Irecv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &req[i]);
      }
      for (i = 0; i < N; i++) {
        int flag;
        MPI_Test(&req[i], &flag, &sta[i]);
      }
      for (i = 0; i < N; i++) {
        MPI_Wait(&req[i], &sta[i]);
      }
    }
    free(r);
/////////////////////////////////////////
////////////////// RANK 2
///////////////////////////////////
  } else if (rank == 2) {
//    MPI_Request request;
//    MPI_Status status;
    MPI_Request req[N];
    MPI_Status sta[N];
    int *r = (int *) malloc(sizeof(int) * DATATOSENT);

    if (A) {
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (B) {
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (C) {
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (D) {
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (E) {
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (F) {
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (G) {
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (H) {
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (I) {
      TRACE_smpi_set_category("I");
      for (i = 0; i < N; i++) {
        MPI_Irecv(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD, &req[i]);
      }
      for (i = 0; i < N; i++) {
        int completed;
        MPI_Waitany(N, req, &completed, sta);
      }
      MPI_Barrier(MPI_COMM_WORLD);

      for (i = 0; i < N; i++) {
        MPI_Send(r, DATATOSENT, MPI_INT, 0, tag, MPI_COMM_WORLD);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (J) {
    }
    free(r);
  }
  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();
  return 0;
}
Esempio n. 14
0
static void complete_something_somehow(unsigned int rndnum, int numreqs, MPI_Request reqs[], int *outcount, int indices[])
{
    int i, idx, flag;

#define COMPLETION_CASES (8)
    switch (rand_range(rndnum, 0, COMPLETION_CASES)) {
        case 0:
            MPI_Waitall(numreqs, reqs, MPI_STATUSES_IGNORE);
            *outcount = numreqs;
            for (i = 0; i < numreqs; ++i) {
                indices[i] = i;
            }
            break;

        case 1:
            MPI_Testsome(numreqs, reqs, outcount, indices, MPI_STATUS_IGNORE);
            if (*outcount == MPI_UNDEFINED) {
                *outcount = 0;
            }
            break;

        case 2:
            MPI_Waitsome(numreqs, reqs, outcount, indices, MPI_STATUS_IGNORE);
            if (*outcount == MPI_UNDEFINED) {
                *outcount = 0;
            }
            break;

        case 3:
            MPI_Waitany(numreqs, reqs, &idx, MPI_STATUS_IGNORE);
            if (idx == MPI_UNDEFINED) {
                *outcount = 0;
            }
            else {
                *outcount = 1;
                indices[0] = idx;
            }
            break;

        case 4:
            MPI_Testany(numreqs, reqs, &idx, &flag, MPI_STATUS_IGNORE);
            if (idx == MPI_UNDEFINED) {
                *outcount = 0;
            }
            else {
                *outcount = 1;
                indices[0] = idx;
            }
            break;

        case 5:
            MPI_Testall(numreqs, reqs, &flag, MPI_STATUSES_IGNORE);
            if (flag) {
                *outcount = numreqs;
                for (i = 0; i < numreqs; ++i) {
                    indices[i] = i;
                }
            }
            else {
                *outcount = 0;
            }
            break;

        case 6:
            /* select a new random index and wait on it */
            rndnum = gen_prn(rndnum);
            idx = rand_range(rndnum, 0, numreqs);
            MPI_Wait(&reqs[idx], MPI_STATUS_IGNORE);
            *outcount = 1;
            indices[0] = idx;
            break;

        case 7:
            /* select a new random index and wait on it */
            rndnum = gen_prn(rndnum);
            idx = rand_range(rndnum, 0, numreqs);
            MPI_Test(&reqs[idx], &flag, MPI_STATUS_IGNORE);
            *outcount = (flag ? 1 : 0);
            indices[0] = idx;
            break;

        default:
            assert(0);
            break;
    }
#undef COMPLETION_CASES
}
Esempio n. 15
0
enum async_status async_mpi(void* session) {
	async_mpi_session* ses = (async_mpi_session*) session;
	switch(ses->state) {
		case ASYNC_MPI_STATE_SEND_OR_RECV: {
			PRINT_SES(ses);
			if((ses->flags & ASYNC_MPI_FLAG_SHOULD_SEND_COUNT) != 0) {
				int r;
				if((ses->flags & ASYNC_MPI_FLAG_IS_SENDING) != 0) {
					//printf("MPI_Isend(%p[%i], %i, MPI_INT, %i, %i, MPI_COMM_WORLD, %p)\n", &(ses->count), ses->count, 1, ses->peer, 0, ses->request);
					// fprintf(stderr, "Isend(1) to %d\n", ses->peer);
					//r = MPI_Isend(&(ses->count), 2, MPI_INT, ses->peer, 0, ses->comm, ses->request);
					ses->tmp[0] = ses->count;
					ses->tmp[1] = ses->tag;
					r = MPI_Isend(ses->tmp, 2, MPI_INT, ses->peer, 0, ses->comm, ses->request);
				} else {
					//printf("MPI_Irecv(%p[%i], %i, MPI_INT, %i, %i, MPI_COMM_WORLD, %p)\n", &(ses->count), ses->count, 1, ses->peer, 0, ses->request);
					//r = MPI_Irecv(&(ses->count), 2, MPI_INT, ses->peer, 0, ses->comm, ses->request);
					r = MPI_Irecv(ses->tmp, 2, MPI_INT, ses->peer, 0, ses->comm, ses->request);
				}
				if(r != MPI_SUCCESS) {
					ses->state = ASYNC_MPI_STATE_FAILURE;
					return ASYNC_FAILURE;
				}
			} else {
				ses->state = ASYNC_MPI_STATE_SEND_OR_RECV2;
				return async_mpi(ses);
			}
			ses->state = ASYNC_MPI_STATE_TEST;
			// fall-through
		}
		case ASYNC_MPI_STATE_TEST: {
			PRINT_SES(ses);
			int flag;
			MPI_Status status;
			MPI_Test(ses->request, &flag, &status);
			if(!flag) {
				return ASYNC_PENDING;
			}
			if((ses->flags & ASYNC_MPI_FLAG_IS_SENDING) == 0) {
				ses->count = ses->tmp[0];
				ses->tag = ses->tmp[1];
				//printf("count=%i source=%i tag=%i error=%i\n", ses->count, status.MPI_SOURCE, status.MPI_TAG, status.MPI_ERROR);
				ses->peer = status.MPI_SOURCE;
				//ses->tag = status.MPI_TAG;
				if(safe_realloc(&(ses->buf), ses->buf, ses->count) <= 0) {
					ses->state = ASYNC_MPI_STATE_FAILURE;
					return ASYNC_FAILURE;
				}
//				fprintf(stderr, "%s:%u: recv message of size %u\n", __FILE__, __LINE__, ses->count);
			}
			ses->state = ASYNC_MPI_STATE_SEND_OR_RECV2;
			// fall-through
		}
		case ASYNC_MPI_STATE_SEND_OR_RECV2: {
			PRINT_SES(ses);
			int r;
			if((ses->flags & ASYNC_MPI_FLAG_IS_SENDING) != 0) {
				//fprintf(stderr, "MPI_Isend(%p[%i,%i], %i, MPI_BYTE, %i, %i, MPI_COMM_WORLD, %p)\n", ses->buf, ((int*)ses->buf)[0], ((int*)ses->buf)[1], ses->count, ses->peer, ses->tag, ses->request);
				// fprintf(stderr, "Isend(2) to %d\n", ses->peer);
				r = MPI_Isend(ses->buf, ses->count, ses->datatype, ses->peer, ses->tag, ses->comm, ses->request);
			} else {
				//fprintf(stderr, "MPI_Irecv(%p[%i,%i], %i, MPI_BYTE, %i, %i, MPI_COMM_WORLD, %p)\n", ses->buf, ((int*)ses->buf)[0], ((int*)ses->buf)[1], ses->count, ses->peer, ses->tag, ses->request);
				r = MPI_Irecv(ses->buf, ses->count, ses->datatype, ses->peer, ses->tag, ses->comm, ses->request);
			}
			if(r != MPI_SUCCESS) {
				//printf("FAILURE! (from async_mpi)\n");
				ses->state = ASYNC_MPI_STATE_FAILURE;
				return ASYNC_FAILURE;
			}
			ses->state = ASYNC_MPI_STATE_TEST2;
			// fall-through
		}
		case ASYNC_MPI_STATE_TEST2: {
			PRINT_SES(ses);
			int flag = 1;
			MPI_Status status;
			MPI_Test(ses->request, &flag, &status);
			//fprintf(stderr, "MPI_Test(%p[%i,%i], %i, MPI_BYTE, %i, %i, MPI_COMM_WORLD, %p)\n", ses->buf, ((int*)ses->buf)[0], ((int*)ses->buf)[1], ses->count, ses->peer, ses->tag, ses->request);
			if(!flag) {
				return ASYNC_PENDING;
			}
			ses->peer = status.MPI_SOURCE;
			//printf("flag = %i\tSOURCE = %i\tTAG = %i\tERROR = %i\n", flag, status.MPI_SOURCE, status.MPI_TAG, status.MPI_ERROR);
			ses->state = ASYNC_MPI_STATE_SUCCESS;
			// fall-through
		}
		case ASYNC_MPI_STATE_SUCCESS: {
			PRINT_SES(ses);
			return ASYNC_SUCCESS;
		}
		case ASYNC_MPI_STATE_FAILURE: {
			PRINT_SES(ses);
			return ASYNC_FAILURE;
		}
		default: {
			printf("UNHANDLED CASE!\n");
			return ASYNC_FAILURE;
		}
	}
}
Esempio n. 16
0
int main( int argc, char **argv )
{
    MPI_Request r1;
    int         size, rank;
    int         err = 0;
    int         partner, buf[10], flag, idx, index;
    MPI_Status  status;

    MPI_Init( &argc, &argv );

    MPI_Comm_size( MPI_COMM_WORLD, &size );
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
    
    if (size < 2) {
	printf( "Cancel test requires at least 2 processes\n" );
	MPI_Abort( MPI_COMM_WORLD, 1 );
    }

    /* 
     * Here is the test.  First, we ensure an unsatisfied Irecv:
     *       process 0             process size-1
     *       Sendrecv              Sendrecv
     *       Irecv                    ----
     *       Cancel                   ----
     *       Sendrecv              Sendrecv
     * Next, we confirm receipt before canceling
     *       Irecv                 Send
     *       Sendrecv              Sendrecv
     *       Cancel
     */
    if (rank == 0) {
	partner = size - 1;
	/* Cancel succeeds for wait/waitall */
	MPI_Send_init( buf, 10, MPI_INT, partner, 0, MPI_COMM_WORLD, &r1 );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	MPI_Start( &r1 );
	MPI_Cancel( &r1 );
	MPI_Wait( &r1, &status );
	MPI_Test_cancelled( &status, &flag ); 
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	if (!flag) {
	    err++; 
	    printf( "Cancel of a send failed where it should succeed (Wait).\n" );
	}
	MPI_Request_free( &r1 ); 

	/* Cancel fails for test/testall */
	buf[0] = 3;
	MPI_Send_init( buf, 3, MPI_INT, partner, 2, MPI_COMM_WORLD, &r1 );
	MPI_Start( &r1 );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	MPI_Cancel( &r1 );
	MPI_Test( &r1, &flag, &status );
	MPI_Test_cancelled( &status, &flag );
	if (flag) {
	    err++;
	    printf( "Cancel of a send succeeded where it shouldn't (Test).\n" );
	}
	MPI_Request_free( &r1 );

	/* Cancel succeeds for waitany */
	MPI_Send_init( buf, 10, MPI_INT, partner, 0, MPI_COMM_WORLD, &r1 );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	MPI_Start( &r1 );
	MPI_Cancel( &r1 );
	MPI_Waitany( 1, &r1, &idx, &status );
	MPI_Test_cancelled( &status, &flag );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	if (!flag) {
	    err++;
	    printf( "Cancel of a send failed where it should succeed (Waitany).\n" );
	}
	MPI_Request_free( &r1 );

	/* Cancel fails for testany */
        buf[0] = 3;
	MPI_Send_init( buf, 3, MPI_INT, partner, 2, MPI_COMM_WORLD, &r1 );
	MPI_Start( &r1 );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	MPI_Cancel( &r1 );
	MPI_Testany( 1, &r1, &idx, &flag, &status );
	MPI_Test_cancelled( &status, &flag );
	if (flag) {
	    err++;
	    printf( "Cancel of a send succeeded where it shouldn't (Testany).\n" );
	}
	MPI_Request_free( &r1 );

	/* Cancel succeeds for waitsome */
	MPI_Send_init( buf, 10, MPI_INT, partner, 0, MPI_COMM_WORLD, &r1 );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	MPI_Start( &r1 );
	MPI_Cancel( &r1 );
	MPI_Waitsome( 1, &r1, &idx, &index, &status );
	MPI_Test_cancelled( &status, &flag );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	if (!flag) {
	    err++;
	    printf( "Cancel of a send failed where it should succeed (Waitsome).\n" );
	}
	MPI_Request_free( &r1 );

	/* Cancel fails for testsome*/
        buf[0] = 3;
	MPI_Send_init( buf, 3, MPI_INT, partner, 2, MPI_COMM_WORLD, &r1 );
	MPI_Start( &r1 );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	MPI_Cancel( &r1 );
	MPI_Testsome( 1, &r1, &idx, &index, &status );
	MPI_Test_cancelled( &status, &flag );
	if (flag) {
	    err++;
	    printf( "Cancel of a send succeeded where it shouldn't (Testsome).\n" );
	}
	MPI_Request_free( &r1 );

	if (err) {
	    printf( "Test failed with %d errors.\n", err );
	}
	else {
	    printf( "Test passed\n" );
	}
    }
    else if (rank == size - 1) {
	partner = 0;
	/* Cancel succeeds for wait/waitall */
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );

	/* Cancel fails for test/testall */
	buf[0] = -1;
	MPI_Recv( buf, 3, MPI_INT, partner, 2, MPI_COMM_WORLD, &status );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );

	if (buf[0] == -1) {
	    printf( "Receive buffer did not change even though cancel should not have suceeded! (Test).\n" );
	    }

	/* Cancel succeeds for waitany */
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	/* Cancel fails  for testany */
	buf[0] = -1;
	MPI_Recv( buf, 3, MPI_INT, partner, 2, MPI_COMM_WORLD, &status );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	if (buf[0] == -1) {
	    printf( "Receive buffer did not change even though cancel should not have suceeded! (Testany).\n" );
	    }

	/* Cancel succeeds for waitsome */
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );
	/* Cancel fails for testsome */
	buf[0] = -1;
	MPI_Recv( buf, 3, MPI_INT, partner, 2, MPI_COMM_WORLD, &status );
	MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_BOTTOM, 0, MPI_INT, partner, 1,
		      MPI_COMM_WORLD, &status );

	if (buf[0] == -1) {
	    printf( "Receive buffer did not change even though cancel should not have suceeded! (Test).\n" );
	    }

    }

    MPI_Finalize();
    return 0;
}
Esempio n. 17
0
FORT_NAME( mpi_test , MPI_TEST)(int *request, int *flag, int *status,
				int *ierror)
{
  *ierror=MPI_Test( (void *)request ,flag,(MPI_Status *)status);
}
Esempio n. 18
0
void do_supervisor_stuff(int argc, char ** argv, struct mw_api_spec *f)
{
  
  //DEBUG_PRINT(("supervisor starting"));
  
  int number_of_slaves;
  MPI_Comm_size(MPI_COMM_WORLD, &number_of_slaves);
  number_of_slaves = number_of_slaves - 2;
  
  MPI_Status status, status1, status2;
  MPI_Request request1, request2;
  
  // keep track of start times
  double * assignment_time1 = malloc(sizeof(double)*number_of_slaves);
  double * assignment_time2 = malloc(sizeof(double)*number_of_slaves);

  // determine how long each worker took
  double * complete_time = malloc(sizeof(double)*number_of_slaves);
  // booleans for failure
  int * failed_worker = calloc(sizeof(int), number_of_slaves);

  // supervisor does blocking receive to get list of workers and their start times
  MPI_Recv(assignment_time1, number_of_slaves, MPI_DOUBLE, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
  //assignment_time2 = assignment_time1;

  // calc approximate time diff between sup and master
  double master_time = assignment_time1[number_of_slaves-1];
  double mytime_off_by = MPI_Wtime() - master_time;

  //DEBUG_PRINT(("supervisor knows when the workers started"));

  int units_received = 0;
  int i;
  int kill_msg, flag1, received_update;
  
  double tot_time=0, sq_err=0, mean=0, stddev=0, threshold=0;
  
  //set up receivers for kill and master updates
  MPI_Irecv(&kill_msg, 1, MPI_INT, 0, KILL_TAG, MPI_COMM_WORLD, &request1);
  MPI_Irecv(assignment_time2, number_of_slaves, MPI_DOUBLE, 0, SUPERVISOR_TAG, MPI_COMM_WORLD, &request2);

  //waiting for updates on start times from master
  while(1) 
  {
    //kill myself if the master says so  
    MPI_Test(&request1, &flag1, &status1);
    if(flag1)
    {
      //DEBUG_PRINT(("SUPERVISOR SUICIDE!"));
      return;
    }
    
    //get a new start time array from master
    MPI_Test(&request2, &received_update, &status2);
    if(received_update)
    {
      //DEBUG_PRINT(("got an update from master"));
    }
    
    //DEBUG_PRINT(("supervisor is about to check if the slaves are different"));

    int found_change = 0;
    //check for differences in working slaves
    for(i=0; i<number_of_slaves; i++) 
    {
      if(failed_worker[i] != 0)
      {
        continue;
      }
      if(assignment_time1[i] == 0.0 && assignment_time2[i] != 0.0)
      {
        //a previously idle worked got assigned something
        assignment_time1[i] = assignment_time2[i];
        found_change = 1;
        DEBUG_PRINT(("Worker %d just got off his lazy ass", i));
        continue;
      }
      if(assignment_time2[i] == 0.0)
      {
        //worker is currently idle, not dead
        if(assignment_time1[i] != 0.0)
        {
            DEBUG_PRINT(("Just found out %d is idle", i));
            assignment_time1[i] = 0.0;
            found_change = 1;
        }
        continue;
      }

      //we have a good worker!
      if(assignment_time1[i] != assignment_time2[i] && received_update)
      {
        //DEBUG_PRINT(("supervisor is impressed by his good worker %d", i));
        complete_time[i] = assignment_time2[i] - assignment_time1[i];
        units_received++;
        tot_time += complete_time[i];
        mean = tot_time/units_received;
        sq_err += pow(complete_time[i] - mean, 2);
        stddev = sqrt(sq_err/units_received);
        //we have enough data to update threshold
        if(units_received >= number_of_slaves/2)
        {
          //DEBUG_PRINT(("the stddev is %f", stddev));
          threshold = mean + 10*stddev + 0.1;
          //DEBUG_PRINT(("the threshold is %f", threshold));
        }
        assignment_time1[i] = assignment_time2[i];
        found_change = 1;
        
      }
      //if we have enough data, we can tell if we have a bad worker :(
      else if(threshold>0 && assignment_time1[i]==assignment_time2[i] && MPI_Wtime() - mytime_off_by - assignment_time1[i] > threshold)
      {
        assert(assignment_time1[i] != 0.0);
        DEBUG_PRINT(("methinks someone is slacking %d", i));
        MPI_Send(&i, 1, MPI_INT, 0, FAIL_TAG, MPI_COMM_WORLD);
        failed_worker[i] = 1;
      }
    }
    if(received_update)
    {
      if(found_change == 0)
      {
          DEBUG_PRINT(("Received an update without any change :("));
      }
      MPI_Irecv(assignment_time2, number_of_slaves, MPI_DOUBLE, 0, SUPERVISOR_TAG, MPI_COMM_WORLD, &request2);
    } 
  }
}
int
main (int argc, char **argv)
{
  int nprocs = -1;
  int rank = -1;
  int comm = MPI_COMM_WORLD;
  char processor_name[128];
  int namelen = 128;
  int bbuf[(BUF_SIZE + MPI_BSEND_OVERHEAD) * 2 * NUM_BSEND_TYPES];
  int buf[BUF_SIZE * 2 * NUM_SEND_TYPES + SLOP];
  int i, j, k, l, m, at_size, send_t_number, index, outcount, total, flag;
  int num_errors, error_count, indices[2 * NUM_SEND_TYPES];
  MPI_Request aReq[2 * NUM_SEND_TYPES];
  MPI_Status aStatus[2 * NUM_SEND_TYPES];

  /* init */
  MPI_Init (&argc, &argv);
  MPI_Comm_size (comm, &nprocs);
  MPI_Comm_rank (comm, &rank);
  MPI_Get_processor_name (processor_name, &namelen);
  printf ("(%d) is alive on %s\n", rank, processor_name);
  fflush (stdout);

  MPI_Buffer_attach (bbuf, sizeof(int) * 
		     (BUF_SIZE + MPI_BSEND_OVERHEAD) * 2 * NUM_BSEND_TYPES);

  if (rank == 0) {
    /* set up persistent sends... */
    send_t_number = NUM_SEND_TYPES - NUM_PERSISTENT_SEND_TYPES;

    MPI_Send_init (&buf[send_t_number * 2 * BUF_SIZE], BUF_SIZE, MPI_INT, 
		    1, send_t_number * 2, comm, &aReq[send_t_number * 2]);
    MPI_Send_init (&buf[(send_t_number * 2 + 1) * BUF_SIZE], 
		    BUF_SIZE, MPI_INT, 1, send_t_number * 2 + 1, 
		    comm, &aReq[send_t_number * 2 + 1]);

    send_t_number++;

    MPI_Bsend_init (&buf[send_t_number * 2 * BUF_SIZE], BUF_SIZE, MPI_INT, 
		    1, send_t_number * 2, comm, &aReq[send_t_number * 2]);
    MPI_Bsend_init (&buf[(send_t_number * 2 + 1) * BUF_SIZE], 
		    BUF_SIZE, MPI_INT, 1, send_t_number * 2 + 1, 
		    comm, &aReq[send_t_number * 2 + 1]);


    send_t_number++;

    MPI_Rsend_init (&buf[send_t_number * 2 * BUF_SIZE], BUF_SIZE, MPI_INT, 
		    1, send_t_number * 2, comm, &aReq[send_t_number * 2]);
    MPI_Rsend_init (&buf[(send_t_number * 2 + 1) * BUF_SIZE], 
		    BUF_SIZE, MPI_INT, 1, send_t_number * 2 + 1, 
		    comm, &aReq[send_t_number * 2 + 1]);

    send_t_number++;

    MPI_Ssend_init (&buf[send_t_number * 2 * BUF_SIZE], BUF_SIZE, MPI_INT, 
		    1, send_t_number * 2, comm, &aReq[send_t_number * 2]);
    MPI_Ssend_init (&buf[(send_t_number * 2 + 1) * BUF_SIZE], 
		    BUF_SIZE, MPI_INT, 1, send_t_number * 2 + 1, 
		    comm, &aReq[send_t_number * 2 + 1]);
  }

  for (m = 0; m < NUM_RECV_TYPES; m++) {
    if ((m == 1) && (rank == 1)) {
      /* set up the persistent receives... */
      for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	MPI_Recv_init (&buf[j * BUF_SIZE], 
		       BUF_SIZE + (j % 2) * SLOP, 
		       MPI_INT, 0, j, comm, &aReq[j]);
      }
    }

    for (l = 0; l < (NUM_COMPLETION_MECHANISMS * 2); l++) {
      for (k = 0; k < (NUM_COMPLETION_MECHANISMS * 2); k++) {
	if (rank == 0) {
	  /* initialize all of the send buffers */
	  for (j = 0; j < NUM_SEND_TYPES; j++) {
	    for (i = 0; i < BUF_SIZE; i++) {
	      buf[2 * j * BUF_SIZE + i] = i;
	      buf[((2 * j + 1) * BUF_SIZE) + i] = BUF_SIZE - 1 - i;
	    }
	  }
	}
	else if (rank == 1) {
	  /* zero out all of the receive buffers */
	  bzero (buf, sizeof(int) * BUF_SIZE * 2 * NUM_SEND_TYPES);
	}

	MPI_Barrier(MPI_COMM_WORLD);

	if (rank == 0) {
	  /* set up transient sends... */
	  send_t_number = 0;
    
	  MPI_Isend (&buf[send_t_number * 2 * BUF_SIZE], BUF_SIZE, MPI_INT,
		     1, send_t_number * 2, comm, &aReq[send_t_number * 2]);
	  MPI_Isend (&buf[(send_t_number * 2 + 1) * BUF_SIZE],
		     BUF_SIZE, MPI_INT, 1, send_t_number * 2 + 1, 
		     comm, &aReq[send_t_number * 2 + 1]);

	  send_t_number++;
	
	  MPI_Ibsend (&buf[send_t_number * 2 * BUF_SIZE], BUF_SIZE, MPI_INT,
		      1, send_t_number * 2, comm, &aReq[send_t_number * 2]);
	  MPI_Ibsend (&buf[(send_t_number * 2 + 1) * BUF_SIZE],
		      BUF_SIZE, MPI_INT, 1, send_t_number * 2 + 1, 
		      comm, &aReq[send_t_number * 2 + 1]);

	  send_t_number++;

	  /* Barrier to ensure receives are posted for rsends... */
	  MPI_Barrier(MPI_COMM_WORLD);
	  
	  MPI_Irsend (&buf[send_t_number * 2 * BUF_SIZE], BUF_SIZE, MPI_INT,
		    1, send_t_number * 2, comm, &aReq[send_t_number * 2]);
	  MPI_Irsend (&buf[(send_t_number * 2 + 1) * BUF_SIZE],
		      BUF_SIZE, MPI_INT, 1, send_t_number * 2 + 1, 
		      comm, &aReq[send_t_number * 2 + 1]);

	  send_t_number++;

	  MPI_Issend (&buf[send_t_number * 2 * BUF_SIZE], BUF_SIZE, MPI_INT,
		      1, send_t_number * 2, comm, &aReq[send_t_number * 2]);
	  MPI_Issend (&buf[(send_t_number * 2 + 1) * BUF_SIZE],
		      BUF_SIZE, MPI_INT, 1, send_t_number * 2 + 1, 
		      comm, &aReq[send_t_number * 2 + 1]);

	  /* just to be paranoid */
	  send_t_number++;
	  assert (send_t_number == 
		  NUM_SEND_TYPES - NUM_PERSISTENT_SEND_TYPES);

	  /* start the persistent sends... */
	  if (k % 2) {
	    MPI_Startall (NUM_PERSISTENT_SEND_TYPES * 2, 
			  &aReq[2 * send_t_number]);
	  }
	  else {
	    for (j = 0; j < NUM_PERSISTENT_SEND_TYPES * 2; j++) {
	      MPI_Start (&aReq[2 * send_t_number + j]);
	    }
	  }
	
	  /* complete the sends */
	  switch (k/2) {
	  case 0:
	    /* use MPI_Wait */
	    for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	      MPI_Wait (&aReq[j], &aStatus[j]);
	    }
	    break;
	  
	  case 1:
	    /* use MPI_Waitall */
	    MPI_Waitall (NUM_SEND_TYPES * 2, aReq, aStatus);
	    break;

	  case 2:
	    /* use MPI_Waitany */
	    for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	      MPI_Waitany (NUM_SEND_TYPES * 2, aReq, &index, aStatus);
	    }
	    
	    break;
	
	  case 3:
	    /* use MPI_Waitsome */
	    total = 0;
	    while (total < NUM_SEND_TYPES * 2) {
	      MPI_Waitsome (NUM_SEND_TYPES * 2, aReq, 
			    &outcount, indices, aStatus);

	      total += outcount;
	    }

	    break;

	  case 4:
	    /* use MPI_Test */
	    for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	      flag = 0;
	    
	      while (!flag) {
		MPI_Test (&aReq[j], &flag, &aStatus[j]);
	      }
	    }
	  
	    break;
	
	  case 5:
	    /* use MPI_Testall */
	    flag = 0;
	    while (!flag) {
	      MPI_Testall (NUM_SEND_TYPES * 2, aReq, &flag, aStatus);
	    }
	  
	    break;
	
	  case 6:
	    /* use MPI_Testany */
	    for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	      flag = 0;
	      while (!flag) {
		MPI_Testany (NUM_SEND_TYPES * 2, aReq, 
			     &index, &flag, aStatus);
	      }
	    }

	    break;
	
	  case 7:
	    /* use MPI_Testsome */
	    total = 0;
	    while (total < NUM_SEND_TYPES * 2) {
	      outcount = 0;

	      while (!outcount) {
		MPI_Testsome (NUM_SEND_TYPES * 2, aReq, 
			      &outcount, indices, aStatus);
	      }

	      total += outcount;
	    }

	    break;

	  default:
	    assert (0);
	    break;
	  }
	}
	else if (rank == 1) {
	  /* start receives for all of the sends */
	  if (m == 0) {
	    for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	      MPI_Irecv (&buf[j * BUF_SIZE], 
			 BUF_SIZE + (j % 2) * SLOP, 
			 MPI_INT, 0, j, comm, &aReq[j]);
	    }
	  }
	  else {
	    /* start the persistent receives... */
	    if (l % 2) {
	      MPI_Startall (NUM_SEND_TYPES * 2, aReq);
	    }
	    else {
	      for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
		MPI_Start (&aReq[j]);
	      }
	    }
	  }

	  /* Barrier to ensure receives are posted for rsends... */
	  MPI_Barrier(MPI_COMM_WORLD);
	
	  /* complete all of the receives... */
	  switch (l/2) {
	  case 0: 
	    /* use MPI_Wait */
	    for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	      MPI_Wait (&aReq[j], &aStatus[j]);
	    }
	    break;
	    
	  case 1:
	    /* use MPI_Waitall */
	    MPI_Waitall (NUM_SEND_TYPES * 2, aReq, aStatus);
	    break;

	  case 2:
	    /* use MPI_Waitany */
	    for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	      MPI_Waitany (NUM_SEND_TYPES * 2, aReq, &index, aStatus);
	    }
	    
	    break;
	
	  case 3:
	    /* use MPI_Waitsome */
	    total = 0;
	    while (total < NUM_SEND_TYPES * 2) {
	      MPI_Waitsome (NUM_SEND_TYPES * 2, aReq, 
			    &outcount, indices, aStatus);

	      total += outcount;
	    }

	    break;
	    
	  case 4:
	    /* use MPI_Test */
	    for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	      flag = 0;
	      
	      while (!flag) {
		MPI_Test (&aReq[j], &flag, &aStatus[j]);
	      }
	    }
	    
	    break;
	    
	  case 5:
	    /* use MPI_Testall */
	    flag = 0;
	    while (!flag) {
	      MPI_Testall (NUM_SEND_TYPES * 2, aReq, &flag, aStatus);
	    }
	    
	    break;
	    
	  case 6:
	    /* use MPI_Testany */
	    for (j = 0; j < NUM_SEND_TYPES * 2; j++) {
	      flag = 0;
	      while (!flag) {
		MPI_Testany (NUM_SEND_TYPES * 2, aReq, 
			     &index, &flag, aStatus);
	      }
	    }
	    
	    break;
	    
	  case 7:
	    /* use MPI_Testsome */
	    total = 0;
	    while (total < NUM_SEND_TYPES * 2) {
	      outcount = 0;

	      while (!outcount) {
		MPI_Testsome (NUM_SEND_TYPES * 2, aReq, 
			      &outcount, indices, aStatus);
	      }
	      
	      total += outcount;
	    }
	    
	    break;
	    
	  default:
	    assert (0);
	    break;
	  }
	}
	else {
	  /* Barrier to ensure receives are posted for rsends... */
	  MPI_Barrier(MPI_COMM_WORLD);
	}
      }
    }
  }

  MPI_Barrier(MPI_COMM_WORLD);

  if (rank == 0) {
    /* free the persistent send requests */
    for (i = 2* (NUM_SEND_TYPES - NUM_PERSISTENT_SEND_TYPES);
	 i < 2 * NUM_SEND_TYPES; i++) {
      MPI_Request_free (&aReq[i]);
    }
  }
  else if (rank == 1) {
    /* free the persistent receive requests */
    for (i = 0; i < 2 * NUM_SEND_TYPES; i++) {
      MPI_Request_free (&aReq[i]);
    }
  }


  MPI_Buffer_detach (bbuf, &at_size);

  assert (at_size == 
	  sizeof(int) * (BUF_SIZE + MPI_BSEND_OVERHEAD) * 2 * NUM_BSEND_TYPES);

  MPI_Finalize ();
  printf ("(%d) Finished normally\n", rank);
}
Esempio n. 20
0
File: MPI-api.c Progetto: 8l/rose
void declareBindings (void)
{
  /* === Point-to-point === */
  void* buf;
  int count;
  MPI_Datatype datatype;
  int dest;
  int tag;
  MPI_Comm comm;
  MPI_Send (buf, count, datatype, dest, tag, comm); // L12
  int source;
  MPI_Status status;
  MPI_Recv (buf, count, datatype, source, tag, comm, &status); // L15
  MPI_Get_count (&status, datatype, &count);
  MPI_Bsend (buf, count, datatype, dest, tag, comm);
  MPI_Ssend (buf, count, datatype, dest, tag, comm);
  MPI_Rsend (buf, count, datatype, dest, tag, comm);
  void* buffer;
  int size;
  MPI_Buffer_attach (buffer, size); // L22
  MPI_Buffer_detach (buffer, &size);
  MPI_Request request;
  MPI_Isend (buf, count, datatype, dest, tag, comm, &request); // L25
  MPI_Ibsend (buf, count, datatype, dest, tag, comm, &request);
  MPI_Issend (buf, count, datatype, dest, tag, comm, &request);
  MPI_Irsend (buf, count, datatype, dest, tag, comm, &request);
  MPI_Irecv (buf, count, datatype, source, tag, comm, &request);
  MPI_Wait (&request, &status);
  int flag;
  MPI_Test (&request, &flag, &status); // L32
  MPI_Request_free (&request);
  MPI_Request* array_of_requests;
  int index;
  MPI_Waitany (count, array_of_requests, &index, &status); // L36
  MPI_Testany (count, array_of_requests, &index, &flag, &status);
  MPI_Status* array_of_statuses;
  MPI_Waitall (count, array_of_requests, array_of_statuses); // L39
  MPI_Testall (count, array_of_requests, &flag, array_of_statuses);
  int incount;
  int outcount;
  int* array_of_indices;
  MPI_Waitsome (incount, array_of_requests, &outcount, array_of_indices,
		array_of_statuses); // L44--45
  MPI_Testsome (incount, array_of_requests, &outcount, array_of_indices,
		array_of_statuses); // L46--47
  MPI_Iprobe (source, tag, comm, &flag, &status); // L48
  MPI_Probe (source, tag, comm, &status);
  MPI_Cancel (&request);
  MPI_Test_cancelled (&status, &flag);
  MPI_Send_init (buf, count, datatype, dest, tag, comm, &request);
  MPI_Bsend_init (buf, count, datatype, dest, tag, comm, &request);
  MPI_Ssend_init (buf, count, datatype, dest, tag, comm, &request);
  MPI_Rsend_init (buf, count, datatype, dest, tag, comm, &request);
  MPI_Recv_init (buf, count, datatype, source, tag, comm, &request);
  MPI_Start (&request);
  MPI_Startall (count, array_of_requests);
  void* sendbuf;
  int sendcount;
  MPI_Datatype sendtype;
  int sendtag;
  void* recvbuf;
  int recvcount;
  MPI_Datatype recvtype;
  MPI_Datatype recvtag;
  MPI_Sendrecv (sendbuf, sendcount, sendtype, dest, sendtag,
		recvbuf, recvcount, recvtype, source, recvtag,
		comm, &status); // L67--69
  MPI_Sendrecv_replace (buf, count, datatype, dest, sendtag, source, recvtag,
			comm, &status); // L70--71
  MPI_Datatype oldtype;
  MPI_Datatype newtype;
  MPI_Type_contiguous (count, oldtype, &newtype); // L74
  int blocklength;
  {
    int stride;
    MPI_Type_vector (count, blocklength, stride, oldtype, &newtype); // L78
  }
  {
    MPI_Aint stride;
    MPI_Type_hvector (count, blocklength, stride, oldtype, &newtype); // L82
  }
  int* array_of_blocklengths;
  {
    int* array_of_displacements;
    MPI_Type_indexed (count, array_of_blocklengths, array_of_displacements,
		      oldtype, &newtype); // L87--88
  }
  {
    MPI_Aint* array_of_displacements;
    MPI_Type_hindexed (count, array_of_blocklengths, array_of_displacements,
                       oldtype, &newtype); // L92--93
    MPI_Datatype* array_of_types;
    MPI_Type_struct (count, array_of_blocklengths, array_of_displacements,
                     array_of_types, &newtype); // L95--96
  }
  void* location;
  MPI_Aint address;
  MPI_Address (location, &address); // L100
  MPI_Aint extent;
  MPI_Type_extent (datatype, &extent); // L102
  MPI_Type_size (datatype, &size);
  MPI_Aint displacement;
  MPI_Type_lb (datatype, &displacement); // L105
  MPI_Type_ub (datatype, &displacement);
  MPI_Type_commit (&datatype);
  MPI_Type_free (&datatype);
  MPI_Get_elements (&status, datatype, &count);
  void* inbuf;
  void* outbuf;
  int outsize;
  int position;
  MPI_Pack (inbuf, incount, datatype, outbuf, outsize, &position, comm); // L114
  int insize;
  MPI_Unpack (inbuf, insize, &position, outbuf, outcount, datatype,
	      comm); // L116--117
  MPI_Pack_size (incount, datatype, comm, &size);

  /* === Collectives === */
  MPI_Barrier (comm); // L121
  int root;
  MPI_Bcast (buffer, count, datatype, root, comm); // L123
  MPI_Gather (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype,
	      root, comm); // L124--125
  int* recvcounts;
  int* displs;
  MPI_Gatherv (sendbuf, sendcount, sendtype,
               recvbuf, recvcounts, displs, recvtype,
	       root, comm); // L128--130
  MPI_Scatter (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype,
               root, comm); // L131--132
  int* sendcounts;
  MPI_Scatterv (sendbuf, sendcounts, displs, sendtype,
		recvbuf, recvcount, recvtype, root, comm); // L134--135
  MPI_Allgather (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype,
                 comm); // L136--137
  MPI_Allgatherv (sendbuf, sendcount, sendtype,
		  recvbuf, recvcounts, displs, recvtype,
		  comm); // L138--140
  MPI_Alltoall (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype,
		comm); // L141--142
  int* sdispls;
  int* rdispls;
  MPI_Alltoallv (sendbuf, sendcounts, sdispls, sendtype,
                 recvbuf, recvcounts, rdispls, recvtype,
		 comm); // L145--147
  MPI_Op op;
  MPI_Reduce (sendbuf, recvbuf, count, datatype, op, root, comm); // L149
#if 0
  MPI_User_function function;
  int commute;
  MPI_Op_create (function, commute, &op); // L153
#endif
  MPI_Op_free (&op); // L155
  MPI_Allreduce (sendbuf, recvbuf, count, datatype, op, comm);
  MPI_Reduce_scatter (sendbuf, recvbuf, recvcounts, datatype, op, comm);
  MPI_Scan (sendbuf, recvbuf, count, datatype, op, comm);

  /* === Groups, contexts, and communicators === */
  MPI_Group group;
  MPI_Group_size (group, &size); // L162
  int rank;
  MPI_Group_rank (group, &rank); // L164
  MPI_Group group1;
  int n;
  int* ranks1;
  MPI_Group group2;
  int* ranks2;
  MPI_Group_translate_ranks (group1, n, ranks1, group2, ranks2); // L170
  int result;
  MPI_Group_compare (group1, group2, &result); // L172
  MPI_Group newgroup;
  MPI_Group_union (group1, group2, &newgroup); // L174
  MPI_Group_intersection (group1, group2, &newgroup);
  MPI_Group_difference (group1, group2, &newgroup);
  int* ranks;
  MPI_Group_incl (group, n, ranks, &newgroup); // L178
  MPI_Group_excl (group, n, ranks, &newgroup);
  extern int ranges[][3];
  MPI_Group_range_incl (group, n, ranges, &newgroup); // L181
  MPI_Group_range_excl (group, n, ranges, &newgroup);
  MPI_Group_free (&group);
  MPI_Comm_size (comm, &size);
  MPI_Comm_rank (comm, &rank);
  MPI_Comm comm1;
  MPI_Comm comm2;
  MPI_Comm_compare (comm1, comm2, &result);
  MPI_Comm newcomm;
  MPI_Comm_dup (comm, &newcomm);
  MPI_Comm_create (comm, group, &newcomm);
  int color;
  int key;
  MPI_Comm_split (comm, color, key, &newcomm); // L194
  MPI_Comm_free (&comm);
  MPI_Comm_test_inter (comm, &flag);
  MPI_Comm_remote_size (comm, &size);
  MPI_Comm_remote_group (comm, &group);
  MPI_Comm local_comm;
  int local_leader;
  MPI_Comm peer_comm;
  int remote_leader;
  MPI_Comm newintercomm;
  MPI_Intercomm_create (local_comm, local_leader, peer_comm, remote_leader, tag,
			&newintercomm); // L204--205
  MPI_Comm intercomm;
  MPI_Comm newintracomm;
  int high;
  MPI_Intercomm_merge (intercomm, high, &newintracomm); // L209
  int keyval;
#if 0
  MPI_Copy_function copy_fn;
  MPI_Delete_function delete_fn;
  void* extra_state;
  MPI_Keyval_create (copy_fn, delete_fn, &keyval, extra_state); // L215
#endif
  MPI_Keyval_free (&keyval); // L217
  void* attribute_val;
  MPI_Attr_put (comm, keyval, attribute_val); // L219
  MPI_Attr_get (comm, keyval, attribute_val, &flag);
  MPI_Attr_delete (comm, keyval);

  /* === Environmental inquiry === */
  char* name;
  int resultlen;
  MPI_Get_processor_name (name, &resultlen); // L226
  MPI_Errhandler errhandler;
#if 0
  MPI_Handler_function function;
  MPI_Errhandler_create (function, &errhandler); // L230
#endif
  MPI_Errhandler_set (comm, errhandler); // L232
  MPI_Errhandler_get (comm, &errhandler);
  MPI_Errhandler_free (&errhandler);
  int errorcode;
  char* string;
  MPI_Error_string (errorcode, string, &resultlen); // L237
  int errorclass;
  MPI_Error_class (errorcode, &errorclass); // L239
  MPI_Wtime ();
  MPI_Wtick ();
  int argc;
  char** argv;
  MPI_Init (&argc, &argv); // L244
  MPI_Finalize ();
  MPI_Initialized (&flag);
  MPI_Abort (comm, errorcode);
}
Esempio n. 21
0
static PetscErrorCode PetscCommBuildTwoSidedFReq_Ibarrier(MPI_Comm comm,PetscMPIInt count,MPI_Datatype dtype,PetscMPIInt nto,const PetscMPIInt *toranks,const void *todata,
                                                          PetscMPIInt *nfrom,PetscMPIInt **fromranks,void *fromdata,PetscMPIInt ntags,MPI_Request **toreqs,MPI_Request **fromreqs,
                                                          PetscErrorCode (*send)(MPI_Comm,const PetscMPIInt[],PetscMPIInt,PetscMPIInt,void*,MPI_Request[],void*),
                                                          PetscErrorCode (*recv)(MPI_Comm,const PetscMPIInt[],PetscMPIInt,void*,MPI_Request[],void*),void *ctx)
{
  PetscErrorCode ierr;
  PetscMPIInt    nrecvs,tag,*tags,done,i;
  MPI_Aint       lb,unitbytes;
  char           *tdata;
  MPI_Request    *sendreqs,*usendreqs,*req,barrier;
  PetscSegBuffer segrank,segdata,segreq;
  PetscBool      barrier_started;

  PetscFunctionBegin;
  ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
  ierr = PetscMalloc1(ntags,&tags);CHKERRQ(ierr);
  for (i=0; i<ntags; i++) {
    ierr = PetscCommGetNewTag(comm,&tags[i]);CHKERRQ(ierr);
  }
  ierr = MPI_Type_get_extent(dtype,&lb,&unitbytes);CHKERRQ(ierr);
  if (lb != 0) SETERRQ1(comm,PETSC_ERR_SUP,"Datatype with nonzero lower bound %ld\n",(long)lb);
  tdata = (char*)todata;
  ierr = PetscMalloc1(nto,&sendreqs);CHKERRQ(ierr);
  ierr = PetscMalloc1(nto*ntags,&usendreqs);CHKERRQ(ierr);
  /* Post synchronous sends */
  for (i=0; i<nto; i++) {
    ierr = MPI_Issend((void*)(tdata+count*unitbytes*i),count,dtype,toranks[i],tag,comm,sendreqs+i);CHKERRQ(ierr);
  }
  /* Post actual payloads.  These are typically larger messages.  Hopefully sending these later does not slow down the
   * synchronous messages above. */
  for (i=0; i<nto; i++) {
    PetscMPIInt k;
    for (k=0; k<ntags; k++) usendreqs[i*ntags+k] = MPI_REQUEST_NULL;
    ierr = (*send)(comm,tags,i,toranks[i],tdata+count*unitbytes*i,usendreqs+i*ntags,ctx);CHKERRQ(ierr);
  }

  ierr = PetscSegBufferCreate(sizeof(PetscMPIInt),4,&segrank);CHKERRQ(ierr);
  ierr = PetscSegBufferCreate(unitbytes,4*count,&segdata);CHKERRQ(ierr);
  ierr = PetscSegBufferCreate(sizeof(MPI_Request),4,&segreq);CHKERRQ(ierr);

  nrecvs  = 0;
  barrier = MPI_REQUEST_NULL;
  /* MPICH-3.2 sometimes does not create a request in some "optimized" cases.  This is arguably a standard violation,
   * but we need to work around it. */
  barrier_started = PETSC_FALSE;
  for (done=0; !done; ) {
    PetscMPIInt flag;
    MPI_Status  status;
    ierr = MPI_Iprobe(MPI_ANY_SOURCE,tag,comm,&flag,&status);CHKERRQ(ierr);
    if (flag) {                 /* incoming message */
      PetscMPIInt *recvrank,k;
      void        *buf;
      ierr = PetscSegBufferGet(segrank,1,&recvrank);CHKERRQ(ierr);
      ierr = PetscSegBufferGet(segdata,count,&buf);CHKERRQ(ierr);
      *recvrank = status.MPI_SOURCE;
      ierr = MPI_Recv(buf,count,dtype,status.MPI_SOURCE,tag,comm,MPI_STATUS_IGNORE);CHKERRQ(ierr);
      ierr = PetscSegBufferGet(segreq,ntags,&req);CHKERRQ(ierr);
      for (k=0; k<ntags; k++) req[k] = MPI_REQUEST_NULL;
      ierr = (*recv)(comm,tags,status.MPI_SOURCE,buf,req,ctx);CHKERRQ(ierr);
      nrecvs++;
    }
    if (!barrier_started) {
      PetscMPIInt sent,nsends;
      ierr = PetscMPIIntCast(nto,&nsends);CHKERRQ(ierr);
      ierr = MPI_Testall(nsends,sendreqs,&sent,MPI_STATUSES_IGNORE);CHKERRQ(ierr);
      if (sent) {
#if defined(PETSC_HAVE_MPI_IBARRIER)
        ierr = MPI_Ibarrier(comm,&barrier);CHKERRQ(ierr);
#elif defined(PETSC_HAVE_MPIX_IBARRIER)
        ierr = MPIX_Ibarrier(comm,&barrier);CHKERRQ(ierr);
#endif
        barrier_started = PETSC_TRUE;
      }
    } else {
      ierr = MPI_Test(&barrier,&done,MPI_STATUS_IGNORE);CHKERRQ(ierr);
    }
  }
  *nfrom = nrecvs;
  ierr = PetscSegBufferExtractAlloc(segrank,fromranks);CHKERRQ(ierr);
  ierr = PetscSegBufferDestroy(&segrank);CHKERRQ(ierr);
  ierr = PetscSegBufferExtractAlloc(segdata,fromdata);CHKERRQ(ierr);
  ierr = PetscSegBufferDestroy(&segdata);CHKERRQ(ierr);
  *toreqs = usendreqs;
  ierr = PetscSegBufferExtractAlloc(segreq,fromreqs);CHKERRQ(ierr);
  ierr = PetscSegBufferDestroy(&segreq);CHKERRQ(ierr);
  ierr = PetscFree(sendreqs);CHKERRQ(ierr);
  ierr = PetscFree(tags);CHKERRQ(ierr);
  ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Esempio n. 22
0
int main(int argc, char *argv[])
{

	// declare mpz structs
	mpz_t n; 
	mpz_t zero;
	mpz_t r;
	mpz_t d;
	mpz_t start;
	mpz_t end;
	mpz_t temp;
	mpz_t my_rank_mpz;
	mpz_t local_end;
	mpz_t current_prime;

	mpz_t global_end;

	mpz_init_set_ui(zero, 0);
	mpz_init(d);

	double t1, t2, totaltime;

	int tag = 0;
	int my_rank, p;
	int source, dest, i;

	mpz_init_set_str(n, argv[1], 10); // initialize the key (n)

	mpz_init(global_end);
	mpz_sqrt(global_end, n);

	// MPI boilerplate
	MPI_Status status;
	MPI_Request request;
	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &p);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

	t1 = MPI_Wtime();

	// initialize mpz structs
	mpz_init(r);
	mpz_init(start);
	mpz_init(local_end);
	mpz_init(end);
	mpz_init(temp);
	mpz_init(current_prime);
	mpz_init(my_rank_mpz);
	mpz_init_set_ui(start, 2);
	mpz_set(temp, start);

	size_t temp_window_size = mpz_sizeinbase(temp, 2);

	mpz_add_ui(temp, temp, temp_window_size);

	for (i = 0; i < my_rank; i++){
		temp_window_size = mpz_sizeinbase(temp, 2);
		mpz_add_ui(temp, temp, temp_window_size);	
	}

	mpz_set(start, temp);
	size_t window_size =  mpz_sizeinbase(start, 2);
	mpz_add_ui(local_end, start, window_size);	


	mpz_init_set_ui(my_rank_mpz, my_rank);
	mpz_init_set(end, global_end);
	mpz_nextprime(current_prime, start);
	mpz_init_set_str(n, argv[1], 10);

	int check = 0;
	int flag = 0;
	int found = 0;

	MPI_Irecv(&found, 1, MPI_INTEGER, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &request);
	MPI_Barrier(MPI_COMM_WORLD);

	while (mpz_cmp(start, end) <= 0){
		while(mpz_cmp(current_prime, local_end) <= 0 && mpz_cmp(current_prime, end) <= 0){
			mpz_mod(r, n, current_prime);
			if (mpz_cmp(zero, r) == 0){
				mpz_divexact(d, n, current_prime);
				gmp_printf("%Zd %Zd\n", d, current_prime);
				found = 1;
				for (dest = 0; dest < p; dest++){
					MPI_Isend(&found, 1, MPI_INTEGER, dest, tag, MPI_COMM_WORLD, &request);
				}
				break;		
			}
			check++;
			if (check == 500){
				check = 0;
				MPI_Test(&request, &flag, &status);
				if (flag){
					found = 1;
					break;
				}
			}
			mpz_nextprime(current_prime, current_prime);	
		}
		if( found == 1){
			break;
		}

		// calculate new start index

		mpz_set(temp, start);
		size_t temp_window_size = mpz_sizeinbase(start, 2);
		mpz_add_ui(temp, temp, temp_window_size);
		mpz_set(start, local_end);
		for (i = my_rank + 1; i < p; i++){
			temp_window_size = mpz_sizeinbase(temp, 2);
			mpz_add_ui(temp, temp, temp_window_size);
		}

		for (i = 0; i < my_rank; i++){
			temp_window_size = mpz_sizeinbase(temp, 2);
			mpz_add_ui(temp, temp, temp_window_size);
		}

		mpz_set(start, temp);

		temp_window_size = mpz_sizeinbase(start, 2);
		mpz_add_ui(local_end, start, temp_window_size);	

		mpz_nextprime(current_prime, start);
	}

	t2 = MPI_Wtime();
	totaltime = t2 - t1;
	MPI_Barrier(MPI_COMM_WORLD);
	if (my_rank == 0){
		char buf[0x1000];
		snprintf(buf, sizeof(buf), "time_%s", argv[1]);
		FILE *f = fopen(buf, "w");
		double other_totaltime = 0;
		fprintf(f, "0\t%1.2e\n", totaltime);
		for (source = 1; source < p; source++){
			MPI_Recv(&other_totaltime, 1, MPI_DOUBLE, source, tag, MPI_COMM_WORLD, &status);
			fprintf(f, "%d\t%1.2e\n", source, other_totaltime);
		}	
		fclose(f); 
	}
	else{
		MPI_Send(&totaltime, 1, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD);
	}	
	MPI_Finalize();
	return 0;
}
Esempio n. 23
0
    void connection_handler::handle_messages()
    {
        detail::handling_messages hm(handling_messages_);       // reset on exit

        bool bootstrapping = hpx::is_starting();
        bool has_work = true;
        std::size_t k = 0;

        hpx::util::high_resolution_timer t;
        std::list<std::pair<int, MPI_Request> > close_requests;

        // We let the message handling loop spin for another 2 seconds to avoid the
        // costs involved with posting it to asio
        while(bootstrapping || (!stopped_ && has_work) || (!has_work && t.elapsed() < 2.0))
        {
            // break the loop if someone requested to pause the parcelport
            if(!enable_parcel_handling_) break;

            // handle all send requests
            {
                hpx::lcos::local::spinlock::scoped_lock l(senders_mtx_);
                for(
                    senders_type::iterator it = senders_.begin();
                    !stopped_ && enable_parcel_handling_ && it != senders_.end();
                    /**/)
                {
                    if((*it)->done())
                    {
                        it = senders_.erase(it);
                    }
                    else
                    {
                        ++it;
                    }
                }
                has_work = !senders_.empty();
            }

            // Send the pending close requests
            {
                hpx::lcos::local::spinlock::scoped_lock l(close_mtx_);
                typedef std::pair<int, int> pair_type;

                BOOST_FOREACH(pair_type p, pending_close_requests_)
                {
                    header close_request = header::close(p.first, p.second);
                    close_requests.push_back(std::make_pair(p.first, MPI_Request()));
                    MPI_Isend(
                        close_request.data(),         // Data pointer
                        close_request.data_size_,     // Size
                        close_request.type(),         // MPI Datatype
                        close_request.rank(),         // Destination
                        0,                            // Tag
                        communicator_,                // Communicator
                        &close_requests.back().second
                    );
                }
                pending_close_requests_.clear();
            }

            // add new receive requests
            std::pair<bool, header> next(acceptor_.next_header());
            if(next.first)
            {
                boost::shared_ptr<receiver> rcv;
                header h = next.second;

                receivers_tag_map_type & tag_map = receivers_map_[h.rank()];

                receivers_tag_map_type::iterator jt = tag_map.find(h.tag());

                if(jt != tag_map.end())
                {
                    rcv = jt->second;
                }
                else
                {
                    rcv = boost::make_shared<receiver>(
                        communicator_
                      , get_next_tag()
                      , h.tag()
                      , h.rank()
                      , *this);
                    tag_map.insert(std::make_pair(h.tag(), rcv));
                }

                if(h.close_request())
                {
                    rcv->close();
                }
                else
                {
                    h.assert_valid();
                    if (static_cast<std::size_t>(h.size()) > this->get_max_message_size())
                    {
                        // report this problem ...
                        HPX_THROW_EXCEPTION(boost::asio::error::operation_not_supported,
                            "mpi::connection_handler::handle_messages",
                            "The size of this message exceeds the maximum inbound data size");
                        return;
                    }
                    if(rcv->async_read(h))
                    {
#ifdef HPX_DEBUG
                        receivers_type::iterator it = std::find(receivers_.begin(), receivers_.end(), rcv);
                        HPX_ASSERT(it == receivers_.end());

#endif
                        receivers_.push_back(rcv);
                    }
                }
            }

            // handle all receive requests
            for(receivers_type::iterator it = receivers_.begin();
                it != receivers_.end(); /**/)
            {
                boost::shared_ptr<receiver> rcv = *it;
                if(rcv->done())
                {
                    HPX_ASSERT(rcv->sender_tag() != -1);
                    if(rcv->closing())
                    {
                        receivers_tag_map_type & tag_map = receivers_map_[rcv->rank()];

                        receivers_tag_map_type::iterator jt = tag_map.find(rcv->sender_tag());
                        HPX_ASSERT(jt != tag_map.end());
                        tag_map.erase(jt);
                        {
                            hpx::lcos::local::spinlock::scoped_lock l(tag_mtx_);
                            free_tags_.push_back(rcv->tag());
                        }
                    }
                    it = receivers_.erase(it);
                }
                else
                {
                    ++it;
                }
            }
            if(!has_work) has_work = !receivers_.empty();

            // handle completed close requests
            for(
                std::list<std::pair<int, MPI_Request> >::iterator it = close_requests.begin();
                !stopped_ && enable_parcel_handling_ && it != close_requests.end();
            )
            {
                int completed = 0;
                MPI_Status status;
                int ret = 0;
                ret = MPI_Test(&it->second, &completed, &status);
                HPX_ASSERT(ret == MPI_SUCCESS);
                if(completed && status.MPI_ERROR != MPI_ERR_PENDING)
                {
                    hpx::lcos::local::spinlock::scoped_lock l(tag_mtx_);
                    free_tags_.push_back(it->first);
                    it = close_requests.erase(it);
                }
                else
                {
                    ++it;
                }
            }
            if(!has_work)
                has_work = !close_requests.empty();

            if (bootstrapping)
                bootstrapping = hpx::is_starting();

            if(has_work)
            {
                t.restart();
                k = 0;
            }
            else
            {
                if(enable_parcel_handling_)
                {
                    hpx::lcos::local::spinlock::yield(k);
                    ++k;
                }
            }
        }
Esempio n. 24
0
int client_thread(void *ptr) {
    int data_in, data_out;
    struct client_data_t client_data = *(struct client_data_t *)ptr;
    // struct timeval tv;
    int percent_done = 0; 
    int chunks_lim = 0;
    int need_to_ask = 0;
    int last_chunk = 0;
    int req_was_issued = 0;
    int req_was_sent = 0;
    int isend_in_fly = 1;
    int wait_for_answer = 0;
    int got_answer = 0;
    off_t data_writen = 0;
    int chunks_writen = 0;
    int fd, ret, i;
    bool infly[256];
    struct aiocb my_aiocb[client_data.maxreqs];
    MPI_Status status;
    MPI_Request request;

    data_out = M_IFNEWCHUNK;
    fd = open( client_data.fname, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
    if (fd < 0) {
        printf("Rank %05d | Error open() for \n", client_data.rank, strerror(errno), client_data.fname);
    }
    for (i=0; i < client_data.maxreqs; i++) {

        bzero( (char *)&my_aiocb[i], sizeof(struct aiocb) );

        // Allocate a data buffer for the aiocb request
        my_aiocb[i].aio_buf = calloc(client_data.bsize+1, 1);
        if (!my_aiocb[i].aio_buf) {
            printf("Rank %05d | Error calloc()[%d]: %s\n", client_data.rank, strerror(errno), i);
            exit(errno);
        }

        // Initialize the necessary fields in the aiocb
        my_aiocb[i].aio_fildes = fd;
        my_aiocb[i].aio_nbytes = client_data.bsize;
        infly[i] = 0;
    }
    
    data_in = -1;
    while(1) {
        /*if (client_data.rank == 0) {
            printf("%05d | Percent done %d %d %d %lli\n", client_data.rank, \
                percent_done, chunks_lim, client_data.csize, data_writen);
        } */ 
        // what hve be done so far?
        percent_done = (int) ((100*(data_writen - client_data.csize*(chunks_lim-1)))/client_data.csize);
        // triggers only on the beginning. Ugly.
        if ((data_writen == 0) && (chunks_lim == 0) && (req_was_issued == 0)) {
            percent_done = 100;
        }
        // we are close to idle. need to ask for another portion of the data
        if ((percent_done > PERCENT_LIM) && (last_chunk == 0) && (req_was_sent == 0) ) {
            need_to_ask = 1;
            got_answer = 0;
            data_in = 0;
        }
        // sending requests
        if ( (need_to_ask == 1) && (req_was_issued == 0 ) && (req_was_sent == 0)) {
            MPI_Isend(&data_out, 1, MPI_INT, 0, M_TAG_CLIENT, *client_data.thread_comm, &request);
            // printf("%05d | Asked for a new chunk\n", client_data.rank);
            req_was_issued = 1;
        }
        // checking if send is finished
        if (req_was_issued == 1) {
            MPI_Test(&request, &isend_in_fly, &status);
            if (isend_in_fly != 0 ) {
                            // printf("%05d req_was_issued \n",client_data.rank);
                req_was_sent = 1;
                req_was_issued = 0;
            }
        }
        // if send request gone, run async receive
        if ((req_was_sent == 1) && (wait_for_answer == 0)) {
            MPI_Irecv(&data_in, 1, MPI_INT, 0, M_TAG_SERVER, *client_data.thread_comm, &request);
                    // printf("%05d wait_for_answer \n",client_data.rank);
            wait_for_answer = 1;
        }
        // check the satatus of the irecv
        if (wait_for_answer == 1) {
            MPI_Test(&request, &isend_in_fly, &status);
            if (isend_in_fly != 0 ) {
                        // printf("%05d got_answer \n",client_data.rank);
                wait_for_answer = 0;
                got_answer = 1;
            }
        }
        // finaly got an answer
        if (got_answer == 1) {
                    // printf("%05d got_answer %d \n",client_data.rank, data_in);
            if (data_in == -1) {
                break;
            }
            if (data_in > 0) {
                chunks_lim += data_in;
            } else {
                last_chunk = 1;
            // printf("%05d last_chunk \n",client_data.rank);
            }
            req_was_sent = 0;
            need_to_ask = 0;
            got_answer = 0;
        }
        // we are here and not the last chunk? that is bad. Probably needs  to decrease PERCENT_LIM
        if (data_writen >= chunks_lim * client_data.csize) {
            // check if we done what needed
            if (last_chunk == 1) {
                break;
            }
    	//	printf("Rank %05d | OOPS. Wrote %d chunks, %lli \n",client_data.rank,chunks_lim,data_writen);
            continue;
        }
        // writing data to file
        for (i=0; i < client_data.maxreqs; i++) {
            if ( aio_error( &my_aiocb[i] ) == EINPROGRESS ) {
                continue;

            } 
            if ((ret = aio_return( &my_aiocb[i] )) < 0) {
                exit(ret);
            } 
            if (data_writen >= chunks_lim * client_data.csize) {
                break;
            }
            my_aiocb[i].aio_offset = data_writen;
            if ((ret = aio_write( &my_aiocb[i] )) < 0) {
                exit(errno);
            }

            data_writen += client_data.bsize;
        }
 
    }
    // waiting for the last bytes are in fly
    for  (i=0; i < client_data.maxreqs; i++) {
        while (aio_error( &my_aiocb[i] ) == EINPROGRESS) 
        if ((ret = aio_return( &my_aiocb[i] )) < 0) {
            exit(ret);
        }
    }
    // send 'bye' to manager thread.
    data_out = M_BYE;
    MPI_Send(&data_out, 1, MPI_INT, status.MPI_SOURCE, M_TAG_CLIENT, *client_data.thread_comm );
    printf("Rank %05d | Wrote %d chunks, %lli \n",client_data.rank,chunks_lim,data_writen);
    return 0;
}
double gradientDescent(double **X, double *Y, double *theta, double **meanAndRange, int features, int examples, int numProcs, int procId){
	char iters[5];
	int iterations;
	double alpha = (1.0 / pow(10, (numProcs / 2) + 1)) * pow(10, (numProcs - procId) / 2);
	double alphaUpdate = .01 / pow(10, procId % 2); 
	double hypothesis[examples];
	double runningSum;
	double gradients[examples];
	double intermediateCost, absCost;
	double previousCost = 0;
	int itsOver = 0;
	int flag = 0;
	MPI_Status status;
	MPI_Request request;

	MPI_Irecv(&itsOver, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &request);
	/*printf("Gradient descent iterations(1-4 digits): ");
	scanf("%s", iters);
	iterations = atoi(iters);
	*/
	iterations = 9999;
	/*Iterates gradient descent iterations times*/
	for(int i = 0; i < iterations; i++){
		/*initialize all the gradients to zero*/
		for(int i = 0; i < features; i++){
			gradients[i] = 0;
		}
		/*Sets the values of the hypothesis, based on the current values of theta*/
		for(int godDamn = 0; godDamn < examples; godDamn++){
			runningSum = 0;
			for(int f**k = 0; f**k < features; f**k++){
				runningSum += theta[f**k] * X[godDamn][f**k]; 
			}
			hypothesis[godDamn] = runningSum;
		}
		/*Actual gradient descent step- adjusts the values of theta by descending the gradient*/
		for(int j = 0; j < examples; j++){
			intermediateCost = (hypothesis[j] - Y[j]);
			for(int godDamn = 0; godDamn < features; godDamn++){
				gradients[godDamn] += intermediateCost * X[j][godDamn];
			}
			for(int k = 0; k < features;k++){
				theta[k] -= (alpha * gradients[k])/examples; 
			}
			absCost = fabs(intermediateCost);
			if(absCost > previousCost){
				alpha /= 2;
			}
			else{
				alpha += alphaUpdate;
			}
			previousCost = absCost;
		}
		if(absCost < 0.0000001){
			return 0;
		}
		MPI_Test(&request, &flag, &status);
		if(flag){
			return -1;
		}
	}
	return absCost;

}
Esempio n. 26
0
File: req.c Progetto: Katetc/cime
FC_FUNC( mpi_test , MPI_TEST)(int *request, int *flag, int *status,
                                int *ierror)
{
  *ierror=MPI_Test( (void *)request ,flag,mpi_c_status(status));
}
Esempio n. 27
0
int wc_mpi_test(wc_mpirequest_t *req, int *flag)
{
	int rc = MPI_Test(req, flag, MPI_STATUS_IGNORE);
	WC_HANDLE_MPI_ERROR(MPI_Test, rc);
	return (rc == MPI_SUCCESS) ? 0 : -1;
}
Esempio n. 28
0
static void test_pair (void)
{
  int prev, next, count, tag, index, i, outcount, indices[2];
  int rank, size, flag, ierr, reqcount;
  double send_buf[TEST_SIZE], recv_buf[TEST_SIZE];
  double buffered_send_buf[TEST_SIZE * 2 + MPI_BSEND_OVERHEAD]; /* factor of two is based on guessing - only dynamic allocation would be safe */
  void *buffer;
  MPI_Status statuses[2];
  MPI_Status status;
  MPI_Request requests[2];
  MPI_Comm dupcom, intercom;
#ifdef V_T

  struct _VT_FuncFrameHandle {
      char *name;
      int func;
      int frame;
  };
  typedef struct _VT_FuncFrameHandle VT_FuncFrameHandle_t;

  VT_FuncFrameHandle_t normal_sends,
      buffered_sends,
      buffered_persistent_sends,
      ready_sends,
      sync_sends,
      nblock_sends,
      nblock_rsends,
      nblock_ssends,
      pers_sends,
      pers_rsends,
      pers_ssends,
      sendrecv,
      sendrecv_repl,
      intercomm;

  int classid;
  VT_classdef( "Application:test_pair", &classid );


#define VT_REGION_DEF( _name, _nameframe, _class ) \
        (_nameframe).name=_name; \
        VT_funcdef( (_nameframe).name, _class, &((_nameframe).func) );
#define VT_BEGIN_REGION( _nameframe ) \
        LOCDEF(); \
        VT_begin( (_nameframe).func )
#define VT_END_REGION( _nameframe ) \
        LOCDEF(); VT_end( (_nameframe).func )
#else
#define VT_REGION_DEF( _name, _nameframe, _class )
#define VT_BEGIN_REGION( _nameframe )
#define VT_END_REGION( _nameframe )

#endif




  ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  ierr = MPI_Comm_size(MPI_COMM_WORLD, &size);
  if ( size < 2 ) {
      if ( rank == 0 ) {
	  printf("Program needs to be run on at least 2 processes.\n");
      }
      ierr = MPI_Abort( MPI_COMM_WORLD, 66 );
  }
  ierr = MPI_Comm_dup(MPI_COMM_WORLD, &dupcom);

  if ( rank >= 2 ) {
      /*      printf( "%d Calling finalize.\n", rank ); */
      ierr = MPI_Finalize( );
      exit(0);
  }

  next = rank + 1;
  if (next >= 2)
    next = 0;

  prev = rank - 1;
  if (prev < 0)
    prev = 1;

  VT_REGION_DEF( "Normal_Sends", normal_sends, classid );
  VT_REGION_DEF( "Buffered_Sends", buffered_sends, classid );
  VT_REGION_DEF( "Buffered_Persistent_Sends", buffered_persistent_sends, classid );
  VT_REGION_DEF( "Ready_Sends", ready_sends, classid );
  VT_REGION_DEF( "Sync_Sends", sync_sends, classid );
  VT_REGION_DEF( "nblock_Sends", nblock_sends, classid );
  VT_REGION_DEF( "nblock_RSends", nblock_rsends, classid );
  VT_REGION_DEF( "nblock_SSends", nblock_ssends, classid );
  VT_REGION_DEF( "Pers_Sends", pers_sends, classid );
  VT_REGION_DEF( "Pers_RSends", pers_rsends, classid );
  VT_REGION_DEF( "Pers_SSends", pers_ssends, classid );
  VT_REGION_DEF( "SendRecv", sendrecv, classid );
  VT_REGION_DEF( "SendRevc_Repl", sendrecv_repl, classid );
  VT_REGION_DEF( "InterComm", intercomm, classid );



/*
 * Normal sends
 */

  VT_BEGIN_REGION( normal_sends );

  if (rank == 0)
    printf ("Send\n");

  tag = 0x100;
  count = TEST_SIZE / 5;

  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0);

    LOCDEF();

    MPI_Send(send_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);
    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE,
              MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    msg_check(recv_buf, prev, tag, count, &status, TEST_SIZE, "send and recv");
  }
  else {

    LOCDEF();

    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE,MPI_ANY_SOURCE, MPI_ANY_TAG,
             MPI_COMM_WORLD, &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,"send and recv");
    init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Send(recv_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);

  }

  VT_END_REGION( normal_sends );


/*
 * Buffered sends
 */

  VT_BEGIN_REGION( buffered_sends );

  if (rank == 0)
    printf ("Buffered Send\n");

  tag = 138;
  count = TEST_SIZE / 5;

  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0);

    LOCDEF();

    MPI_Buffer_attach(buffered_send_buf, sizeof(buffered_send_buf));
    MPI_Bsend(send_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);
    MPI_Buffer_detach(&buffer, &size);
    if(buffer != buffered_send_buf || size != sizeof(buffered_send_buf)) {
        printf ("[%d] Unexpected buffer returned by MPI_Buffer_detach(): %p/%d != %p/%d\n", rank, buffer, size, buffered_send_buf, (int)sizeof(buffered_send_buf));
        MPI_Abort(MPI_COMM_WORLD, 201);
    }
    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE,
              MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    msg_check(recv_buf, prev, tag, count, &status, TEST_SIZE, "send and recv");
  }
  else {

    LOCDEF();

    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE,MPI_ANY_SOURCE, MPI_ANY_TAG,
             MPI_COMM_WORLD, &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,"send and recv");
    init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Send(recv_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);

  }

  VT_END_REGION( buffered_sends );


/*
 * Buffered sends
 */

  VT_BEGIN_REGION( buffered_persistent_sends );

  if (rank == 0)
    printf ("Buffered Persistent Send\n");

  tag = 238;
  count = TEST_SIZE / 5;

  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0);

    LOCDEF();

    MPI_Buffer_attach(buffered_send_buf, sizeof(buffered_send_buf));
    MPI_Bsend_init(send_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD, requests);
    MPI_Start(requests);
    MPI_Wait(requests, statuses);
    MPI_Request_free(requests);
    MPI_Buffer_detach(&buffer, &size);
    if(buffer != buffered_send_buf || size != sizeof(buffered_send_buf)) {
        printf ("[%d] Unexpected buffer returned by MPI_Buffer_detach(): %p/%d != %p/%d\n", rank, buffer, size, buffered_send_buf, (int)sizeof(buffered_send_buf));
        MPI_Abort(MPI_COMM_WORLD, 201);
    }
    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE,
              MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    msg_check(recv_buf, prev, tag, count, &status, TEST_SIZE, "send and recv");
  }
  else {

    LOCDEF();

    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE,MPI_ANY_SOURCE, MPI_ANY_TAG,
             MPI_COMM_WORLD, &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,"send and recv");
    init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Send(recv_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);

  }

  VT_END_REGION( buffered_persistent_sends );


/*
 * Ready sends.  Note that we must insure that the receive is posted
 * before the rsend; this requires using Irecv.
 */


  VT_BEGIN_REGION( ready_sends );

  if (rank == 0)
    printf ("Rsend\n");

  tag = 1456;
  count = TEST_SIZE / 3;

  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0);
    MPI_Recv(MPI_BOTTOM, 0, MPI_INT, next, tag, MPI_COMM_WORLD, &status);
    MPI_Rsend(send_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);
    MPI_Probe(MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status);
    if (status.MPI_SOURCE != prev)
      printf ("Incorrect src, expected %d, got %d\n",prev, status.MPI_SOURCE);

    if (status.MPI_TAG != tag)
      printf ("Incorrect tag, expected %d, got %d\n",tag, status.MPI_TAG);

    MPI_Get_count(&status, MPI_DOUBLE, &i);
    if (i != count)
      printf ("Incorrect count, expected %d, got %d\n",count,i);

    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
             MPI_COMM_WORLD, &status);

    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,
               "rsend and recv");
  }
  else {
    MPI_Irecv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
              MPI_COMM_WORLD, requests);
    MPI_Send( MPI_BOTTOM, 0, MPI_INT, next, tag, MPI_COMM_WORLD);
    MPI_Wait(requests, &status);

    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,
               "rsend and recv");
    init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Send(recv_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);
  }

  VT_END_REGION( ready_sends );

/*
 * Synchronous sends
 */

  VT_BEGIN_REGION( sync_sends );

  if (rank == 0)
    printf ("Ssend\n");

  tag = 1789;
  count = TEST_SIZE / 3;

  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0);
    MPI_Iprobe(MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &flag, &status);
    if (flag)
      printf ("Iprobe succeeded! source %d, tag %d\n",status.MPI_SOURCE,
                                                      status.MPI_TAG);

    MPI_Ssend(send_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);

    while (!flag)
      MPI_Iprobe(MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &flag, &status);

    if (status.MPI_SOURCE != prev)
      printf ("Incorrect src, expected %d, got %d\n",prev, status.MPI_SOURCE);

    if (status.MPI_TAG != tag)
      printf ("Incorrect tag, expected %d, got %d\n",tag, status.MPI_TAG);

    MPI_Get_count(&status, MPI_DOUBLE, &i);

    if (i != count)
      printf ("Incorrect count, expected %d, got %d\n",count,i);

    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
             MPI_COMM_WORLD, &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE, "ssend and recv");
  }
  else {
    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
             MPI_COMM_WORLD, &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE, "ssend and recv"); init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Ssend(recv_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);
  }

  VT_END_REGION( sync_sends );

/*
 * Nonblocking normal sends
 */

  VT_BEGIN_REGION( nblock_sends );

  if (rank == 0)
    printf ("Isend\n");

  tag = 2123;
  count = TEST_SIZE / 5;

  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
    MPI_Irecv(recv_buf, TEST_SIZE, MPI_DOUBLE,MPI_ANY_SOURCE, MPI_ANY_TAG,
              MPI_COMM_WORLD, requests);
    init_test_data(send_buf,TEST_SIZE,0);
    MPI_Isend(send_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD,
              (requests+1));
    MPI_Waitall(2, requests, statuses);
    rq_check( requests, 2, "isend and irecv" );

    msg_check(recv_buf,prev,tag,count,statuses, TEST_SIZE,"isend and irecv");
  }
  else {
    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE,MPI_ANY_SOURCE, MPI_ANY_TAG,
             MPI_COMM_WORLD, &status);
    msg_check(recv_buf,prev,tag,count,&status, TEST_SIZE,"isend and irecv"); init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Isend(recv_buf, count, MPI_DOUBLE, next, tag,MPI_COMM_WORLD,
              (requests));
    MPI_Wait((requests), &status);
    rq_check(requests, 1, "isend (and recv)");
  }



  VT_END_REGION( nblock_sends );

/*
 * Nonblocking ready sends
 */


  VT_BEGIN_REGION( nblock_rsends );

  if (rank == 0)
    printf ("Irsend\n");

  tag = 2456;
  count = TEST_SIZE / 3;

  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
    MPI_Irecv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
              MPI_COMM_WORLD, requests);
    init_test_data(send_buf,TEST_SIZE,0);
    MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, next, 0,
                  MPI_BOTTOM, 0, MPI_INT, next, 0,
                  dupcom, &status);
    MPI_Irsend(send_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD,
               (requests+1));
    reqcount = 0;
    while (reqcount != 2) {
      MPI_Waitany( 2, requests, &index, statuses);
      if( index == 0 ) {
	  memcpy( &status, statuses, sizeof(status) );
      }
      reqcount++;
    }

    rq_check( requests, 1, "irsend and irecv");
    msg_check(recv_buf,prev,tag,count,&status, TEST_SIZE,"irsend and irecv");
  }
  else {
    MPI_Irecv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
              MPI_COMM_WORLD, requests);
    MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, next, 0,
                  MPI_BOTTOM, 0, MPI_INT, next, 0,
                  dupcom, &status);
    flag = 0;
    while (!flag)
      MPI_Test(requests, &flag, &status);

    rq_check( requests, 1, "irsend and irecv (test)");
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,
               "irsend and irecv"); init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Irsend(recv_buf, count, MPI_DOUBLE, next, tag,
               MPI_COMM_WORLD, requests);
    MPI_Waitall(1, requests, statuses);
    rq_check( requests, 1, "irsend and irecv");
  }

  VT_END_REGION( nblock_rsends );

/*
 * Nonblocking synchronous sends
 */

  VT_BEGIN_REGION( nblock_ssends );

  if (rank == 0)
    printf ("Issend\n");

  tag = 2789;
  count = TEST_SIZE / 3;
  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
    MPI_Irecv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
              MPI_COMM_WORLD, requests );
    init_test_data(send_buf,TEST_SIZE,0);
    MPI_Issend(send_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD,
               (requests+1));
    flag = 0;
    while (!flag)
      MPI_Testall(2, requests, &flag, statuses);

    rq_check( requests, 2, "issend and irecv (testall)");
    msg_check( recv_buf, prev, tag, count, statuses, TEST_SIZE, 
               "issend and recv");
  }
  else {
    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
             MPI_COMM_WORLD, &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,
               "issend and recv"); init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Issend(recv_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD,requests);

    flag = 0;
    while (!flag)
      MPI_Testany(1, requests, &index, &flag, statuses);

    rq_check( requests, 1, "issend and recv (testany)");
  }


  VT_END_REGION( nblock_ssends );


/*
 * Persistent normal sends
 */

  VT_BEGIN_REGION( pers_sends );

  if (rank == 0)
    printf ("Send_init\n");

  tag = 3123;
  count = TEST_SIZE / 5;

  clear_test_data(recv_buf,TEST_SIZE);

  MPI_Send_init(send_buf, count, MPI_DOUBLE, next, tag,
                MPI_COMM_WORLD, requests);
  MPI_Recv_init(recv_buf, TEST_SIZE, MPI_DOUBLE,MPI_ANY_SOURCE, MPI_ANY_TAG,
                MPI_COMM_WORLD, (requests+1));

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0);
    MPI_Startall(2, requests);
    MPI_Waitall(2, requests, statuses);
    msg_check( recv_buf, prev, tag, count, (statuses+1),
               TEST_SIZE, "persistent send/recv");
  }
  else {
    MPI_Start((requests+1));
    MPI_Wait((requests+1), &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,
               "persistent send/recv");
    init_test_data(send_buf,TEST_SIZE,1);


    MPI_Start(requests);
    MPI_Wait(requests, &status);
  }
  MPI_Request_free(requests);
  MPI_Request_free((requests+1));


  VT_END_REGION( pers_sends );

/*
 * Persistent ready sends
 */

  VT_BEGIN_REGION( pers_rsends );

  if (rank == 0)
    printf ("Rsend_init\n");

  tag = 3456;
  count = TEST_SIZE / 3;

  clear_test_data(recv_buf,TEST_SIZE);

  MPI_Rsend_init(send_buf, count, MPI_DOUBLE, next, tag,
                  MPI_COMM_WORLD, requests);
  MPI_Recv_init(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE,
                 MPI_ANY_TAG, MPI_COMM_WORLD, (requests+1));

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0); MPI_Barrier( MPI_COMM_WORLD );
    MPI_Startall(2, requests);
    reqcount = 0;
    while (reqcount != 2) {
      MPI_Waitsome(2, requests, &outcount, indices, statuses);
      for (i=0; i<outcount; i++) {
        if (indices[i] == 1) {
          msg_check( recv_buf, prev, tag, count, (statuses+i),
                     TEST_SIZE, "waitsome");
        }
	reqcount++;
      }
    }
  }
  else {
    MPI_Start((requests+1)); MPI_Barrier( MPI_COMM_WORLD );
    flag = 0;
    while (!flag)
      MPI_Test((requests+1), &flag, &status);

    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE, "test");

    init_test_data(send_buf,TEST_SIZE,1);

 
    MPI_Start(requests);
    MPI_Wait(requests, &status);
  }
  MPI_Request_free(requests);
  MPI_Request_free((requests+1));


  VT_END_REGION( pers_rsends );


/*
 * Persistent synchronous sends
 */


  VT_BEGIN_REGION( pers_ssends );

  if (rank == 0)
    printf ("Ssend_init\n");

  tag = 3789;
  count = TEST_SIZE / 3;

  clear_test_data(recv_buf,TEST_SIZE);

  MPI_Ssend_init(send_buf, count, MPI_DOUBLE, next, tag,
                 MPI_COMM_WORLD, (requests+1));
  MPI_Recv_init(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE,
                 MPI_ANY_TAG, MPI_COMM_WORLD, requests);

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0);
    MPI_Startall(2, requests);

    reqcount = 0;
    while (reqcount != 2) {
      MPI_Testsome(2, requests, &outcount, indices, statuses);
      for (i=0; i<outcount; i++) {
        if (indices[i] == 0) {
          msg_check( recv_buf, prev, tag, count, (statuses+i),
                     TEST_SIZE, "testsome");
        }
	reqcount++;
      }
    }
  }
  else {
    MPI_Start(requests);
    flag = 0;
    while (!flag)
      MPI_Testany(1, requests, &index, &flag, statuses);

    msg_check( recv_buf, prev, tag, count, statuses, TEST_SIZE, "testany" );

    init_test_data(send_buf,TEST_SIZE,1);


     MPI_Start((requests+1));
     MPI_Wait((requests+1), &status);
  }
  MPI_Request_free(requests);
  MPI_Request_free((requests+1));


  VT_END_REGION( pers_ssends );


/*
 * Send/receive.
 */


  VT_BEGIN_REGION( sendrecv );

  if (rank == 0)
    printf ("Sendrecv\n");

  tag = 4123;
  count = TEST_SIZE / 5;

  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0);
    MPI_Sendrecv(send_buf, count, MPI_DOUBLE, next, tag,
                 recv_buf, count, MPI_DOUBLE, prev, tag,
                 MPI_COMM_WORLD, &status );

    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,
               "sendrecv");
  }
  else {
    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE,
             MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,
               "recv/send"); init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Send(recv_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);
  }


  VT_END_REGION( sendrecv );

#ifdef V_T
  VT_flush();
#endif


/*
 * Send/receive replace.
 */

  VT_BEGIN_REGION( sendrecv_repl );

  if (rank == 0)
    printf ("Sendrecv_replace\n");

  tag = 4456;
  count = TEST_SIZE / 3;

  if (rank == 0) {
      init_test_data(recv_buf, TEST_SIZE,0);
    for (i=count; i< TEST_SIZE; i++)
      recv_buf[i] = 0.0;

    MPI_Sendrecv_replace(recv_buf, count, MPI_DOUBLE,
                         next, tag, prev, tag, MPI_COMM_WORLD, &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,
               "sendrecvreplace");
  }
  else {
    clear_test_data(recv_buf,TEST_SIZE);
    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE,
             MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    msg_check( recv_buf, prev, tag, count, &status, TEST_SIZE,
               "recv/send for replace"); init_test_data(recv_buf,TEST_SIZE,1);
    MPI_Send(recv_buf, count, MPI_DOUBLE, next, tag, MPI_COMM_WORLD);
  }

  VT_END_REGION( sendrecv_repl );


/*
 * Send/Receive via inter-communicator
 */

  VT_BEGIN_REGION( intercomm );

  MPI_Intercomm_create(MPI_COMM_SELF, 0, MPI_COMM_WORLD, next, 1, &intercom);

  if (rank == 0)
    printf ("Send via inter-communicator\n");

  tag = 4018;
  count = TEST_SIZE / 5;

  clear_test_data(recv_buf,TEST_SIZE);

  if (rank == 0) {
      init_test_data(send_buf,TEST_SIZE,0);

    LOCDEF();

    MPI_Send(send_buf, count, MPI_DOUBLE, 0, tag, intercom);
    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE, MPI_ANY_SOURCE,
              MPI_ANY_TAG, intercom, &status);
    msg_check(recv_buf, 0, tag, count, &status, TEST_SIZE, "send and recv via inter-communicator");
  }
  else if (rank == 1) {

    LOCDEF();

    MPI_Recv(recv_buf, TEST_SIZE, MPI_DOUBLE,MPI_ANY_SOURCE, MPI_ANY_TAG,
             intercom, &status);
    msg_check( recv_buf, 0, tag, count, &status, TEST_SIZE,"send and recv via inter-communicator");
    init_test_data(recv_buf,TEST_SIZE,0);
    MPI_Send(recv_buf, count, MPI_DOUBLE, 0, tag, intercom);

  }

  VT_END_REGION( normal_sends );



  MPI_Comm_free(&intercom);
  MPI_Comm_free(&dupcom);
} 
 void peano::applications::puregrid::repositories::GridConstructionMovieBatchJobRepositoryState::send(int destination, int tag) {
    MPI_Request* sendRequestHandle = new MPI_Request();
    MPI_Status   status;
    int          flag = 0;
    int          result;
    
    clock_t      timeOutWarning   = -1;
    clock_t      timeOutShutdown  = -1;
    bool         triggeredTimeoutWarning = false;
    
    #ifdef Asserts
    _senderRank = -1;
    #endif
    
    result = MPI_Isend(
       this, 1, Datatype, destination,
       tag, tarch::parallel::Node::getInstance().getCommunicator(),
       sendRequestHandle
    );
    if  (result!=MPI_SUCCESS) {
       std::ostringstream msg;
       msg << "was not able to send message peano::applications::puregrid::repositories::GridConstructionMovieBatchJobRepositoryState "
       << toString()
       << " to node " << destination
       << ": " << tarch::parallel::MPIReturnValueToString(result);
       _log.error( "send(int)",msg.str() );
    }
    result = MPI_Test( sendRequestHandle, &flag, &status );
    while (!flag) {
       if (timeOutWarning==-1)   timeOutWarning   = tarch::parallel::Node::getInstance().getDeadlockWarningTimeStamp();
       if (timeOutShutdown==-1)  timeOutShutdown  = tarch::parallel::Node::getInstance().getDeadlockTimeOutTimeStamp();
       result = MPI_Test( sendRequestHandle, &flag, &status );
       if (result!=MPI_SUCCESS) {
          std::ostringstream msg;
          msg << "testing for finished send task for peano::applications::puregrid::repositories::GridConstructionMovieBatchJobRepositoryState "
          << toString()
          << " sent to node " << destination
          << " failed: " << tarch::parallel::MPIReturnValueToString(result);
          _log.error("send(int)", msg.str() );
       }
       
       // deadlock aspect
       if (
          tarch::parallel::Node::getInstance().isTimeOutWarningEnabled() &&
          (clock()>timeOutWarning) &&
          (!triggeredTimeoutWarning)
       ) {
          tarch::parallel::Node::getInstance().writeTimeOutWarning(
          "peano::applications::puregrid::repositories::GridConstructionMovieBatchJobRepositoryState",
          "send(int)", destination
          );
          triggeredTimeoutWarning = true;
       }
       if (
          tarch::parallel::Node::getInstance().isTimeOutDeadlockEnabled() &&
          (clock()>timeOutShutdown)
       ) {
          tarch::parallel::Node::getInstance().triggerDeadlockTimeOut(
          "peano::applications::puregrid::repositories::GridConstructionMovieBatchJobRepositoryState",
          "send(int)", destination
          );
       }
       tarch::parallel::Node::getInstance().receiveDanglingMessages();
    }
    
    delete sendRequestHandle;
    #ifdef Debug
    _log.debug("send(int,int)", "sent " + toString() );
    #endif
    
 }
/*
 * Class:     mpjdev_natmpjdev_NativeRecvRequest
 * Method:    Test
 * Signature: (Lmpjdev/Status;)Lmpjdev/Status;
 */
JNIEXPORT jobject JNICALL Java_mpjdev_natmpjdev_NativeRecvRequest_Test(
    JNIEnv *env, jobject thisObject, jobject stat) {

  /*
   * Conventionaly our itest() 
   * provide iprobe like functionality. 
   * 
   * So we have 3 options:
   * 1: change our mpi.Request Test() and don't call Wait() then
   * we have to change implementations of itest() in all the devices
   * 
   * 2: Put if-else in mpi.Request Test() to distinguish between native
   * and pure. This is messy. And provide the real MPI_Test() functionality
   * here.
   * 
   * 3: Provide iprobe functionality here and don't change anything in
   * the upper layers. This requires introducing source and tag in
   * NativeRecvRequest
   * 
   * We are opting for option 2 right now.
   * 
   */

  int flag;

  MPI_Request request = (MPI_Request)(
      (*env)->GetLongField(env, thisObject, reqhandleID));

  MPI_Status mpi_status;

  MPI_Test(&request, &flag, &mpi_status);

  if (flag) {

    int elements;

    MPI_Get_count(&mpi_status, MPI_BYTE, &elements);

    (*env)->SetIntField(env, stat, mpjdev_Status_sourceID,
        mpi_status.MPI_SOURCE);
    (*env)->SetIntField(env, stat, mpjdev_Status_tagID, mpi_status.MPI_TAG);

    //seting the number of elements as size of the buffer and in the iwait() method
    // we pass it to setSize() method of buffer 
    // bufferHandle.setSize(status.numEls);
    // later numEls is again initialized with getSectionSize() of the buffer
    (*env)->SetIntField(env, stat, mpjdev_Status_numEls, elements);

    // I am also setting this because we need it in mpi/Status Get_count
    // method : TODO remove magic numbers
    (*env)->SetIntField(env, stat, mpjdev_Status_countInBytes,
        (jint)(elements - 8 - 8)); // 8 is the size of section header
    // and 8 recv overhead

    //check if dynamic buffer?
    jobject mpjbuf;
    jobject staticBuffer;
    jbyteArray directBuffer;
    char *buffer_address = NULL;

    /* Get the static Buffer Related things.. */
    mpjbuf = (*env)->GetObjectField(env, thisObject,
        mpjdev_natmpjdev_NativeRequest_mpjbuf);
    staticBuffer = (*env)->GetObjectField(env, mpjbuf,
        FID_mpjbuf_Buffer_staticBuffer);
    directBuffer = (*env)->GetObjectField(env, staticBuffer,
        FID_mpjbuf_NIOBuffer_buffer);
    buffer_address = (char *) (*env)->GetDirectBufferAddress(env,
        (jobject) directBuffer);

    char encoding = 0;
    int dbuf_len = -1;

    encoding = buffer_address[0];
    if (encoding == 1) {

      dbuf_len = (((int) (unsigned char) buffer_address[4]) << 24)
          | (((int) (unsigned char) buffer_address[5]) << 16)
          | (((int) (unsigned char) buffer_address[6]) << 8)
          | (((int) (unsigned char) buffer_address[7]));

      /* Declarations of Dynamic Buffer */
      jboolean isCopy = JNI_TRUE;
      jbyteArray darr;
      jbyte * dBuffer;

      MPI_Status mpi_status_dyn;

      MPI_Comm mpi_comm = (MPI_Comm)(*env)->GetLongField(env, thisObject,
          mpjdev_natmpjdev_NativeRequest_comHandle);

      darr = (*env)->NewByteArray(env, dbuf_len);
      // perhaps no need for this - use malloc instead
      dBuffer = (*env)->GetByteArrayElements(env, darr, &isCopy);

      // This is wrong here Why blocking? we need to set the NativeSendRequest
      // wait to not call wait on dynamic buffer, else deadlock arises
      MPI_Recv(dBuffer, dbuf_len, MPI_BYTE, mpi_status.MPI_SOURCE,
          mpi_status.MPI_TAG + 10001, mpi_comm, &mpi_status_dyn);

      (*env)->SetByteArrayRegion(env, darr, 0, dbuf_len, dBuffer);

      jmethodID setdbuf = (*env)->GetMethodID(env, CL_mpjbuf_Buffer,
          "setDynamicBuffer", "([B)V");
      (*env)->CallVoidMethod(env, mpjbuf, setdbuf, darr);

    }

    return stat;

  } else
    return NULL;

}