root/mpich2/trunk/src/mpi/datatype/type_hindexed.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_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 j;
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 (j=0; j < count; j++) {
117                    MPIR_ERRTEST_ARGNEG(blocklens[j], "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.