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 #include <mpid_dataloop.h>
10 #include <stdlib.h>
11
12 /* #define MPID_TYPE_ALLOC_DEBUG */
13
14 /*@
15 MPID_Type_contiguous - create a contiguous datatype
16
17 Input Parameters:
18 + count - number of elements in the contiguous block
19 - oldtype - type (using handle) of datatype on which vector is based
20
21 Output Parameters:
22 . newtype - handle of new contiguous datatype
23
24 Return Value:
25 MPI_SUCCESS on success, MPI error code on failure.
26 @*/
MPID_Type_contiguous(int count,MPI_Datatype oldtype,MPI_Datatype * newtype)27 int MPID_Type_contiguous(int count,
28 MPI_Datatype oldtype,
29 MPI_Datatype *newtype)
30 {
31 int mpi_errno = MPI_SUCCESS;
32 int is_builtin;
33 int el_sz;
34 MPI_Datatype el_type;
35 MPID_Datatype *new_dtp;
36
37 if (count == 0) return MPID_Type_zerolen(newtype);
38
39 /* allocate new datatype object and handle */
40 new_dtp = (MPID_Datatype *) MPIU_Handle_obj_alloc(&MPID_Datatype_mem);
41 /* --BEGIN ERROR HANDLING-- */
42 if (!new_dtp)
43 {
44 mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
45 "MPID_Type_contiguous",
46 __LINE__, MPI_ERR_OTHER,
47 "**nomem", 0);
48 return mpi_errno;
49 }
50 /* --END ERROR HANDLING-- */
51
52 /* handle is filled in by MPIU_Handle_obj_alloc() */
53 MPIU_Object_set_ref(new_dtp, 1);
54 new_dtp->is_permanent = 0;
55 new_dtp->is_committed = 0;
56 new_dtp->attributes = NULL;
57 new_dtp->cache_id = 0;
58 new_dtp->name[0] = 0;
59 new_dtp->contents = NULL;
60
61 new_dtp->dataloop = NULL;
62 new_dtp->dataloop_size = -1;
63 new_dtp->dataloop_depth = -1;
64 new_dtp->hetero_dloop = NULL;
65 new_dtp->hetero_dloop_size = -1;
66 new_dtp->hetero_dloop_depth = -1;
67
68 is_builtin = (HANDLE_GET_KIND(oldtype) == HANDLE_KIND_BUILTIN);
69
70 if (is_builtin)
71 {
72 el_sz = MPID_Datatype_get_basic_size(oldtype);
73 el_type = oldtype;
74
75 new_dtp->size = count * el_sz;
76 new_dtp->has_sticky_ub = 0;
77 new_dtp->has_sticky_lb = 0;
78 new_dtp->true_lb = 0;
79 new_dtp->lb = 0;
80 new_dtp->true_ub = count * el_sz;
81 new_dtp->ub = new_dtp->true_ub;
82 new_dtp->extent = new_dtp->ub - new_dtp->lb;
83
84 new_dtp->alignsize = el_sz;
85 new_dtp->n_elements = count;
86 new_dtp->element_size = el_sz;
87 new_dtp->eltype = el_type;
88 new_dtp->is_contig = 1;
89 new_dtp->max_contig_blocks = 1;
90
91 }
92 else
93 {
94 /* user-defined base type (oldtype) */
95 MPID_Datatype *old_dtp;
96
97 MPID_Datatype_get_ptr(oldtype, old_dtp);
98 el_sz = old_dtp->element_size;
99 el_type = old_dtp->eltype;
100
101 new_dtp->size = count * old_dtp->size;
102 new_dtp->has_sticky_ub = old_dtp->has_sticky_ub;
103 new_dtp->has_sticky_lb = old_dtp->has_sticky_lb;
104
105 MPID_DATATYPE_CONTIG_LB_UB((MPI_Aint) count,
106 old_dtp->lb,
107 old_dtp->ub,
108 old_dtp->extent,
109 new_dtp->lb,
110 new_dtp->ub);
111
112 /* easiest to calc true lb/ub relative to lb/ub; doesn't matter
113 * if there are sticky lb/ubs or not when doing this.
114 */
115 new_dtp->true_lb = new_dtp->lb + (old_dtp->true_lb - old_dtp->lb);
116 new_dtp->true_ub = new_dtp->ub + (old_dtp->true_ub - old_dtp->ub);
117 new_dtp->extent = new_dtp->ub - new_dtp->lb;
118
119 new_dtp->alignsize = old_dtp->alignsize;
120 new_dtp->n_elements = count * old_dtp->n_elements;
121 new_dtp->element_size = old_dtp->element_size;
122 new_dtp->eltype = el_type;
123
124 new_dtp->is_contig = old_dtp->is_contig;
125 if(old_dtp->is_contig)
126 new_dtp->max_contig_blocks = 1;
127 else
128 new_dtp->max_contig_blocks = count * old_dtp->max_contig_blocks;
129 }
130
131 *newtype = new_dtp->handle;
132
133 MPIU_DBG_MSG_P(DATATYPE,VERBOSE,"contig type %x created.",
134 new_dtp->handle);
135
136 return mpi_errno;
137 }
138
139