~ubuntu-branches/ubuntu/hardy/openmpi/hardy-updates

« back to all changes in this revision

Viewing changes to ompi/mca/coll/basic/coll_basic_gatherv.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2006-10-15 00:46:11 UTC
  • Revision ID: james.westby@ubuntu.com-20061015004611-uuhxnaxyjmuxfd5h
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
 
3
 *                         University Research and Technology
 
4
 *                         Corporation.  All rights reserved.
 
5
 * Copyright (c) 2004-2005 The University of Tennessee and The University
 
6
 *                         of Tennessee Research Foundation.  All rights
 
7
 *                         reserved.
 
8
 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, 
 
9
 *                         University of Stuttgart.  All rights reserved.
 
10
 * Copyright (c) 2004-2005 The Regents of the University of California.
 
11
 *                         All rights reserved.
 
12
 * $COPYRIGHT$
 
13
 * 
 
14
 * Additional copyrights may follow
 
15
 * 
 
16
 * $HEADER$
 
17
 */
 
18
 
 
19
#include "ompi_config.h"
 
20
#include "coll_basic.h"
 
21
 
 
22
#include "mpi.h"
 
23
#include "ompi/constants.h"
 
24
#include "ompi/datatype/datatype.h"
 
25
#include "ompi/mca/coll/coll.h"
 
26
#include "ompi/mca/coll/base/coll_tags.h"
 
27
#include "coll_basic.h"
 
28
 
 
29
/*
 
30
 *      gatherv_intra
 
31
 *
 
32
 *      Function:       - basic gatherv operation
 
33
 *      Accepts:        - same arguments as MPI_Gatherb()
 
34
 *      Returns:        - MPI_SUCCESS or error code
 
35
 */
 
36
int
 
37
mca_coll_basic_gatherv_intra(void *sbuf, int scount,
 
38
                             struct ompi_datatype_t *sdtype,
 
39
                             void *rbuf, int *rcounts, int *disps,
 
40
                             struct ompi_datatype_t *rdtype, int root,
 
41
                             struct ompi_communicator_t *comm)
 
42
{
 
43
    int i;
 
44
    int rank;
 
45
    int size;
 
46
    int err;
 
47
    char *ptmp;
 
48
    long lb;
 
49
    long extent;
 
50
 
 
51
    size = ompi_comm_size(comm);
 
52
    rank = ompi_comm_rank(comm);
 
53
 
 
54
    /* Everyone but root sends data and returns.  Don't send anything
 
55
       for sendcounts of 0 (even though MPI_Gatherv has a guard for 0
 
56
       counts, this routine is used elsewhere, like the implementation
 
57
       of allgatherv, so it's possible to get here with a scount of
 
58
       0) */
 
59
 
 
60
    if (rank != root) {
 
61
        if (scount > 0) {
 
62
            return MCA_PML_CALL(send(sbuf, scount, sdtype, root,
 
63
                                     MCA_COLL_BASE_TAG_GATHERV,
 
64
                                     MCA_PML_BASE_SEND_STANDARD, comm));
 
65
        }
 
66
        return MPI_SUCCESS;
 
67
    }
 
68
 
 
69
    /* I am the root, loop receiving data. */
 
70
 
 
71
    err = ompi_ddt_get_extent(rdtype, &lb, &extent);
 
72
    if (OMPI_SUCCESS != err) {
 
73
        return OMPI_ERROR;
 
74
    }
 
75
 
 
76
    for (i = 0; i < size; ++i) {
 
77
        ptmp = ((char *) rbuf) + (extent * disps[i]);
 
78
 
 
79
        if (i == rank) {
 
80
            /* simple optimization */
 
81
            if (MPI_IN_PLACE != sbuf && (0 < scount) && (0 < rcounts[i])) {
 
82
                err = ompi_ddt_sndrcv(sbuf, scount, sdtype,
 
83
                                      ptmp, rcounts[i], rdtype);
 
84
            }
 
85
        } else {
 
86
            /* Only receive if there is something to receive */
 
87
            if (rcounts[i] > 0) {
 
88
                err = MCA_PML_CALL(recv(ptmp, rcounts[i], rdtype, i,
 
89
                                        MCA_COLL_BASE_TAG_GATHERV,
 
90
                                        comm, MPI_STATUS_IGNORE));
 
91
            }
 
92
        }
 
93
 
 
94
        if (MPI_SUCCESS != err) {
 
95
            return err;
 
96
        }
 
97
    }
 
98
 
 
99
    /* All done */
 
100
 
 
101
    return MPI_SUCCESS;
 
102
}
 
103
 
 
104
 
 
105
/*
 
106
 *      gatherv_inter
 
107
 *
 
108
 *      Function:       - basic gatherv operation
 
109
 *      Accepts:        - same arguments as MPI_Gatherv()
 
110
 *      Returns:        - MPI_SUCCESS or error code
 
111
 */
 
112
int
 
113
mca_coll_basic_gatherv_inter(void *sbuf, int scount,
 
114
                             struct ompi_datatype_t *sdtype,
 
115
                             void *rbuf, int *rcounts, int *disps,
 
116
                             struct ompi_datatype_t *rdtype, int root,
 
117
                             struct ompi_communicator_t *comm)
 
118
{
 
119
    int i;
 
120
    int rank;
 
121
    int size;
 
122
    int err;
 
123
    char *ptmp;
 
124
    long lb;
 
125
    long extent;
 
126
    ompi_request_t **reqs = comm->c_coll_basic_data->mccb_reqs;
 
127
 
 
128
    size = ompi_comm_remote_size(comm);
 
129
    rank = ompi_comm_rank(comm);
 
130
 
 
131
    /* If not root, receive data.  Note that we will only get here if
 
132
     * scount > 0 or rank == root. */
 
133
 
 
134
    if (MPI_PROC_NULL == root) {
 
135
        /* do nothing */
 
136
        err = OMPI_SUCCESS;
 
137
    } else if (MPI_ROOT != root) {
 
138
        /* Everyone but root sends data and returns. */
 
139
        err = MCA_PML_CALL(send(sbuf, scount, sdtype, root,
 
140
                                MCA_COLL_BASE_TAG_GATHERV,
 
141
                                MCA_PML_BASE_SEND_STANDARD, comm));
 
142
    } else {
 
143
        /* I am the root, loop receiving data. */
 
144
        err = ompi_ddt_get_extent(rdtype, &lb, &extent);
 
145
        if (OMPI_SUCCESS != err) {
 
146
            return OMPI_ERROR;
 
147
        }
 
148
 
 
149
        for (i = 0; i < size; ++i) {
 
150
            ptmp = ((char *) rbuf) + (extent * disps[i]);
 
151
            err = MCA_PML_CALL(irecv(ptmp, rcounts[i], rdtype, i,
 
152
                                     MCA_COLL_BASE_TAG_GATHERV,
 
153
                                     comm, &reqs[i]));
 
154
            if (OMPI_SUCCESS != err) {
 
155
                return err;
 
156
            }
 
157
        }
 
158
 
 
159
        err = ompi_request_wait_all(size, reqs, MPI_STATUSES_IGNORE);
 
160
    }
 
161
 
 
162
    /* All done */
 
163
    return err;
 
164
}