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