File: ad_subarray.c

package info (click to toggle)
openmpi 5.0.8-3
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 201,692 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 (93 lines) | stat: -rw-r--r-- 2,967 bytes parent folder | download | duplicates (8)
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
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

#include "adio.h"
#include "adio_extern.h"

int ADIO_Type_create_subarray(int ndims,
                              int *array_of_sizes,
                              int *array_of_subsizes,
                              int *array_of_starts,
                              int order, MPI_Datatype oldtype, MPI_Datatype * newtype)
{
    MPI_Aint lb, ub, extent, disps[1], size;
    int i, blklens[3];
    MPI_Datatype tmp1, tmp2, types[3];

    MPI_Type_get_extent(oldtype, &lb, &extent);

    if (order == MPI_ORDER_FORTRAN) {
        /* dimension 0 changes fastest */
        if (ndims == 1) {
            MPI_Type_contiguous(array_of_subsizes[0], oldtype, &tmp1);
        } else {
            MPI_Type_vector(array_of_subsizes[1],
                            array_of_subsizes[0], array_of_sizes[0], oldtype, &tmp1);

            size = (MPI_Aint) array_of_sizes[0] * extent;
            for (i = 2; i < ndims; i++) {
                size *= (MPI_Aint) array_of_sizes[i - 1];
                MPI_Type_create_hvector(array_of_subsizes[i], 1, size, tmp1, &tmp2);
                MPI_Type_free(&tmp1);
                tmp1 = tmp2;
            }
        }

        /* add displacement and UB */
        disps[0] = array_of_starts[0];
        size = 1;
        for (i = 1; i < ndims; i++) {
            size *= (MPI_Aint) array_of_sizes[i - 1];
            disps[0] += size * (MPI_Aint) array_of_starts[i];
        }
        /* rest done below for both Fortran and C order */
    }

    else {      /* order == MPI_ORDER_C */

        /* dimension ndims-1 changes fastest */
        if (ndims == 1) {
            MPI_Type_contiguous(array_of_subsizes[0], oldtype, &tmp1);
        } else {
            MPI_Type_vector(array_of_subsizes[ndims - 2],
                            array_of_subsizes[ndims - 1],
                            array_of_sizes[ndims - 1], oldtype, &tmp1);

            size = (MPI_Aint) array_of_sizes[ndims - 1] * extent;
            for (i = ndims - 3; i >= 0; i--) {
                size *= (MPI_Aint) array_of_sizes[i + 1];
                MPI_Type_create_hvector(array_of_subsizes[i], 1, size, tmp1, &tmp2);
                MPI_Type_free(&tmp1);
                tmp1 = tmp2;
            }
        }

        /* add displacement and UB */
        disps[0] = array_of_starts[ndims - 1];
        size = 1;
        for (i = ndims - 2; i >= 0; i--) {
            size *= (MPI_Aint) array_of_sizes[i + 1];
            disps[0] += size * (MPI_Aint) array_of_starts[i];
        }
    }

    disps[0] *= extent;

    ub = extent;
    for (i = 0; i < ndims; i++)
        ub *= (MPI_Aint) array_of_sizes[i];

    lb = 0;
    blklens[0] = 1;
    types[0] = tmp1;

    MPI_Type_create_struct(1, blklens, disps, types, &tmp2);
    MPI_Type_create_resized(tmp2, lb, ub, newtype);

    MPI_Type_free(&tmp1);
    MPI_Type_free(&tmp2);

    return MPI_SUCCESS;
}