2012-04-22 18 views
0

私はCとMPIを学ぼうとしていますが、このプログラムはn個の浮動小数点の合計を計算します。MPI、calloc and free:

/home/xx/PRIMO/primo.exe::無料():無効次のサイズ(速い):0x000000000109bda0 /home/xx/PRIMO/primo.exe:無料():無効なしかし、私はエラーを持っています次のサイズ(速い):0x00000000024fada0

どのような向きにするのか分かりません。ここではプログラム:

#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); 

    } 

} 

答えて

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>ヘッダーファイルがないことを警告します。それがジャンク値、未定義の動作になるよう

+2

新しいコードでは、一般的に '-Wall -Wextra -Werror'を使用することをお勧めします。これは、あなたがこれらの種類の問題を捕らえるのを助け、 '-Werror'は新しい問題が導入されたときに実際に気づくように(実際には問題ではないとしても)すべての警告を実際に修正することを意味します。 –

+0

ありがとうございます。私はちょっと愚かです:) – Antonio

-1
// global vars 
`int menum, nproc, namelen;` 
// ****** Declaring variebles ****** 
// int n, tag, packet_size, rest, j, i; 

PACKET_SIZEは、のcallocは

`numbers_loc = (float*) calloc(packet_size, sizeof (float));` 
`packet_size = n/nproc; 

` グローバル変数NPROCが0に初期化することによって、いくつかの数を割ることになる100%成功する必要はなく、定義されていません。 0これは例外をスローするはずです。

`rest = n % nproc;` 

上記の文も許可されません。 私は、エラーの上を抑圧するための任意のメカニズムがある場合は、その後、制御はPACKET_SIZEが未定義であるとnumbers_locがジャンクサイズで割り当てられているよう

`// ****** partial sums, first level ****** 
for(j = 0; j < packet_size; j++) { 
    sum += numbers_loc[j]; 
} ` 

numbers_locが破損される文

以下になれば知りません。 free(numbers_loc);

+3

答えを読めるようにしてください... – 11684