______,永远滴神! 2021-03-20 15:30 采纳率: 0%
浏览 139

Fatal error in MPI_Scatter: Invalid buffer pointer

随机生成方阵与向量并让他们相乘的代码,当矩阵维数大于int的限制(所以用了long)就会出现这个报错,为什么?

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "mpi.h"
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <malloc.h>
#include <stdlib.h>

//produce random number in a certain range
double frand(double fmin, double fmax)
{
    double f = (double)rand() / ((double)RAND_MAX + 1.0);
    return fmin + f * (fmax - fmin);
}

int main(int argc, char* argv[])
{
    int numprocs, myid, namelen, a;
    long i, j, k, l, N1 = 0, N = 0, N2 = 0, part = 0;
    char procs_name[MPI_MAX_PROCESSOR_NAME];
    double* matrix_A, * part_A, * vector_b, * answer, * vector_c;
    double time1, time2, time3, time4;
    double sqr_sum = 0, A = 0;//normalization factor
    double* norm_vector, * norm_c;
    FILE* fp = fopen("time.txt", "a");

    //MPI initialization
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Get_processor_name(procs_name, &namelen);

    fprintf(stdout, "Process %d of %d on %s\n", myid, numprocs, procs_name);
    fflush(stdout);

    //define matrix_A and vector_b
    if (myid == 0)
    {
        printf("Enter a vector dimension:");
        fflush(stdout);
        scanf_s("%ld", &N1);
        time1 = MPI_Wtime();
        a = N1 % numprocs;
        printf("%d\n", a);
        if (a > 0)
        {
            N = N1 + a;
        }
        else
        {
            N = N1;
        }
        N2 = N * N1;
        part = N / numprocs;
    }
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&N2, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&N1, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&part, 1, MPI_INT, 0, MPI_COMM_WORLD);

    //prepare for matrix_A and vectors
    matrix_A = (double*)malloc(sizeof(double) * N2);
    vector_b = (double*)malloc(sizeof(double) * N1);
    part_A = (double*)malloc(sizeof(double) * N2);
    answer = (double*)malloc(sizeof(double) * N);
    vector_c = (double*)malloc(sizeof(double) * N);
    if (myid == 0)
    {
        for (j = 0; j < N2; j++)
        {
            if (j < N1 * N1)
                matrix_A[j] = frand(0.0, 5.0);//save matrix_A as a one-dimension array
            else
                matrix_A[j] = 0;
        }
        for (k = 0; k < N1; k++)
        {
            vector_b[k] = frand(0.0, 5.0);
        }
        for (l = 0; l < N; l++)
        {
            answer[l] = 0;
        }
    }
    
    //distribution
    MPI_Bcast(vector_b, N1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(answer, N, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Scatter(matrix_A, part * N1, MPI_DOUBLE, part_A, part * N1, MPI_DOUBLE, 0, MPI_COMM_WORLD);

    if (myid == 0)
        time2 = MPI_Wtime();

    //Multiplication
    for (i = myid * part * N1; i < (myid + 1) * part * N1; i++)
    {
        answer[i / N1] += part_A[i] * vector_b[i % N1];
    }
    MPI_Allreduce(answer, vector_c, N, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
    if (myid == 0)
        time3 = MPI_Wtime();

    //normalize vector_c
    for (i = myid; i < N; i += numprocs)
    {
        sqr_sum += vector_c[i] * vector_c[i];
    }
    MPI_Allreduce(&sqr_sum, &A, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
    A = sqrt(A);//normalization factor
    norm_vector = (double*)malloc(sizeof(double) * N);
    norm_c = (double*)malloc(sizeof(double) * N);
    for (j = 0; j < N; j++)
    {
        norm_vector[j] = 0;
    }
    for (i = myid; i < N; i += numprocs)
    {
        norm_vector[i] = vector_c[i] / A;
    }
    MPI_Allreduce(norm_vector, norm_c, N, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
    if (myid == 0)
    {
        time4 = MPI_Wtime();
        printf("Time of computing and normalization is %f\t", time4 - time2);
        printf("\tTime of total process is %f\n", time4 - time1);
        printf("Number of processes is %d\n", numprocs);
        fprintf(fp, "%f\t%f\t%d\t%ld\n", time4 - time2, time4 - time1, numprocs, N1);
        fclose(fp);
    }
    MPI_Barrier(MPI_COMM_WORLD);
    free(matrix_A);
    free(vector_b);
    free(vector_c);
    free(answer);
    free(norm_vector);
    free(norm_c);
    free(part_A);
    MPI_Finalize();
    return 0;
}

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-07-24 00:02
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    在你的程序中,你使用了MPI_Scatter函数来传递数组到其他节点。但是,在传递过程中,有一个错误:MPI_Scatter函数要求一个合法的缓冲区指针作为参数,但是在传递的过程中,没有提供这样的指针。

    在你的程序中,当你将矩阵和向量传递给MPI_Scatter时,你需要指定每个元素应该存储在哪里。你应该创建一个新的数组,而不是直接使用原始的矩阵或向量数组。

    此外,你也需要确保你正确地初始化这些新分配的数组,并且它们能够正确地接收来自其他节点的数据。例如,你可以尝试以下修改:

    // Prepare the new arrays for storage
    
    // Initialize the matrices and vectors
    if (myid == 0)
    {
        matrix_A = (double*)malloc(N2 * sizeof(double));
        vector_b = (double*)malloc(N1 * sizeof(double));
        part_A = (double*)malloc(N2 * sizeof(double));
        answer = (double*)malloc(N * sizeof(double));
        vector_c = (double*)malloc(N * sizeof(double));
    
        // Fill the new arrays with data
        for (j = 0; j < N2; j++) 
        {
            if (j < N1 * N1)
                matrix_A[j] = frand(0.0, 5.0); // save matrix_A as a one-dimensional array
            else
                matrix_A[j] = 0;
    
            vector_b[j % N1] = frand(0.0, 5.0);
        }
    
        for (k = 0; k < N1; k++) 
        {
            vector_b[N1 * k] = frand(0.0, 5.0);
        }
    
        for (l = 0; l < N; l++) 
        {
            answer[l] = 0;
        }
    }
    
    // Distribute the data across all nodes
    MPI_Bcast(vector_b, N1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(answer, N, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    
    // Scatter the data from the root node to all other nodes
    MPI_Scatter(matrix_A, part * N1, MPI_DOUBLE, part_A, part * N1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    

    这段代码首先定义了一个新的矩阵和向量数组,然后将它们传递给MPI_Scatter函数,这样就可以避免出现Invalid buffer pointer错误。

    评论

报告相同问题?