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