msmpi 高性能并行计算 移植并行细胞自动机报错

发布于:2024-05-03 ⋅ 阅读:(33) ⋅ 点赞:(0)

报错情况如图

 代码来源

元胞自动机生命游戏C语言并行实现 – OmegaXYZ

稍微修改,因为相对路径在 msmpi 10.1.1 中失效

Microsoft Windows [版本 10.0.22000.2538]
(c) Microsoft Corporation。保留所有权利。

C:\Users\ASUS>mpiexec -n 9 "C:\Users\ASUS\Desktop\testMPI\MPIS.exe"

job aborted:
[ranks] message

[0] terminated

[1] fatal error
Fatal error in MPI_Recv: Message truncated, error stack:
MPI_Recv(buf=0x000002F82B501D6C, count=0, MPI_INT, src=0, tag=1, MPI_COMM_WORLD, status=0x00007FF66B1CD0A0) failed
Message from rank 0 and tag 1 truncated; 12 bytes received but buffer size is 0

[2-8] terminated

---- error analysis -----

[1] on LAPTOP-MUD6OOHE
mpi has detected a fatal error and aborted C:\Users\ASUS\Desktop\testMPI\MPIS.exe

---- error analysis -----

C:\Users\ASUS>

windows msmpi 移植 linux  代码如下

#include <stdio.h>
#include <string.h>
#include <mpi/mpi.h>
#include <stdlib.h>
#include <io.h>
//https://www.omegaxyz.com/2022/01/26/c_game_of_life/?utm_source=tuicool&utm_medium=referral
static int MAX_M;
static int MAX_N;
static int epoch;
static int DEAD = 0;
static int ALIVE = 1;

double exe_time;
int size, myid, s, ver, row, col, dir;

int *local_matrix = NULL;
int *tmpmatrix = NULL;
int *global_matrix = NULL;
int *newglobal_matrix = NULL;
MPI_Request requests[4];
MPI_Status status[4];


FILE * matrix;

void display(int *local_matrix) {
	int i, j;
	printf("%10c", ' ');
	printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
	for (i = 0; i < MAX_M; i++) {
		printf("\n%10c", ' ');
		for (j = 0; j < MAX_N; j++)
			if (local_matrix[i * MAX_N + j] == ALIVE)
				printf("+");
			else
				printf("-");
	}
	printf("\n%10c\n", ' ');
}


int adj8(int neighbor, int row, int col) {
	int res;
	if (neighbor == 2) {
		return local_matrix[row * MAX_N + col];
	} else if (neighbor == 3) {
		return ALIVE;
	} else {
		return DEAD;
	}
}


int main(int argc, char *argv[]) {
	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &size);
	MPI_Comm_rank(MPI_COMM_WORLD, &myid);
	ver = MAX_M / size;

