This repository was archived by the owner on Jul 4, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmpi_navier.cpp
More file actions
91 lines (78 loc) · 2.59 KB
/
mpi_navier.cpp
File metadata and controls
91 lines (78 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <mpi.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int my_rank;
int nprocs;
int nprocs_y;
int nprocs_x;
int my_rank_x;
int my_rank_y;
int prev_y;
int next_y;
int next_x;
int prev_x;
int imax_full;
int jmax_full;
int gbl_i_begin;
int gbl_j_begin;
MPI_Comm cartcomm;
MPI_Datatype row, column;
void mpi_setup(int *imax, int *jmax) {
//Initialise: get #of processes and process id
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
int dims[2] = {0,0}; int periods[2] = {0,0};
int reorder = 0;
MPI_Dims_create(nprocs, 2, dims);
nprocs_x = dims[0];
nprocs_y = dims[1];
//Create cartesian communicator for 2D, dims[0]*dims[1] processes,
//without periodicity and reordering
MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, reorder, &cartcomm);
//Figure out process X,Y coordinates
MPI_Comm_rank(cartcomm, &my_rank);
//Get my coordinates coords[0] and coords[1]
int coords[2];
MPI_Cart_coords(cartcomm, my_rank, 2, coords);
my_rank_x = coords[0];
my_rank_y = coords[1];
//Figure out neighbours
//Get my neighbours in dimension 0
MPI_Cart_shift(cartcomm, 0, 1, &prev_x, &next_x);
//Get my neighbours in dirmension 1
MPI_Cart_shift(cartcomm, 1, 1, &prev_y, &next_y);
//Save original full sizes in x and y directions
//Modify imax and jmax (pay attention to integer divisions's rounding issues!)
imax_full = *imax;
*imax = *imax / nprocs_x;
if (my_rank_x == nprocs_x -1){
int remainder = imax_full % nprocs_x;
*imax = *imax + remainder;
}
jmax_full = *jmax;
*jmax = *jmax / nprocs_y;
if (my_rank_y == nprocs_y -1){
int remainder = jmax_full % nprocs_y;
*jmax = *jmax + remainder;
}
//Figure out beginning i and j index in terms of global indexing
gbl_i_begin = my_rank_x * (imax_full / nprocs_x);
gbl_j_begin = my_rank_y * (jmax_full / nprocs_y);
//Let's set up MPI Datatypes
MPI_Type_vector((*imax+2), 1,1,MPI_DOUBLE, &row);
MPI_Type_vector((*jmax+2), 1,(*imax+2),MPI_DOUBLE, &column);
MPI_Type_commit(&row);
MPI_Type_commit(&column);
}
void exchange_halo(int imax, int jmax, double *arr) {
//Exchange halos: prev_y, next_y, prev_x, next_x
MPI_Sendrecv(&arr[1], 1, column, prev_x, 421,
&arr[imax+1], 1, column, next_x, 421, cartcomm, MPI_STATUS_IGNORE);
MPI_Sendrecv(&arr[imax+0], 1, column, next_x, 421,
&arr[0], 1, column, prev_x, 421, cartcomm, MPI_STATUS_IGNORE);
MPI_Sendrecv(&arr[(jmax)*(imax+2)], 1, row, next_y, 421,
&arr[0], 1, row, prev_y, 421, cartcomm, MPI_STATUS_IGNORE);
MPI_Sendrecv(&arr[1*(imax+2)], 1, row, prev_y, 421,
&arr[(jmax+1)*(imax+2)], 1, row, next_y, 421, cartcomm, MPI_STATUS_IGNORE);
}