MPI矩阵向量乘法的回报,有时正确有时怪异值 [英] MPI matrix-vector-multiplication returns sometimes correct sometimes weird values

查看:258
本文介绍了MPI矩阵向量乘法的回报,有时正确有时怪异值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code:

    //Start MPI...
MPI_Init(&argc, &argv);

int size = atoi(argv[1]);
int delta = 10;
int rnk;
int p;
int root = 0;

MPI_Status mystatus;
MPI_Comm_rank(MPI_COMM_WORLD, &rnk);
MPI_Comm_size(MPI_COMM_WORLD, &p);

//Checking compatibility of size and number of processors
assert(size % p == 0);

//Initialize vector...
double *vector = NULL;
vector = malloc(size*sizeof(double));
double *matrix = NULL;

//Rank 0 -----------------------------------
if (rnk == 0) {

    //Initialize vector...
    srand(1);
    for (int i = 0; i < size; i++) {
        vector[i] = rand() % delta + 1;
    }
    printf("Initial vector:");
    print_vector(vector, size);

    //Initialize matrix...
    matrix = malloc(size*size*sizeof(double));
    srand(2);
    for (int i = 0; i < (size*size); i++) {
        matrix[i] = rand() % delta + 1;
    }

    //Print matrix...
    printf("Initial matrix:");
    print_flat_matrix(matrix, size);

}

//Calculating chunk_size...
int chunk_size = size/p;

//Initialize submatrix..
double *submatrix = malloc(size*chunk_size*sizeof(double));

//Initialize result vector...
double *result = malloc(chunk_size*sizeof(double));

//Broadcasting vector...
MPI_Bcast(vector, size, MPI_DOUBLE, root, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);

//Scattering matrix...
MPI_Scatter(matrix, (size*chunk_size), MPI_DOUBLE, submatrix, (size*chunk_size), MPI_DOUBLE, root, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);

printf("I am rank %d and first element of my vector is: %f and of my matrix1: %f/matrix2: %f/matrix3: %f/matrix4: %f\n", rnk, vector[0], submatrix[0], submatrix[1], submatrix[2], submatrix[3]);

//Calculating...
for (int i = 0; i < chunk_size; i++) {
    for (int j = 0; j < size; j++) {
        result[i] += (submatrix[(i*size)+j] * vector[j]);
        printf("Rank %d; current result: %f, ", rnk, result[i]);
    }
    printf("\n");
    printf("Rank %d; result: %f...\n", rnk, result[i]);
}

printf("Rank: %d; first result: %f\n", rnk, result[0]);


double *final_result = NULL;
//Rank 0 -----------------------------------
if (rnk == 0) {
    final_result = malloc(size*sizeof(double));
}

//Gather...
MPI_Gather(result, chunk_size, MPI_DOUBLE, final_result, chunk_size, MPI_DOUBLE, root, MPI_COMM_WORLD);


//Rank 0 -----------------------------------
if (rnk == 0) {
    printf("Final result:\n");
    print_vector(final_result, size);

    free(matrix);
    free(final_result);
}

free(submatrix);
free(result);
free(vector);

MPI_Finalize();

当我运行它运行到完成没有错误的计划,但我在最后打印值并不总是正确的。有时候,我收到正确的输出载体,有时是部分正确的,有时甚至完全错误的。错误的值是2个完全值是由错误的或者他们是号(在我看来,必须有一个错误的内存访问的一些很长的序列没用,但我无法找到任何东西,也奇怪,因为它有时作品)。

When I run the program it runs to completion without errors, but the values I print at the end aren't always the correct ones. Sometimes I receive the vector with correct output, sometimes it's partially correct and sometimes completely wrong. The wrong values are either wrong by exactly the value of 2 or they are some very long useless sequence of number (Which seems to me there has to be a wrong memory access, but I can't find anything and also weird, because it sometimes works).

我也总是选择我的尺寸,因此将通过MPI适合创建的进程数。 MPI创建我的机器上4个过程(测试和检查值),所以测试我的算法我一直choosen 4作为大小的值。也与较大尺寸发生同样的问题。

I also always choose my size so it'll fit the number of created processes by mpi. mpi creates 4 processes on my machine (tested and checked value), so for testing my algorithm I've always choosen 4 as the value for size. Same problem occurs also with bigger sizes.

期待您的帮助和投入的家伙,先谢谢了!

Looking forward to your help and inputs guys, thanks in advance!

PS:我是用C

推荐答案

您熟悉的valgrind?它会提醒你注意的问题的行,立竿见影。

Are you familiar with valgrind? It will draw your attention to the problematic line straight away.

您的麻烦似乎是这一行:

Your trouble appears to be this line:

result[i] += (submatrix[(i*size)+j] * vector[j]);

是什么结果[开始]?有人脱下堆。有时候,如果你是幸运的,这将是零。不要指望运气用C

What was result[] initially? It was pulled off the heap. Sometimes, if you are lucky, it will be zero. Don't count on luck with C.

有许多方式来初始化所述阵列。这里有几个办法,在顺序列出由最有可能被优化:

There are many ways to initialize the array. Here are a few approaches, listed in order by most likely to be optimized:

分配结果[]用calloc:

Allocate result[] with calloc:

double *result = calloc(chunk_size , sizeof(double));

或者初始化memset的数组:

Or, initialize the array with memset:

double *result = malloc(chunk_size *sizeof(double));
memset(result, 0, chunk_size *sizeof(double));

或,人们可以循环阵列上

or, one could loop over the array

for (i=0; i < chunk_size; i++)
    result[i] = 0.0

这篇关于MPI矩阵向量乘法的回报,有时正确有时怪异值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