File: ad_pvfs2_io_list.c

package info (click to toggle)
openmpi 5.0.8-4
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 201,684 kB
  • sloc: ansic: 613,078; makefile: 42,353; sh: 11,194; javascript: 9,244; f90: 7,052; java: 6,404; perl: 5,179; python: 1,859; lex: 740; fortran: 61; cpp: 20; tcl: 12
file content (547 lines) | stat: -rw-r--r-- 22,223 bytes parent folder | download | duplicates (5)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

#include "adio.h"
#include <assert.h>
#include "adio_extern.h"
#include "ad_pvfs2.h"
#include "ad_pvfs2_io.h"
#include "ad_pvfs2_common.h"

#define COALESCE_REGIONS        /* TODO: would we ever want to *not* coalesce? */
#define MAX_OL_COUNT 64
int ADIOI_PVFS2_StridedListIO(ADIO_File fd, void *buf, int count,
                              MPI_Datatype datatype, int file_ptr_type,
                              ADIO_Offset offset, ADIO_Status * status,
                              int *error_code, int rw_type)
{
    /* list I/O parameters */
    int i = -1, ret = -1;
    int tmp_filetype_size = -1;
    int64_t cur_io_size = 0, io_size = 0;
    int etype_size = -1;
    int num_etypes_in_filetype = -1, num_filetypes = -1;
    int etypes_in_filetype = -1, size_in_filetype = -1;
    int bytes_into_filetype = 0;
    MPI_Offset total_bytes_accessed = 0;

    /* parameters for offset-length pairs arrays */
    int64_t buf_off_arr[MAX_OL_COUNT];
    int32_t buf_len_arr[MAX_OL_COUNT];
    int64_t file_off_arr[MAX_OL_COUNT];
    int32_t file_len_arr[MAX_OL_COUNT];
    int32_t buf_ol_count = 0;
    int32_t file_ol_count = 0;

    /* parameters for flattened memory and file datatypes */
    int flat_buf_index = 0;
    int flat_file_index = 0;
    int64_t cur_flat_buf_reg_off = 0;
    int64_t cur_flat_file_reg_off = 0;
    ADIOI_Flatlist_node *flat_buf_p, *flat_file_p;
    MPI_Count buftype_size = -1, filetype_size = -1;
    MPI_Aint lb, filetype_extent = -1, buftype_extent = -1;;
    int buftype_is_contig = -1, filetype_is_contig = -1;

    /* PVFS2 specific parameters */
    PVFS_Request mem_req, file_req;
    ADIOI_PVFS2_fs *pvfs_fs;
    PVFS_sysresp_io resp_io;
    static char myname[] = "ADIOI_PVFS2_STRIDED_LISTIO";

    if (fd->atomicity) {
        *error_code = MPIO_Err_create_code(MPI_SUCCESS,
                                           MPIR_ERR_RECOVERABLE,
                                           myname, __LINE__,
                                           MPI_ERR_ARG,
                                           "Atomic noncontiguous writes"
                                           " are not supported by PVFS2", 0);
        return -1;
    }

    MPI_Type_size_x(fd->filetype, &filetype_size);
    if (filetype_size == 0) {
        *error_code = MPI_SUCCESS;
        return -1;
    }
    MPI_Type_get_extent(fd->filetype, &lb, &filetype_extent);
    MPI_Type_size_x(datatype, &buftype_size);
    MPI_Type_get_extent(datatype, &lb, &buftype_extent);
    io_size = buftype_size * count;

    pvfs_fs = (ADIOI_PVFS2_fs *) fd->fs_ptr;

    /* Flatten the memory datatype
     * (file datatype has already been flattened in ADIO open
     * unless it is contibuous, then we need to flatten it manually)
     * and set the correct buffers for flat_buf and flat_file */
    ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
    ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
    if (buftype_is_contig == 0) {
        flat_buf_p = ADIOI_Flatten_and_find(datatype);
    } else {
        /* flatten and add to the list */
        flat_buf_p = (ADIOI_Flatlist_node *) ADIOI_Malloc(sizeof(ADIOI_Flatlist_node));
        flat_buf_p->blocklens = (ADIO_Offset *) ADIOI_Malloc(sizeof(ADIO_Offset));
        flat_buf_p->indices = (ADIO_Offset *) ADIOI_Malloc(sizeof(ADIO_Offset));
        /* For the buffer, we can optimize the buftype, this is not
         * possible with the filetype since it is tiled */
        buftype_size = buftype_size * count;
        buftype_extent = buftype_size * count;
        flat_buf_p->blocklens[0] = buftype_size;
        flat_buf_p->indices[0] = 0;
        flat_buf_p->count = 1;
    }
    if (filetype_is_contig == 0) {
        /* TODO: why does avery say this should already have been
         * flattened in Open, but also says contig types don't get
         * flattened */
        flat_file_p = ADIOI_Flatten_and_find(fd->filetype);
    } else {
        /* flatten and add to the list */
        flat_file_p = (ADIOI_Flatlist_node *) ADIOI_Malloc(sizeof(ADIOI_Flatlist_node));
        flat_file_p->blocklens = (ADIO_Offset *) ADIOI_Malloc(sizeof(ADIO_Offset));
        flat_file_p->indices = (ADIO_Offset *) ADIOI_Malloc(sizeof(ADIO_Offset));
        flat_file_p->blocklens[0] = filetype_size;
        flat_file_p->indices[0] = 0;
        flat_file_p->count = 1;
    }

    /* Find out where we are in the flattened filetype (the block index,
     * how far into the block, and how many bytes_into_filetype)
     * If the file_ptr_type == ADIO_INDIVIDUAL we will use disp, fp_ind
     * to figure this out (offset should always be zero)
     * If file_ptr_type == ADIO_EXPLICIT, we will use disp and offset
     * to figure this out. */

    etype_size = fd->etype_size;
    num_etypes_in_filetype = filetype_size / etype_size;
    if (file_ptr_type == ADIO_INDIVIDUAL) {
        int flag = 0;
        /* Should have already been flattened in ADIO_Open */
        num_filetypes = -1;
        while (!flag) {
            num_filetypes++;
            for (i = 0; i < flat_file_p->count; i++) {
                /* Start on a non zero-length region */
                if (flat_file_p->blocklens[i]) {
                    if (fd->disp + flat_file_p->indices[i] +
                        (num_filetypes * filetype_extent) +
                        flat_file_p->blocklens[i] > fd->fp_ind &&
                        fd->disp + flat_file_p->indices[i] <= fd->fp_ind) {
                        flat_file_index = i;
                        cur_flat_file_reg_off = fd->fp_ind -
                            (fd->disp + flat_file_p->indices[i] +
                             (num_filetypes * filetype_extent));
                        flag = 1;
                        break;
                    } else
                        bytes_into_filetype += flat_file_p->blocklens[i];
                }
            }
        }
        /* Impossible that we don't find it in this datatype */
        assert(i != flat_file_p->count);
    } else {
        num_filetypes = (int) (offset / num_etypes_in_filetype);
        etypes_in_filetype = (int) (offset % num_etypes_in_filetype);
        size_in_filetype = etypes_in_filetype * etype_size;

        tmp_filetype_size = 0;
        for (i = 0; i < flat_file_p->count; i++) {
            tmp_filetype_size += flat_file_p->blocklens[i];
            if (tmp_filetype_size > size_in_filetype) {
                flat_file_index = i;
                cur_flat_file_reg_off = flat_file_p->blocklens[i] -
                    (tmp_filetype_size - size_in_filetype);
                bytes_into_filetype = offset * filetype_size - flat_file_p->blocklens[i];
                break;
            }
        }
    }
#ifdef DEBUG_LIST
    fprintf(stderr, "ADIOI_PVFS2_StridedListIO: (fd->fp_ind=%Ld,fd->disp=%Ld,"
            " offset=%Ld)\n(flat_file_index=%d,cur_flat_file_reg_off=%Ld,"
            "bytes_into_filetype=%d)\n",
            fd->fp_ind, fd->disp, offset, flat_file_index,
            cur_flat_file_reg_off, bytes_into_filetype);
#endif
#ifdef DEBUG_LIST2
    fprintf(stderr, "flat_buf:\n");
    for (i = 0; i < flat_buf_p->count; i++)
        fprintf(stderr, "(offset, length) = (%Ld, %d)\n",
                flat_buf_p->indices[i], flat_buf_p->blocklens[i]);
    fprintf(stderr, "flat_file:\n");
    for (i = 0; i < flat_file_p->count; i++)
        fprintf(stderr, "(offset, length) = (%Ld, %d)\n",
                flat_file_p->indices[i], flat_file_p->blocklens[i]);
#endif

    /* total data written */
    cur_io_size = 0;
    while (cur_io_size != io_size) {
        /* Initialize the temporarily unrolling lists and
         * and associated variables */
        buf_ol_count = 0;
        file_ol_count = 0;
        for (i = 0; i < MAX_OL_COUNT; i++) {
            buf_off_arr[i] = 0;
            buf_len_arr[i] = 0;
            file_off_arr[i] = 0;
            file_len_arr[i] = 0;
        }

        /* Generate the offset-length pairs for a
         * list I/O operation */
        gen_listio_arr(flat_buf_p,
                       &flat_buf_index,
                       &cur_flat_buf_reg_off,
                       buftype_size,
                       buftype_extent,
                       flat_file_p,
                       &flat_file_index,
                       &cur_flat_file_reg_off,
                       filetype_size,
                       filetype_extent,
                       MAX_OL_COUNT,
                       fd->disp,
                       bytes_into_filetype,
                       &cur_io_size,
                       io_size,
                       buf_off_arr,
                       buf_len_arr, &buf_ol_count, file_off_arr, file_len_arr, &file_ol_count);

        assert(buf_ol_count <= MAX_OL_COUNT);
        assert(file_ol_count <= MAX_OL_COUNT);
#ifdef DEBUG_LIST2
        print_buf_file_ol_pairs(buf_off_arr,
                                buf_len_arr,
                                buf_ol_count,
                                file_off_arr, file_len_arr, file_ol_count, buf, rw_type);
#endif
#ifdef DEBUG_LIST2
        do {
            int y, z;
            fprintf(stderr, "ad_pvfs2_io_list.c::\n");
            for (y = 0; y < buf_ol_count; y++) {
                for (z = 0; z < buf_len_arr[y]; z++) {
                    fprintf(stderr, "buf[%d][%d]=%c\n", y, z, ((char *) buf + buf_off_arr[y])[z]);
                }
            }
        } while (0);
#endif

        /* Run list I/O operation */
        ret = PVFS_Request_hindexed(buf_ol_count, buf_len_arr, buf_off_arr, PVFS_BYTE, &mem_req);

        ret = PVFS_Request_hindexed(file_ol_count, file_len_arr,
                                    file_off_arr, PVFS_BYTE, &file_req);
        if (rw_type == READ) {
            ret = PVFS_sys_read(pvfs_fs->object_ref, file_req, 0,
                                buf, mem_req, &(pvfs_fs->credentials), &resp_io);
        } else {
            ret = PVFS_sys_write(pvfs_fs->object_ref, file_req, 0,
                                 buf, mem_req, &(pvfs_fs->credentials), &resp_io);
        }
        if (ret != 0) {
            fprintf(stderr, "ADIOI_PVFS2_StridedListIO: Warning - PVFS_sys_"
                    "read/write returned %d and completed %lld bytes.\n",
                    ret, (long long) resp_io.total_completed);
            *error_code = MPIO_Err_create_code(MPI_SUCCESS,
                                               MPIR_ERR_RECOVERABLE,
                                               myname, __LINE__,
                                               ADIOI_PVFS2_error_convert(ret),
                                               "Error in PVFS_sys_io \n", 0);
            PVFS_Request_free(&mem_req);
            PVFS_Request_free(&file_req);
            goto error_state;
        }
        total_bytes_accessed += resp_io.total_completed;

        PVFS_Request_free(&mem_req);
        PVFS_Request_free(&file_req);
    }

#ifdef DEBUG_LIST
    fprintf(stderr, "ADIOI_PVFS2_StridedListIO: "
            "total_bytes_accessed=%Ld,ret=%d\n", total_bytes_accessed, ret);
#endif

    if (file_ptr_type == ADIO_INDIVIDUAL)
        fd->fp_ind += total_bytes_accessed;
    *error_code = MPI_SUCCESS;

  error_state:
#ifdef HAVE_STATUS_SET_BYTES
    /* TODO: why the cast? */
    MPIR_Status_set_bytes(status, datatype, total_bytes_accessed);
/* This is a temporary way of filling in status. The right way is to
   keep track of how much data was actually written by ADIOI_BUFFERED_WRITE. */
#endif
    if (buftype_is_contig != 0) {
        ADIOI_Free(flat_buf_p->blocklens);
        ADIOI_Free(flat_buf_p->indices);
        ADIOI_Free(flat_buf_p);
    }

    if (filetype_is_contig != 0) {
        ADIOI_Free(flat_file_p->blocklens);
        ADIOI_Free(flat_file_p->indices);
        ADIOI_Free(flat_file_p);
    }

    return 0;
}

