我正在尝试学习C和MPI,这个程序计算n个浮点数的总和。但我有一个错误:
/home/xx/PRIMO/primo.exe:free():下一个大小无效(快):0x000000000109bda0 /home/xx/PRIMO/primo.exe:free():下一个大小无效(快):0x00000000024fada0
2天我不知道转向哪个方向。这个程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "mpi.h"
#define HOST 0
// prototypes
void initialize( int argc, char *argv[] );
float *create_array( int n );
void data_scatter( float *numbers, float *numbers_loc, int packet_size, int rest );
void validations();
// global vars
int menum, nproc, namelen;
int main(int argc, char *argv[]) {
initialize( argc, argv );
if( menum == HOST ) printf("Program started\n");
if( menum == HOST ) validations();
// ****** Declaring variebles ******
int n, tag, packet_size, rest, j, i;
float *numbers, *numbers_loc;
float sum = 0.0;
numbers_loc = (float*) calloc( packet_size, sizeof (float) );
MPI_Status info;
// ****** data distribution ******
scanf("%d", &n);
if( menum == HOST ) numbers = create_array( n );
MPI_Bcast( &n, 1, MPI_INT, 0, MPI_COMM_WORLD );
double start_time = MPI_Wtime();
packet_size = n / nproc;
rest = n % nproc;
if( menum < rest ) ++packet_size;
data_scatter( numbers, numbers_loc, packet_size, rest );
// ****** partial sums, first level ******
for( j = 0; j < packet_size; j++) {
sum += numbers_loc[j];
}
free(numbers_loc);
// ****** iterating phase ******
for( i = 0; i < log2(nproc); i++) {
int pow1 = (int) pow(2, i);
tag = pow1 + 15;
if( (menum % pow1) == 0) {
int pow2 = (int) pow(2,i+1);
if( (menum % pow2) == 0 ) {
float other_sum = 0;
MPI_Recv( &other_sum, 1, MPI_INT, menum + pow1, tag, MPI_COMM_WORLD, &info );
sum += other_sum;
} else {
MPI_Send( &sum, 1, MPI_INT, menum - pow1, tag, MPI_COMM_WORLD );
}
}
}
// ****** printing result ******
if( menum == HOST ) {
printf( "TOTAL SUM: %.2f\n", sum);
}
double end_time = MPI_Wtime();
double time = end_time - start_time;
double max = 0;
printf( "%d time %f\n", menum, time );
MPI_Reduce( &time, &max, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD );
if(menum == HOST) printf( "%d max time %f\n", menum, max );
printf("Program terminated\n");
MPI_Finalize();
return 0;
}
void initialize( int argc, char *argv[] ) {
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&menum);
MPI_Comm_size(MPI_COMM_WORLD,&nproc);
}
float *create_array( int n ) {
float sequenzial_sum = 0;
int i;
printf("Creating Array of dimension: %d\n", n);
float *array = (float*) calloc( n, sizeof(float));
srand( time(NULL) );
for( i=0; i < n; i++) {
array[i] = ((float) rand())/ ((float) RAND_MAX);
sequenzial_sum += array[i];
printf("-%f-", array[i]);
}
printf("\n");
printf("Array creation terminated, sum = %.2f \n", sequenzial_sum);
return array;
}
void data_scatter( float *numbers, float *numbers_loc, int packet_size, int rest ) {
MPI_Status info;
int start = 0, offset = packet_size, i, tag;
if( menum == HOST ) {
memcpy(numbers_loc, numbers, packet_size * sizeof(float));
for( i=1; i < nproc; i++ ) {
start += offset;
if( rest == i) --offset;
tag = 22 + i;
MPI_Send( &numbers[start], offset, MPI_INT, i, tag, MPI_COMM_WORLD );
}
free(numbers);
} else {
tag = 22 + menum;
MPI_Recv( numbers_loc, packet_size, MPI_INT, 0, tag, MPI_COMM_WORLD, &info );
}
}
void validations() {
if( ( fmod(log2( nproc ), 1.0) != 0 )) {
printf("CPU number must ne a power of 2\n");
MPI_Abort( MPI_COMM_WORLD, -1 );
}
}
答案 0 :(得分:4)
int n, tag, packet_size, rest, j, i;
float *numbers, *numbers_loc;
float sum = 0.0;
numbers_loc = (float*) calloc( packet_size, sizeof (float) );
我不确定我是否在这里遗漏了一些内容,但packet_size
在没有初始化的情况下使用。使用-Wall
进行编译实际上会向您发出警告。
-Wall
还会警告您错过了<time.h>
标头文件。
答案 1 :(得分:-1)
// global vars
`int menum, nproc, namelen;`
// ****** Declaring variebles ******
// int n, tag, packet_size, rest, j, i;
packet_size没有定义,所以它将是垃圾值,未定义的行为,calloc不需要成功100%
`numbers_loc = (float*) calloc( packet_size, sizeof (float) );`
`packet_size = n / nproc;
` 全局变量nproc将初始化为0并将某个数字除以0这应该抛出异常。
`rest = n % nproc;`
上述声明也是不允许的。 我不知道是否有任何机制来压制上述错误,然后如果控制权来自以下陈述
`// ****** partial sums, first level ******
for( j = 0; j < packet_size; j++) {
sum += numbers_loc[j];
} `
numbers_loc将被破坏,因为packet_size未定义且numbers_loc分配有垃圾大小。
free(numbers_loc);