Я пытаюсь отправить / recv в C ++ структуру данных, которая выглядит следующим образом:
/* PSEUDOCODE */
const int N = getN(); // not available at compile time
const int M = getM();
struct package{
int foo;
double bar;
/* I know array members do not work this way,
this is pseudocode. */
int flop[N];
double blep[M];
};
Поскольку M
и N
являются постоянными во время выполнения, я могу сделать MPI_Type_create_struct()
, и новый тип данных будет хорошим во всем.
Мой вопрос заключается в том, как реализовать структуру данных, как описано выше.
std::vector<>
не будет работать, потому что он не последовательный.
Гибкие члены массива, такие как []
или [0]
, имеют неопределенное поведение в c ++ и не работают для двух из M
и N
.
Так что вместо этого я должен использовать malloc()
:
class Package {
public:
// in buffer[]: bar, blep[], foo, flop[]
// in that order and one directly follows another.
Package():
buffer((double*) malloc((M + 1) * sizeof(double) +
(N + 1) * sizeof(int))),
bar(buffer), blep(buffer + 1),
foo((int*) (blep + M)),
flop(foo + 1) {}
~Package(){
free(buffer);
}
// construct / free the derived datatype
static void initialize(unsigned inN, unsigned inM) {
N = inN;
M = inM;
MPI_Aint offsets[2] = {0, (int)(sizeof(double)) * (M + 1)};
int blocks[2] = {M + 1, N + 1};
MPI_Datatype types[2] = {MPI_DOUBLE, MPI_INT};
MPI_Type_create_struct(2, blocks, offsets, types, &packageType);
MPI_Type_commit(&packageType);
}
static void finalize() {
MPI_Type_free(&packageType);
}
int send(int rank, int tag) {
return MPI_Send(buffer, 1, packageType,
rank, tag, MPI_COMM_WORLD);
}
int recv(int rank, int tag) {
return MPI_Recv(buffer, 1, packageType,
rank, tag, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
}
private:
double * buffer;
static int M;
static int N;
static MPI_Datatype packageType;
public:
// interface variables
double * const bar;
double * const blep;
int * const foo;
int * const flop;
};
int Package::N = 0;
int Package::M = 0;
MPI_Datatype Package::packageType = MPI_CHAR;
Я протестировал приведенный выше код, и он, кажется, работает должным образом, но я не уверен, что делаю что-то, что на самом деле является неопределенным поведением. В частности:
Можно ли использовать sizeof()
для MPI_Type_create_struct()
? Некоторые примеры, которые я нахожу, используют MPI_Type_get_extent()
, и я понятия не имею, в чем разница.
Я не уверен, стоит ли сохранять новый тип данных в элементе static
. Примеры, которые я нашел, вместо этого передают как аргумент. Есть ли какая-то конкретная причина для этого?
Я также запутался, если этот метод является переносимым. Я надеюсь , что он должен быть таким же переносимым, как struct
основанные методы, но, возможно, я что-то упустил?