/* To do: Fix the code to coalesce the offset-length pairs for memory
 * and file. */

/* gen_listio_arr - fills in offset-length pairs for memory and file
 * for list I/O */
int gen_listio_arr(ADIOI_Flatlist_node * flat_buf_p,
                   int *flat_buf_index_p,
                   int64_t * cur_flat_buf_reg_off_p,
                   int flat_buf_size,
                   int flat_buf_extent,
                   ADIOI_Flatlist_node * flat_file_p,
                   int *flat_file_index_p,
                   int64_t * cur_flat_file_reg_off_p,
                   int flat_file_size,
                   int flat_file_extent,
                   int max_ol_count,
                   ADIO_Offset disp,
                   int bytes_into_filetype,
                   int64_t * bytes_completed,
                   int64_t total_io_size,
                   int64_t buf_off_arr[],
                   int32_t buf_len_arr[],
                   int32_t * buf_ol_count_p,
                   int64_t file_off_arr[], int32_t file_len_arr[], int32_t * file_ol_count_p)
{
    int region_size = -1;

    /* parameters for flattened memory and file datatypes */
    int64_t cur_flat_buf_reg_left = 0;
    int64_t cur_flat_file_reg_left = 0;

#ifdef DEBUG_LIST2
    fprintf(stderr, "gen_list_arr:\n");
#endif

    if ((*buf_ol_count_p) != 0 || (*file_ol_count_p) != 0) {
        fprintf(stderr, "buf_ol_count != 0 || file_ol_count != 0\n");
        return -1;
    }

    /* Start on a non-zero memory and file region
     * Note this does not affect the bytes_completed
     * since no data is in these regions.  Initialize the
     * first memory and file offsets. */
    while (flat_buf_p->blocklens[(*flat_buf_index_p)] == 0) {
        (*flat_buf_index_p) = ((*flat_buf_index_p) + 1) % flat_buf_p->count;
    }
    buf_off_arr[*buf_ol_count_p] =
        (*bytes_completed / flat_buf_size) *
        flat_buf_extent + flat_buf_p->indices[*flat_buf_index_p] + *cur_flat_buf_reg_off_p;
    buf_len_arr[*buf_ol_count_p] = 0;

    while (flat_file_p->blocklens[(*flat_file_index_p)] == 0) {
        (*flat_file_index_p) = ((*flat_file_index_p) + 1) % flat_file_p->count;
    }
    file_off_arr[*file_ol_count_p] = disp +
        (((bytes_into_filetype + *bytes_completed) / flat_file_size) *
         flat_file_extent) + flat_file_p->indices[*flat_file_index_p] + *cur_flat_file_reg_off_p;
    file_len_arr[*file_ol_count_p] = 0;

#ifdef DEBUG_LIST2
    fprintf(stderr, "initial buf_off_arr[%d] = %Ld\n", *buf_ol_count_p,
            buf_off_arr[*buf_ol_count_p]);
    fprintf(stderr, "initial file_off_arr[%d] = %Ld\n", *file_ol_count_p,
            file_off_arr[*file_ol_count_p]);
#endif

    while (*bytes_completed != total_io_size
           && (*buf_ol_count_p) < max_ol_count && (*file_ol_count_p) < max_ol_count) {
        /* How much data is left in the current piece in
         * the flattened datatypes */
        cur_flat_buf_reg_left = flat_buf_p->blocklens[*flat_buf_index_p]
            - *cur_flat_buf_reg_off_p;
        cur_flat_file_reg_left = flat_file_p->blocklens[*flat_file_index_p]
            - *cur_flat_file_reg_off_p;

#ifdef DEBUG_LIST2
        fprintf(stderr,
                "flat_buf_index=%d flat_buf->blocklens[%d]=%d\n"
                "cur_flat_buf_reg_left=%Ld "
                "*cur_flat_buf_reg_off_p=%Ld\n"
                "flat_file_index=%d flat_file->blocklens[%d]=%d\n"
                "cur_flat_file_reg_left=%Ld "
                "*cur_flat_file_reg_off_p=%Ld\n"
                "bytes_completed=%Ld\n"
                "buf_ol_count=%d file_ol_count=%d\n"
                "buf_len_arr[%d]=%d file_len_arr[%d]=%d\n\n",
                *flat_buf_index_p, *flat_buf_index_p,
                flat_buf_p->blocklens[*flat_buf_index_p],
                cur_flat_buf_reg_left,
                *cur_flat_buf_reg_off_p,
                *flat_file_index_p, *flat_file_index_p,
                flat_file_p->blocklens[*flat_file_index_p],
                cur_flat_file_reg_left,
                *cur_flat_file_reg_off_p,
                *bytes_completed,
                *buf_ol_count_p, *file_ol_count_p,
                *buf_ol_count_p,
                buf_len_arr[*buf_ol_count_p], *file_ol_count_p, file_len_arr[*file_ol_count_p]);
#endif

        /* What is the size of the next contiguous region agreed
         * upon by both memory and file regions that does not
         * surpass the file size */
        if (cur_flat_buf_reg_left > cur_flat_file_reg_left)
            region_size = cur_flat_file_reg_left;
        else
            region_size = cur_flat_buf_reg_left;

        if (region_size > total_io_size - *bytes_completed)
            region_size = total_io_size - *bytes_completed;

        /* Add this piece to both the mem and file arrays
         * coalescing offset-length pairs if possible and advance
         * the pointers through the flatten mem and file datatypes
         * as well Note: no more than a single piece can be done
         * since we take the smallest one possible */

        if (cur_flat_buf_reg_left == region_size) {
#ifdef DEBUG_LIST2
            fprintf(stderr, "reached end of memory block...\n");
#endif
            (*flat_buf_index_p) = ((*flat_buf_index_p) + 1) % flat_buf_p->count;
            while (flat_buf_p->blocklens[(*flat_buf_index_p)] == 0) {
                (*flat_buf_index_p) = ((*flat_buf_index_p) + 1) % flat_buf_p->count;
            }
            *cur_flat_buf_reg_off_p = 0;

#ifdef COALESCE_REGIONS
            if (*buf_ol_count_p != 0) {
                if (buf_off_arr[(*buf_ol_count_p) - 1] +
                    buf_len_arr[(*buf_ol_count_p) - 1] == buf_off_arr[*buf_ol_count_p]) {
                    buf_len_arr[(*buf_ol_count_p) - 1] += region_size;
                } else {
                    buf_len_arr[*buf_ol_count_p] += region_size;
                    (*buf_ol_count_p)++;
                }
            } else {
#endif
                buf_len_arr[*buf_ol_count_p] += region_size;
                (*buf_ol_count_p)++;
#ifdef COALESCE_REGIONS
            }
#endif

            /* Don't prepare for the next piece if we have reached
             * the limit or else it will segment fault. */
            if ((*buf_ol_count_p) != max_ol_count) {
                buf_off_arr[*buf_ol_count_p] =
                    ((*bytes_completed + region_size) / flat_buf_size) *
                    flat_buf_extent +
                    flat_buf_p->indices[*flat_buf_index_p] + (*cur_flat_buf_reg_off_p);
                buf_len_arr[*buf_ol_count_p] = 0;
            }
        } else if (cur_flat_buf_reg_left > region_size) {
#ifdef DEBUG_LIST2
            fprintf(stderr, "advanced %d in memory block...\n", region_size);
#endif
            (*cur_flat_buf_reg_off_p) += region_size;
            buf_len_arr[*buf_ol_count_p] += region_size;
        } else {
            fprintf(stderr, "gen_listio_arr: Error\n");
        }

        /* To calculate the absolute file offset we need to
         * add the disp, how many filetypes we have gone through,
         * the relative block offset in the filetype and how far
         * into the block we have gone. */
        if (cur_flat_file_reg_left == region_size) {
#ifdef DEBUG_LIST2
            fprintf(stderr, "reached end of file block...\n");
#endif
            (*flat_file_index_p) = ((*flat_file_index_p) + 1) % flat_file_p->count;
            while (flat_file_p->blocklens[(*flat_file_index_p)] == 0) {
                (*flat_file_index_p) = ((*flat_file_index_p) + 1) % flat_file_p->count;
            }
            (*cur_flat_file_reg_off_p) = 0;

#ifdef COALESCE_REGIONS
            if (*file_ol_count_p != 0) {
                if (file_off_arr[(*file_ol_count_p) - 1] +
                    file_len_arr[(*file_ol_count_p) - 1] == file_off_arr[*file_ol_count_p]) {
                    file_len_arr[(*file_ol_count_p) - 1] += region_size;
                } else {
                    file_len_arr[*file_ol_count_p] += region_size;
                    (*file_ol_count_p)++;
                }
            } else {
#endif
                file_len_arr[*file_ol_count_p] += region_size;
                (*file_ol_count_p)++;
#ifdef COALESCE_REGIONS
            }
#endif

            /* Don't prepare for the next piece if we have reached
             * the limit or else it will segment fault. */
            if ((*file_ol_count_p) != max_ol_count) {
                file_off_arr[*file_ol_count_p] = disp +
                    (((bytes_into_filetype + *bytes_completed + region_size)
                      / flat_file_size) *
                     flat_file_extent) +
                    flat_file_p->indices[*flat_file_index_p] + (*cur_flat_file_reg_off_p);
                file_len_arr[*file_ol_count_p] = 0;
            }
        } else if (cur_flat_file_reg_left > region_size) {
#ifdef DEBUG_LIST2
            fprintf(stderr, "advanced %d in file block...\n", region_size);
#endif
            (*cur_flat_file_reg_off_p) += region_size;
            file_len_arr[*file_ol_count_p] += region_size;
        } else {
            fprintf(stderr, "gen_listio_arr: Error\n");
        }
#ifdef DEBUG_LIST2
        fprintf(stderr, "------------------------------\n\n");
#endif
        *bytes_completed += region_size;
    }
    /* Increment the count if we stopped in the middle of a
     * memory or file region */
    if (*cur_flat_buf_reg_off_p != 0)
        (*buf_ol_count_p)++;
    if (*cur_flat_file_reg_off_p != 0)
        (*file_ol_count_p)++;

    return 0;
}

void print_buf_file_ol_pairs(int64_t buf_off_arr[],
                             int32_t buf_len_arr[],
                             int32_t buf_ol_count,
                             int64_t file_off_arr[],
                             int32_t file_len_arr[], int32_t file_ol_count, void *buf, int rw_type)
{
    int i = -1;

    fprintf(stderr, "buf_ol_pairs(offset,length) count = %d\n", buf_ol_count);
    for (i = 0; i < buf_ol_count; i++) {
        fprintf(stderr, "(%lld, %d) ", (long long) buf_off_arr[i], buf_len_arr[i]);
    }
    fprintf(stderr, "\n");

    fprintf(stderr, "file_ol_pairs(offset,length) count = %d\n", file_ol_count);
    for (i = 0; i < file_ol_count; i++) {
        fprintf(stderr, "(%lld, %d) ", (long long) file_off_arr[i], file_len_arr[i]);
    }
    fprintf(stderr, "\n\n");

}