Пример 4.11 Обратен примеру 4.2, MPI_SCATTER рассылает 100 чисел типа int из корневого процесса каждому процессу в группе (рис. 4.7).
MPI_Comm comm;
int gsize,*sendbuf;
int root, rbuf[100];
...
MPI_Comm_size(comm, &gsize);
sendbuf = (int *)malloc(gsize*100*sizeof(int));
...
MPI_Scatter(sendbuf, 100, MPI_INT, rbuf, 100, MPI_INT, root, comm);
Пример 4.12 Обратен примеру 4.5. Корневой процесс рассылает множества из 100 чисел типа int остальным процессам, но множества размещены в посылающем буфере с шагом stride, поэтому нужно использовать MPI_SCATTERV. Полагаем stride > 100 (рис. 4.8).
MPI_Comm comm;
int gsize,*sendbuf;
int root, rbuf[100], i, *displs, *scounts;
...
MPI_Comm_size(comm, &gsize);
sendbuf = (int*)malloc(gsize*stride*sizeof(int));
...
displs = (int*)malloc(gsize*sizeof(int));
scounts = (int*)malloc(gsize*sizeof(int));
for (i=0; i<gsize; ++i) {
displs[i] = i*stride;
scounts[i] = 100;
}
MPI_Scatterv(sendbuf, scounts, displs, MPI_INT, rbuf, 100,
MPI_INT, root, comm);
Пример 4.13 Обратен примеру 4.9, на стороне корневого процесса используется изменяющийся stride между блоками чисел, на приемной стороне производится прием в i-й столбец С-массива размера 100x150 (рис. 4.9).
MPI_Comm comm;
int gsize,recvarray[100][150],*rptr;
int root, *sendbuf, myrank, bufsize, *stride;
MPI_Datatype rtype;
int i, *displs, *scounts, offset;
...
MPI_Comm_size(comm, &gsize);
MPI_Comm_rank(comm, &myrank);
stride = (int *)malloc(gsize*sizeof(int));
...
/* stride[i] for i = 0 to gsize-1 is set somehow
* sendbuf comes from elsewhere
*/
...
displs = (int*)malloc(gsize*sizeof(int));
scounts = (int*)malloc(gsize*sizeof(int));
offset = 0;
for (i=0; i<gsize; ++i) {
displs[i] = offset;
offset += stride[i];
scounts[i] = 100 - i;
}
/* создается тип данных для посылаемого столбца
*/
MPI_Type_vector(100-myrank, 1, 150, MPI_INT, &rtype);
MPI_Type_commit(&rtype);
rptr = &recvarray[0][myrank];
MPI_Scatterv(sendbuf, scounts, displs, MPI_INT, rptr,
1, rtype, root, comm);