Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <stdbool.h>
- #include <unistd.h>
- #include <time.h>
- #include "mpi.h"
- #define OCEAN_SIZE 10 //rozmiar siatki
- #define HUNGRY_MAX 10 //maksymalny czas glodowania
- #define MATURITY 10 //maksymalny czas zycia
- #define LIFE_TIME 50 //czas zycia akwarium torusa
- typedef struct {
- int table[OCEAN_SIZE][OCEAN_SIZE]; //pole: 0-puste, 1-ryba, 2-rekin
- int hungry[OCEAN_SIZE][OCEAN_SIZE]; //czas glodowania
- int lifeTime[OCEAN_SIZE][OCEAN_SIZE];
- int movePosiblity[OCEAN_SIZE][OCEAN_SIZE]; //czy rybka/rekin moze ruszyc - jak wykorzysta ruch to 0
- } Area2D;
- int i,world_rank, world_size, seed;
- int iterateCounter = 0;
- MPI_Status status;
- MPI_Request request;
- Area2D ocean;
- Area2D leftPart, rightPart, upperPart, bottomPart; //po lewej i po prawej i gora i dol
- int leftProcess, rightProcess, upperProcess, bottomProcess; // sasiedzi
- MPI_Datatype typeArray[4], MPI_AREA;
- MPI_Aint offsets[4], address[5];
- int blockcounts[4];
- void printTab(int table[OCEAN_SIZE][OCEAN_SIZE]){
- printf("Czesc oceanu dla procesu %d w chwilczasowej t = %d:\n", world_rank,iterateCounter);
- for(int i = 0 ; i < OCEAN_SIZE ; i++){
- for(int j = 0 ; j < OCEAN_SIZE ; j++)
- printf("%d ",table[j][i]);
- printf("\n");
- }
- printf("\n");
- }
- void genRand(int table[OCEAN_SIZE][OCEAN_SIZE]){
- for(int i = 0 ; i < OCEAN_SIZE ; i++)
- for(int j = 0 ; j < OCEAN_SIZE ; j++){
- table[i][j] = rand()%3;
- }
- }
- void begin(int lifeTime[OCEAN_SIZE][OCEAN_SIZE]){
- for(int i = 0 ; i < OCEAN_SIZE ; i++)
- for(int j = 0 ; j < OCEAN_SIZE ; j++){
- lifeTime[i][j] = 0;
- }
- }
- void setSides(){
- if(world_rank%3 == 0)
- leftProcess = world_rank + 2;
- else
- leftProcess = world_rank - 1;
- if(world_rank%3 == 2)
- rightProcess = world_rank - 2;
- else
- rightProcess = world_rank + 1;
- if(world_rank < 3)
- upperProcess = world_rank + 2*3;
- else
- upperProcess = world_rank - 3;
- if(world_rank >= (3*2))
- bottomProcess = world_rank - 2*3;
- else
- bottomProcess = world_rank + 3;
- }
- void makeMove(int table[OCEAN_SIZE][OCEAN_SIZE], int newX, int newY, int previousX, int previousY, int movePosiblity[OCEAN_SIZE][OCEAN_SIZE], int lifeTime[OCEAN_SIZE][OCEAN_SIZE], int hungry[OCEAN_SIZE][OCEAN_SIZE], Area2D leftPart, Area2D rightPart, Area2D upperPart, Area2D bottomPart){
- int* newPos = &(table[newX][newY]);
- int* newCanMove = &(movePosiblity[newX][newY]);
- int* newLifeTime = &(lifeTime[newX][newY]);
- int* newHungry = &(hungry[newX][newY]);
- //graniceX
- if(newX<0){
- newPos = &(leftPart.table[OCEAN_SIZE-1][newY]);
- newCanMove = &(leftPart.movePosiblity[OCEAN_SIZE-1][newY]);
- newLifeTime = &(leftPart.lifeTime[OCEAN_SIZE-1][newY]);
- newHungry = &(leftPart.hungry[OCEAN_SIZE-1][newY]);
- }
- if(newX>=OCEAN_SIZE){
- newPos = &(rightPart.table[0][newY]);
- newCanMove = &(rightPart.movePosiblity[0][newY]);
- newLifeTime = &(rightPart.lifeTime[0][newY]);
- newHungry = &(rightPart.hungry[0][newY]);
- }
- //graniceY:
- if(newY==OCEAN_SIZE){
- newPos = &(bottomPart.table[newX][0]);
- newCanMove = &(bottomPart.movePosiblity[newX][0]);
- newLifeTime = &(bottomPart.lifeTime[newX][0]);
- newHungry = &(bottomPart.hungry[newX][0]);
- }
- if(newY<0){
- newPos = &(upperPart.table[newX][OCEAN_SIZE-1]);
- newCanMove = &(upperPart.movePosiblity[newX][OCEAN_SIZE-1]);
- newLifeTime = &(upperPart.lifeTime[newX][OCEAN_SIZE-1]);
- newHungry = &(upperPart.hungry[newX][OCEAN_SIZE-1]);
- }
- //jezeli to jest rekin:
- if(table[previousX][previousY] == 2){
- //...i rusza na pole rybki
- if(*newPos == 1)
- hungry[previousX][previousY] = 0;
- }
- *newPos = table[previousX][previousY];
- *newCanMove = 0;//NOWE MA BYC
- table[previousX][previousY] = 0;
- movePosiblity[previousX][previousY] = 0;
- *newLifeTime = lifeTime[previousX][previousY];//NOWE MA BYC
- lifeTime[previousX][previousY] = 0;
- *newHungry = hungry[previousX][previousY];//NOWE MA BYC
- hungry[previousX][previousY] = 0;
- //jezeli to jest stara rybka to rodzi nowa w starym miejscu:
- if(*newPos == 1 && *newLifeTime >= MATURITY)
- table[previousX][previousY] = 1;
- //jezeli to jest stary rekin to rodzi nowego rekina w starym miejscu:
- if(*newPos == 2 && *newLifeTime >= MATURITY)
- table[previousX][previousY] = 2;
- }
- void fishMove(int table[OCEAN_SIZE][OCEAN_SIZE], int movePosiblity[OCEAN_SIZE][OCEAN_SIZE], int i, int j, int lifeTime[OCEAN_SIZE][OCEAN_SIZE], int hungry[OCEAN_SIZE][OCEAN_SIZE], Area2D leftPart, Area2D rightPart, Area2D upperPart, Area2D bottomPart){
- if(movePosiblity[i][j]){
- int newX = (i+1);
- int newY = (j);
- if(table[newX][newY]==0)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- if(movePosiblity[i][j]){
- int newX = (i);
- int newY = (j+1);
- if(table[newX][newY]==0)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- if(movePosiblity[i][j]){
- int newX = (i-1);
- int newY = (j);
- if(table[newX][newY]==0)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- if(movePosiblity[i][j]){
- int newX = (i);
- int newY = (j-1);
- if(table[newX][newY]==0)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- }
- void sharkMove(int table[OCEAN_SIZE][OCEAN_SIZE], int movePosiblity[OCEAN_SIZE][OCEAN_SIZE], int i, int j, int lifeTime[OCEAN_SIZE][OCEAN_SIZE], int hungry[OCEAN_SIZE][OCEAN_SIZE], Area2D planeR, Area2D planeL, Area2D planeU, Area2D planeB){
- //jak jest gdzies ryba:
- if(movePosiblity[i][j]){
- int newX = (i+1);
- int newY = (j);
- if(table[newX][newY]==1)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- if(movePosiblity[i][j]){
- int newX = (i);
- int newY = (j+1);
- if(table[newX][newY]==1)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- if(movePosiblity[i][j]){
- int newX = (i-1);
- int newY = (j);
- if(table[newX][newY]==1)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- if(movePosiblity[i][j]){
- int newX = (i);
- int newY = (j-1);
- if(table[newX][newY]==1)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- //jezeli pole puste:
- if(movePosiblity[i][j]){
- int newX = (i+1);
- int newY = (j);
- if(table[newX][newY]==0 || table[newX][newY]==1)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- if(movePosiblity[i][j]){
- int newX = (i);
- int newY = (j+1);
- if(table[newX][newY]==0 || table[newX][newY]==1)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- if(movePosiblity[i][j]){
- int newX = (i-1);
- int newY = (j);
- if(table[newX][newY]==0 || table[newX][newY]==1)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- if(movePosiblity[i][j]){
- int newX = (i);
- int newY = (j-1);
- if(table[newX][newY]==0 || table[newX][newY]==1)
- makeMove(table, newX, newY, i, j, movePosiblity, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- }
- void iterate(int table[OCEAN_SIZE][OCEAN_SIZE], int movePosiblity[OCEAN_SIZE][OCEAN_SIZE], int lifeTime[OCEAN_SIZE][OCEAN_SIZE], int hungry[OCEAN_SIZE][OCEAN_SIZE], Area2D leftPart, Area2D rightPart, Area2D upperPart, Area2D bottomPart){
- Area2D plL;
- for(int i = 0 ; i < OCEAN_SIZE ; i++)
- for(int j = 0 ; j < OCEAN_SIZE ; j++){
- //dla rybki:
- if(table[i][j] == 1){
- //zwiekszenie wieku rybki:
- if(movePosiblity[i][j]==1)
- lifeTime[i][j]++;
- //proba ruchu: -probuje plynac z pradem (najlepiej w prawo)
- fishMove(table, movePosiblity, i, j, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- //dla rekina:
- if(table[i][j] == 2){
- //zwiekszenie wieku i glodu rekina:
- if(movePosiblity[i][j]==1){
- lifeTime[i][j]++;
- hungry++;
- }
- //umieranie rekina ze starosci:
- if(hungry[i][j]>=HUNGRY_MAX)
- table[i][j]=0;
- //proba ruchu: -probuje plynac z pradem (najlepiej w prawo) jezeli jeszcze zyje
- if(table[i][j]==2)
- sharkMove(table, movePosiblity, i, j, lifeTime, hungry, leftPart, rightPart, upperPart, bottomPart);
- }
- }
- //update reszty brzegow:
- //lewo:
- MPI_Send(&leftPart, 1, MPI_AREA, rightProcess,
- 0, MPI_COMM_WORLD);
- //prawo:
- MPI_Send(&rightPart, 1, MPI_AREA, leftProcess,
- 0, MPI_COMM_WORLD);
- //dol:
- MPI_Send(&bottomPart, 1, MPI_AREA, upperProcess,
- 0, MPI_COMM_WORLD);
- //gora:
- MPI_Send(&upperPart, 1, MPI_AREA, bottomProcess,
- 0, MPI_COMM_WORLD);
- MPI_Recv(&plL, 1, MPI_AREA, leftProcess, 0,
- MPI_COMM_WORLD, &status);
- for(int i = 0; i<OCEAN_SIZE; i++){
- ocean.table[0][i] = plL.table[0][i];
- ocean.movePosiblity[0][i] = plL.movePosiblity[0][i];
- ocean.lifeTime[0][i] = plL.lifeTime[0][i];
- ocean.hungry[0][i] = plL.hungry[0][i];
- }
- MPI_Recv(&plL, 1, MPI_AREA, rightProcess, 0,
- MPI_COMM_WORLD, &status);
- for(int i = 0; i<OCEAN_SIZE; i++){
- ocean.table[OCEAN_SIZE-1][i] = plL.table[OCEAN_SIZE-1][i];
- ocean.movePosiblity[OCEAN_SIZE-1][i] = plL.movePosiblity[OCEAN_SIZE-1][i];
- ocean.lifeTime[OCEAN_SIZE-1][i] = plL.lifeTime[OCEAN_SIZE-1][i];
- ocean.hungry[OCEAN_SIZE-1][i] = plL.hungry[OCEAN_SIZE-1][i];
- }
- MPI_Recv(&plL, 1, MPI_AREA, bottomProcess, 0,
- MPI_COMM_WORLD, &status);
- for(int i = 0; i<OCEAN_SIZE; i++){
- ocean.table[i][OCEAN_SIZE-1] = plL.table[i][0];
- ocean.movePosiblity[i][OCEAN_SIZE-1] = plL.movePosiblity[i][OCEAN_SIZE-1];
- ocean.lifeTime[i][OCEAN_SIZE-1] = plL.lifeTime[i][OCEAN_SIZE-1];
- ocean.hungry[i][OCEAN_SIZE-1] = plL.hungry[i][OCEAN_SIZE-1];
- }
- MPI_Recv(&plL, 1, MPI_AREA, upperProcess, 0,
- MPI_COMM_WORLD, &status);
- for(int i = 0; i<OCEAN_SIZE; i++){
- ocean.table[i][0] = plL.table[i][0];
- ocean.movePosiblity[i][0] = plL.movePosiblity[i][0];
- ocean.lifeTime[i][0] = plL.lifeTime[i][0];
- ocean.hungry[i][0] = plL.hungry[i][0];
- }
- }
- void tryToSynchro(int movePosiblity[OCEAN_SIZE][OCEAN_SIZE]){
- MPI_Send(&ocean, 1, MPI_AREA, rightProcess,
- 0, MPI_COMM_WORLD);
- MPI_Send(&ocean, 1, MPI_AREA, leftProcess,
- 0, MPI_COMM_WORLD);
- MPI_Send(&ocean, 1, MPI_AREA, upperProcess,
- 0, MPI_COMM_WORLD);
- MPI_Send(&ocean, 1, MPI_AREA, bottomProcess,
- 0, MPI_COMM_WORLD);
- MPI_Recv(&leftPart, 1, MPI_AREA, leftProcess, 0,
- MPI_COMM_WORLD, &status);
- MPI_Recv(&rightPart, 1, MPI_AREA, rightProcess, 0,
- MPI_COMM_WORLD, &status);
- MPI_Recv(&bottomPart, 1, MPI_AREA, bottomProcess, 0,
- MPI_COMM_WORLD, &status);
- MPI_Recv(&upperPart, 1, MPI_AREA, upperProcess, 0,
- MPI_COMM_WORLD, &status);
- //movePosiblity = true dla kazdej rybki
- for(int i = 0 ; i < OCEAN_SIZE ; i++)
- for(int j = 0 ; j < OCEAN_SIZE ; j++)
- movePosiblity[i][j]=1;
- }
- int main(int argc, char** argv)
- {
- MPI_Init(&argc, &argv);
- MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
- MPI_Comm_size(MPI_COMM_WORLD, &world_size);
- //pobierania adresow:
- MPI_Address(&ocean, &address[0]);
- MPI_Address(&ocean.table, &address[1]);
- MPI_Address(&ocean.hungry, &address[2]);
- MPI_Address(&ocean.lifeTime, &address[3]);
- MPI_Address(&ocean.movePosiblity, &address[4]);
- //liczenie offsetow blokow:
- offsets[0]=address[1]-address[0];
- offsets[1]=address[2]-address[0];
- offsets[2]=address[3]-address[0];
- offsets[3]=address[4]-address[0];
- //typy blokow:
- typeArray[0]=MPI_INT;
- typeArray[1]=MPI_INT;
- typeArray[2]=MPI_INT;
- typeArray[3]=MPI_INT;
- //liczebnosci blokow:
- blockcounts[0]=OCEAN_SIZE*OCEAN_SIZE;
- blockcounts[1]=OCEAN_SIZE*OCEAN_SIZE;
- blockcounts[2]=OCEAN_SIZE*OCEAN_SIZE;
- blockcounts[3]=OCEAN_SIZE*OCEAN_SIZE;
- //commit strukturki:
- MPI_Type_struct(4, blockcounts, offsets, typeArray, &MPI_AREA);
- MPI_Type_commit(&MPI_AREA);
- seed = time(NULL);
- srand(seed);
- //losowe wypelnienie:
- begin(ocean.lifeTime);
- genRand(ocean.table);
- leftProcess = world_rank - 1;
- rightProcess = world_rank + 1;
- upperProcess = world_rank - 3;
- bottomProcess = world_rank + 3;
- setSides();
- while(iterateCounter<LIFE_TIME){
- tryToSynchro(ocean.movePosiblity);
- if(world_rank == 0)
- printTab(ocean.table);
- MPI_Barrier(MPI_COMM_WORLD);
- iterate(ocean.table, ocean.movePosiblity, ocean.lifeTime, ocean.hungry, leftPart, rightPart, upperPart, bottomPart);
- iterateCounter++;
- MPI_Barrier(MPI_COMM_WORLD);
- }
- printf("koniec ");
- MPI_Finalize();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement