2011-01-19 3 views
3

私はMPIライブラリを使ってcでプログラムを書こうとしています。 私のプログラムでは、私はTSPを解決しています(ただし、特別なアルゴリズムはありません...)。 私の入力パラメータはint nCites,int xCoord[]およびint yCoord[]です。 私はCoordinatesにバンドルし、MPI_Bcastを使用してすべてのスレッドで利用できるようにしています。cでMPI_Reduceを使う

私の問題はこれです。各スレッドのすべてのパスの重みの計算が終わったら、それらを1つの結果、つまり最高のものに減らしたいと思います。私はMPI_Reduceを使用しようとしましたが、これは混乱し、セグメンテーションフォルト(スレッドの1つで、通常はroot)を引き起こします。

これは、メインコードと構造体である:

typedef struct Coordinates_t { 
    int* x; 
    int* y; 
    int n; 
} Coordinates; 

typedef struct PathAndLength_t { 
    int* path; 
    int pathSize; 
    int length; 
} PathAndLength; 

void comparePaths(void* a, void* b, int* len, MPI_Datatype* dataType) { 
    ... 
} 

int tsp_main(int nCites, int xCoord[], int yCoord[], int P[]){ 
    int numOfProcs, rank; 
    if (MPI_Comm_size(MPI_COMM_WORLD, &numOfProcs)) 
     throw "Error: MPI_Comm_size failed"; 
    if (MPI_Comm_rank(MPI_COMM_WORLD, &rank)) 
     throw "Error: MPI_Comm_rank failed"; 

    Coordinates crds; 
    crds.x = xCoord; 
    crds.y = yCoord; 
    crds.n = nCites; 

    MPI_Datatype data; 
    createInDataType(&crds, &data); 

    if (MPI_Bcast(&crds, 1, data, 0, MPI_COMM_WORLD)) 
     throw "Error: MPI_Comm_size failed"; 

     ... 

    PathAndLength* pal = (PathAndLength*)malloc(sizeof(PathAndLength)); 
    pal->path = (int*)malloc(sizeof(int)*crds.n); 

    pal->length = min_length; 
    for (int i = 0; i < crds.n; ++i) { 
     (pal->path)[i] = min_path[i]; 
    } 
    pal->pathSize = crds.n; 
    MPI_Datatype outDatatype; 
    MPI_Op op; 

    createOutDataType(pal, &outDatatype); 

    MPI_Op_create(&comparePaths, 1, &op); 

    PathAndLength* result = (PathAndLength*)malloc(sizeof(PathAndLength)); 
    result->path = (int*)malloc(sizeof(int)*crds.n); 
    MPI_Reduce(pal, result, crds.n, outDatatype, op, 0, MPI_COMM_WORLD); 

    ... 

    return result->length; 
} 

そして、これらは私が私のコードで使用createOutDataTypecreateInDataType、次のとおりですので、多くのコードを含むため

void createInDataType(Coordinates* indata, MPI_Datatype* message_type_ptr) { 
    // Build a derived datatype 
    int block_lengths[3]; 
    MPI_Aint displacements[3]; 
    MPI_Aint addresses[4]; 
    MPI_Datatype typelist[3]; 

    // First specify the types 
    typelist[0] = typelist[1] = typelist[2] = MPI_INT; 

    // Specify the number of elements of each type 
    block_lengths[0] = block_lengths[1] = indata->n; 
    block_lengths[2] = 1; 

    // Calculate the displacements of the members relative to indata 
    MPI_Address(indata, &addresses[0]); 
    MPI_Address(indata->x, &addresses[1]); 
    MPI_Address(indata->y, &addresses[2]); 
    MPI_Address(&indata->n, &addresses[3]); 
    displacements[0] = addresses[1] - addresses[0]; 
    displacements[1] = addresses[2] - addresses[0]; 
    displacements[2] = addresses[3] - addresses[0]; 

    // Create the derived type 
    MPI_Type_struct(3, block_lengths, displacements, typelist, message_type_ptr); 

    // Commit it so that it can be used 
    MPI_Type_commit(message_type_ptr); 
} 

void createOutDataType(PathAndLength* outdata, MPI_Datatype* message_type_ptr) { 
    // Build a derived datatype 
    int block_lengths[2]; 
    MPI_Aint displacements[2]; 
    MPI_Aint addresses[3]; 
    MPI_Datatype typelist[2]; 

    // First specify the types 
    typelist[0] = MPI_INT; 
    typelist[1] = MPI_INT; 

    // Specify the number of elements of each type 
    block_lengths[0] = outdata->pathSize; 
    block_lengths[1] = 1; 

    // Calculate the displacements of the members relative to outdata 
    MPI_Address(outdata, &addresses[0]); 
    MPI_Address(outdata->path, &addresses[1]); 
    MPI_Address(&outdata->length, &addresses[2]); 
    displacements[0] = addresses[1] - addresses[0]; 
    displacements[1] = addresses[2] - addresses[0]; 

    // Create the derived type 
    MPI_Type_struct(2, block_lengths, displacements, typelist, message_type_ptr); 

    // Commit it so that it can be used 
    MPI_Type_commit(message_type_ptr); 
} 

申し訳ありませんが、私は「couldn何があっても無関係なものを決める...
ありがとう。

答えて

3
PathAndLength* result = (PathAndLength*)malloc(sizeof(PathAndLength)); 
result->path = (int*)malloc(sizeof(int)*crds.n); 
MPI_Reduce(pal, result, crds.n, outDatatype, op, 0, MPI_COMM_WORLD); 

あなたはサイズsizeof(PathAndLength)の結果バッファにcrds.n*outDatatype Sを受けています。あなたにはデザイン上の欠陥があるようです。

+2

+1「outDatatype': 'MPI_Reduce(pal、result、1、outDatatype、op、0、MPI_COMM_WORLD); ' – suszterpatt

+0

これはここで起こっていることですか? 'outDatatype'が' result'に挿入され、 'crds.n'は私の便宜のためのパラメータに過ぎず、私の' MPI_Op'関数に送られるという印象を受けました。 ちょっと、12時間のデバッグがあります... RTFM huh? – hizki

+0

@susの可能性はほとんどありますが、PathAndLengthにはポインタメンバーがあります - mpiフレンドリーではありません – Anycorn

関連する問題