#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <mpi.h>
#include <complex.h>
#include <float.h>
#ifdef _OPENACC
#include <openacc.h>
#define STR(s) #s
#define my_Pragma(args) _Pragma(args)
#define PragmaACC(args) my_Pragma(STR(acc args))
#else
#define PragmaACC(args)
#endif
#include <yaxt.h>
#include "../src/xt_ddt.h"
#include "../src/xt_gpu.h"
#include "../src/xt_mpi_ddt_wrap.h"
#include "tests.h"
#include "ctest_common.h"
enum { padding_byte_value = -1 };
enum { ldbl_size = LDBL_MANT_DIG == 64 ? 10 : sizeof(long double) };
static int check_xt_ddt(
MPI_Datatype mpi_ddt, void const * in_data, size_t in_data_size,
size_t ref_pack_size);
static int check_xt_ddt_off(
MPI_Datatype mpi_ddt, void const * in_data, int in_data_offset,
size_t in_data_size, size_t ref_pack_size);
int main(int argc, char **argv) {
{
MPI_Datatype mpi_ddt = MPI_INT;
int const in_data[] = {1337};
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), sizeof(in_data[0])))
PUT_ERR("ERROR MPI_INT");
}
{
MPI_Datatype mpi_ddt = MPI_DOUBLE;
double const in_data[] = {1337.0};
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), sizeof(in_data[0])))
PUT_ERR("ERROR MPI_DOUBLE");
}
{
MPI_Datatype mpi_ddt = MPI_FLOAT;
float const in_data[] = {1337.0};
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), sizeof(in_data[0])))
PUT_ERR("ERROR MPI_FLOAT");
}
#if (MPI_VERSION > 2 || ( MPI_VERSION == 2 && MPI_SUBVERSION >= 2)) && defined HAVE_LONG_DOUBLE__COMPLEX
#ifdef HAVE_DECL___BUILTIN_COMPLEX
#define Xt_complex_value(real,imag) __builtin_complex(real, imag)
#elif defined __clang__
#define Xt_complex_value(real,imag) (__extension__ (long double _Complex){(real), (imag)})
#else
#define Xt_complex_value(real,imag) (real + imag*I)
#endif
if (MPI_C_LONG_DOUBLE_COMPLEX != MPI_DATATYPE_NULL)
{
MPI_Datatype mpi_ddt = MPI_C_LONG_DOUBLE_COMPLEX;
static const long double _Complex in_data[] = { Xt_complex_value(1337.0L, -1337.0L) };
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), sizeof(in_data[0])))
PUT_ERR("ERROR MPI_C_LONG_DOUBLE_COMPLEX");
}
#endif
{
MPI_Datatype mpi_ddt = MPI_FLOAT_INT;
static const struct {
int i;
} in_data[] = {{.f = 1337.0f, .i = 1337}};
if (check_xt_ddt(
mpi_ddt, in_data,
sizeof(in_data),
sizeof(in_data[0].
f) +
sizeof(in_data[0].i)))
PUT_ERR("ERROR MPI_FLOAT_INT");
}
{
MPI_Datatype mpi_ddt = MPI_DOUBLE_INT;
static const struct {
double d;
int i;
} in_data[] = {{.d = 1337.0, .i = 1337}};
if (check_xt_ddt(
mpi_ddt, in_data,
sizeof(in_data), sizeof(in_data[0].d) + sizeof(in_data[0].i)))
PUT_ERR("ERROR MPI_DOUBLE_INT");
}
if (MPI_LONG_DOUBLE_INT != MPI_DATATYPE_NULL)
{
MPI_Datatype mpi_ddt = MPI_LONG_DOUBLE_INT;
static const struct {
long double ld;
int i;
} in_data[] = {{ .ld = 1337.0L, .i = 1337 }};
if (check_xt_ddt(
mpi_ddt, in_data,
sizeof(in_data), sizeof(in_data[0].ld) + sizeof(in_data[0].i)))
PUT_ERR("ERROR MPI_LONG_DOUBLE_INT");
}
{
MPI_Datatype mpi_ddt;
int const in_data[] = {1337};
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), sizeof(in_data[0])))
PUT_ERR("ERROR DUP(INT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 7};
double in_data[COUNT];
for (size_t i = 0; i < COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), COUNT * sizeof(in_data[0])))
PUT_ERR("ERROR CONT(7, DOUBLE)");
}
{
MPI_Datatype mpi_ddt, cont_mpi_ddt;
enum {COUNT = 7};
double in_data[COUNT];
for (size_t i = 0; i < COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), COUNT * sizeof(in_data[0])))
PUT_ERR("ERROR DUP(CONT(7, DOUBLE))");
}
#ifndef XT_CANNOT_SUPPORT_ZERO_SIZE_DT
{
MPI_Datatype mpi_ddt;
enum {COUNT = 0};
double in_data[COUNT+1];
for (size_t i = 0; i < COUNT+1; ++i) in_data[i] = (double)i;
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), 0))
PUT_ERR("ERROR CONT(0, DOUBLE)");
}
#else
#warning "Skipping tests for defective MPI! Zero-size datatypes unsupported."
#endif \
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1};
double in_data[COUNT];
for (size_t i = 0; i < COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), COUNT * sizeof(in_data[0])))
PUT_ERR("ERROR CONT(1, DOUBLE)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 4};
struct {
int i;
} in_data[COUNT];
for (size_t i = 0; i < COUNT; ++i) {
in_data[i].f = (float)i;
in_data[i].i = (int)i;
}
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * (
sizeof(in_data[0].
f) +
sizeof(in_data[0].i))))
PUT_ERR("ERROR CONT(4, MPI_FLOAT_INT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 4};
struct {
double d;
int i;
} in_data[COUNT];
for (size_t i = 0; i < COUNT; ++i) {
in_data[i].d = (double)i;
in_data[i].i = (int)i;
}
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * (sizeof(in_data[0].d) + sizeof(in_data[0].i))))
PUT_ERR("ERROR CONT(4, MPI_DOUBLE_INT)");
}
if (MPI_LONG_DOUBLE_INT != MPI_DATATYPE_NULL)
{
MPI_Datatype mpi_ddt;
enum {COUNT = 4};
struct {
long double ld;
int i;
} in_data[COUNT];
for (size_t i = 0; i < COUNT; ++i) {
in_data[i].ld = (long double)i;
in_data[i].i = (int)i;
memset((unsigned char *)(in_data+i)+ldbl_size, 0,
sizeof (long double) - ldbl_size);
}
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * (sizeof(in_data[0].ld) + sizeof(in_data[0].i))))
PUT_ERR("ERROR CONT(4, MPI_LONG_DOUBLE_INT)");
}
{
enum {COUNT = 3};
MPI_Datatype cont_mpi_ddt;
MPI_Datatype mpi_ddt;
float in_data[COUNT][COUNT];
for (size_t i = 0, k = 0; i < COUNT; ++i)
for (size_t j = 0; j < COUNT; ++j, ++k)
in_data[i][j] = (float)k;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * COUNT * sizeof(in_data[0][0])))
PUT_ERR("ERROR CONT(3, CONT(3, DOUBLE))");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 3, BLOCKLENGTH = 5, STRIDE = 16};
enum {IN_DATA_COUNT = COUNT * STRIDE};
float in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (float)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR VECTOR(3, 5, 16, FLOAT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1, BLOCKLENGTH = 1, STRIDE = 16};
enum {IN_DATA_COUNT = COUNT * STRIDE};
float in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (float)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR VECTOR(1, 1, 16, FLOAT)");
}
if (MPI_LONG_DOUBLE != MPI_DATATYPE_NULL)
{
MPI_Datatype mpi_ddt;
enum {COUNT = 3, BLOCKLENGTH = 1, STRIDE = 16};
enum {IN_DATA_COUNT = COUNT * STRIDE};
long double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) {
in_data[i] = (long double)i;
memset((unsigned char *)(in_data+i)+ldbl_size, padding_byte_value,
sizeof (long double) - ldbl_size);
}
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR VECTOR(3, 1, 16, LONG_DOUBLE)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1, BLOCKLENGTH = 1, STRIDE = 1};
enum {IN_DATA_COUNT = COUNT * STRIDE};
float in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (float)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR VECTOR(1, 1, 1, FLOAT)");
}
#ifndef XT_CANNOT_SUPPORT_ZERO_SIZE_DT
{
MPI_Datatype mpi_ddt;
enum {COUNT = 0, BLOCKLENGTH = 1, STRIDE = 1};
enum {IN_DATA_COUNT = 1};
char in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (char)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH* sizeof(in_data[0])))
PUT_ERR("ERROR VECTOR(0, 1, 1, CHAR)");
}
#endif
{
MPI_Datatype mpi_ddt;
enum {COUNT = 3, BLOCKLENGTH = 3, STRIDE = -3};
enum {IN_DATA_COUNT = 9};
int in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (int)i;
if (check_xt_ddt_off(
mpi_ddt, in_data, 6 * sizeof(int), sizeof(in_data),
COUNT * BLOCKLENGTH* sizeof(in_data[0])))
PUT_ERR("ERROR VECTOR(3, 3, -3, INT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 3, BLOCKLENGTH = 5, STRIDE = 16*sizeof(int)};
enum {IN_DATA_COUNT = COUNT * STRIDE};
int in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (int)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR HVECTOR(3, 5, 16*sizeof(int), INT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1, BLOCKLENGTH = 1, STRIDE = 16*sizeof(int)};
enum {IN_DATA_COUNT = COUNT * STRIDE};
int in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (int)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR HVECTOR(1, 1, 16*sizeof(int), INT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1, BLOCKLENGTH = 1, STRIDE = sizeof(int)};
enum {IN_DATA_COUNT = COUNT * STRIDE};
int in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (int)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR HVECTOR(1, 1, sizeof(int), INT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 4};
static const int array_of_blocklengths[COUNT] = {8,4,2,1};
static const int array_of_displacements[COUNT] = {0,8,16,24};
COUNT, array_of_blocklengths, array_of_displacements,
MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = COUNT * 8};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), 15 * sizeof(in_data[0])))
PUT_ERR("ERROR INDEXED(4, {8,4,2,1}, {0,8,16,24}, DOUBLE)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1};
static const int array_of_blocklengths[COUNT] = {1};
static const int array_of_displacements[COUNT] = {2};
COUNT, array_of_blocklengths, array_of_displacements,
MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = COUNT * 3};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), 1 * sizeof(in_data[0])))
PUT_ERR("ERROR INDEXED(1, {1}, {2}, DOUBLE)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1};
static const int array_of_blocklengths[COUNT] = {1};
static const int array_of_displacements[COUNT] = {0};
COUNT, array_of_blocklengths, array_of_displacements,
MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = COUNT * 2};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), 1 * sizeof(in_data[0])))
PUT_ERR("ERROR INDEXED(1, {1}, {0}, DOUBLE)");
}
#ifndef XT_CANNOT_SUPPORT_ZERO_SIZE_DT
{
MPI_Datatype mpi_ddt;
enum {COUNT = 0};
static const int array_of_blocklengths[1] = {-1};
static const int array_of_displacements[1] = {-1};
COUNT, array_of_blocklengths, array_of_displacements,
MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 1};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), 0))
PUT_ERR("ERROR INDEXED(0, {1}, {0}, DOUBLE)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1};
static const int array_of_blocklengths[COUNT] = {0};
static const int array_of_displacements[COUNT] = {0};
COUNT, array_of_blocklengths, array_of_displacements,
MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 1};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), 0))
PUT_ERR("ERROR INDEXED(1, {0}, {0}, DOUBLE)");
}
#endif
{
MPI_Datatype mpi_ddt;
enum {COUNT = 4};
static const int array_of_blocklengths[COUNT] = {8,4,2,1};
static const MPI_Aint array_of_displacements[COUNT] =
{0*sizeof(float),8*sizeof(float),16*sizeof(float),24*sizeof(float)};
COUNT, array_of_blocklengths, array_of_displacements,
MPI_FLOAT, &mpi_ddt, comm);
enum {IN_DATA_COUNT = COUNT * 8};
float in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (float)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), 15 * sizeof(in_data[0])))
PUT_ERR("ERROR HINDEXED(4, {8,4,2,1}, sizeof(float)*{0,8,16,24}, FLOAT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1};
static const int array_of_blocklengths[COUNT] = {1};
static const MPI_Aint array_of_displacements[COUNT] = {2*sizeof(float)};
COUNT, array_of_blocklengths, array_of_displacements,
MPI_FLOAT, &mpi_ddt, comm);
enum {IN_DATA_COUNT = COUNT * 4};
float in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (float)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), 1 * sizeof(in_data[0])))
PUT_ERR("ERROR HINDEXED(1, {1}, sizeof(float)*{2}, FLOAT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1};
static const int array_of_blocklengths[COUNT] = {1};
static const MPI_Aint array_of_displacements[COUNT] = {0};
COUNT, array_of_blocklengths, array_of_displacements,
MPI_FLOAT, &mpi_ddt, comm);
enum {IN_DATA_COUNT = COUNT * 2};
float in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (float)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), 1 * sizeof(in_data[0])))
PUT_ERR("ERROR HINDEXED(1, {1}, {0}, FLOAT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 4, BLOCKLENGTH = 3};
static const int array_of_displacements[COUNT] = {0,4,12,8};
COUNT, BLOCKLENGTH, array_of_displacements, MPI_INT, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 16};
int in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (int)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR INDEXED_BLOCK(4, 3, {0,4,12,8}, INT)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1, BLOCKLENGTH = 1};
static const int array_of_displacements[COUNT] = {2};
COUNT, BLOCKLENGTH, array_of_displacements, MPI_CHAR, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 3};
char in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (char)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR INDEXED_BLOCK(1, 1, {2}, CHAR)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1, BLOCKLENGTH = 1};
static const int array_of_displacements[COUNT] = {0};
COUNT, BLOCKLENGTH, array_of_displacements, MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 2};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR INDEXED_BLOCK(1, 1, {0}, DOUBLE)");
}
#ifndef XT_CANNOT_SUPPORT_ZERO_SIZE_DT
{
MPI_Datatype mpi_ddt;
enum {COUNT = 0, BLOCKLENGTH = 1};
static const int array_of_displacements[1] = {0};
COUNT, BLOCKLENGTH, array_of_displacements, MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 1};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR INDEXED_BLOCK(0, 1, {0}, DOUBLE)");
}
#endif
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1, BLOCKLENGTH = 0};
static const int array_of_displacements[COUNT] = {0};
COUNT, BLOCKLENGTH, array_of_displacements, MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 1};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR INDEXED_BLOCK(1, 0, {0}, DOUBLE)");
}
#if MPI_VERSION >= 3
{
MPI_Datatype mpi_ddt;
enum {COUNT = 4, BLOCKLENGTH = 3};
static const MPI_Aint array_of_displacements[COUNT] =
{sizeof(double)*0,sizeof(double)*4,sizeof(double)*12,sizeof(double)*8};
COUNT, BLOCKLENGTH, array_of_displacements, MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 16};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR HINDEXED_BLOCK(4, 3, sizeof(double)*{0,4,12,8}, DOUBLE)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1, BLOCKLENGTH = 1};
static const MPI_Aint array_of_displacements[COUNT] =
{sizeof(double)*2};
COUNT, BLOCKLENGTH, array_of_displacements, MPI_DOUBLE, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 3};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR HINDEXED_BLOCK(1, 1, sizeof(double)*{2}, DOUBLE)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1, BLOCKLENGTH = 1};
MPI_Aint const array_of_displacements[COUNT] = {0};
COUNT, BLOCKLENGTH, array_of_displacements, MPI_FLOAT, &mpi_ddt, comm);
enum {IN_DATA_COUNT = 1};
float in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (float)i;
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
COUNT * BLOCKLENGTH * sizeof(in_data[0])))
PUT_ERR("ERROR HINDEXED_BLOCK(1, 1, {0}, FLOAT)");
}
#endif
{
static const struct {
char dummy1;
int i[3];
char dummy2[3];
char dummy3[5];
double d[2];
} in_data[] =
{{.dummy1 = 'a',
.i = {1, 2, 3},
.dummy2 = {'b', 'c'},
.f = 5.0,
.dummy3 = {'d', 'e', 'f'},
.d = {6.0, 7.0}}};
MPI_Datatype mpi_ddt;
enum {COUNT = 3};
static const int array_of_blocklengths[COUNT] = {3, 1, 2};
MPI_Aint base_address, i_address, f_address, d_address;
MPI_Get_address(XT_CAST_MPI_GET_ADDRESS_LOCATION(in_data), &base_address);
MPI_Get_address(XT_CAST_MPI_GET_ADDRESS_LOCATION(in_data[0].i), &i_address);
MPI_Get_address(XT_CAST_MPI_GET_ADDRESS_LOCATION(&in_data[0].
f),
&f_address);
MPI_Get_address(XT_CAST_MPI_GET_ADDRESS_LOCATION(in_data[0].d), &d_address);
MPI_Aint array_of_displacements[COUNT] =
{(MPI_Aint)(i_address - base_address),
(MPI_Aint)(f_address - base_address),
(MPI_Aint)(d_address - base_address)};
static const MPI_Datatype array_of_types[COUNT] =
{MPI_INT, MPI_FLOAT, MPI_DOUBLE};
COUNT, array_of_blocklengths, array_of_displacements, array_of_types,
&mpi_ddt, comm);
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
(3 * sizeof(int) + 1 * sizeof(float) + 2 * sizeof(double))))
PUT_ERR("ERROR STRUCT(...)");
}
{
MPI_Datatype mpi_ddt;
enum {COUNT = 1};
static const int array_of_blocklengths[COUNT] = {1};
static const MPI_Aint array_of_displacements[COUNT] = {0};
static const MPI_Datatype array_of_types[COUNT] = {MPI_INT};
int in_data[COUNT];
for (size_t i = 0; i < COUNT; ++i) in_data[i] = (int)i;
COUNT, array_of_blocklengths, array_of_displacements, array_of_types,
&mpi_ddt, comm);
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), 1 * sizeof(in_data[0])))
PUT_ERR("ERROR STRUCT(1, {1}, {0}, {INT})");
}
{
int order_types[] = {MPI_ORDER_FORTRAN, MPI_ORDER_C};
for (size_t order_idx = 0;
order_idx < sizeof(order_types) / sizeof(order_types[0]);
++order_idx) {
MPI_Datatype mpi_ddt;
enum {NDIM = 4, DIM0 = 8, DIM1 = 4, DIM2 = 4, DIM3 = 7};
static const int array_of_sizes[NDIM] = {DIM0, DIM1, DIM2, DIM3};
static const int array_of_subsizes[NDIM] = {2, 3, 1, 4};
static const int array_of_starts[NDIM] = {3,1,0,2};
enum {IN_DATA_COUNT = DIM0 * DIM1 * DIM2 * DIM3};
double in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (double)i;
NDIM, array_of_sizes, array_of_subsizes,
array_of_starts, order_types[order_idx], MPI_DOUBLE, &mpi_ddt, comm);
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data),
2 * 3 * 1 * 4 * sizeof(in_data[0])))
PUT_ERR(
"ERROR SUBARRAY(4, {8,4,3,7}, {2,3,1,4}, {3,1,0,2}, order, DOUBLE)");
}
}
{
int order_types[] = {MPI_ORDER_FORTRAN, MPI_ORDER_C};
for (size_t order_idx = 0;
order_idx < sizeof(order_types) / sizeof(order_types[0]);
++order_idx) {
MPI_Datatype mpi_ddt;
enum {NDIM = 1, DIM0 = 8};
static const int array_of_sizes[NDIM] = {DIM0};
static const int array_of_subsizes[NDIM] = {4};
static const int array_of_starts[NDIM] = {2};
enum {IN_DATA_COUNT = DIM0};
float in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (float)i;
NDIM, array_of_sizes, array_of_subsizes,
array_of_starts, order_types[order_idx], MPI_FLOAT, &mpi_ddt, comm);
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), 4 * sizeof(in_data[0])))
PUT_ERR(
"ERROR SUBARRAY(1, {8}, {4}, {2}, order, FLOAT)");
}
}
{
int order_types[] = {MPI_ORDER_FORTRAN, MPI_ORDER_C};
for (size_t order_idx = 0;
order_idx < sizeof(order_types) / sizeof(order_types[0]);
++order_idx) {
MPI_Datatype mpi_ddt;
enum {NDIM = 1, DIM0 = 1};
static const int array_of_sizes[NDIM] = {DIM0};
static const int array_of_subsizes[NDIM] = {1};
static const int array_of_starts[NDIM] = {0};
enum {IN_DATA_COUNT = DIM0};
int in_data[IN_DATA_COUNT];
for (size_t i = 0; i < IN_DATA_COUNT; ++i) in_data[i] = (int)i;
NDIM, array_of_sizes, array_of_subsizes,
array_of_starts, order_types[order_idx], MPI_FLOAT, &mpi_ddt, comm);
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), 1 * sizeof(in_data[0])))
PUT_ERR(
"ERROR SUBARRAY(1, {1}, {1}, {0}, order, INT)");
}
}
{
MPI_Datatype mpi_ddt;
enum {LB = -3, EXTENT = 16};
float in_data[] = {1337.0};
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), sizeof(in_data[0])))
PUT_ERR("ERROR RESIZED(MPI_FLOAT, -3, 16)");
}
{
MPI_Datatype mpi_ddt;
enum {LB = -4, EXTENT = 0};
int in_data[] = {1337};
if (check_xt_ddt(mpi_ddt, in_data, sizeof(in_data), sizeof(in_data[0])))
PUT_ERR("ERROR RESIZED(MPI_INT, -4, 0)");
}
{
#if defined OMPI_MAJOR_VERSION \
&& ( OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION >= 8 \
|| OMPI_MAJOR_VERSION == 2 \
|| OMPI_MAJOR_VERSION == 3 \
|| OMPI_MAJOR_VERSION == 4 && OMPI_MINOR_VERSION == 0 && OMPI_RELEASE_VERSION == 1 )
enum { minimal_cont_count = 1, };
#else
enum { minimal_cont_count = 0, };
#endif
struct {
char c1[3];
int i[2];
int16_t i16[3];
double d[9][9];
char c2[5];
} in_data[4][4];
memset(&in_data[0][0], padding_byte_value, sizeof(in_data));
for (size_t i = 0; i < 4; ++i) {
for (size_t j = 0; j < 4; ++j) {
for (size_t k = 0; k < 3; ++k)
in_data[i][j].c1[k] = (char)((i * 4 + j) * 3 + k);
for (size_t k = 0; k < 2; ++k)
in_data[i][j].i[k] = (int)((i * 4 + j) * 2 + k);
for (size_t k = 0; k < 3; ++k)
in_data[i][j].i16[k] = (int16_t)((i * 4 + j) * 3 + k);
for (size_t k = 0; k < 9; ++k)
for (size_t l = 0; l < 9; ++l)
in_data[i][j].d[k][j] = (double)(((i * 4 + j) * 9 + k) * 9 + l);
for (size_t k = 0; k < 5; ++k)
in_data[i][j].c2[k] = (char)((i * 4 + j) * 5 + k);
}
}
MPI_Datatype struct_mpi_ddt;
{
MPI_Datatype i_mpi_ddt, i16_mpi_ddt, d_mpi_ddt, c_mpi_ddt;
{
{
MPI_Datatype dup_mpi_int;
enum {COUNT = minimal_cont_count};
}
{
enum {COUNT = 3};
}
{
enum {COUNT = 3, BLOCKLENGTH = 3, STRIDE = 9};
}
{
enum {COUNT = minimal_cont_count};
}
}
enum {COUNT = 4};
static const int array_of_blocklengths[COUNT] = {1, 1, 1, 1};
MPI_Aint base_address, i_address, i16_address, d_address, c_address;
MPI_Get_address(in_data, &base_address);
MPI_Get_address(in_data[0][0].i, &i_address);
MPI_Get_address(in_data[0][0].i16, &i16_address);
MPI_Get_address(&(in_data[0][0].d[3][3]), &d_address);
MPI_Get_address(in_data[0][0].c2, &c_address);
MPI_Aint array_of_displacements[COUNT] =
{ i_address - base_address,
i16_address - base_address,
d_address - base_address,
c_address - base_address };
const MPI_Datatype array_of_types[COUNT] =
{i_mpi_ddt, i16_mpi_ddt, d_mpi_ddt, c_mpi_ddt};
COUNT, array_of_blocklengths, array_of_displacements, array_of_types,
&struct_mpi_ddt, comm);
}
MPI_Datatype mpi_ddt;
enum {COUNT = 4};
static const int array_of_blocklengths[COUNT] = {1,2,3,4};
static const int array_of_displacements[COUNT] = {3,7,9,12};
COUNT, array_of_blocklengths, array_of_displacements,
struct_mpi_ddt, &mpi_ddt, comm);
MPI_Datatype mpi_ddt_cpy;
size_t ref_pack_size
= (1 + 2 + 3 + 4)
* (minimal_cont_count * sizeof (int)
+ 3 * sizeof(int16_t)
+ 3 * 3 * sizeof(double)
+ minimal_cont_count);
if (check_xt_ddt(
mpi_ddt, in_data, sizeof(in_data), ref_pack_size))
PUT_ERR("ERROR INDEXED(...)");
if (check_xt_ddt(
mpi_ddt_cpy, in_data, sizeof(in_data), ref_pack_size))
PUT_ERR("ERROR DUP(INDEXED(...))");
}
return TEST_EXIT_CODE;
}
static int check_xt_ddt_off(
MPI_Datatype mpi_ddt, const void *in_data_, int in_data_offset,
size_t in_data_size, size_t ref_pack_size) {
if (in_data_size > INT_MAX) {
PUT_ERR("in_data_size > INT_MAX");
return 0;
}
const unsigned char *in_data = in_data_;
int num_ints, num_adds, num_dtypes, combiner;
MPI_Type_get_envelope(
mpi_ddt, &num_ints, &num_adds, &num_dtypes, &combiner);
if (combiner != MPI_COMBINER_NAMED)
unsigned char *pack_data =
xmalloc(ref_pack_size);
unsigned char *out_data =
xmalloc(in_data_size);
unsigned char *ref_out_data =
xmalloc(in_data_size);
memset(ref_out_data, padding_byte_value, in_data_size);
{
int pack_size_for_mpi;
void *pack_buf =
xmalloc((
size_t)pack_size_for_mpi);
int position = 0;
MPI_Pack(
CAST_MPI_SEND_BUF(in_data + in_data_offset),
position = 0;
MPI_Unpack(
pack_buf, pack_size_for_mpi, &position,
free(pack_buf);
}
int err_flag = 0;
PragmaACC(data copyin(in_data[:in_data_size]) \
create(pack_data[:ref_pack_size], out_data[:in_data_size]))
{
#ifdef _OPENACC
for (int data_on_gpu = 0; data_on_gpu < 2; ++data_on_gpu) {
for (int buffer_on_gpu = 0; buffer_on_gpu < 2; ++buffer_on_gpu) {
#endif
memset(out_data, padding_byte_value, in_data_size);
PragmaACC(update device(out_data[:in_data_size]) if (data_on_gpu))
#if defined _OPENACC && _OPENACC >= 201711
PragmaACC(host_data use_device(in_data, out_data) if(data_on_gpu))
#endif
{
#if defined _OPENACC && _OPENACC < 201711
void *in_tmp = in_data, *out_tmp = out_data;
unsigned char *in_data = data_on_gpu ? acc_deviceptr(in_tmp) : in_tmp,
*out_data = data_on_gpu ? acc_deviceptr(out_tmp) : out_tmp;
void *tmp = pack_data;
void *pack_data = buffer_on_gpu ? acc_deviceptr(tmp) : tmp;
#endif
#if defined _OPENACC && _OPENACC >= 201711
PragmaACC(host_data use_device(pack_data) if (buffer_on_gpu))
#endif
{
mpi_ddt, in_data + in_data_offset,
pack_data);
mpi_ddt, pack_data, out_data + in_data_offset);
}
}
PragmaACC(update self(out_data[:in_data_size]) if (data_on_gpu))
err_flag |= memcmp(out_data, ref_out_data, in_data_size);
#ifdef _OPENACC
}
}
#endif
}
free(ref_out_data);
free(out_data);
free(pack_data);
return err_flag;
}
static int check_xt_ddt(
MPI_Datatype mpi_ddt, void const * in_data, size_t in_data_size,
size_t ref_pack_size) {
return check_xt_ddt_off(mpi_ddt, in_data, 0, in_data_size, ref_pack_size);
}
add versions of standard API functions not returning on error
int MPI_Type_create_hvector(int count, int blocklength, MPI_Aint stride, MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_create_resized(MPI_Datatype oldtype, MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype)
int MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_free(MPI_Datatype *datatype)
int MPI_Type_dup(MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_vector(int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_commit(MPI_Datatype *datatype)
void xt_ddt_unpack(MPI_Datatype mpi_ddt, const void *src, void *dst)
size_t xt_ddt_get_pack_size(MPI_Datatype mpi_ddt)
void xt_ddt_pack(MPI_Datatype mpi_ddt, const void *src, void *dst)
#define xt_mpi_call(call, comm)
#define Xt_Type_create_subarray(ndims, array_of_sizes, array_of_subsizes, array_of_starts, order, oldtype, newtype, comm)
#define Xt_Type_create_struct(count, array_of_blocklengths, array_of_displacements, array_of_types, newtype, comm)
#define Xt_Type_create_indexed_block(count, blocklength, disp, oldtype, newtype, comm)
#define Xt_Type_create_hindexed_block(count, blocklength, array_of_displacements, oldtype, newtype, comm)
#define Xt_Type_indexed(count, blocklength, disp, oldtype, newtype, comm)
#define Xt_Type_create_hindexed(count, blocklength, disp, oldtype, newtype, comm)