root/mpich2/trunk/src/mpi/datatype/type_hindexed.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_hindexed */
11#if defined(HAVE_PRAGMA_WEAK)
12#pragma weak MPI_Type_hindexed = PMPI_Type_hindexed
13#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
14#pragma _HP_SECONDARY_DEF PMPI_Type_hindexed  MPI_Type_hindexed
15#elif defined(HAVE_PRAGMA_CRI_DUP)
16#pragma _CRI duplicate MPI_Type_hindexed as PMPI_Type_hindexed
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_hindexed
24#define MPI_Type_hindexed PMPI_Type_hindexed
25
26#endif
27
28#undef FUNCNAME
29#define FUNCNAME MPI_Type_hindexed
30
31/*@
32    MPI_Type_hindexed - Creates an indexed datatype with offsets in bytes
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 - byte displacement of each block (array of MPI_Aint)
38- old_type - old datatype (handle)
39
40Output Parameter:
41. newtype - new datatype (handle)
42
43.N Deprecated
44This routine is replaced by 'MPI_Type_create_hindexed'.
45
46.N ThreadSafe
47
48.N Fortran
49
50The indices are displacements, and are based on a zero origin.  A common error
51is to do something like to following
52.vb
53    integer a(100)
54    integer blens(10), indices(10)
55    do i=1,10
56         blens(i)   = 1
5710       indices(i) = (1 + (i-1)*10) * sizeofint
58    call MPI_TYPE_HINDEXED(10,blens,indices,MPI_INTEGER,newtype,ierr)
59    call MPI_TYPE_COMMIT(newtype,ierr)
60    call MPI_SEND(a,1,newtype,...)
61.ve
62expecting this to send 'a(1),a(11),...' because the indices have values
63'1,11,...'.   Because these are `displacements` from the beginning of 'a',
64it actually sends 'a(1+1),a(1+11),...'.
65
66If you wish to consider the displacements as indices into a Fortran array,
67consider declaring the Fortran array with a zero origin
68.vb
69    integer a(0:99)
70.ve
71
72.N Errors
73.N MPI_SUCCESS
74.N MPI_ERR_TYPE
75.N MPI_ERR_COUNT
76.N MPI_ERR_EXHAUSTED
77.N MPI_ERR_ARG
78@*/
79int MPI_Type_hindexed(int count,
80                      int blocklens[],
81                      MPI_Aint indices[],
82                      MPI_Datatype old_type,
83                      MPI_Datatype *newtype)
84{
85    static const char FCNAME[] = "MPI_Type_hindexed";
86    int mpi_errno = MPI_SUCCESS;
87    MPID_Datatype *new_dtp;
88    int i, *ints;
89    MPIU_CHKLMEM_DECL(1);
90    MPID_MPI_STATE_DECL(MPID_STATE_MPI_TYPE_HINDEXED);
91
92    MPIR_ERRTEST_INITIALIZED_ORDIE();
93   
94    MPIU_THREAD_CS_ENTER(ALLFUNC,);
95    MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_TYPE_HINDEXED);
96
97#   ifdef HAVE_ERROR_CHECKING
98    {
99        MPID_BEGIN_ERROR_CHECKS;
100        {
101            int i;
102            MPID_Datatype *datatype_ptr = NULL;
103
104            MPIR_ERRTEST_COUNT(count, mpi_errno);
105            MPIR_ERRTEST_DATATYPE(old_type, "datatype", mpi_errno);
106            if (count > 0) {
107                MPIR_ERRTEST_ARGNULL(blocklens, "blocklens", mpi_errno);
108                MPIR_ERRTEST_ARGNULL(indices, "indices", mpi_errno);
109            }
110            if (mpi_errno == MPI_SUCCESS) {
111                if (HANDLE_GET_KIND(old_type) != HANDLE_KIND_BUILTIN) {
112                    MPID_Datatype_get_ptr( old_type, datatype_ptr );
113                    MPID_Datatype_valid_ptr(datatype_ptr, mpi_errno);
114                }
115                /* verify that all blocklengths are >= 0 */
116                for (i=0; i < count; i++) {
117                    MPIR_ERRTEST_ARGNEG(blocklens[i], "blocklen", mpi_errno);
118                }
119            }
120            MPIR_ERRTEST_ARGNULL(newtype, "newtype", mpi_errno);
121            if (mpi_errno != MPI_SUCCESS) goto fn_fail;
122        }
123        MPID_END_ERROR_CHECKS;
124    }
125#   endif /* HAVE_ERROR_CHECKING */
126
127    /* ... body of routine ...  */
128   
129    mpi_errno = MPID_Type_indexed(count,
130                                  blocklens,
131                                  indices,
132                                  1, /* displacements in bytes */
133                                  old_type,
134                                  newtype);
135    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
136
137    MPIU_CHKLMEM_MALLOC(ints, int *, (count + 1) * sizeof(int), mpi_errno, "contents integer array");
138
139    /* copy ints into temporary buffer (count and blocklengths) */
140    ints[0] = count;
141    for (i=0; i < count; i++)
142    {
143        ints[i+1] = blocklens[i];
144    }
145
146    MPID_Datatype_get_ptr(*newtype, new_dtp);
147    mpi_errno = MPID_Datatype_set_contents(new_dtp,
148                                           MPI_COMBINER_HINDEXED,
149                                           count+1, /* ints */
150                                           count, /* aints (displs) */
151                                           1, /* types */
152                                           ints,
153                                           indices,
154                                           &old_type);
155    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
156
157    /* ... end of body of routine ... */
158
159  fn_exit:
160    MPIU_CHKLMEM_FREEALL();
161    MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_TYPE_HINDEXED);
162    MPIU_THREAD_CS_EXIT(ALLFUNC,);
163    return mpi_errno;
164
165  fn_fail:
166    /* --BEGIN ERROR HANDLING-- */
167#   ifdef HAVE_ERROR_CHECKING
168    {
169        mpi_errno = MPIR_Err_create_code(
170            mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_type_hindexed",
171            "**mpi_type_hindexed %d %p %p %D %p", count, blocklens, indices, old_type, newtype);
172    }
173#   endif
174    mpi_errno = MPIR_Err_return_comm( NULL, FCNAME, mpi_errno );
175    goto fn_exit;
176    /* --END ERROR HANDLING-- */
177}
Note: See TracBrowser for help on using the browser.