cuốn sách gpt4 ai đã làm

c - MPI_Allreduce không hoạt động như mong đợi - SOR đỏ-đen

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 08:34:54 30 4
mua khóa gpt4 Nike

Tôi đang triển khai phiên bản song song của SOR đỏ-đen.

Phần MPI_Allreduce mà tôi muốn nhận được lỗi tối đa cho mỗi quy trình không hoạt động. Nó không bao giờ thay đổi, ngay cả khi chỉ có một quy trình, nó sẽ cho giá trị cao hơn 2.0. Chuyện gì đang xảy ra vậy? ?

Đây là đoạn mã, phần thú vị nằm ở cuối quy trình sor.

#include 
#include
#include
#include
#include

#xác định M 700

int numtasks, xếp hạng, inext, iprev, ista, iend;

gấp đôi unew[M + 2][M + 2] = {{ 0 }};
nghiệm kép[M + 2][M + 2] = {{ 0 }};

uold kép[M + 2][M + 2] = {{ 0 }};

đôi bufs1[M + 2];
đôi bufs2[M + 2];

đôi bufr1[M + 2];
đôi bufr2[M + 2];

MPI_Request ireqs1;
MPI_Request ireqs2;

MPI_Request ireqr1;
MPI_Request ireqr2;

MPI_Tình trạng hiện tại;

lỗi tính toán kép(giải pháp kép[][M + 2], gấp đôi u[][M + 2], const int m);
int sor(double unew[][M + 2], double uold[][M + 2], double Solution[][M + 2], const double omega, const double tol, const int m);
void para_range(const int n1, const int n2, const int nprocs, const int irank, int * hạn chế ista, int * hạn chế iend);
void shift(const int iflg);
nội tuyến int min(const int a, const int b);

int main(int argc, char * argv[])
{
const int m = M;

int ierr = MPI_Init(&argc, &argv);

if(ierr != MPI_SUCCESS)
{
perror("Khởi tạo MPI không thành công. Chấm dứt T800.\n");
exit(1);
}

int tôi, j;

const kép bắt đầu = MPI_Wtime();

const double pi = 4.0 * atan(1.0);

const kép h = pi / (m + 1);

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

for(i = 0; i < m + 2; ++i)
{
uold[i][M + 1] = sin(i * h);
}

for(i = 0; i < m + 2; ++i)
{
for(j = 0; j < m + 1; ++j)
{
uold[i][j] = j * h * uold[i][M + 1];
}
}

for(i = 0; i < m + 2; ++i)
{
for(j = 0; j < m + 2; ++j)
{
Solution[i][j] = sinh(j * h) * sin(i * h) / sinh(pi);
}
}

para_range(0, m, numtasks, xếp hạng, &ista, &iend);

//printf("xếp hạng %d: từ %d đến %d\n", xếp hạng, ista, iend);

inext = thứ hạng + 1;
iprev = thứ hạng - 1;

if(inext == numtasks)
{
inext = MPI_PROC_NULL;
}

nếu(iprev == -1)
{
iprev = MPI_PROC_NULL;
}

const kép omega = 2.0 / ( 1.0 + sin(pi / (m + 1)) );
const kép tol = 0,001;

const int iters = sor(unew, uold, Solution, omega, tol, m);

const kết thúc kép = MPI_Wtime();

MPI_Finalize();

nếu(xếp hạng==0)
{
printf("\n");
printf("Omega = %f\n", omega);
printf("Phải mất %d lần lặp.\n", iters);

printf("Tổng thời gian = %f\n\n\n", kết thúc - bắt đầu);
}

return 0;
}

lỗi tính toán kép(giải pháp kép[][M + 2], gấp đôi u[][M + 2], const int m)
{
lỗi kép = 0,0;
int tôi, j;

for(i = 1; i < m + 1; ++i)
{
for(j = 1; j < m + 1; ++j)
{
const double abs_diff = fabs(solution[i][j] - u[i][j]);

if(lỗi < abs_diff)
{
lỗi = abs_diff;
}
}
}

lỗi trả về;
}

