float * simulate(const float alpha, const long n_segments, const int n_steps, float *d_buf1, float *d_buf2, const int rank, const int world_size, const long segments_per_process) {
float* d_t = d_buf1; // buffer for d(*, t)
float* d_t1 = d_buf2; // buffer for d(*, t+1)
const long start_segment = segments_per_process*((long)rank) +1L;
const long last_segment = segments_per_process*((long)rank+1L)+1L;
const float dx = 1.0f/(float)n_segments;
const float phase = 0.5f;
MPI_Status stat;
for(int t = 0; t < n_steps; t++) {
#pragma omp parallel for simd
for(long i = start_segment; i < last_segment; i++) {
const float L_x = L(alpha,phase,i*dx);
d_t1[i] = L_x*(d_t[i+1] + d_t[i-1])
+2.0f*(1.0f-L_x)*(d_t[i])
- d_t1[i]; // The algorithm calls for d(i, t-1) here, but that is currently contained in d_t1
}
float* temp = d_t1; d_t1 = d_t; d_t = temp;
MPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, &d_t[1], segments_per_process, MPI_FLOAT, MPI_COMM_WORLD);
}
return d_t;
}
Это программа для расчета вибрации струны с использованием MPI. В этой программе мы должны выполнить задачу с MPI_Send и MPI_Recv, используя заданный ранг.Так что это может быть выполнено более эффективно
Это модификация, которую я сделал, чтобы реализовать ответ @Peter Cordes.Это не дает правильный вывод, вы можете увидеть, если я сделал что-то не так?
float * simulate(const float alpha, const long n_segments, const int n_steps, float *d_buf1, float *d_buf2, const int rank, const int world_size, const long segments_per_process) {
float* d_t = d_buf1; // buffer for d(*, t)
float* d_t1 = d_buf2; // buffer for d(*, t+1)
const long start_segment = segments_per_process*((long)rank) +1L;
const long last_segment = segments_per_process*((long)rank+1L)+1L;
const float dx = 1.0f/(float)n_segments;
const float phase = 0.5f;
MPI_Status stat;
for(int t = 0; t < n_steps; t++) {
MPI_Barrier(MPI_COMM_WORLD);
#pragma omp parallel for simd
for(long i = start_segment; i < last_segment; i++) {
const float L_x = L(alpha,phase,i*dx);
d_t1[i] = L_x*(d_t[i+1] + d_t[i-1])
+2.0f*(1.0f-L_x)*(d_t[i])
- d_t1[i]; // The algorithm calls for d(i, t-1) here, but that is currently contained in d_t1
}
float* temp = d_t1; d_t1 = d_t; d_t = temp;
/*MPI_Bcast(&d_t,1,
MPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, &d_t[1], segments_per_process, MPI_FLOAT, MPI_COMM_WORLD);
*/
MPI_Send(&d_t, 1, MPI_FLOAT, rank - 1, 0, MPI_COMM_WORLD);
MPI_Send(&d_t[segments_per_process-1], 1, MPI_FLOAT, rank + 1, 1, MPI_COMM_WORLD);
MPI_Recv(&d_t, 1, MPI_FLOAT, rank, 0, MPI_COMM_WORLD,&stat);
MPI_Recv(&d_t[segments_per_process-1], 1, MPI_FLOAT, rank, 1, MPI_COMM_WORLD, &stat);
}
return d_t;
}