//	epoch= atoi(argv[1]);
//	MAX_M= atoi(argv[2]);
//	MAX_N= atoi(argv[3]);

	epoch = 100;
	MAX_M = 3;
	MAX_N = 3;

	local_matrix = (int*)malloc(sizeof(int) * (ver + 2) * MAX_N);
	tmpmatrix = (int*)malloc(sizeof(int) * (ver + 2) * MAX_N);
	for (row = 0; row < ver + 2; row++) {
		for (col = 0; col < MAX_N; col++) {
			local_matrix[row * MAX_N + col] = DEAD;
			tmpmatrix[row * MAX_N + col] = DEAD;
		}
	}
	//Initialization
	if (myid == 0) {
		int i;
		
		global_matrix = (int*)malloc(sizeof(int) * MAX_M * MAX_N);
		newglobal_matrix = (int*)malloc(sizeof(int) * MAX_M * MAX_N);


		// windows 的 msmpi 相对路径不能读取,只能用绝对路径,但是可以通过获取当前文件所在文件夹来拼出来绝对路径
		FILE* fp;
		fp = fopen("C:\\Users\\ASUS\\Desktop\\testMPI\\matrixv6.txt", "w");
		fprintf(fp, "hello\n");
		fclose(fp);

		char path[PATH_MAX + 100]; //PATH_MAX is defined in limits.h
		getcwd(path, sizeof(path));  		// io.h 获取当前文件夹位置
		printf("%s\n", path);
		strcat(path, "\\matrixv7.txt");		// 在当前文件夹位置加入数据
		printf("%s\n", path);
		fp = fopen(path, "w");

		for (int i = 0; i < MAX_M; i++) {
			for (int j = 0; j < MAX_N; j++) {
				fprintf(fp, "%d ", 1);
			}
			fprintf(fp, "\n");
		}

		fclose(fp);

		if ((matrix = fopen(path, "r")) == NULL) {
			printf("the file can not open.");
			return -1;
		}

		for (row = 0; row < MAX_M; row++) {
			for (col = 0; col < MAX_N; col++) {
				fscanf(matrix, "%d ", &global_matrix[row * MAX_N + col]);
			}
			fscanf(matrix, "\n");
		}

		memcpy(&local_matrix[MAX_N], &global_matrix[0], ver * MAX_N * sizeof(int));
		for (dir = 1; dir < size; dir++) {
			MPI_Send(&global_matrix[dir * ver * MAX_N], ver * MAX_N, MPI_INT, dir, 1, MPI_COMM_WORLD);
		}

		display(global_matrix);
	} else {
		//For each processor, there is a local matrix.
		MPI_Recv(&local_matrix[MAX_N], ver * MAX_N, MPI_INT, 0, 1, MPI_COMM_WORLD, status);
	}


	exe_time = -MPI_Wtime();


	for (int count = 0; count < epoch; count++) {
		int req_id = 0;
		if (myid == 0) {
			MPI_Isend(&local_matrix[(ver)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]);
			MPI_Irecv(&local_matrix[(ver + 1)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]);
			printf("\n");
			display(local_matrix);
		} else {
			MPI_Irecv(local_matrix, MAX_N, MPI_INT, myid - 1, 1, MPI_COMM_WORLD, &requests[req_id++]);
			MPI_Isend(&local_matrix[(ver)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]);
			MPI_Irecv(&local_matrix[(ver + 1)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]);
			MPI_Isend(&local_matrix[MAX_N], MAX_N, MPI_INT, myid - 1, 1, MPI_COMM_WORLD, &requests[req_id++]);
		}
		MPI_Waitall(req_id, requests, status);

		for (row = 1; row < ver + 1; row += 1) {
			for (col = 0; col < MAX_N; col++) {
				int neighbor = 0, c, r;
				for (r = row - 1; r <= row + 1; r++)
					for (c = col - 1; c <= col + 1; c++) {
						if (c < 0 || c >= MAX_N) continue;
						if (local_matrix[r * MAX_N + c] == ALIVE) neighbor++;
					}
				if (local_matrix[row * MAX_N + col] == ALIVE)
					neighbor--;
				tmpmatrix[row * MAX_N + col] = adj8(neighbor, row, col);
			}
		}

		for (row = 1; row < ver + 1; row += 1) {
			for (col = 0; col < MAX_N; col++) {
				local_matrix[row * MAX_N + col] = tmpmatrix[row * MAX_N + col];
			}
		}
	}
	if (myid == 0) {
		exe_time += MPI_Wtime();
		printf("Time: %lf \n", exe_time);
		memcpy(global_matrix, &local_matrix[MAX_N], ver * MAX_N * sizeof(int));
		for (dir = 1; dir < size; dir++) {
			MPI_Recv(&global_matrix[dir * ver * MAX_N], ver * MAX_N, MPI_INT, dir, 1, MPI_COMM_WORLD, status);
		}
		printf("Last Status:\n");
		display(global_matrix);
	} else {
		MPI_Send(&local_matrix[MAX_N], ver * MAX_N, MPI_INT, 0, 1, MPI_COMM_WORLD);
	}
	MPI_Finalize();
	return 0;
}