0

私は構造体を持っています:

typedef struct 
{ 
double distance;
int* path;
} tour;

次に、すべてのプロセスから結果を収集しようとしています。

   MPI_Gather(&best, sizeof(tour), MPI_BEST, all_best, sizeof(tour)*proc_count, MPI_BEST, 0, MPI_COMM_WORLD);

ルートを収集した後、all_bestには通常の要素が1つだけ含まれ、他の要素にはゴミが含まれていることを確認してください。all_bestのタイプはツアー*です。

MPI_BESTの初期化:

 void ACO_Build_best(tour *tour,int city_count, MPI_Datatype *mpi_type /*out*/)
 {
int block_lengths[2];
MPI_Aint displacements[2];
MPI_Datatype typelist[2];
MPI_Aint start_address;
MPI_Aint address;

block_lengths[0] = 1;
block_lengths[1] = city_count;

typelist[0] = MPI_DOUBLE;
typelist[1] = MPI_INT;

MPI_Address(&(tour->distance), &displacements[0]);
MPI_Address(&(tour->path), &displacements[1]);

displacements[1] = displacements[1] - displacements[0];
displacements[0] = 0;

MPI_Type_struct(2, block_lengths, displacements, typelist, mpi_type);
MPI_Type_commit(mpi_type);
}

どんなアイデアでも大歓迎です。

4

1 に答える 1

3

に誤った長さを渡すことは別としてMPI_Gather、MPI は実際にはポインターへのポインターに従いません。このような構造化型を使用するdistanceと、値とpathポインターの値を送信することになります (基本的に、他のプロセスに送信されると意味をなさないアドレス)。distance基本的に の要素数が得られると仮定すると、とpathの組み合わせで目標を達成できます。MPI_GatherMPI_Gatherv

まず、長さを収集します。

int counts[proc_count];

MPI_Gather(&best->distance, 1, MPI_INT, counts, 1, MPI_INT, 0, MPI_COMM_WORLD);

counts正しい長さが入力されたので、引き続き使用MPI_Gathervしてすべてのパスを受け取ることができます。

int disps[proc_count];

disps[0] = 0;
for (int i = 1; i < proc_count; i++)
   disps[i] = disps[i-1] + counts[i-1];
// Allocate space for the concatenation of all paths
int *all_paths = malloc((disps[proc_count-1] + counts[proc_count-1])*sizeof(int));
MPI_Gatherv(best->path, best->distance, MPI_INT,
            all_paths, counts, disps, MPI_INT, 0, MPI_COMM_WORLD);

これで、 のすべてのパスが連結されましたall_paths。の位置からcounts[i]始まる要素を取得することで、個々のパスを調べたり抽出したりできます。または、構造体の配列を構築して、すでに割り当てられ、入力されているパス ストレージを使用することもできます。disps[i]all_pathstour

tour *all_best = malloc(proc_count*sizeof(tour));
for (int i = 0; i < proc_count; i++)
{
   all_best[i].distance = counts[i];
   all_best[i].path = &all_paths[disps[i]];
}

または、代わりにセグメントを複製できます。

for (int i = 0; i < proc_count; i++)
{
   all_best[i].distance = counts[i];
   all_best[i].path = malloc(counts[i]*sizeof(int));
   memcpy(all_best[i].path, &all_paths[disps[i]], counts[i]*sizeof(int));
}
// all_paths is not needed any more and can be safely free()-ed

編集:構造の定義を見落としていたためtour、上記のコードは実際には次のように機能します。

struct
{
   int distance;
   int *path;
}

どこdistanceで の重要な要素の数を保持しpathます。これはあなたのケースとは異なりますが、どのようtour.pathに割り当てられているか (およびサイズ設定されているか) に関する情報がなければ、特定の解決策を提供するのは困難です。

于 2012-12-07T13:12:21.087 に答える