This source file includes following definitions.
- ADIOI_GEN_ReadStrided
1
2
3
4
5
6
7
8 #include "adio.h"
9 #include "adio_extern.h"
10
11 #define ADIOI_BUFFERED_READ \
12 { \
13 if (req_off >= readbuf_off + readbuf_len) { \
14 readbuf_off = req_off; \
15 readbuf_len = (unsigned) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));\
16 ADIO_ReadContig(fd, readbuf, readbuf_len, MPI_BYTE, \
17 ADIO_EXPLICIT_OFFSET, readbuf_off, &status1, error_code); \
18 if (*error_code != MPI_SUCCESS) return; \
19 } \
20 while (req_len > readbuf_off + readbuf_len - req_off) { \
21 ADIOI_Assert((readbuf_off + readbuf_len - req_off) == (int) (readbuf_off + readbuf_len - req_off));\
22 partial_read = (int) (readbuf_off + readbuf_len - req_off); \
23 tmp_buf = (char *) ADIOI_Malloc(partial_read); \
24 memcpy(tmp_buf, readbuf+readbuf_len-partial_read, partial_read); \
25 ADIOI_Free(readbuf); \
26 readbuf = (char *) ADIOI_Malloc(partial_read + max_bufsize); \
27 memcpy(readbuf, tmp_buf, partial_read); \
28 ADIOI_Free(tmp_buf); \
29 readbuf_off += readbuf_len-partial_read; \
30 readbuf_len = (unsigned) (partial_read + ADIOI_MIN(max_bufsize, \
31 end_offset-readbuf_off+1)); \
32 ADIO_ReadContig(fd, readbuf+partial_read, readbuf_len-partial_read, \
33 MPI_BYTE, ADIO_EXPLICIT_OFFSET, readbuf_off+partial_read, \
34 &status1, error_code); \
35 if (*error_code != MPI_SUCCESS) return; \
36 } \
37 ADIOI_Assert((ADIO_Size) req_len == (size_t)req_len); \
38 memcpy((char *)buf + userbuf_off, readbuf+req_off-readbuf_off, req_len); \
39 }
40
41
42 void ADIOI_GEN_ReadStrided(ADIO_File fd, void *buf, int count,
43 MPI_Datatype datatype, int file_ptr_type,
44 ADIO_Offset offset, ADIO_Status *status, int
45 *error_code)
46 {
47
48
49
50
51 ADIOI_Flatlist_node *flat_buf, *flat_file;
52 ADIO_Offset i_offset, new_brd_size, brd_size, size;
53 int i, j, k, st_index=0;
54 MPI_Count num, bufsize;
55 int n_etypes_in_filetype;
56 ADIO_Offset n_filetypes, etype_in_filetype, st_n_filetypes, size_in_filetype;
57 ADIO_Offset abs_off_in_filetype=0, new_frd_size, frd_size=0, st_frd_size;
58 MPI_Count filetype_size, etype_size, buftype_size, partial_read;
59 MPI_Aint filetype_extent, buftype_extent, lb;
60 int buf_count, buftype_is_contig, filetype_is_contig;
61 ADIO_Offset userbuf_off, req_len, sum;
62 ADIO_Offset off, req_off, disp, end_offset=0, readbuf_off, start_off;
63 char *readbuf, *tmp_buf, *value;
64 int info_flag;
65 unsigned max_bufsize, readbuf_len;
66 ADIO_Status status1;
67
68 if (fd->hints->ds_read == ADIOI_HINT_DISABLE) {
69
70
71
72 ADIOI_GEN_ReadStrided_naive(fd,
73 buf,
74 count,
75 datatype,
76 file_ptr_type,
77 offset,
78 status,
79 error_code);
80 return;
81 }
82
83 *error_code = MPI_SUCCESS;
84
85 ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
86 ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
87
88 MPI_Type_size_x(fd->filetype, &filetype_size);
89 if ( ! filetype_size ) {
90 #ifdef HAVE_STATUS_SET_BYTES
91 MPIR_Status_set_bytes(status, datatype, 0);
92 #endif
93 *error_code = MPI_SUCCESS;
94 return;
95 }
96
97 MPI_Type_get_extent(fd->filetype, &lb, &filetype_extent);
98 MPI_Type_size_x(datatype, &buftype_size);
99 MPI_Type_get_extent(datatype, &lb, &buftype_extent);
100 etype_size = fd->etype_size;
101
102 ADIOI_Assert((buftype_size * count) == ((ADIO_Offset)(MPI_Count)buftype_size * (ADIO_Offset)count));
103 bufsize = buftype_size * count;
104
105
106
107 value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
108 ADIOI_Info_get(fd->info, "ind_rd_buffer_size", MPI_MAX_INFO_VAL, value,
109 &info_flag);
110 max_bufsize = atoi(value);
111 ADIOI_Free(value);
112
113
114 if (!buftype_is_contig && filetype_is_contig) {
115
116
117
118 flat_buf = ADIOI_Flatten_and_find(datatype);
119
120 off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind :
121 fd->disp + (ADIO_Offset)etype_size * offset;
122
123 start_off = off;
124 end_offset = off + bufsize - 1;
125 readbuf_off = off;
126 readbuf = (char *) ADIOI_Malloc(max_bufsize);
127 readbuf_len = (unsigned) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));
128
129
130 if ((fd->atomicity) && ADIO_Feature(fd, ADIO_LOCKS))
131 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
132
133 ADIO_ReadContig(fd, readbuf, readbuf_len, MPI_BYTE,
134 ADIO_EXPLICIT_OFFSET, readbuf_off, &status1, error_code);
135 if (*error_code != MPI_SUCCESS) return;
136
137 for (j=0; j<count; j++)
138 {
139 for (i=0; i<flat_buf->count; i++) {
140 userbuf_off = (ADIO_Offset)j*(ADIO_Offset)buftype_extent + flat_buf->indices[i];
141 req_off = off;
142 req_len = flat_buf->blocklens[i];
143 ADIOI_BUFFERED_READ
144 off += flat_buf->blocklens[i];
145 }
146 }
147
148 if ((fd->atomicity) && ADIO_Feature(fd, ADIO_LOCKS))
149 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
150
151 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
152
153 ADIOI_Free(readbuf);
154 }
155
156 else {
157
158
159 flat_file = ADIOI_Flatlist;
160 while (flat_file->type != fd->filetype) flat_file = flat_file->next;
161 disp = fd->disp;
162
163 if (file_ptr_type == ADIO_INDIVIDUAL) {
164
165 offset = fd->fp_ind - disp;
166 n_filetypes = (offset - flat_file->indices[0]) / filetype_extent;
167 offset -= (ADIO_Offset)n_filetypes * filetype_extent;
168
169
170
171 for (i=0; i<flat_file->count; i++) {
172 ADIO_Offset dist;
173 if (flat_file->blocklens[i] == 0) continue;
174 dist = flat_file->indices[i] + flat_file->blocklens[i] - offset;
175
176 if (dist == 0) {
177 i++;
178 offset = flat_file->indices[i];
179 frd_size = flat_file->blocklens[i];
180 break;
181 }
182 if (dist > 0) {
183 frd_size = dist;
184 break;
185 }
186 }
187 st_index = i;
188 offset += disp + (ADIO_Offset)n_filetypes*filetype_extent;
189 }
190 else {
191 n_etypes_in_filetype = filetype_size/etype_size;
192 n_filetypes = offset / n_etypes_in_filetype;
193 etype_in_filetype = offset % n_etypes_in_filetype;
194 size_in_filetype = etype_in_filetype * etype_size;
195
196 sum = 0;
197 for (i=0; i<flat_file->count; i++) {
198 sum += flat_file->blocklens[i];
199 if (sum > size_in_filetype) {
200 st_index = i;
201 frd_size = sum - size_in_filetype;
202 abs_off_in_filetype = flat_file->indices[i] +
203 size_in_filetype - (sum - flat_file->blocklens[i]);
204 break;
205 }
206 }
207
208
209 offset = disp + (ADIO_Offset) n_filetypes*filetype_extent +
210 abs_off_in_filetype;
211 }
212
213 start_off = offset;
214
215
216
217
218 if (buftype_is_contig && bufsize <= frd_size) {
219
220 ADIO_ReadContig(fd, buf, count, datatype, ADIO_EXPLICIT_OFFSET,
221 offset, status, error_code);
222
223 if (file_ptr_type == ADIO_INDIVIDUAL) {
224
225
226 fd->fp_ind = offset + bufsize;
227 if (bufsize == frd_size) {
228 do {
229 st_index++;
230 if (st_index == flat_file->count) {
231 st_index = 0;
232 n_filetypes++;
233 }
234 } while (flat_file->blocklens[st_index] == 0);
235 fd->fp_ind = disp + flat_file->indices[st_index]
236 + n_filetypes*filetype_extent;
237 }
238 }
239 fd->fp_sys_posn = -1;
240 #ifdef HAVE_STATUS_SET_BYTES
241 MPIR_Status_set_bytes(status, datatype, bufsize);
242 #endif
243 return;
244 }
245
246
247
248
249 st_frd_size = frd_size;
250 st_n_filetypes = n_filetypes;
251 i_offset = 0;
252 j = st_index;
253 off = offset;
254 frd_size = ADIOI_MIN(st_frd_size, bufsize);
255 while (i_offset < bufsize) {
256 i_offset += frd_size;
257 end_offset = off + frd_size - 1;
258
259 j = (j+1) % flat_file->count;
260 n_filetypes += (j == 0) ? 1 : 0;
261 while (flat_file->blocklens[j]==0) {
262 j = (j+1) % flat_file->count;
263 n_filetypes += (j == 0) ? 1 : 0;
264 }
265 off = disp + flat_file->indices[j] + n_filetypes*(ADIO_Offset)filetype_extent;
266 frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset);
267 }
268
269
270 if ((fd->atomicity) && ADIO_Feature(fd, ADIO_LOCKS))
271 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
272
273 readbuf_off = 0;
274 readbuf_len = 0;
275 readbuf = (char *) ADIOI_Malloc(max_bufsize);
276
277 if (buftype_is_contig && !filetype_is_contig) {
278
279
280
281
282 i_offset = 0;
283 j = st_index;
284 off = offset;
285 n_filetypes = st_n_filetypes;
286 frd_size = ADIOI_MIN(st_frd_size, bufsize);
287 while (i_offset < bufsize) {
288 if (frd_size) {
289
290
291
292
293
294 req_off = off;
295 req_len = frd_size;
296 userbuf_off = i_offset;
297 ADIOI_BUFFERED_READ
298 }
299 i_offset += frd_size;
300
301 if (off + frd_size < disp + flat_file->indices[j] +
302 flat_file->blocklens[j] + n_filetypes*(ADIO_Offset)filetype_extent)
303 off += frd_size;
304
305
306 else {
307 j = (j+1) % flat_file->count;
308 n_filetypes += (j == 0) ? 1 : 0;
309 while (flat_file->blocklens[j]==0) {
310 j = (j+1) % flat_file->count;
311 n_filetypes += (j == 0) ? 1 : 0;
312 }
313 off = disp + flat_file->indices[j] +
314 n_filetypes*(ADIO_Offset)filetype_extent;
315 frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset);
316 }
317 }
318 }
319 else {
320
321
322 flat_buf = ADIOI_Flatten_and_find(datatype);
323
324 k = num = buf_count = 0;
325 i_offset = flat_buf->indices[0];
326 j = st_index;
327 off = offset;
328 n_filetypes = st_n_filetypes;
329 frd_size = st_frd_size;
330 brd_size = flat_buf->blocklens[0];
331
332 while (num < bufsize) {
333 size = ADIOI_MIN(frd_size, brd_size);
334 if (size) {
335
336
337
338 req_off = off;
339 req_len = size;
340 userbuf_off = i_offset;
341 ADIOI_BUFFERED_READ
342 }
343
344 new_frd_size = frd_size;
345 new_brd_size = brd_size;
346
347 if (size == frd_size) {
348
349 j = (j+1) % flat_file->count;
350 n_filetypes += (j == 0) ? 1 : 0;
351 while (flat_file->blocklens[j]==0) {
352 j = (j+1) % flat_file->count;
353 n_filetypes += (j == 0) ? 1 : 0;
354 }
355 off = disp + flat_file->indices[j] +
356 n_filetypes*(ADIO_Offset)filetype_extent;
357
358 new_frd_size = flat_file->blocklens[j];
359 if (size != brd_size) {
360 i_offset += size;
361 new_brd_size -= size;
362 }
363 }
364
365 if (size == brd_size) {
366
367
368 k = (k + 1)%flat_buf->count;
369 buf_count++;
370 i_offset = ((ADIO_Offset)buftype_extent*(ADIO_Offset)(buf_count/flat_buf->count) +
371 flat_buf->indices[k]);
372 new_brd_size = flat_buf->blocklens[k];
373 if (size != frd_size) {
374 off += size;
375 new_frd_size -= size;
376 }
377 }
378 ADIOI_Assert(((ADIO_Offset)num + size) == (unsigned)(num + size));
379 num += size;
380 frd_size = new_frd_size;
381 brd_size = new_brd_size;
382 }
383 }
384
385 if ((fd->atomicity) && ADIO_Feature(fd, ADIO_LOCKS))
386 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
387
388 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
389
390 ADIOI_Free(readbuf);
391 }
392
393 fd->fp_sys_posn = -1;
394
395 #ifdef HAVE_STATUS_SET_BYTES
396 MPIR_Status_set_bytes(status, datatype, bufsize);
397
398
399
400 #endif
401
402 if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
403 }