-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathromio_patch.c
114 lines (96 loc) · 3.91 KB
/
romio_patch.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
*
* Copyright (C) 2014 UChicgo/Argonne, LLC.
* See COPYRIGHT notice in top-level directory.
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <mpi.h>
/* utility function for creating large contiguous types: algorithim from BigMPI
* https://github.com/jeffhammond/BigMPI */
static int type_create_contiguous_x(MPI_Count count, MPI_Datatype oldtype, MPI_Datatype * newtype)
{
/* to make 'count' fit MPI-3 type processing routines (which take integer
* counts), we construct a type consisting of N INT_MAX chunks followed by
* a remainder. e.g for a count of 4000000000 bytes you would end up with
* one 2147483647-byte chunk followed immediately by a 1852516353-byte
* chunk */
MPI_Datatype chunks, remainder;
MPI_Aint lb, extent, disps[2];
int blocklens[2];
MPI_Datatype types[2];
/* truly stupendously large counts will overflow an integer with this math,
* but that is a problem for a few decades from now. Sorry, few decades
* from now! */
assert(count / INT_MAX == (int) (count / INT_MAX));
int c = (int) (count / INT_MAX); /* OK to cast until 'count' is 256 bits */
int r = count % INT_MAX;
MPI_Type_vector(c, INT_MAX, INT_MAX, oldtype, &chunks);
MPI_Type_contiguous(r, oldtype, &remainder);
MPI_Type_get_extent(oldtype, &lb, &extent);
blocklens[0] = 1;
blocklens[1] = 1;
disps[0] = 0;
disps[1] = c * extent * INT_MAX;
types[0] = chunks;
types[1] = remainder;
MPI_Type_create_struct(2, blocklens, disps, types, newtype);
MPI_Type_free(&chunks);
MPI_Type_free(&remainder);
return MPI_SUCCESS;
}
/* like MPI_Type_create_hindexed, except array_of_lengths can be a larger datatype.
*
* Hindexed provides 'count' pairs of (displacement, length), but what if
* length is longer than an integer? We will create 'count' types, using
* contig if length is small enough, or something more complex if not */
int __wrap_ADIOI_Type_create_hindexed_x(int count,
const MPI_Count array_of_blocklengths[],
const MPI_Aint array_of_displacements[],
MPI_Datatype oldtype, MPI_Datatype * newtype)
{
int i, ret;
MPI_Datatype *types;
int *blocklens;
int is_big = 0;
types = (MPI_Datatype*) malloc(count * sizeof(MPI_Datatype));
blocklens = (int*) malloc(count * sizeof(int));
/* squashing two loops into one.
* - Look in the array_of_blocklengths for any large values
* - convert MPI_Count items (if they are not too big) into int-sized items
* after this loop we will know if we can use MPI_type_hindexed or if we
* need a more complicated BigMPI-style struct-of-chunks.
*
* Why not use the struct-of-chunks in all cases? HDF5 reported a bug,
* which I have not yet precicesly nailed down, but appears to have
* something to do with struct-of-chunks when the chunks are small */
/* See https://github.com/pmodels/mpich/pull/3089 */
for (i = 0; i < count; i++) {
if (array_of_blocklengths[i] > INT_MAX) {
blocklens[i] = 1;
is_big = 1;
type_create_contiguous_x(array_of_blocklengths[i], oldtype, &(types[i]));
} else {
/* OK to cast: checked for "bigness" above */
blocklens[i] = (int) array_of_blocklengths[i];
types[i] = oldtype;
}
}
if (is_big) {
ret = MPI_Type_create_struct(count, blocklens, array_of_displacements, types, newtype);
for (i = 0; i < count; i++)
if (types[i] != oldtype)
MPI_Type_free(&(types[i]));
} else {
ret = MPI_Type_create_hindexed(count, blocklens, array_of_displacements, oldtype, newtype);
}
free(types);
free(blocklens);
return ret;
}
/*
* vim: ts=8 sts=4 sw=4 noexpandtab
*/