int sor(double unew[][M + 2], double uold[][M + 2], double Solution[][M + 2], const double omega, const double tol, const int m)
{
int tôi, j;

int iters = 0;
lỗi kép = tính_error (giải pháp, uold, m);
lỗi kép2 = lỗi;
nhiệt độ gấp đôi;

while(error2 > tol)
{
ca (0);

for(i = 1; i < m + 1; ++i)
{
for(j = (i % 2) + 1; j < m + 1; j += 2)
{
nhiệt độ = 0,25 * (uold[i][j - 1] + uold[i - 1][j]
+ uold[i + 1][j] + uold[i][j + 1]) - uold[i][j];
uold[i][j] += omega * temp;
}
}

ca (1);

for(i = 1; i < m + 1; ++i)
{
for(j = ((i + 1) % 2) + 1; j < m + 1; j += 2)
{
nhiệt độ = 0,25 * (uold[i][j - 1] + uold[i - 1][j]
+ uold[i + 1][j] + uold[i][j + 1]) - uold[i][j];
uold[i][j] += omega * temp;
}
}

++ người lặp lại;

if(iter % 20 == 0)
{
// ĐIỀU NÀY KHÔNG TUYỆT VỜI
error = tính_error(giải pháp, uold, m);
MPI_Allreduce(&error, &error2, 1, MPI_REAL, MPI_MAX, MPI_COMM_WORLD);

//printf("%d=%f\n", xếp hạng, error2);
}
}

trả lại lần lặp;
}

void para_range(const int n1, const int n2, const int nprocs, const int irank, int * hạn chế ista, int * hạn chế iend)
{
const int iwork = ((n2 - n1)/nprocs) + 1;

*ista = min(irank * iwork + n1, n2 + 1);
*iend = min(*ista + iwork - 1, n2);
}

dịch chuyển void(const int iflg)
{
const int is1 = ((ista + iflg) % 2) + 1;
const int is2 = ((iend + iflg) % 2) + 1;

const int ir1 = 3 - is1;
const int ir2 = 3 - is2;

int i, icnt1=0, icnt2=0;

nếu(xếp hạng != 0)
{
icnt1 = 0;

for(i = is1; i < M; i += 2)
{
++icnt1;
bufs1[icnt1] = unew[i][ista];
}
}

if (xếp hạng != numtasks - 1)
{
icnt2 = 0;

for(i = is2; i < M; i += 2)
{
++icnt2;
bufs2[icnt2] = unew[i][iend];
}
}

MPI_Isend(bufs1, icnt1, MPI_REAL, iprev, 1, MPI_COMM_WORLD, &ireqs1);
MPI_Isend(bufs2, icnt2, MPI_REAL, inext, 1, MPI_COMM_WORLD, &ireqs2);

MPI_Irecv(bufr1, M + 2, MPI_REAL, iprev, 1, MPI_COMM_WORLD, &ireqr1);
MPI_Irecv(bufr2, M + 2, MPI_REAL, inext, 1, MPI_COMM_WORLD, &ireqr2);

MPI_Wait(&ireqs1, &status);
MPI_Wait(&ireqs2, &status);

MPI_Wait(&ireqr1, &status);
MPI_Wait(&ireqr2, &status);

int icnt;

nếu(xếp hạng != 0)
{
icnt = 0;

for(i = ir1; i < M; i += 2)
{
++icnt;
unew[i][ista - 1] = bufr1[icnt];
}
}

if(rank != numtasks - 1)
{
icnt = 0;

for(i = ir2; i < M; i += 2)
{
++icnt;
unew[i][iend + 1] = bufr2[icnt];
}
}
}

nội tuyến int min(const int a, const int b)
{
nếu (a > b)
{
return b;
}

trả lại một;
}

câu trả lời hay nhất

MPI_REAL cho Fortran THỰC TẾ loại, thường tương ứng với float. Kiểu dữ liệu bạn đang giảm là gấp đôi , vì vậy bạn nên sử dụng thay thế MPI_DOUBLE. Điều tương tự cũng áp dụng cho các cuộc gọi MPI trong các phần khác của chương trình.

Về c - MPI_Allreduce không hoạt động như mong đợi - SOR đỏ đen, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/26684480/

30 4 0
không gian vũ trụ
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress