1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2013 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
12 static MPI_Datatype make_largexfer_type_struct(MPI_Offset nbytes)
14 int typechunk_size = 1024*1024; /* in bytes: TODO: figure out how big a
15 chunk is really needed */
18 MPI_Datatype memtype, chunktype;
20 /* need to cook up a new datatype to accomodate large datatypes */
21 /* first pass: chunks of 1 MiB plus an additional remainder. Does require
22 * 8 byte MPI_Aint, which should have been checked for earlier */
24 chunk_count = nbytes/typechunk_size;
25 remainder = nbytes % typechunk_size;
26 MPI_Type_contiguous(typechunk_size, MPI_BYTE, &chunktype);
27 MPI_Type_commit(&chunktype);
29 /* a zero remainder means we can just count contigs */
31 MPI_Type_contiguous(chunk_count, chunktype, &memtype);
32 MPI_Type_free(&chunktype);
34 if (sizeof(MPI_Aint) <= sizeof(int)) {
35 return MPI_DATATYPE_NULL;
37 /* struct type: some number of chunks plus remaining bytes tacked
39 int lens[] = {chunk_count, remainder};
40 MPI_Aint disp[] = {0, (MPI_Aint) typechunk_size * (MPI_Aint)chunk_count};
41 MPI_Datatype types[] = {chunktype, MPI_BYTE};
43 MPI_Type_struct(2, lens, disp, types, &memtype);
44 MPI_Type_free(&chunktype);
46 MPI_Type_commit(&memtype);
49 static MPI_Datatype make_largexfer_type_hindexed(MPI_Offset nbytes)
52 int chunk_size = 1024*1024;
57 /* need to cook up a new datatype to accomodate large datatypes */
58 /* Does require 8 byte MPI_Aint, which should have been checked for earlier
61 if (sizeof(MPI_Aint) <= sizeof(int)) {
62 return MPI_DATATYPE_NULL;
65 /* ceiling division */
66 count = 1 + ((nbytes -1) / chunk_size );
68 blocklens = calloc(count, sizeof(int));
69 disp = calloc(count, sizeof(MPI_Aint));
72 for (i=0; i<(count-1); i++) {
73 blocklens[i] = chunk_size;
74 disp[i] = (MPI_Aint)chunk_size*i;
76 blocklens[count-1] = nbytes-((MPI_Aint)chunk_size*i);
77 disp[count-1] = (MPI_Aint)chunk_size*(count-1);
79 MPI_Type_create_hindexed(count, blocklens, disp, MPI_BYTE, &memtype);
80 MPI_Type_commit(&memtype);
86 int testtype(MPI_Datatype type, MPI_Offset expected) {
87 MPI_Count size, lb, extent;
89 MPI_Type_size_x(type, &size);
92 printf("ERROR: type size apparently overflowed integer\n");
96 if (size != expected) {
97 printf("reported type size %lld does not match expected %lld\n",
102 MPI_Type_get_true_extent_x(type, &lb, &extent);
104 printf("ERROR: type should have lb of 0, reported %lld\n", lb);
108 if (extent != size) {
109 printf("ERROR: extent should match size, not %lld\n", extent);
116 int main(int argc, char **argv)
121 MPI_Init(&argc, &argv);
122 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
123 MPI_Comm_size(MPI_COMM_WORLD, &size);
126 MPI_Offset expected_sizes[NR_TYPES] = {1024UL*1024UL*2400UL,
129 MPI_Datatype types[NR_TYPES];
131 /* a contig type, itself large, but does not need 8 byte aints */
132 types[0] = make_largexfer_type_struct(expected_sizes[0]);
133 /* struct with addresses out past 2 GiB */
134 types[1] = make_largexfer_type_struct(expected_sizes[1]);
135 /* similar, but with hindexed type */
136 types[2] = make_largexfer_type_hindexed(expected_sizes[2]);
138 for (i=0; i<NR_TYPES; i++) {
139 if (types[i] != MPI_DATATYPE_NULL) {
140 nerrors += testtype(types[i], expected_sizes[i]);
141 MPI_Type_free(&(types[i]));
148 printf("found %d errors\n", nerrors);
150 printf(" No errors\n");