//___________________________________________________________________________________________ TNamed* KVIntegerList::CreateTNamed() { //Cree un objet TNamed //le nom de la partition est le champ TNamed::fName et la population de la partition dans le champ TNamed::fTitle //voir TNamed //L'objet cree doit etre effacé après utilisation par l'utilisateur TNamed* nm = new TNamed(GetName(), Form("%d", GetPopulation())); return nm; }
//___________________________________________________________________________________________ void KVIntegerList::Streamer(TBuffer& R__b) { //Streamer specifique //l'écriture dans un fichier root se fait par l'intermédiaire de la classe TNamed //seul, le nom et la partition et sa population sont enregistrées dans le fichier //la lecture utilise aussi le streamer de TNamed, puis il y a un appel a la routine // protected DeducePartitionFromTNamed() qui permet de recréer complètement l'objet KVIntegerList if (R__b.IsReading()) { R__b.ReadClassBuffer(TNamed::Class(), this); DeducePartitionFromTNamed(); } else { SetTitle(Form("%d", GetPopulation())); R__b.WriteClassBuffer(TNamed::Class(), this); } }
long CargoHolder::GetContain(CargoType ct) const { if (ct >= 0) return mContains[ct]; else if (ct == POPULATION) return GetPopulation(); else if (ct == FUEL) { const Fleet * f = dynamic_cast<const Fleet *>(this); if (f == NULL) return 0; else return f->GetFuel(); } else { assert(false); return 0; } }
//___________________________________________________________________________________________ void KVIntegerList::Print(Option_t*) const { //Classe dérivée de TNamed, Imprime la liste formattée et la population associée Info("Print", "%s : population %d", GetName(), GetPopulation()); }
int main (int argc, char *argv[]) { MPI_Request reqSR[4], reqRR[4], reqSF[4], reqRF[4]; MPI_Status statRR[4], statRF[4], statSR[4], statSF[4]; MPI_Comm cartcomm; int n_proc, nbrs[4], dims[2], periods[2]={1,1}, reorder=1; int landNS, landWE, err,i; float sumFox, sumRabb, nbrab, nbfox, model[2][3]; double time; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &n_proc); if(rank==0){ time= MPI_Wtime(); printf("N_proc:%d",n_proc); } /**************************************************** ********** CASO DE 1 PROCESSO ****************** ***************************************************/ if (n_proc==1) { echoSingle(); }else{ /**************************************************** **********+++ MULTI PROCESSOS ****************** ***************************************************/ int lado = sqrt(n_proc); dims[0] = lado; dims[1] = lado; if((lado * lado) != n_proc){ if(rank==0) printf("ERRO: Numero incorreto de processos\n"); MPI_Finalize(); exit(0); } MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, reorder, &cartcomm); MPI_Comm_rank(cartcomm, &rank); MPI_Cart_coords(cartcomm, rank, 2, coords); MPI_Cart_shift(cartcomm, 0, 1, &nbrs[UP], &nbrs[DOWN]); MPI_Cart_shift(cartcomm, 1, 1, &nbrs[LEFT], &nbrs[RIGHT]); //Actualizar offsets de cada processo landNS = offsetNS = NS_Size / lado; landWE = offsetWE = WE_Size / lado; if(coords[0] == (lado-1)){ offsetNS += NS_Size % lado; } if(coords[1] == (lado-1)){ offsetWE += WE_Size % lado; } //Buffers para envio e receção de dados float buf_sendFoxN[offsetWE],buf_sendFoxS[offsetWE],buf_sendFoxW[offsetNS],buf_sendFoxE[offsetNS]; float buf_recvFoxN[offsetWE],buf_recvFoxS[offsetWE],buf_recvFoxW[offsetNS],buf_recvFoxE[offsetNS]; float buf_sendRabbitN[offsetWE],buf_sendRabbitS[offsetWE],buf_sendRabbitW[offsetNS],buf_sendRabbitE[offsetNS]; float buf_recvRabbitN[offsetWE],buf_recvRabbitS[offsetWE],buf_recvRabbitW[offsetNS],buf_recvRabbitE[offsetNS]; float Rabbit[offsetNS+2][offsetWE+2]; float Fox[offsetNS+2][offsetWE+2]; /* The next two arrays are used in function Evolve() to compute * the next generation of rabbits and foxes. */ float TRabbit[offsetNS+2][offsetWE+2]; float TFox[offsetNS+2][offsetWE+2]; //Inicialização das comunicações //********* Raposas ************** //Enviar //Cima e baixo MPI_Send_init(&buf_sendFoxN[0], offsetWE, MPI_FLOAT, nbrs[UP], 0, cartcomm, &reqSF[UP]); MPI_Send_init(&buf_sendFoxS[0], offsetWE, MPI_FLOAT, nbrs[DOWN], 0, cartcomm, &reqSF[DOWN]); //Esquerda e direita MPI_Send_init(&buf_sendFoxW[0], offsetNS, MPI_FLOAT, nbrs[LEFT], 0, cartcomm, &reqSF[LEFT]); MPI_Send_init(&buf_sendFoxE[0], offsetNS, MPI_FLOAT, nbrs[RIGHT], 0, cartcomm, &reqSF[RIGHT]); //Receber //Cima e Baixo MPI_Recv_init(&buf_recvFoxS[0], offsetWE, MPI_FLOAT, nbrs[DOWN], 0, cartcomm, &reqRF[DOWN]); MPI_Recv_init(&buf_recvFoxN[0], offsetWE, MPI_FLOAT, nbrs[UP], 0, cartcomm, &reqRF[UP]); //Esquerda e direita MPI_Recv_init(&buf_recvFoxE[0], offsetNS, MPI_FLOAT, nbrs[RIGHT], 0, cartcomm, &reqRF[RIGHT]); MPI_Recv_init(&buf_recvFoxW[0], offsetNS, MPI_FLOAT, nbrs[LEFT], 0, cartcomm, &reqRF[LEFT]); //********* Coelhos *************** //Enviar //Cima e baixo MPI_Send_init(&buf_sendRabbitN[0], offsetWE, MPI_FLOAT, nbrs[UP], 0, cartcomm, &reqSR[UP]); MPI_Send_init(&buf_sendRabbitS[0], offsetWE, MPI_FLOAT, nbrs[DOWN], 0, cartcomm, &reqSR[DOWN]); //Esquerda e direita MPI_Send_init(&buf_sendRabbitW[0], offsetNS, MPI_FLOAT, nbrs[LEFT], 0, cartcomm, &reqSR[LEFT]); MPI_Send_init(&buf_sendRabbitE[0], offsetNS, MPI_FLOAT, nbrs[RIGHT], 0, cartcomm, &reqSR[RIGHT]); //Receber //Cima e Baixo MPI_Recv_init(&buf_recvRabbitS[0], offsetWE, MPI_FLOAT, nbrs[DOWN], 0, cartcomm, &reqRR[DOWN]); MPI_Recv_init(&buf_recvRabbitN[0], offsetWE, MPI_FLOAT, nbrs[UP], 0, cartcomm, &reqRR[UP]); //Esquerda e direita MPI_Recv_init(&buf_recvRabbitE[0], offsetNS, MPI_FLOAT, nbrs[RIGHT], 0, cartcomm, &reqRR[RIGHT]); MPI_Recv_init(&buf_recvRabbitW[0], offsetNS, MPI_FLOAT, nbrs[LEFT], 0, cartcomm, &reqRR [LEFT]); /* Initialise the problem. */ err = SetLand(Rabbit,Fox,model,landNS, landWE); // Iterate. for( k=1; k<=NITER; k++) { /****************************************************** **** Começa comunicação de actualização ******** ******************************************************/ //************** Envios ***************/ //Raposas //Cima e baixo for(i=1; i <= offsetWE; i++) buf_sendFoxN[i-1] = Fox[1][i]; MPI_Start(&reqSF[UP]); for(i=1; i <= offsetWE; i++) buf_sendFoxS[i-1] = Fox[offsetNS][i]; MPI_Start(&reqSF[DOWN]); //Esquerda e direita for(i=1; i <= offsetNS; i++) buf_sendFoxW[i-1] = Fox[i][1]; MPI_Start(&reqSF[LEFT]); for(i=1; i <= offsetNS; i++) buf_sendFoxE[i-1] = Fox[i][offsetWE]; MPI_Start(&reqSF[RIGHT]); //Coelhos //Cima e baixo for(i=1; i <= offsetWE; i++) buf_sendRabbitN[i-1] = Rabbit[1][i]; MPI_Start(&reqSR[UP]); for(i=1; i <= offsetWE; i++) buf_sendRabbitS[i-1] = Rabbit[offsetNS][i]; MPI_Start(&reqSR[DOWN]); //Esquerda e direita for(i=1; i <= offsetNS; i++) buf_sendRabbitW[i-1] = Rabbit[i][1]; MPI_Start(&reqSR[LEFT]); for(i=1; i <= offsetNS; i++) buf_sendRabbitE[i-1] = Rabbit[i][offsetWE]; MPI_Start(&reqSR[RIGHT]); //************** Recepção ***************/ //Raposas //Cima e baixo MPI_Start(&reqRF[DOWN]); MPI_Start(&reqRF[UP]); //Esquerda e direita MPI_Start(&reqRF[RIGHT]); MPI_Start(&reqRF[LEFT]); //Coelhos //Cima e baixo MPI_Start(&reqRR[DOWN]); MPI_Start(&reqRR[UP]); //Esquerda e direita MPI_Start(&reqRR[RIGHT]); MPI_Start(&reqRR[LEFT]); //Esperar pelos Receives e aplicar alterações nos quadros //Raposas MPI_Waitall(4, reqRR , statRR); for(i=1; i <= offsetWE; i++) Fox[offsetNS+1][i] = buf_recvFoxS[i-1]; for(i=1; i <= offsetWE; i++) Fox[0][i] = buf_recvFoxN[i-1]; for(i=1; i <= offsetNS; i++) Fox[i][offsetWE+1] = buf_recvFoxE[i-1]; for(i=1; i <= offsetNS; i++) Fox[i][0] = buf_recvFoxW[i-1]; //Coelhos MPI_Waitall(4, reqRF, statRF); for(i=1; i <= offsetWE; i++) Rabbit[offsetNS+1][i] = buf_recvRabbitS[i-1]; for(i=1; i <= offsetWE; i++) Rabbit[0][i] = buf_recvRabbitN[i-1]; for(i=1; i <= offsetNS; i++) Rabbit[i][offsetWE+1] = buf_recvRabbitE[i-1]; for(i=1; i <= offsetNS; i++) Rabbit[i][0] = buf_recvRabbitW[i-1]; /****************************************************** **** Termina comunicação de actualização ******** ******************************************************/ err = Evolve(Rabbit,Fox,TRabbit,TFox,model); if( !(k%PERIOD) ) { err = GetPopulation(Rabbit,&nbrab); err = GetPopulation(Fox,&nbfox); MPI_Reduce(&nbrab, &sumRabb, 1, MPI_FLOAT, MPI_SUM, 0, cartcomm); MPI_Reduce(&nbfox, &sumFox, 1, MPI_FLOAT, MPI_SUM, 0, cartcomm); //if(rank==0) // printf("Year %d: %.0f rabbits and %.0f foxes\n", k, sumRabb, sumFox); } //Esperar que os Sends estejam concluidos para ter a certeza que que já podemos mexer nos buffers //(Não creio de que 100% obrigatório) MPI_Waitall(4, reqSR , statSR); MPI_Waitall(4, reqSF , statSF); } if(rank==0) printf("Year %d: %.0f rabbits and %.0f foxes\n", k, sumRabb, sumFox); } if(rank==0) printf("Time: %f\n",MPI_Wtime()-time); MPI_Finalize(); return 0; }