我正在尝试用C语言使用MPI进行图像卷积。我的想法是将图像分成不同的块,让不同的进程进行不同的排名,然后将它们聚集在一个根进程中。
我对C语言很陌生,你能给我解释一下这个错误以及如何解决它吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <mpi.h>
#define IMAGE_IN "logo.pgm"
#define IMAGE_OUT "result.pgm"
/* function declarations */
int * read_image (char file_name[], int *p_h, int *p_w, int *p_levels);
void write_image (int *image, char file_name[], int h, int w, int levels);
int* convolve(int *image_in, int *image_out, int kernel[3][3], int height, int width,int first_row, int last_row,int chunk_size) {
int i, j, x, y;
int sum, max_val, min_val;
/* initialize max_val and min_val */
max_val = image_in[0];
min_val = image_in[0];
for (i = first_row; i < last_row; i++) {
for (j = 1; j < width - 1; j++) {
sum = 0;
for (x = -1; x <= 1; x++) {
for (y = -1; y <= 1; y++) {
sum += kernel[x+1][y+1] * image_in[(i+x)*width+(j+y)];
}
}
/* update max_val and min_val */
if (sum > max_val) {
max_val = sum;
}
if (sum < min_val) {
min_val = sum;
}
image_out[i*width+j] = sum;
}
}
printf("min is:%d\n", min_val);
printf("max is: %d\n",max_val);
/* normalize pixel values */
for (i = first_row; i < last_row; i++) {
for (j = 1; j < width - 1; j++) {
image_out[i*width+j] = 255 * (image_out[i*width+j] - min_val) / (max_val - min_val);
}
}
return image_out;
}
int main(int argc, char *argv[])
{
int i, j, h, w, levels ;
struct timeval tdeb, tfin;
int *image_in, *image_out;
int my_rank;
int num_procs;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
image_in = read_image (IMAGE_IN, &h, &w, &levels);
int chunk_size= h/num_procs;
printf ("chunk size is %d \n", chunk_size);
int first_row= my_rank* chunk_size+1;
int last_row= first_row+ chunk_size-1;
printf ("first row is %d \n", first_row);
printf ("last row is %d \n", last_row);
/* image processing (just a copy in this example) */
gettimeofday(&tdeb, NULL);
int kernel[3][3]={{0,-1,0},
{-1,5,-1},
{0,-1,0}};
int *local_image = malloc(chunk_size * w*sizeof(int));
image_out = malloc (h*w*sizeof(int));
local_image=convolve(image_in, image_out, kernel, chunk_size, w,first_row,last_row,chunk_size);
MPI_Gather(local_image, chunk_size*w,MPI_INT,image_out, h*w, MPI_INT, 0, MPI_COMM_WORLD);
gettimeofday(&tfin, NULL);
printf ("computation time (microseconds): %ld\n", (tfin.tv_sec - tdeb.tv_sec)*1000000 + (tfin.tv_usec - tdeb.tv_usec));
write_image (local_image, IMAGE_OUT, h, w, levels);
MPI_Finalize();
free (image_in);
free (image_out);
return 0;
}
/*
* read an image from a file and dynamic memory allocation for it
* param1 : name of the image file
* param2 : where to store the height
* param3 : where to store the weight
* param4 : where to store the number of levels
* return : address of the pixels
*/
int * read_image (char file_name[], int *p_h, int *p_w, int *p_levels){
FILE *fin;
int i, j, h, w, levels ;
char buffer[80];
int *image;
/* open P2 image */
fin = fopen (IMAGE_IN, "r");
if (fin == NULL){
printf ("file open error\n");
exit(-1);
}
fscanf (fin, "%s", buffer);
if (strcmp (buffer, "P2")){
printf ("the image format must be P2\n");
exit(-1);
}
fgets (buffer, 80, fin);
fgets (buffer, 80, fin);
fscanf (fin, "%d%d", &w, &h);
fscanf (fin, "%d", &levels);
printf ("image reading ... h = %d w = %d\n", h, w);
/* dynamic memory allocation for the pixels */
image = malloc (h*w*sizeof(int));
/* pixels reading */
for (i = 0; i < h ; i++)
for (j = 0; j < w; j++)
fscanf (fin, "%d", image +i*w +j);
fclose (fin);
*p_h = h;
*p_w = w;
*p_levels=levels;
return image;
}
/*
* write an image in a file
* param1 : address of the pixels
* param2 : name of the image file
* param3 : the height
* param4 : the weight
* param5 : the number of levels
* return : void
*/
void write_image (int *image, char file_name[], int h, int w, int levels){
FILE *fout;
int i, j;
/* open the file */
fout=fopen(IMAGE_OUT,"w");
if (fout == NULL){
printf ("file opening error\n");
exit(-1);
}
/* header write */
fprintf(fout,"P2\n# test \n%d %d\n%d\n", w, h, levels);
/* format P2, commentary, w x h points, levels */
/* pixels writing*/
for (i = 0; i < h ; i++)
for (j = 0; j < w; j++)
fprintf (fout, "%d\n", image[i*w+j]);
fclose (fout);
return;
}
一切正常,直到出现这个错误。
在文件src/mpi/datatype/typeps/src/typep_yaksa_pack.c的第286行中Assert失败:假的
memcpy参数内存范围重叠,dst_= 0x 7 f56 ed 5 be 010 src_= 0x 7 f56 ed 5 be 010 len_=1557836
在节点0上中止(1):内部错误
1条答案
按热度按时间nnt7mjpx1#
你应该仔细看看
MPI_Gather
函数。首先,尝试注解掉它,看看错误是否消失。如果是这种情况,你可能会向MPI_Gather
传递错误的参数。你得到的错误来自MPI库的某个地方,因为除了初始化之外,你在程序中使用的唯一函数是MPI_Gather
。