Я начал писать комментарий, но мне не хватило места, так что дальше. Во-первых, этот код компилируется и выполняется на имплементации HP-MPI, к которой у меня есть доступ:
#include <mpi.h>
int main(int argc, char* argv[])
{
MPI_Init(&argc, &argv);
int count = 2;
int lengths[] = { 1, 1 };
MPI_Aint disp[] = { 0, 0 };
MPI_Datatype types[] = { MPI_DOUBLE, MPI_CHAR };
MPI_Datatype weird_type;
MPI_Type_struct(count, lengths, disp, types, &weird_type);
MPI_Type_commit(&weird_type);
MPI_Finalize();
return 0;
}
Однако карта типов { (double, 0), (char,0) }
не будет вести себя как объединение: если вы отправляете данные с этой картой типов, тот же адрес памяти сначала будет интерпретироваться как double
, затем как char
, и оба значения будет отправлено (при условии, что реализация не взорвется).
Я могу думать только об одном вероятном случае использования для такого рода поведения: рассмотрим карту типов { (MPI_CHAR, 0), (MPI_BYTE,0) }
. Отправка переменной char
с использованием этого типа будет выполнять преобразование представления в первом случае, но не во втором: таким образом, вы можете проверить, одинакова ли кодировка символов на машине отправителя и получателя. Конечно, есть другие способы сделать это, но, тем не менее, опция есть. Хотя более вероятный сценарий состоит в том, что стандарт просто не касается экзотических особых случаев.
Кроме того, что касается отрицательных смещений: я фактически использовал их раньше, когда мне приходилось передавать данные из связанной структуры данных (например, графика). Это не для слабонервных, но вот псевдокод моего алгоритма:
std::vector<MPI_Aint> displacements;
for (each node n in the graph)
{
if ( n needs to be sent )
{
displacements.push_back(<MPI address of n>);
}
}
for (int i=0; i<displacements.size(); i++)
{
// compute the element #i's offset from the first one
displacements[i] -= displacements[0];
}
// create HIndexed datatype where blocks consist of one node,
// and begin at the memory addresses in 'displacements'
// send nodes as one element of the previously defined type,
// beginning at the address of the first node
Надеюсь, вы сможете увидеть важность отрицательных смещений оттуда: невозможно сказать, где находятся различные узлы в памяти, поэтому вполне возможно, что некоторые узлы будут в более ранних местоположениях, чем тот, в котором мы начинаем обход графика. 1016 *