1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2017 The University of Tennessee and The University
7 * of Tennessee Research Foundation. All rights
8 * reserved.
9 * Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
10 * University of Stuttgart. All rights reserved.
11 * Copyright (c) 2004-2005 The Regents of the University of California.
12 * All rights reserved.
13 * Copyright (c) 2013 Los Alamos National Security, LLC. All rights
14 * reserved.
15 * $COPYRIGHT$
16 *
17 * Additional copyrights may follow
18 *
19 * $HEADER$
20 */
21
22 #include "ompi_config.h"
23 #include <stdio.h>
24 #include <limits.h>
25
26 #include "ompi/runtime/params.h"
27 #include "ompi/datatype/ompi_datatype.h"
28 #include "opal/datatype/opal_datatype_internal.h"
29
30 int ompi_datatype_get_elements (ompi_datatype_t *datatype, size_t ucount, size_t *count)
31 {
32 size_t internal_count, size, total;
33 int rc, i;
34
35 *count = 0;
36 if (OMPI_SUCCESS != (rc = ompi_datatype_type_size (datatype, &size))) {
37 return OMPI_ERR_BAD_PARAM;
38 }
39
40 if (size == 0) {
41 /* If the size of the datatype is zero let's return a count of zero */
42 return OMPI_SUCCESS;
43 }
44
45 internal_count = ucount / size; /* how many full types? */
46 size = ucount - internal_count * size; /* leftover bytes */
47
48 /* if basic type we should return the same result as MPI_Get_count (internal_count) if
49 there are no leftover bytes */
50 if (!ompi_datatype_is_predefined(datatype)) {
51 if (0 != internal_count) {
52 opal_datatype_compute_ptypes(&datatype->super);
53 /* count the basic elements in the datatype */
54 for (i = OPAL_DATATYPE_FIRST_TYPE, total = 0 ; i < OPAL_DATATYPE_MAX_PREDEFINED ; ++i) {
55 total += datatype->super.ptypes[i];
56 }
57 internal_count = total * internal_count;
58 }
59 if (size > 0) {
60 /* If there are any leftover bytes, compute the number of predefined
61 * types in the datatype that can fit in these bytes.
62 */
63 if (-1 == (i = ompi_datatype_get_element_count (datatype, size))) {
64 return OMPI_ERR_VALUE_OUT_OF_BOUNDS;
65 }
66
67 internal_count += i;
68 }
69 } else if (0 != size) {
70 /* no leftover is supported for predefined types */
71 return OMPI_ERR_VALUE_OUT_OF_BOUNDS;
72 }
73
74 *count = internal_count;
75
76 return OMPI_SUCCESS;
77 }