- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试学习 MPI 并尝试使用示例。
我收到类似
的错误 Fatal error in PMPI_Scatter: Invalid buffer pointer, error stack:
PMPI_Scatter(783): MPI_Scatter(sbuf=0x6021e0, scount=16, MPI_INT, rbuf=0x6021e0, rcount=16, MPI_INT, root=0, MPI_COMM_WORLD) failed
PMPI_Scatter(710): Buffers must not be aliased
===================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= EXIT CODE: 1
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
我的代码是:
#include <mpi.h>
#include <stdio.h>
#define SIZE 8 /* Size of matrices */
#define MAX_RAND 100
int A[SIZE][SIZE], B[SIZE][1], C[SIZE][1],D[SIZE][SIZE],E[SIZE][1];
void fill_matrix(int m[SIZE][SIZE])
{
//static int n=0;
int i, j;
printf("\n*****************************\n");
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++){
m[i][j] = rand() % MAX_RAND;
printf("%2d ", m[i][j]);
}
printf("\n");
}
printf("\n*****************************\n");
}
void fill_vector(int m[SIZE][1])
{
//static int n=0;
int i, j;
printf("\n*****************************\n");
for (i=0; i<SIZE; i++)
{
for (j=0; j<1; j++){
m[i][j] = rand() % MAX_RAND;
printf("%2d ", m[i][j]);
}
printf("\n");
}
printf("\n*****************************\n");
}
void print_matrix(int m[SIZE][SIZE])
{
int i, j = 0;
for (i=0; i<SIZE; i++) {
printf("\n\t| ");
for (j=0; j<SIZE; j++)
printf("%2d ", m[i][j]);
printf("|");
}
}
void print_vector(int m[SIZE][1])
{
int i, j = 0;
for (i=0; i<SIZE; i++) {
printf("\n\t| ");
for (j=0; j<1; j++)
printf("%2d ", m[i][j]);
printf("|");
}
}
int main(int argc, char *argv[])
{
int myrank, P, from, to, i, j, k;
// int tag = 666; /* any value will do */
// MPI_Status status;
MPI_Init (&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank); /* who am i */
MPI_Comm_size(MPI_COMM_WORLD, &P); /* number of processors */
if (SIZE%P!=0) {
if (myrank==0) printf("Matrix size not divisible by number of processors\n");
MPI_Finalize();
exit(-1);
}
from = myrank * SIZE/P;
to = ((myrank+1) * SIZE/P);
/* Process 0 fills the input matrices and broadcasts them to the rest */
/* (actually, only the relevant stripe of A is sent to each process) */
if (myrank==0) {
{
//static int n=0;
int i, j;
printf("\n*****************************\n");
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++){
A[i][j] = rand() % MAX_RAND;
printf("%d ", A[i][j]);
}
printf("\n");
}
printf("\n*****************************\n");
}
fill_vector(B);
}
int s=SIZE*SIZE/P;
// printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
MPI_Bcast (B, SIZE*1, MPI_INT, 0, MPI_COMM_WORLD);
// printf("\n\n%d",s);
//print_vector(s);
//printf("\n\n");
MPI_Scatter (&A, SIZE*SIZE/P, MPI_INT, &A[from], SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
for (i=from; i<to; i++)
for (j=0; j<SIZE; j++) {
C[i][0]=0;
for (k=0; k<SIZE; k++){
C[i][0] += A[i][k]*B[k][0];
}
}
MPI_Gather (&C[from], SIZE*SIZE/P, MPI_INT, &C, SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
if (myrank==0) {
printf("\n\n");
{
int i, j = 0;
for (i=0; i<SIZE; i++) {
printf("\n\t| ");
for (j=0; j<SIZE; j++)
printf("%d ", A[i][j]);
printf("|");
}
}
printf("\n\n");
print_matrix(D);
printf("\n\n\t * \n");
print_vector(B);
printf("\n\n\t = \n");
print_vector(C);
printf("\n\n");
print_vector(E);
printf("\n\n");
}
MPI_Finalize();
return 0;
}
因为我是 JAVA 程序员,我对指针知之甚少,所以如果我的问题听起来很愚蠢,请原谅我,因为我还在学习。我在这里要做的是将 A 矩阵行拆分到不同的处理器并广播整个 B vector 并将两者相乘得到 C vector ,然后我想再次使用收集函数接收它。
最佳答案
您的代码产生了两件事:
如您所料,一个是与指针相关的错误。 MPI_Scatter()
需要指向要发送的数据的指针和指向接收数据的缓冲区的指针。例如,因为 A
是一个二维数组(在内存中是连续的):
MPI_Scatter (&A[0][0], SIZE*SIZE/P, MPI_INT, &A[from][0], SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
其中 &A[0][0]
是指向发送缓冲区的指针,&A[from][0]
是指向接收缓冲区的指针。
第二个问题在 MPI_Gather()
中。当然,也会出现与第一个错误相同的错误。此外,C
是 vector ,而不是矩阵:要发送的整数数量远低于 SIZE*SIZE/P
。因此,要发送的整数个数是SIZE/P
。
MPI_Gather (&C[from][0], SIZE/P, MPI_INT, &C[0][0], SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
其中 int C[SIZE][1]
是一个 vector 。
这是您的代码,稍作修改:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#define SIZE 8 /* Size of matrices */
#define MAX_RAND 100
int A[SIZE][SIZE], B[SIZE][1], C[SIZE][1];//D[SIZE][SIZE],E[SIZE][1];
void fill_matrix(int m[SIZE][SIZE])
{
//static int n=0;
int i, j;
printf("\n*****************************\n");
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++){
m[i][j] = rand() % MAX_RAND;
printf("%2d ", m[i][j]);
}
printf("\n");
}
printf("\n*****************************\n");
}
void fill_vector(int m[SIZE][1])
{
//static int n=0;
int i, j;
printf("\n*****************************\n");
for (i=0; i<SIZE; i++)
{
for (j=0; j<1; j++){
m[i][j] = rand() % MAX_RAND;
printf("%2d ", m[i][j]);
}
printf("\n");
}
printf("\n*****************************\n");
}
void print_matrix(int m[SIZE][SIZE])
{
int i, j = 0;
for (i=0; i<SIZE; i++) {
printf("\n\t| ");
for (j=0; j<SIZE; j++)
printf("%2d ", m[i][j]);
printf("|");
}
}
void print_vector(int m[SIZE][1])
{
int i, j = 0;
for (i=0; i<SIZE; i++) {
printf("\n\t| ");
for (j=0; j<1; j++)
printf("%2d ", m[i][j]);
printf("|");
}
}
int main(int argc, char *argv[])
{
int myrank, P, from, to, i, j, k;
// int tag = 666; /* any value will do */
// MPI_Status status;
MPI_Init (&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank); /* who am i */
MPI_Comm_size(MPI_COMM_WORLD, &P); /* number of processors */
if (SIZE%P!=0) {
if (myrank==0) printf("Matrix size not divisible by number of processors\n");
MPI_Finalize();
exit(-1);
}
from = myrank * SIZE/P;
to = ((myrank+1) * SIZE/P);
/* Process 0 fills the input matrices and broadcasts them to the rest */
/* (actually, only the relevant stripe of A is sent to each process) */
if (myrank==0) {
//static int n=0;
int i, j;
printf("\n*****************************\n");
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++){
A[i][j] = rand() % MAX_RAND;
printf("%d ", A[i][j]);
}
printf("\n");
printf("\n*****************************\n");
}
fill_vector(B);
}
//int s=SIZE*SIZE/P;
// printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
MPI_Bcast (B, SIZE*1, MPI_INT, 0, MPI_COMM_WORLD);
// printf("\n\n%d",s);
//print_vector(s);
//printf("\n\n");
if(myrank==0){
MPI_Scatter (&A[0][0], SIZE*SIZE/P, MPI_INT, MPI_IN_PLACE, SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
}else{
MPI_Scatter (&A[0][0], SIZE*SIZE/P, MPI_INT, &A[from][0], SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
}
printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
for (i=from; i<to; i++)
for (j=0; j<SIZE; j++) {
C[i][0]=0;
for (k=0; k<SIZE; k++){
C[i][0] += A[i][k]*B[k][0];
}
}
if(myrank==0){
MPI_Gather (MPI_IN_PLACE, SIZE/P, MPI_INT, &C[0][0], SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
}else{
MPI_Gather (&C[from][0], SIZE/P, MPI_INT, &C[0][0], SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
}
if (myrank==0) {
printf("\n\n");
{
int i, j = 0;
for (i=0; i<SIZE; i++) {
printf("\n\t| ");
for (j=0; j<SIZE; j++)
printf("%d ", A[i][j]);
printf("|");
}
}
printf("\n\n");
// print_matrix(D);
printf("\n\n\t * \n");
print_vector(B);
printf("\n\n\t = \n");
print_vector(C);
printf("\n\n");
// print_vector(E);
// printf("\n\n");
}
MPI_Finalize();
return 0;
}
可以通过mpicc main.c -o main -Wall
编译,通过mpirun -np 4 main
运行。
我想 srand()
没有被用来获得可重现的结果。如果您计划使用更大的数组,则需要分配它们。如果是这样,请查看以下问题:sending blocks of 2D array in C using MPI
编辑:我应该注意到发送缓冲区和接收缓冲区是相同的。这称为缓冲区别名(参见 Mvapich2 buffer aliasing),必须使用标记 MPI_IN_PLACE
(参见 How does MPI_IN_PLACE work with MPI_Scatter?)。上面的代码相应地进行了修改。很抱歉之前的回答不完整!
关于c - MPI_Scatter 和 Gather 用于 MPI 中的二维矩阵,使用 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33507024/
我想发送二维数组的列,每个列到单独的进程。我现在有一个完整的 2d 数组,但我被 MPI_Scatter 困住了。如何将整列作为字段发送? 谢谢 编辑: 我有数组 - float a[100][101
我正在尝试修改我的程序,以便代码看起来更好。现在我正在使用 MPI_Send 和 MPI_Recv,但我正在尝试使其与 MPI_Scatter 一起使用。我有一个名为 All_vals 的数组,我尝试
我正在开发一个并行排序程序来学习 MPI,但我一直在使用 MPI_Scatter 时遇到问题。每次我尝试运行时,我都会得到以下信息: reading input Scattering input _p
我知道,在处理 openMpi 时没有全局变量的概念/含义,因此当特定线程正在更改变量时,该变量的值仍将设置为其他进程中的默认值。我知道 MPI_Scatter() 的功能。 当我使用这样的东西时,
我是 MPI 世界的新手,我有点困惑.. 我使用“MPI_Scatter”将数组“分解”成多个部分。但情况是...它可以在多台机器上运行该程序吗? 我的观点是:我是否必须使用 MPI_Send 和 M
我有一个分配在连续内存空间中的动态二维数组,但是如果我尝试使用 MPI_Scatter 将该数组分散到两个 MPI 进程中,将导致段错误,整个代码粘贴在这里: dynamic_2d_array.h #
我是 MPI 的新手,我正在尝试编写使用 MPI_scatter 的程序。我有 4 个节点(0、1、2、3)。 Node0是master,其他都是slave。 Master 询问用户要发送给 slav
我正在尝试通过同一个通信器,使用非阻塞版本的通信,将两个不同的、独立的数组从等级 0 分散到所有其他数组。 沿着这些线的东西: //do some stuff with arrays here...
我想使用这种特定的内存分配方式将一个二维数组分散到其他二维数组中(每个进程一个)。 int (*matrix)[cols] = malloc(sizeof *matrix* rows); 我一直收到
我有这个串行代码,我正在尝试使用 MPI 将其转换为并行代码。但是,我似乎无法让 MPI_Scatter() 函数在不崩溃的情况下正常工作。该函数遍历名为 cells 的数组并修改一些值。 下面是原始
我正在使用 MPI 编写我的第一个程序,我很难尝试使用 MPI_Scatter 将数据正确发送到其他进程,修改它们并使用 MPI_Gather 接收值。代码如下: int** matrix; int
我正在尝试使用 MPI 库解决一个简单的程序。 进程0上存储了4*N×4*N的矩阵,矩阵每边的长度为DIM LEN = 4*N。我需要创建一个对角数据类型。但是,数据类型应该只覆盖对角线上的 N 个连
伙计们!我写了一段代码,用 MPI 计算两个巨大 vector 的标量积。首先,等级为 0 的进程创建两个随机 vector ,并通过 MPI_Scatter 将其发送给其余进程。之后,他们计算部分和
我的第一个想法是MPI_Scatter并且应该在if(proc_id == 0)子句中使用发送缓冲区分配,因为数据应该只分散一次并且每次进程只需要发送缓冲区中的一部分数据,但它无法正常工作。 看来,在
我正在学习 OpenMPI。尝试了一个简单的 MPI_Scatter 示例: #include using namespace std; int main() { int numProcs,
我的问题很简单,MPI_Scatter函数定义是: #include void MPI::Comm::Scatter(const void* sendbuf, int sendcount, cons
我正在尝试找到随机生成的数字的最大值。对此有任何想法... 我正在使用 MPI_Scatter 将随机生成的数字分成相等的进程。我正在使用 MPI_Reduce 从每个进程中获取最大值。 #inclu
我对 MPI_Scatter 有疑问。不知道如何使用它,我当前的程序在启动时因段错误而崩溃。 我猜 MPI_Scatter 的参数存在问题,尤其是在使用正确的运算符(& 或 * 或 void)调用它时
我是 mpi 编程的新手。我刚刚在 c 中使用 mpi_scatter 尝试了一个并行搜索程序。我想知道我的程序是否正确。但是当我执行一个没有 MPI_SCATTER 的程序时,即线性搜索,与并行程序
我正在尝试使用 MPI 编写矩阵 vector 乘法程序。我正在尝试将矩阵的列发送到单独的进程并在本地计算结果。最后,我使用 MPI_SUM 操作执行了 MPI_Reduce。 发送矩阵的行很容易,因
我是一名优秀的程序员,十分优秀!