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 #undef FCNAME
13 #define FCNAME "MPID_Type_dup"
14
15 /* #define MPID_TYPE_ALLOC_DEBUG */
16
17 /*@
18 MPID_Type_dup - create a copy of a datatype
19
20 Input Parameters:
21 - oldtype - handle of original datatype
22
23 Output Parameters:
24 . newtype - handle of newly created copy of datatype
25
26 Return Value:
27 0 on success, -1 on failure.
28 @*/
MPID_Type_dup(MPI_Datatype oldtype,MPI_Datatype * newtype)29 int MPID_Type_dup(MPI_Datatype oldtype,
30 MPI_Datatype *newtype)
31 {
32 int mpi_errno = MPI_SUCCESS;
33 MPID_Datatype *new_dtp = 0, *old_dtp;
34
35 if (HANDLE_GET_KIND(oldtype) == HANDLE_KIND_BUILTIN) {
36 /* create a new type and commit it. */
37 mpi_errno = MPID_Type_contiguous(1, oldtype, newtype);
38 if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
39 }
40 else {
41 /* allocate new datatype object and handle */
42 new_dtp = (MPID_Datatype *) MPIU_Handle_obj_alloc(&MPID_Datatype_mem);
43 if (!new_dtp) {
44 /* --BEGIN ERROR HANDLING-- */
45 mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
46 "MPID_Type_dup", __LINE__, MPI_ERR_OTHER,
47 "**nomem", 0);
48 goto fn_fail;
49 /* --END ERROR HANDLING-- */
50 }
51
52 MPID_Datatype_get_ptr(oldtype, old_dtp);
53
54 /* fill in datatype */
55 MPIU_Object_set_ref(new_dtp, 1);
56 /* new_dtp->handle is filled in by MPIU_Handle_obj_alloc() */
57 new_dtp->is_contig = old_dtp->is_contig;
58 new_dtp->size = old_dtp->size;
59 new_dtp->extent = old_dtp->extent;
60 new_dtp->ub = old_dtp->ub;
61 new_dtp->lb = old_dtp->lb;
62 new_dtp->true_ub = old_dtp->true_ub;
63 new_dtp->true_lb = old_dtp->true_lb;
64 new_dtp->alignsize = old_dtp->alignsize;
65 new_dtp->has_sticky_ub = old_dtp->has_sticky_ub;
66 new_dtp->has_sticky_lb = old_dtp->has_sticky_lb;
67 new_dtp->is_permanent = old_dtp->is_permanent;
68 new_dtp->is_committed = old_dtp->is_committed;
69 new_dtp->attributes = NULL; /* ??? */
70 new_dtp->cache_id = -1; /* ??? */
71 new_dtp->name[0] = 0; /* ??? */
72 new_dtp->n_elements = old_dtp->n_elements;
73 new_dtp->element_size = old_dtp->element_size;
74 new_dtp->eltype = old_dtp->eltype;
75
76 new_dtp->dataloop = NULL;
77 new_dtp->dataloop_size = old_dtp->dataloop_size;
78 new_dtp->dataloop_depth = old_dtp->dataloop_depth;
79 new_dtp->hetero_dloop = NULL;
80 new_dtp->hetero_dloop_size = old_dtp->hetero_dloop_size;
81 new_dtp->hetero_dloop_depth = old_dtp->hetero_dloop_depth;
82
83 *newtype = new_dtp->handle;
84
85 if (old_dtp->is_committed) {
86 MPIU_Assert(old_dtp->dataloop != NULL);
87 MPID_Dataloop_dup(old_dtp->dataloop,
88 old_dtp->dataloop_size,
89 &new_dtp->dataloop);
90 if (old_dtp->hetero_dloop != NULL) {
91 /* at this time MPI_COMPLEX doesn't have this loop...
92 * -- RBR, 02/01/2007
93 */
94 MPID_Dataloop_dup(old_dtp->hetero_dloop,
95 old_dtp->hetero_dloop_size,
96 &new_dtp->hetero_dloop);
97 }
98 }
99 }
100
101 MPIU_DBG_MSG_D(DATATYPE,VERBOSE, "dup type %x created.", *newtype);
102
103 fn_fail:
104 return mpi_errno;
105 }
106