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

Revision 3177, 5.0 KB (checked in by gropp, 14 months ago)

Switch to the new macro for the global thread critical section (most of this is an automated change, tested against the MPICH2 test suite)

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 i;
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 (i=0; i < count; i++) {
115                    MPIR_ERRTEST_ARGNEG(blocklens[i], "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.