root/mpich2/trunk/src/mpi/datatype/type_indexed.c @ 4888

Revision 4888, 5.0 KB (checked in by buntinas, 5 months ago)

squashed more warnings

Line 
1/* -*- Mode: C; c-basic-offset:4 ; -*- */
2/*
3 *
4 *  (C) 2001 by Argonne National Laboratory.
5 *      See COPYRIGHT in top-level directory.
6 */
7
8#include "mpiimpl.h"
9
10/* -- Begin Profiling Symbol Block for routine MPI_Type_indexed */
11#if defined(HAVE_PRAGMA_WEAK)
12#pragma weak MPI_Type_indexed = PMPI_Type_indexed
13#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
14#pragma _HP_SECONDARY_DEF PMPI_Type_indexed  MPI_Type_indexed
15#elif defined(HAVE_PRAGMA_CRI_DUP)
16#pragma _CRI duplicate MPI_Type_indexed as PMPI_Type_indexed
17#endif
18/* -- End Profiling Symbol Block */
19
20/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
21   the MPI routines */
22#ifndef MPICH_MPI_FROM_PMPI
23#undef MPI_Type_indexed
24#define MPI_Type_indexed PMPI_Type_indexed
25
26#endif
27
28#undef FUNCNAME
29#define FUNCNAME MPI_Type_indexed
30
31/*@
32    MPI_Type_indexed - Creates an indexed datatype
33
34Input Parameters:
35+ count - number of blocks -- also number of entries in indices and blocklens
36. blocklens - number of elements in each block (array of nonnegative integers)
37. indices - displacement of each block in multiples of old_type (array of
38  integers)
39- old_type - old datatype (handle)
40
41Output Parameter:
42. newtype - new datatype (handle)
43
44.N ThreadSafe
45
46.N Fortran
47
48The indices are displacements, and are based on a zero origin.  A common error
49is to do something like to following
50.vb
51    integer a(100)
52    integer blens(10), indices(10)
53    do i=1,10
54         blens(i)   = 1
5510       indices(i) = 1 + (i-1)*10
56    call MPI_TYPE_INDEXED(10,blens,indices,MPI_INTEGER,newtype,ierr)
57    call MPI_TYPE_COMMIT(newtype,ierr)
58    call MPI_SEND(a,1,newtype,...)
59.ve
60expecting this to send 'a(1),a(11),...' because the indices have values
61'1,11,...'.   Because these are `displacements` from the beginning of 'a',
62it actually sends 'a(1+1),a(1+11),...'.
63
64If you wish to consider the displacements as indices into a Fortran array,
65consider declaring the Fortran array with a zero origin
66.vb
67    integer a(0:99)
68.ve
69
70.N Errors
71.N MPI_ERR_COUNT
72.N MPI_ERR_TYPE
73.N MPI_ERR_ARG
74.N MPI_ERR_EXHAUSTED
75@*/
76int MPI_Type_indexed(int count,
77                     int blocklens[],
78                     int indices[],
79                     MPI_Datatype old_type,
80                     MPI_Datatype *newtype)
81{
82    static const char FCNAME[] = "MPI_Type_indexed";
83    int mpi_errno = MPI_SUCCESS;
84    MPID_Datatype *new_dtp;
85    int i, *ints;
86    MPIU_CHKLMEM_DECL(1);
87    MPID_MPI_STATE_DECL(MPID_STATE_MPI_TYPE_INDEXED);
88
89    MPIR_ERRTEST_INITIALIZED_ORDIE();
90   
91    MPIU_THREAD_CS_ENTER(ALLFUNC,);
92    MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_TYPE_INDEXED);
93
94    /* Validate parameters and objects (post conversion) */
95#   ifdef HAVE_ERROR_CHECKING
96    {
97        MPID_BEGIN_ERROR_CHECKS;
98        {
99            int j;
100            MPID_Datatype *datatype_ptr = NULL;
101
102            MPIR_ERRTEST_COUNT(count,mpi_errno);
103            if (count > 0) {
104                MPIR_ERRTEST_ARGNULL(blocklens, "blocklens", mpi_errno);
105                MPIR_ERRTEST_ARGNULL(indices, "indices", mpi_errno);
106            }
107            MPIR_ERRTEST_DATATYPE(old_type, "datatype", mpi_errno);
108            if (mpi_errno == MPI_SUCCESS) {
109                if (HANDLE_GET_KIND(old_type) != HANDLE_KIND_BUILTIN) {
110                    MPID_Datatype_get_ptr( old_type, datatype_ptr );
111                    MPID_Datatype_valid_ptr( datatype_ptr, mpi_errno );
112                }
113                /* verify that all blocklengths are >= 0 */
114                for (j=0; j < count; j++) {
115                    MPIR_ERRTEST_ARGNEG(blocklens[j], "blocklen", mpi_errno);
116                }
117            }
118            MPIR_ERRTEST_ARGNULL(newtype, "newtype", mpi_errno);
119            if (mpi_errno != MPI_SUCCESS) goto fn_fail;
120        }
121        MPID_END_ERROR_CHECKS;
122    }
123#   endif /* HAVE_ERROR_CHECKING */
124
125    /* ... body of routine ...  */
126   
127    mpi_errno = MPID_Type_indexed(count,
128                                  blocklens,
129                                  indices,
130                                  0, /* displacements not in bytes */
131                                  old_type,
132                                  newtype);
133    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
134
135    /* copy all integer values into a temporary buffer; this
136     * includes the count, the blocklengths, and the displacements.
137     */
138    MPIU_CHKLMEM_MALLOC(ints, int *, (2 * count + 1) * sizeof(int), mpi_errno, "contents integer array");
139
140    ints[0] = count;
141
142    for (i=0; i < count; i++) {
143        ints[i+1] = blocklens[i];
144    }
145    for (i=0; i < count; i++) {
146        ints[i + count + 1] = indices[i];
147    }
148    MPID_Datatype_get_ptr(*newtype, new_dtp);
149    mpi_errno = MPID_Datatype_set_contents(new_dtp,
150                                           MPI_COMBINER_INDEXED,
151                                           2*count + 1, /* ints */
152                                           0, /* aints  */
153                                           1, /* types */
154                                           ints,
155                                           NULL,
156                                           &old_type);
157    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
158
159    /* ... end of body of routine ... */
160
161  fn_exit:
162    MPIU_CHKLMEM_FREEALL();
163    MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_TYPE_INDEXED);
164    MPIU_THREAD_CS_EXIT(ALLFUNC,);
165    return mpi_errno;
166
167  fn_fail:
168    /* --BEGIN ERROR HANDLING-- */
169#   ifdef HAVE_ERROR_CHECKING
170    {
171        mpi_errno = MPIR_Err_create_code(
172            mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_type_indexed",
173            "**mpi_type_indexed %d %p %p %D %p", count,blocklens, indices, old_type, newtype);
174    }
175#   endif
176    mpi_errno = MPIR_Err_return_comm( NULL, FCNAME, mpi_errno );
177    goto fn_exit;
178    /* --END ERROR HANDLING-- */
179}
Note: See TracBrowser for help on using the browser.