2012-08-16 23:11:35 +04:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2009-2012 Oak Ridge National Laboratory. All rights reserved.
|
|
|
|
* Copyright (c) 2009-2012 Mellanox Technologies. All rights reserved.
|
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
/** @file */
|
|
|
|
|
|
|
|
#include "ompi_config.h"
|
|
|
|
|
|
|
|
#include "ompi/constants.h"
|
|
|
|
#include "opal/threads/mutex.h"
|
|
|
|
#include "ompi/communicator/communicator.h"
|
|
|
|
#include "ompi/mca/coll/coll.h"
|
|
|
|
#include "ompi/mca/bcol/bcol.h"
|
|
|
|
#include "opal/sys/atomic.h"
|
|
|
|
#include "ompi/mca/coll/ml/coll_ml.h"
|
2012-08-29 18:10:42 +04:00
|
|
|
#include "ompi/mca/coll/ml/coll_ml_inlines.h"
|
2012-08-16 23:11:35 +04:00
|
|
|
#include "ompi/mca/coll/ml/coll_ml_allocation.h"
|
|
|
|
#include "coll_ml_colls.h"
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/uio.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* This routine re-orders and packs user data. The assumption is that
|
|
|
|
* there is per-process data, the amount of data is the same for all
|
|
|
|
* ranks, and the user data is contigous.
|
|
|
|
*/
|
|
|
|
int mca_coll_ml_pack_reorder_contiguous_data(mca_coll_ml_collective_operation_progress_t *coll_op)
|
|
|
|
{
|
|
|
|
int i, rank;
|
|
|
|
void *user_buf, *library_buf;
|
|
|
|
size_t bytes_per_proc;
|
|
|
|
mca_coll_ml_module_t *ml_module = (mca_coll_ml_module_t *)
|
|
|
|
coll_op->coll_module;
|
|
|
|
mca_coll_ml_topology_t *topo_info = coll_op->coll_schedule->topo_info;
|
|
|
|
ptrdiff_t ptr_dif;
|
|
|
|
|
|
|
|
/* get the offset into each processes data. The assumption is that
|
|
|
|
* we are manipulating the same amount of data for each process.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* figure out how much data per-proc to copy */
|
|
|
|
bytes_per_proc=coll_op->fragment_data.per_rank_fragment_size;
|
|
|
|
|
|
|
|
/* loop over all the ranks in the communicator */
|
|
|
|
for( i=0 ; i < ompi_comm_size(ml_module->comm) ; i++ ) {
|
|
|
|
|
|
|
|
/* look up the rank of the i'th element in the sorted list */
|
|
|
|
rank = topo_info->sort_list[i];
|
|
|
|
|
|
|
|
/* get the pointer to user data */
|
|
|
|
user_buf=coll_op->full_message.src_user_addr;
|
|
|
|
/* compute offset into the user buffer */
|
|
|
|
|
|
|
|
/* offset for data already processed */
|
|
|
|
ptr_dif=rank*coll_op->full_message.n_bytes_per_proc_total+
|
|
|
|
coll_op->fragment_data.offset_into_user_buffer_per_proc;
|
|
|
|
user_buf=(void *) ((char *)user_buf+ptr_dif);
|
|
|
|
/*
|
|
|
|
rank*coll_op->full_message.n_bytes_per_proc_total+
|
|
|
|
coll_op->fragment_data.offset_into_user_buffer_per_proc);
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* get the pointer to the ML buffer */
|
|
|
|
library_buf= (void *)
|
|
|
|
((char *)coll_op->variable_fn_params.src_desc->data_addr+i*bytes_per_proc);
|
|
|
|
|
|
|
|
/* copy the data */
|
|
|
|
memcpy(library_buf, user_buf, bytes_per_proc);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This routine re-orders and packs user data. The assumption is that
|
|
|
|
* there is per-process data, the amount of data is the same for all
|
|
|
|
* ranks, and the user data is contigous.
|
|
|
|
*/
|
|
|
|
int mca_coll_ml_pack_reorder_noncontiguous_data(mca_coll_ml_collective_operation_progress_t *coll_op)
|
|
|
|
{
|
|
|
|
int i, rank;
|
|
|
|
void *user_buf, *library_buf;
|
|
|
|
size_t bytes_per_proc;
|
|
|
|
ptrdiff_t ptr_dif;
|
|
|
|
mca_coll_ml_module_t *ml_module = (mca_coll_ml_module_t *)
|
|
|
|
coll_op->coll_module;
|
|
|
|
mca_coll_ml_topology_t *topo_info = coll_op->coll_schedule->topo_info;
|
|
|
|
|
|
|
|
/* get the offset into each processes data. The assumption is that
|
|
|
|
* we are manipulating the same amount of data for each process.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* figure out how much data per-proc to copy */
|
|
|
|
bytes_per_proc = coll_op->fragment_data.per_rank_fragment_size;
|
|
|
|
|
|
|
|
/* loop over all the ranks in the communicator */
|
|
|
|
for(i = 0; i < ompi_comm_size(ml_module->comm); i++ ) {
|
|
|
|
|
|
|
|
/* look up the rank of the i'th element in the sorted list */
|
|
|
|
rank = topo_info->sort_list[i];
|
|
|
|
|
|
|
|
/* get the pointer to user data */
|
|
|
|
user_buf=coll_op->full_message.src_user_addr;
|
|
|
|
/* compute offset into the user buffer */
|
|
|
|
|
|
|
|
/* offset for data already processed */
|
|
|
|
ptr_dif=rank*coll_op->full_message.send_count*
|
|
|
|
coll_op->full_message.send_extent+
|
|
|
|
coll_op->fragment_data.offset_into_user_buffer_per_proc;
|
|
|
|
user_buf=(void *) ((char *)user_buf+ptr_dif);
|
|
|
|
|
|
|
|
/* get the pointer to the ML buffer */
|
|
|
|
library_buf= (void *)
|
|
|
|
((char *)coll_op->variable_fn_params.src_desc->data_addr+i*bytes_per_proc);
|
|
|
|
|
|
|
|
/* copy the data */
|
|
|
|
memcpy(library_buf, user_buf, bytes_per_proc);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
|