MPI를 처음 접했고 이것이 올바른 접근 방법인지 확신 할 수 없습니다. 또는이 방식으로 MPI를 사용해야하지만 내 문제는 다음과 같습니다.구조체 배열의 각 요소에 대한 mpi 통신기
사용자 정의 구조에 대한 포인터 배열이 있습니다. 각 프로세스에서 어떤 일이 일어나고 있는지에 따라 배열 요소는 NULL이거나 사용자 정의 구조의 인스턴스에 대한 포인터 일 수 있습니다. 이제 MPI를 통해 서로 통신하기 위해 배열의 요소가 필요합니다. 일부는 존재하지 않기 때문에 이것은 문제가됩니다.
나는 정교해야한다 : 구조는 통신이 일어날 필요가있는 기능에 대한 포인터를 가지고있다. 요소가 있으면 함수가 호출됩니다. 그렇지 않은 경우.
내 아이디어 : 요소가 NOT NULL 인 모든 프로세서를 포함하는 배열의 각 요소에 전용 MPI 통신기를 만듭니다. 그런 다음 해당 요소에 대한 통신 중에이 통신기를 참조하십시오.
배열의 각 요소에 대해 하나씩 MPI 통신기의 "배열"을 만들 수 있습니까? 그리고 나서 각 요소에 대해 MPI_COMM_ARRAY [i]를 참조 하시겠습니까? 아니면 완전히 막 다른 길에 있고 배열 엔트리로서 NULL을 사용하면 안된다. 이것을 "깔끔하게"코딩하는 방법은 무엇입니까?
이것은 내가 지금 가지고있는 것의 단순화입니다. 우연히 모든 프로세스에서 셀이 존재하면 작동합니다. 그렇지 않으면 실패합니다. 예제 코드 :
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
void * createcell();
void Cell_givenumberofvertices(void * _self, int * NbOfVertices);
void Cell_givenumberofvertices_parallel(void * _self, int * NbOfVertices);
void Cell_addvertex(void * _self);
void addvertex(void * _self);
void getnumberofvertices(void * _self, int * NbOfVertices);
struct Cell{
unsigned NbOfVertices;
void (* givenumberofvertices)(void * _self, int * NbOfVertices);
void (* addvertex)(void * _self);
};
void * createcell(){
struct Cell * self = calloc(1, sizeof(struct Cell));
int world_size;
MPI_Comm_size(MPI_COMM_WORLD,&world_size);
self->NbOfVertices = 0;
self->addvertex = Cell_addvertex;
if(world_size==0) self->givenumberofvertices = Cell_givenumberofvertices;
else self->givenumberofvertices = Cell_givenumberofvertices_parallel;
return self;
}
void Cell_givenumberofvertices(void * _self, int * NbOfVertices){
struct Cell * self = _self;
* NbOfVertices = self->NbOfVertices;
return;
}
void Cell_givenumberofvertices_parallel(void * _self, int * NbOfVertices){
struct Cell * self = _self;
int world_size, world_rank;
int i;
int * NbVertxOnProcess;
int totalnumberofvertices=0;
MPI_Comm_size(MPI_COMM_WORLD,&world_size);
MPI_Comm_rank(MPI_COMM_WORLD,&world_rank);
NbVertxOnProcess = (int *) malloc(world_size*sizeof(int));
MPI_Gather(&(self->NbOfVertices),1,MPI_UNSIGNED,NbVertxOnProcess,1,MPI_INT,0,MPI_COMM_WORLD);
for(i=0;i<world_size;i++) totalnumberofvertices+=NbVertxOnProcess[i];
* NbOfVertices = totalnumberofvertices;
return;
}
void Cell_addvertex(void * _self){
struct Cell * self = _self;
self->NbOfVertices ++;
return;
}
void addvertex(void * _self){
struct Cell * self = _self;
self->addvertex(self);
}
void getnumberofvertices(void * _self, int * NbOfVertices){
struct Cell * self = _self;
self->givenumberofvertices(self, NbOfVertices);
}
int main(int argc, char *argv[]) {
void ** cells;
int i,j;
const int numberofcells = 100;
const int numberofvertices = 100;
const float domainlength = 115.4;
float grid[numberofcells];
float vertexcoordinates[numberofvertices];
int world_rank;
MPI_Init(NULL,NULL);
/* create array of Cell pointers */
cells = (void **) calloc(numberofcells,sizeof(void *));
/* create grid */
for(i=0;i<numberofcells;i++){
grid[i]=domainlength/numberofcells*(i+1);
}
/* generate random vertex coordinates */
MPI_Comm_rank(MPI_COMM_WORLD,&world_rank);
srand((unsigned int) world_rank);
for(i=0;i<numberofvertices;i++){
vertexcoordinates[i]=((float)rand()/(float)(RAND_MAX)) * domainlength;
}
/* find the cell the vertex is in */
for(i=0;i<numberofvertices;i++){
for(j=0;j<numberofcells;j++){
float lb, ub;
if(j==0) lb=0.0;
else lb=grid[j-1];
ub = grid[j];
if(lb<vertexcoordinates[i]&&vertexcoordinates[i]<ub){
if(!cells[j]){
cells[j]=createcell();
}
addvertex(cells[j]);
}
}
}
for(i=0;i<numberofcells;i++){
if(cells[i]){
int NbVertxInCell;
getnumberofvertices(cells[i], &NbVertxInCell);
printf("%i vertices in cell number %i \n",NbVertxInCell,i);
}
}
MPI_Finalize();
return 0;
}
몇 가지 코드를 제시해주십시오 수 있습니다 될 수있다, 당신의 설명은 따라하기가 매우 어렵다.예를 들어 "사용자 정의 구조체 배열"은 사용자 정의 구조체에 대한 배열로 간주됩니다. –
충분히 공정하게, 나는 그것이 지금 더 분명하기를 바란다. 문제는 * Cell_givenumberofvertices_parallel() * –