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

Revision 3177, 4.7 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_create_struct */
11#if defined(HAVE_PRAGMA_WEAK)
12#pragma weak MPI_Type_create_struct = PMPI_Type_create_struct
13#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
14#pragma _HP_SECONDARY_DEF PMPI_Type_create_struct  MPI_Type_create_struct
15#elif defined(HAVE_PRAGMA_CRI_DUP)
16#pragma _CRI duplicate MPI_Type_create_struct as PMPI_Type_create_struct
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_create_struct
24#define MPI_Type_create_struct PMPI_Type_create_struct
25
26#endif
27
28#undef FUNCNAME
29#define FUNCNAME MPI_Type_create_struct
30
31/*@
32   MPI_Type_create_struct - Create an MPI datatype from a general set of
33   datatypes, displacements, and block sizes
34
35   Input Parameters:
36+ count - number of blocks (integer) --- also number of entries in arrays
37  array_of_types, array_of_displacements and array_of_blocklengths
38. array_of_blocklength - number of elements in each block (array of integer)
39. array_of_displacements - byte displacement of each block (array of address integer)
40- array_of_types - type of elements in each block (array of handles to
41  datatype objects)
42
43   Output Parameter:
44. newtype - new datatype (handle)
45
46.N ThreadSafe
47
48.N Fortran
49
50.N Errors
51.N MPI_SUCCESS
52.N MPI_ERR_ARG
53.N MPI_ERR_TYPE
54@*/
55int MPI_Type_create_struct(int count,
56                           int array_of_blocklengths[],
57                           MPI_Aint array_of_displacements[],
58                           MPI_Datatype array_of_types[],
59                           MPI_Datatype *newtype)
60{
61    static const char FCNAME[] = "MPI_Type_create_struct";
62    int mpi_errno = MPI_SUCCESS;
63    int i, *ints;
64    MPID_Datatype *new_dtp;
65    MPIU_CHKLMEM_DECL(1);
66    MPID_MPI_STATE_DECL(MPID_STATE_MPI_TYPE_CREATE_STRUCT);
67
68    MPIR_ERRTEST_INITIALIZED_ORDIE();
69
70    MPIU_THREAD_CS_ENTER(ALLFUNC,);
71    MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_TYPE_CREATE_STRUCT);
72
73#   ifdef HAVE_ERROR_CHECKING
74    {
75        MPID_BEGIN_ERROR_CHECKS;
76        {
77            int i;
78            MPID_Datatype *datatype_ptr = NULL;
79
80            MPIR_ERRTEST_COUNT(count,mpi_errno);
81            if (mpi_errno != MPI_SUCCESS) goto fn_fail;
82
83            if (count > 0) {
84                MPIR_ERRTEST_ARGNULL(array_of_blocklengths, "blocklens", mpi_errno);
85                MPIR_ERRTEST_ARGNULL(array_of_displacements, "indices", mpi_errno);
86                MPIR_ERRTEST_ARGNULL(array_of_types, "types", mpi_errno);
87                if (mpi_errno != MPI_SUCCESS) goto fn_fail;
88            }
89
90            for (i=0; i < count; i++) {
91                MPIR_ERRTEST_ARGNEG(array_of_blocklengths[i], "blocklen", mpi_errno);
92                MPIR_ERRTEST_DATATYPE(array_of_types[i], "datatype[i]",
93                                      mpi_errno);
94                if (mpi_errno != MPI_SUCCESS) goto fn_fail;
95                       
96                if (array_of_types[i] != MPI_DATATYPE_NULL && HANDLE_GET_KIND(array_of_types[i]) != HANDLE_KIND_BUILTIN) {
97                    MPID_Datatype_get_ptr(array_of_types[i], datatype_ptr);
98                    MPID_Datatype_valid_ptr(datatype_ptr, mpi_errno);
99                    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
100                }
101            }
102        }
103        MPID_END_ERROR_CHECKS;
104    }
105#   endif /* HAVE_ERROR_CHECKING */
106
107    /* ... body of routine ... */
108
109    mpi_errno = MPID_Type_struct(count,
110                                 array_of_blocklengths,
111                                 array_of_displacements,
112                                 array_of_types,
113                                 newtype);
114
115    /* --BEGIN ERROR HANDLING-- */
116    if (mpi_errno != MPI_SUCCESS)
117        goto fn_fail;
118    /* --END ERROR HANDLING-- */
119
120    MPIU_CHKLMEM_MALLOC_ORJUMP(ints, int *, (count + 1) * sizeof(int), mpi_errno, "content description");
121
122    ints[0] = count;
123    for (i=0; i < count; i++)
124    {
125        ints[i+1] = array_of_blocklengths[i];
126    }
127
128    MPID_Datatype_get_ptr(*newtype, new_dtp);
129    mpi_errno = MPID_Datatype_set_contents(new_dtp,
130                                           MPI_COMBINER_STRUCT,
131                                           count+1, /* ints (cnt,blklen) */
132                                           count, /* aints (disps) */
133                                           count, /* types */
134                                           ints,
135                                           array_of_displacements,
136                                           array_of_types);
137
138    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
139
140    /* ... end of body of routine ... */
141
142  fn_exit:
143    MPIU_CHKLMEM_FREEALL();
144    MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_TYPE_CREATE_STRUCT);
145    MPIU_THREAD_CS_EXIT(ALLFUNC,);
146    return mpi_errno;
147
148  fn_fail:
149    /* --BEGIN ERROR HANDLING-- */
150#   ifdef HAVE_ERROR_CHECKING
151    {
152        mpi_errno = MPIR_Err_create_code(
153            mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_type_create_struct",
154            "**mpi_type_create_struct %d %p %p %p %p", count, array_of_blocklengths, array_of_displacements,
155            array_of_types, newtype);
156    }
157#   endif
158    mpi_errno = MPIR_Err_return_comm(NULL, FCNAME, mpi_errno);
159    goto fn_exit;
160    /* --END ERROR HANDLING-- */
161}
Note: See TracBrowser for help on using the browser.