Initial import of the HAN collective module
a hierarchical, architecture-aware collective communication module. Add Reduce and remove up_seg_size and low_seg_size in Bcast Increase HAN's priority Signed-off-by: Xi Luo <xluo12@vols.utk.edu> Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
Этот коммит содержится в:
родитель
5c16e968b1
Коммит
feb5a7113c
49
ompi/mca/coll/han/Makefile.am
Обычный файл
49
ompi/mca/coll/han/Makefile.am
Обычный файл
@ -0,0 +1,49 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
# of Tennessee Research Foundation. All rights
|
||||||
|
# reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
sources = \
|
||||||
|
coll_han.h \
|
||||||
|
coll_han_trigger.h \
|
||||||
|
coll_han_bcast.c \
|
||||||
|
coll_han_reduce.c \
|
||||||
|
coll_han_scatter.c \
|
||||||
|
coll_han_gather.c \
|
||||||
|
coll_han_allreduce.c \
|
||||||
|
coll_han_allgather.c \
|
||||||
|
coll_han_component.c \
|
||||||
|
coll_han_module.c \
|
||||||
|
coll_han_trigger.c \
|
||||||
|
coll_han_utils.c
|
||||||
|
|
||||||
|
# Make the output library in this directory, and name it either
|
||||||
|
# mca_<type>_<name>.la (for DSO builds) or libmca_<type>_<name>.la
|
||||||
|
# (for static builds).
|
||||||
|
|
||||||
|
component_noinst =
|
||||||
|
component_install =
|
||||||
|
if MCA_BUILD_ompi_coll_han_DSO
|
||||||
|
component_install += mca_coll_han.la
|
||||||
|
else
|
||||||
|
component_noinst += libmca_coll_han.la
|
||||||
|
endif
|
||||||
|
|
||||||
|
# See ompi/mca/btl/sm/Makefile.am for an explanation of
|
||||||
|
# libmca_common_sm.la.
|
||||||
|
|
||||||
|
mcacomponentdir = $(ompilibdir)
|
||||||
|
mcacomponent_LTLIBRARIES = $(component_install)
|
||||||
|
mca_coll_han_la_SOURCES = $(sources)
|
||||||
|
mca_coll_han_la_LDFLAGS = -module -avoid-version
|
||||||
|
mca_coll_han_la_LIBADD =
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = $(component_noinst)
|
||||||
|
libmca_coll_han_la_SOURCES =$(sources)
|
||||||
|
libmca_coll_han_la_LDFLAGS = -module -avoid-version
|
410
ompi/mca/coll/han/coll_han.h
Обычный файл
410
ompi/mca/coll/han/coll_han.h
Обычный файл
@ -0,0 +1,410 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MCA_COLL_HAN_EXPORT_H
|
||||||
|
#define MCA_COLL_HAN_EXPORT_H
|
||||||
|
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include "mpi.h"
|
||||||
|
#include "ompi/mca/mca.h"
|
||||||
|
#include "ompi/mca/coll/coll.h"
|
||||||
|
#include "ompi/communicator/communicator.h"
|
||||||
|
#include "ompi/include/mpi.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_base_functions.h"
|
||||||
|
#include "opal/util/info.h"
|
||||||
|
#include "ompi/op/op.h"
|
||||||
|
#include "opal/runtime/opal_progress.h"
|
||||||
|
#include "ompi/mca/pml/pml.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_tags.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_base_functions.h"
|
||||||
|
#include "coll_han_trigger.h"
|
||||||
|
|
||||||
|
BEGIN_C_DECLS typedef struct {
|
||||||
|
uint32_t umod;
|
||||||
|
uint32_t lmod;
|
||||||
|
uint32_t fs;
|
||||||
|
uint32_t ualg;
|
||||||
|
uint32_t us;
|
||||||
|
} selection;
|
||||||
|
|
||||||
|
struct mca_bcast_argu_s {
|
||||||
|
mca_coll_task_t *cur_task;
|
||||||
|
void *buff;
|
||||||
|
int seg_count;
|
||||||
|
struct ompi_datatype_t *dtype;
|
||||||
|
int root_low_rank;
|
||||||
|
int root_up_rank;
|
||||||
|
struct ompi_communicator_t *up_comm;
|
||||||
|
struct ompi_communicator_t *low_comm;
|
||||||
|
int num_segments;
|
||||||
|
int cur_seg;
|
||||||
|
int w_rank;
|
||||||
|
int last_seg_count;
|
||||||
|
bool noop;
|
||||||
|
};
|
||||||
|
typedef struct mca_bcast_argu_s mca_bcast_argu_t;
|
||||||
|
|
||||||
|
struct mca_reduce_argu_s {
|
||||||
|
mca_coll_task_t *cur_task;
|
||||||
|
void *sbuf;
|
||||||
|
void *rbuf;
|
||||||
|
int seg_count;
|
||||||
|
struct ompi_datatype_t *dtype;
|
||||||
|
struct ompi_op_t *op;
|
||||||
|
int root_low_rank;
|
||||||
|
int root_up_rank;
|
||||||
|
struct ompi_communicator_t *up_comm;
|
||||||
|
struct ompi_communicator_t *low_comm;
|
||||||
|
int num_segments;
|
||||||
|
int cur_seg;
|
||||||
|
int w_rank;
|
||||||
|
int last_seg_count;
|
||||||
|
bool noop;
|
||||||
|
};
|
||||||
|
typedef struct mca_reduce_argu_s mca_reduce_argu_t;
|
||||||
|
|
||||||
|
struct mca_allreduce_argu_s {
|
||||||
|
mca_coll_task_t *cur_task;
|
||||||
|
void *sbuf;
|
||||||
|
void *rbuf;
|
||||||
|
int seg_count;
|
||||||
|
struct ompi_datatype_t *dtype;
|
||||||
|
struct ompi_op_t *op;
|
||||||
|
int root_up_rank;
|
||||||
|
int root_low_rank;
|
||||||
|
struct ompi_communicator_t *up_comm;
|
||||||
|
struct ompi_communicator_t *low_comm;
|
||||||
|
int num_segments;
|
||||||
|
int cur_seg;
|
||||||
|
int w_rank;
|
||||||
|
int last_seg_count;
|
||||||
|
bool noop;
|
||||||
|
ompi_request_t *req;
|
||||||
|
int *completed;
|
||||||
|
};
|
||||||
|
typedef struct mca_allreduce_argu_s mca_allreduce_argu_t;
|
||||||
|
|
||||||
|
struct mca_scatter_argu_s {
|
||||||
|
mca_coll_task_t *cur_task;
|
||||||
|
void *sbuf;
|
||||||
|
void *sbuf_inter_free;
|
||||||
|
void *sbuf_reorder_free;
|
||||||
|
int scount;
|
||||||
|
struct ompi_datatype_t *sdtype;
|
||||||
|
void *rbuf;
|
||||||
|
int rcount;
|
||||||
|
struct ompi_datatype_t *rdtype;
|
||||||
|
int root;
|
||||||
|
int root_up_rank;
|
||||||
|
int root_low_rank;
|
||||||
|
struct ompi_communicator_t *up_comm;
|
||||||
|
struct ompi_communicator_t *low_comm;
|
||||||
|
int w_rank;
|
||||||
|
bool noop;
|
||||||
|
ompi_request_t *req;
|
||||||
|
};
|
||||||
|
typedef struct mca_scatter_argu_s mca_scatter_argu_t;
|
||||||
|
|
||||||
|
struct mca_gather_argu_s {
|
||||||
|
mca_coll_task_t *cur_task;
|
||||||
|
void *sbuf;
|
||||||
|
void *sbuf_inter_free;
|
||||||
|
int scount;
|
||||||
|
struct ompi_datatype_t *sdtype;
|
||||||
|
void *rbuf;
|
||||||
|
int rcount;
|
||||||
|
struct ompi_datatype_t *rdtype;
|
||||||
|
int root;
|
||||||
|
int root_up_rank;
|
||||||
|
int root_low_rank;
|
||||||
|
struct ompi_communicator_t *up_comm;
|
||||||
|
struct ompi_communicator_t *low_comm;
|
||||||
|
int w_rank;
|
||||||
|
bool noop;
|
||||||
|
ompi_request_t *req;
|
||||||
|
};
|
||||||
|
typedef struct mca_gather_argu_s mca_gather_argu_t;
|
||||||
|
|
||||||
|
struct mca_allgather_argu_s {
|
||||||
|
mca_coll_task_t *cur_task;
|
||||||
|
void *sbuf;
|
||||||
|
void *sbuf_inter_free;
|
||||||
|
int scount;
|
||||||
|
struct ompi_datatype_t *sdtype;
|
||||||
|
void *rbuf;
|
||||||
|
int rcount;
|
||||||
|
struct ompi_datatype_t *rdtype;
|
||||||
|
int root_low_rank;
|
||||||
|
struct ompi_communicator_t *up_comm;
|
||||||
|
struct ompi_communicator_t *low_comm;
|
||||||
|
int w_rank;
|
||||||
|
bool noop;
|
||||||
|
bool is_mapbycore;
|
||||||
|
int *topo;
|
||||||
|
ompi_request_t *req;
|
||||||
|
};
|
||||||
|
typedef struct mca_allgather_argu_s mca_allgather_argu_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure to hold the han coll component. First it holds the
|
||||||
|
* base coll component, and then holds a bunch of
|
||||||
|
* han-coll-component-specific stuff (e.g., current MCA param
|
||||||
|
* values).
|
||||||
|
*/
|
||||||
|
typedef struct mca_coll_han_component_t {
|
||||||
|
/** Base coll component */
|
||||||
|
mca_coll_base_component_2_0_0_t super;
|
||||||
|
|
||||||
|
/** MCA parameter: Priority of this component */
|
||||||
|
int han_priority;
|
||||||
|
/* whether output the log message */
|
||||||
|
int han_output;
|
||||||
|
/* segment size for bcast */
|
||||||
|
uint32_t han_bcast_segsize;
|
||||||
|
/* up level module for bcast */
|
||||||
|
uint32_t han_bcast_up_module;
|
||||||
|
/* low level module for bcast */
|
||||||
|
uint32_t han_bcast_low_module;
|
||||||
|
/* segment size for reduce */
|
||||||
|
uint32_t han_reduce_segsize;
|
||||||
|
/* up level module for reduce */
|
||||||
|
uint32_t han_reduce_up_module;
|
||||||
|
/* low level module for reduce */
|
||||||
|
uint32_t han_reduce_low_module;
|
||||||
|
/* segment size for allreduce */
|
||||||
|
uint32_t han_allreduce_segsize;
|
||||||
|
/* up level module for allreduce */
|
||||||
|
uint32_t han_allreduce_up_module;
|
||||||
|
/* low level module for allreduce */
|
||||||
|
uint32_t han_allreduce_low_module;
|
||||||
|
/* up level module for allgather */
|
||||||
|
uint32_t han_allgather_up_module;
|
||||||
|
/* low level module for allgather */
|
||||||
|
uint32_t han_allgather_low_module;
|
||||||
|
/* up level module for gather */
|
||||||
|
uint32_t han_gather_up_module;
|
||||||
|
/* low level module for gather */
|
||||||
|
uint32_t han_gather_low_module;
|
||||||
|
/* up level module for scatter */
|
||||||
|
uint32_t han_scatter_up_module;
|
||||||
|
/* low level module for scatter */
|
||||||
|
uint32_t han_scatter_low_module;
|
||||||
|
/* whether enable auto tune */
|
||||||
|
uint32_t han_auto_tune;
|
||||||
|
/* create a 3D array
|
||||||
|
* num_processes (n): 2 4 8 16 32 64 (6)
|
||||||
|
* num_core (c): 2 4 8 12 (4)
|
||||||
|
* message size (m): 1 - 4194304 (23)
|
||||||
|
*/
|
||||||
|
uint32_t han_auto_tune_n;
|
||||||
|
uint32_t han_auto_tune_c;
|
||||||
|
uint32_t han_auto_tune_m;
|
||||||
|
selection *han_auto_tuned;
|
||||||
|
} mca_coll_han_component_t;
|
||||||
|
|
||||||
|
/** Coll han module */
|
||||||
|
typedef struct mca_coll_han_module_t {
|
||||||
|
/** Base module */
|
||||||
|
mca_coll_base_module_t super;
|
||||||
|
|
||||||
|
/* Whether this module has been lazily initialized or not yet */
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
struct ompi_communicator_t *cached_comm;
|
||||||
|
struct ompi_communicator_t **cached_low_comms;
|
||||||
|
struct ompi_communicator_t **cached_up_comms;
|
||||||
|
int *cached_vranks;
|
||||||
|
int *cached_topo;
|
||||||
|
bool is_mapbycore;
|
||||||
|
} mca_coll_han_module_t;
|
||||||
|
OBJ_CLASS_DECLARATION(mca_coll_han_module_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global component instance
|
||||||
|
*/
|
||||||
|
OMPI_MODULE_DECLSPEC extern mca_coll_han_component_t mca_coll_han_component;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* coll module functions
|
||||||
|
*/
|
||||||
|
int mca_coll_han_init_query(bool enable_progress_threads, bool enable_mpi_threads);
|
||||||
|
|
||||||
|
mca_coll_base_module_t *mca_coll_han_comm_query(struct ompi_communicator_t *comm, int *priority);
|
||||||
|
|
||||||
|
int han_request_free(ompi_request_t ** request);
|
||||||
|
|
||||||
|
/* Subcommunicator creation */
|
||||||
|
void mca_coll_han_comm_create(struct ompi_communicator_t *comm, mca_coll_han_module_t * han_module);
|
||||||
|
|
||||||
|
/* Gather topology information */
|
||||||
|
int mca_coll_han_pow10_int(int pow_value);
|
||||||
|
int mca_coll_han_hostname_to_number(char *hostname, int size);
|
||||||
|
void mca_coll_han_topo_get(int *topo, struct ompi_communicator_t *comm, int num_topo_level);
|
||||||
|
void mca_coll_han_topo_sort(int *topo, int start, int end, int size, int level, int num_topo_level);
|
||||||
|
bool mca_coll_han_topo_is_mapbycore(int *topo, struct ompi_communicator_t *comm,
|
||||||
|
int num_topo_level);
|
||||||
|
int *mca_coll_han_topo_init(struct ompi_communicator_t *comm, mca_coll_han_module_t * han_module,
|
||||||
|
int num_topo_level);
|
||||||
|
void mca_coll_han_topo_print(int *topo, struct ompi_communicator_t *comm, int num_topo_level);
|
||||||
|
|
||||||
|
/* Utils */
|
||||||
|
void mca_coll_han_get_ranks(int *vranks, int root, int low_size, int *root_low_rank,
|
||||||
|
int *root_up_rank);
|
||||||
|
uint32_t han_auto_tuned_get_n(uint32_t n);
|
||||||
|
uint32_t han_auto_tuned_get_c(uint32_t c);
|
||||||
|
uint32_t han_auto_tuned_get_m(uint32_t m);
|
||||||
|
|
||||||
|
|
||||||
|
/* Bcast */
|
||||||
|
void mac_coll_han_set_bcast_argu(mca_bcast_argu_t * argu, mca_coll_task_t * cur_task, void *buff,
|
||||||
|
int seg_count, struct ompi_datatype_t *dtype,
|
||||||
|
int root_up_rank, int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int num_segments, int cur_seg, int w_rank, int last_seg_count,
|
||||||
|
bool noop);
|
||||||
|
int mca_coll_han_bcast_intra(void *buff, int count, struct ompi_datatype_t *dtype, int root,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module);
|
||||||
|
int mca_coll_han_bcast_t0_task(void *task_argu);
|
||||||
|
int mca_coll_han_bcast_t1_task(void *task_argu);
|
||||||
|
|
||||||
|
/* Reduce */
|
||||||
|
void mac_coll_han_set_reduce_argu(mca_reduce_argu_t * argu, mca_coll_task_t * cur_task,
|
||||||
|
void *sbuf,
|
||||||
|
void *rbuf, int seg_count, struct ompi_datatype_t *dtype,
|
||||||
|
struct ompi_op_t *op,
|
||||||
|
int root_up_rank, int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int num_segments, int cur_seg, int w_rank, int last_seg_count,
|
||||||
|
bool noop);
|
||||||
|
|
||||||
|
int mca_coll_han_reduce_intra(const void *sbuf,
|
||||||
|
void *rbuf,
|
||||||
|
int count,
|
||||||
|
struct ompi_datatype_t *dtype,
|
||||||
|
ompi_op_t* op,
|
||||||
|
int root,
|
||||||
|
struct ompi_communicator_t *comm,
|
||||||
|
mca_coll_base_module_t * module);
|
||||||
|
|
||||||
|
int mca_coll_han_reduce_t0_task(void *task_argu);
|
||||||
|
int mca_coll_han_reduce_t1_task(void *task_argu);
|
||||||
|
|
||||||
|
/* Allreduce */
|
||||||
|
void mac_coll_han_set_allreduce_argu(mca_allreduce_argu_t * argu,
|
||||||
|
mca_coll_task_t * cur_task,
|
||||||
|
void *sbuf,
|
||||||
|
void *rbuf,
|
||||||
|
int seg_count,
|
||||||
|
struct ompi_datatype_t *dtype,
|
||||||
|
struct ompi_op_t *op,
|
||||||
|
int root_up_rank,
|
||||||
|
int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int num_segments,
|
||||||
|
int cur_seg,
|
||||||
|
int w_rank,
|
||||||
|
int last_seg_count,
|
||||||
|
bool noop, ompi_request_t * req, int *completed);
|
||||||
|
int mca_coll_han_allreduce_intra(const void *sbuf,
|
||||||
|
void *rbuf,
|
||||||
|
int count,
|
||||||
|
struct ompi_datatype_t *dtype,
|
||||||
|
struct ompi_op_t *op,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module);
|
||||||
|
int mca_coll_han_allreduce_t0_task(void *task_argu);
|
||||||
|
int mca_coll_han_allreduce_t1_task(void *task_argu);
|
||||||
|
int mca_coll_han_allreduce_t2_task(void *task_argu);
|
||||||
|
int mca_coll_han_allreduce_t3_task(void *task_argu);
|
||||||
|
|
||||||
|
/* Scatter */
|
||||||
|
int
|
||||||
|
mca_coll_han_scatter_intra(const void *sbuf, int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf, int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module);
|
||||||
|
int mca_coll_han_scatter_us_task(void *task_argu);
|
||||||
|
int mca_coll_han_scatter_ls_task(void *task_argu);
|
||||||
|
void mac_coll_han_set_scatter_argu(mca_scatter_argu_t * argu,
|
||||||
|
mca_coll_task_t * cur_task,
|
||||||
|
void *sbuf,
|
||||||
|
void *sbuf_inter_free,
|
||||||
|
void *sbuf_reorder_free,
|
||||||
|
int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf,
|
||||||
|
int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root,
|
||||||
|
int root_up_rank,
|
||||||
|
int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int w_rank, bool noop, ompi_request_t * req);
|
||||||
|
|
||||||
|
/* Gatter */
|
||||||
|
int
|
||||||
|
mca_coll_han_gather_intra(const void *sbuf, int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf, int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module);
|
||||||
|
int mca_coll_han_gather_lg_task(void *task_argu);
|
||||||
|
int mca_coll_han_gather_ug_task(void *task_argu);
|
||||||
|
void mac_coll_han_set_gather_argu(mca_gather_argu_t * argu,
|
||||||
|
mca_coll_task_t * cur_task,
|
||||||
|
void *sbuf,
|
||||||
|
void *sbuf_inter_free,
|
||||||
|
int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf,
|
||||||
|
int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root,
|
||||||
|
int root_up_rank,
|
||||||
|
int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int w_rank, bool noop, ompi_request_t * req);
|
||||||
|
|
||||||
|
/* Allgather */
|
||||||
|
int
|
||||||
|
mca_coll_han_allgather_intra(const void *sbuf, int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf, int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module);
|
||||||
|
int mca_coll_han_allgather_lg_task(void *task_argu);
|
||||||
|
int mca_coll_han_allgather_uag_task(void *task_argu);
|
||||||
|
int mca_coll_han_allgather_lb_task(void *task_argu);
|
||||||
|
void mac_coll_han_set_allgather_argu(mca_allgather_argu_t * argu,
|
||||||
|
mca_coll_task_t * cur_task,
|
||||||
|
void *sbuf,
|
||||||
|
void *sbuf_inter_free,
|
||||||
|
int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf,
|
||||||
|
int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int w_rank,
|
||||||
|
bool noop, bool is_mapbycore, int *topo, ompi_request_t * req);
|
||||||
|
|
||||||
|
END_C_DECLS
|
||||||
|
#endif /* MCA_COLL_HAN_EXPORT_H */
|
240
ompi/mca/coll/han/coll_han_allgather.c
Обычный файл
240
ompi/mca/coll/han/coll_han_allgather.c
Обычный файл
@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "coll_han.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_base_functions.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_tags.h"
|
||||||
|
#include "ompi/mca/pml/pml.h"
|
||||||
|
#include "coll_han_trigger.h"
|
||||||
|
|
||||||
|
void mac_coll_han_set_allgather_argu(mca_allgather_argu_t * argu,
|
||||||
|
mca_coll_task_t * cur_task,
|
||||||
|
void *sbuf,
|
||||||
|
void *sbuf_inter_free,
|
||||||
|
int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf,
|
||||||
|
int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int w_rank,
|
||||||
|
bool noop, bool is_mapbycore, int *topo, ompi_request_t * req)
|
||||||
|
{
|
||||||
|
argu->cur_task = cur_task;
|
||||||
|
argu->sbuf = sbuf;
|
||||||
|
argu->sbuf_inter_free = sbuf_inter_free;
|
||||||
|
argu->scount = scount;
|
||||||
|
argu->sdtype = sdtype;
|
||||||
|
argu->rbuf = rbuf;
|
||||||
|
argu->rcount = rcount;
|
||||||
|
argu->rdtype = rdtype;
|
||||||
|
argu->root_low_rank = root_low_rank;
|
||||||
|
argu->up_comm = up_comm;
|
||||||
|
argu->low_comm = low_comm;
|
||||||
|
argu->w_rank = w_rank;
|
||||||
|
argu->noop = noop;
|
||||||
|
argu->is_mapbycore = is_mapbycore;
|
||||||
|
argu->topo = topo;
|
||||||
|
argu->req = req;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mca_coll_han_allgather_intra(const void *sbuf, int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf, int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module)
|
||||||
|
{
|
||||||
|
int w_rank;
|
||||||
|
w_rank = ompi_comm_rank(comm);
|
||||||
|
|
||||||
|
/* Create the subcommunicators */
|
||||||
|
mca_coll_han_module_t *han_module = (mca_coll_han_module_t *) module;
|
||||||
|
mca_coll_han_comm_create(comm, han_module);
|
||||||
|
ompi_communicator_t *low_comm =
|
||||||
|
han_module->cached_low_comms[mca_coll_han_component.han_allgather_low_module];
|
||||||
|
ompi_communicator_t *up_comm =
|
||||||
|
han_module->cached_up_comms[mca_coll_han_component.han_allgather_up_module];
|
||||||
|
int low_rank = ompi_comm_rank(low_comm);
|
||||||
|
|
||||||
|
ompi_request_t *temp_request = NULL;
|
||||||
|
/* Set up request */
|
||||||
|
temp_request = OBJ_NEW(ompi_request_t);
|
||||||
|
OMPI_REQUEST_INIT(temp_request, false);
|
||||||
|
temp_request->req_state = OMPI_REQUEST_ACTIVE;
|
||||||
|
temp_request->req_type = 0;
|
||||||
|
temp_request->req_free = han_request_free;
|
||||||
|
temp_request->req_status.MPI_SOURCE = 0;
|
||||||
|
temp_request->req_status.MPI_TAG = 0;
|
||||||
|
temp_request->req_status.MPI_ERROR = 0;
|
||||||
|
temp_request->req_status._cancelled = 0;
|
||||||
|
temp_request->req_status._ucount = 0;
|
||||||
|
|
||||||
|
/* Init topo */
|
||||||
|
int *topo = mca_coll_han_topo_init(comm, han_module, 2);
|
||||||
|
|
||||||
|
int root_low_rank = 0;
|
||||||
|
/* Create lg (lower level gather) task */
|
||||||
|
mca_coll_task_t *lg = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup lg task arguments */
|
||||||
|
mca_allgather_argu_t *lg_argu = malloc(sizeof(mca_allgather_argu_t));
|
||||||
|
mac_coll_han_set_allgather_argu(lg_argu, lg, (char *) sbuf, NULL, scount, sdtype, rbuf, rcount,
|
||||||
|
rdtype, root_low_rank, up_comm, low_comm, w_rank,
|
||||||
|
low_rank != root_low_rank, han_module->is_mapbycore, topo,
|
||||||
|
temp_request);
|
||||||
|
/* Init lg task */
|
||||||
|
init_task(lg, mca_coll_han_allgather_lg_task, (void *) (lg_argu));
|
||||||
|
/* Issure lg task */
|
||||||
|
issue_task(lg);
|
||||||
|
|
||||||
|
ompi_request_wait(&temp_request, MPI_STATUS_IGNORE);
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lg: lower level (shared memory) gather task */
|
||||||
|
int mca_coll_han_allgather_lg_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_allgather_argu_t *t = (mca_allgather_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d] HAN Allgather: lg\n",
|
||||||
|
t->w_rank));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
|
||||||
|
/* If the process is one of the node leader */
|
||||||
|
char *tmp_buf = NULL;
|
||||||
|
char *tmp_rbuf = NULL;
|
||||||
|
if (!t->noop) {
|
||||||
|
int low_size = ompi_comm_size(t->low_comm);
|
||||||
|
ptrdiff_t rsize, rgap = 0;
|
||||||
|
rsize = opal_datatype_span(&t->rdtype->super, (int64_t) t->rcount * low_size, &rgap);
|
||||||
|
tmp_buf = (char *) malloc(rsize);
|
||||||
|
tmp_rbuf = tmp_buf - rgap;
|
||||||
|
}
|
||||||
|
/* Shared memory gather */
|
||||||
|
t->low_comm->c_coll->coll_gather((char *) t->sbuf, t->scount, t->sdtype, tmp_rbuf, t->rcount,
|
||||||
|
t->rdtype, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_gather_module);
|
||||||
|
t->sbuf = tmp_rbuf;
|
||||||
|
t->sbuf_inter_free = tmp_buf;
|
||||||
|
|
||||||
|
/* Create uag (upper level all-gather) task */
|
||||||
|
mca_coll_task_t *uag = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup uag task arguments */
|
||||||
|
t->cur_task = uag;
|
||||||
|
/* Init uag task */
|
||||||
|
init_task(uag, mca_coll_han_allgather_uag_task, (void *) t);
|
||||||
|
/* Issure uag task */
|
||||||
|
issue_task(uag);
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* uag: upper level (inter-node) all-gather task */
|
||||||
|
int mca_coll_han_allgather_uag_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_allgather_argu_t *t = (mca_allgather_argu_t *) task_argu;
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
|
||||||
|
if (t->noop) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] HAN Allgather: uag noop\n", t->w_rank));
|
||||||
|
} else {
|
||||||
|
int low_size = ompi_comm_size(t->low_comm);
|
||||||
|
int up_size = ompi_comm_size(t->up_comm);
|
||||||
|
char *reorder_buf = NULL;
|
||||||
|
char *reorder_rbuf = NULL;
|
||||||
|
if (t->is_mapbycore) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: HAN Allgather is bycore: ", t->w_rank));
|
||||||
|
reorder_rbuf = (char *) t->rbuf;
|
||||||
|
} else {
|
||||||
|
ptrdiff_t rsize, rgap = 0;
|
||||||
|
rsize =
|
||||||
|
opal_datatype_span(&t->rdtype->super, (int64_t) t->rcount * low_size * up_size,
|
||||||
|
&rgap);
|
||||||
|
reorder_buf = (char *) malloc(rsize);
|
||||||
|
reorder_rbuf = reorder_buf - rgap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inter node allgather */
|
||||||
|
t->up_comm->c_coll->coll_allgather((char *) t->sbuf, t->scount * low_size, t->sdtype,
|
||||||
|
reorder_rbuf, t->rcount * low_size, t->rdtype,
|
||||||
|
t->up_comm, t->up_comm->c_coll->coll_allgather_module);
|
||||||
|
|
||||||
|
if (t->sbuf_inter_free != NULL) {
|
||||||
|
free(t->sbuf_inter_free);
|
||||||
|
t->sbuf_inter_free = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] HAN Allgather: ug allgather finish\n", t->w_rank));
|
||||||
|
|
||||||
|
/* Reorder the node leader's rbuf, copy data from tmp_rbuf to rbuf */
|
||||||
|
if (!t->is_mapbycore) {
|
||||||
|
int i, j;
|
||||||
|
ptrdiff_t rextent;
|
||||||
|
ompi_datatype_type_extent(t->rdtype, &rextent);
|
||||||
|
for (i = 0; i < up_size; i++) {
|
||||||
|
for (j = 0; j < low_size; j++) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: HAN Allgather copy from %d %d\n", t->w_rank,
|
||||||
|
(i * low_size + j) * 2 + 1,
|
||||||
|
t->topo[(i * low_size + j) * 2 + 1]));
|
||||||
|
ompi_datatype_copy_content_same_ddt(t->rdtype, (ptrdiff_t) t->rcount,
|
||||||
|
(char *) t->rbuf +
|
||||||
|
rextent *
|
||||||
|
(ptrdiff_t) t->topo[(i * low_size + j) * 2 +
|
||||||
|
1] *
|
||||||
|
(ptrdiff_t) t->rcount,
|
||||||
|
reorder_rbuf + rextent * (i * low_size +
|
||||||
|
j) *
|
||||||
|
(ptrdiff_t) t->rcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(reorder_buf);
|
||||||
|
reorder_buf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Create lb (low level broadcast) task */
|
||||||
|
mca_coll_task_t *lb = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup lb task arguments */
|
||||||
|
t->cur_task = lb;
|
||||||
|
/* Init lb task */
|
||||||
|
init_task(lb, mca_coll_han_allgather_lb_task, (void *) t);
|
||||||
|
/* Issure lb task */
|
||||||
|
issue_task(lb);
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lb: low level (shared-memory) broadcast task */
|
||||||
|
int mca_coll_han_allgather_lb_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_allgather_argu_t *t = (mca_allgather_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d] HAN Allgather: uag noop\n",
|
||||||
|
t->w_rank));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
int low_size = ompi_comm_size(t->low_comm);
|
||||||
|
int up_size = ompi_comm_size(t->up_comm);
|
||||||
|
t->low_comm->c_coll->coll_bcast((char *) t->rbuf, t->rcount * low_size * up_size, t->rdtype,
|
||||||
|
t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_bcast_module);
|
||||||
|
|
||||||
|
ompi_request_t *temp_req = t->req;
|
||||||
|
free(t);
|
||||||
|
ompi_request_complete(temp_req, 1);
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
|
||||||
|
}
|
395
ompi/mca/coll/han/coll_han_allreduce.c
Обычный файл
395
ompi/mca/coll/han/coll_han_allreduce.c
Обычный файл
@ -0,0 +1,395 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "coll_han.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_base_functions.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_tags.h"
|
||||||
|
#include "ompi/mca/pml/pml.h"
|
||||||
|
#include "coll_han_trigger.h"
|
||||||
|
|
||||||
|
/* Only work with regular situation (each node has equal number of processes) */
|
||||||
|
|
||||||
|
void mac_coll_han_set_allreduce_argu(mca_allreduce_argu_t * argu,
|
||||||
|
mca_coll_task_t * cur_task,
|
||||||
|
void *sbuf,
|
||||||
|
void *rbuf,
|
||||||
|
int seg_count,
|
||||||
|
struct ompi_datatype_t *dtype,
|
||||||
|
struct ompi_op_t *op,
|
||||||
|
int root_up_rank,
|
||||||
|
int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int num_segments,
|
||||||
|
int cur_seg,
|
||||||
|
int w_rank,
|
||||||
|
int last_seg_count,
|
||||||
|
bool noop, ompi_request_t * req, int *completed)
|
||||||
|
{
|
||||||
|
argu->cur_task = cur_task;
|
||||||
|
argu->sbuf = sbuf;
|
||||||
|
argu->rbuf = rbuf;
|
||||||
|
argu->seg_count = seg_count;
|
||||||
|
argu->dtype = dtype;
|
||||||
|
argu->op = op;
|
||||||
|
argu->root_up_rank = root_up_rank;
|
||||||
|
argu->root_low_rank = root_low_rank;
|
||||||
|
argu->up_comm = up_comm;
|
||||||
|
argu->low_comm = low_comm;
|
||||||
|
argu->num_segments = num_segments;
|
||||||
|
argu->cur_seg = cur_seg;
|
||||||
|
argu->w_rank = w_rank;
|
||||||
|
argu->last_seg_count = last_seg_count;
|
||||||
|
argu->noop = noop;
|
||||||
|
argu->req = req;
|
||||||
|
argu->completed = completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each segment of the messsage needs to go though 4 steps to perform MPI_Allreduce:
|
||||||
|
* lr: lower level (shared-memory or intra-node) reduce,
|
||||||
|
* ur: upper level (inter-node) reduce,
|
||||||
|
* ub: upper level (inter-node) bcast,
|
||||||
|
* lb: lower level (shared-memory or intra-node) bcast.
|
||||||
|
* Hence, in each iteration, there is a combination of collective operations which is called a task.
|
||||||
|
* | seg 0 | seg 1 | seg 2 | seg 3 |
|
||||||
|
* iter 0 | lr | | | | task: t0, contains lr
|
||||||
|
* iter 1 | ur | lr | | | task: t1, contains ur and lr
|
||||||
|
* iter 2 | ub | ur | lr | | task: t2, contains ub, ur and lr
|
||||||
|
* iter 3 | lb | ub | ur | lr | task: t3, contains lb, ub, ur and lr
|
||||||
|
* iter 4 | | lb | ub | ur | task: t3, contains lb, ub and ur
|
||||||
|
* iter 5 | | | lb | ub | task: t3, contains lb and ub
|
||||||
|
* iter 6 | | | | lb | task: t3, contains lb
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
mca_coll_han_allreduce_intra(const void *sbuf,
|
||||||
|
void *rbuf,
|
||||||
|
int count,
|
||||||
|
struct ompi_datatype_t *dtype,
|
||||||
|
struct ompi_op_t *op,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module)
|
||||||
|
{
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(dtype, &lb, &extent);
|
||||||
|
int w_rank;
|
||||||
|
w_rank = ompi_comm_rank(comm);
|
||||||
|
int seg_count = count;
|
||||||
|
size_t typelng;
|
||||||
|
ompi_datatype_type_size(dtype, &typelng);
|
||||||
|
|
||||||
|
/* Create the subcommunicators */
|
||||||
|
mca_coll_han_module_t *han_module = (mca_coll_han_module_t *) module;
|
||||||
|
mca_coll_han_comm_create(comm, han_module);
|
||||||
|
ompi_communicator_t *low_comm;
|
||||||
|
ompi_communicator_t *up_comm;
|
||||||
|
/* Auto tune is enabled */
|
||||||
|
if (mca_coll_han_component.han_auto_tune && mca_coll_han_component.han_auto_tuned != NULL) {
|
||||||
|
uint32_t n = han_auto_tuned_get_n(ompi_comm_size(han_module->cached_up_comms[0]));
|
||||||
|
uint32_t c = han_auto_tuned_get_c(ompi_comm_size(han_module->cached_low_comms[0]));
|
||||||
|
uint32_t m = han_auto_tuned_get_m(typelng * count);
|
||||||
|
uint32_t id =
|
||||||
|
n * mca_coll_han_component.han_auto_tune_c * mca_coll_han_component.han_auto_tune_m +
|
||||||
|
c * mca_coll_han_component.han_auto_tune_m + m +
|
||||||
|
mca_coll_han_component.han_auto_tune_n * mca_coll_han_component.han_auto_tune_c *
|
||||||
|
mca_coll_han_component.han_auto_tune_m;
|
||||||
|
uint32_t umod = mca_coll_han_component.han_auto_tuned[id].umod;
|
||||||
|
uint32_t lmod = mca_coll_han_component.han_auto_tuned[id].lmod;
|
||||||
|
uint32_t fs = mca_coll_han_component.han_auto_tuned[id].fs;
|
||||||
|
/* ualg and us are only available when using ADAPT */
|
||||||
|
/*
|
||||||
|
uint32_t ualg = mca_coll_han_component.han_auto_tuned[id].ualg;
|
||||||
|
uint32_t us = mca_coll_han_component.han_auto_tuned[id].us;
|
||||||
|
*/
|
||||||
|
/* Set up umod */
|
||||||
|
up_comm = han_module->cached_up_comms[umod];
|
||||||
|
/* Set up lmod */
|
||||||
|
low_comm = han_module->cached_low_comms[lmod];
|
||||||
|
/* Set up fs */
|
||||||
|
COLL_BASE_COMPUTED_SEGCOUNT((size_t) fs, typelng, seg_count);
|
||||||
|
/* Set up ualg and us, which is only available when using ADAPT */
|
||||||
|
/*
|
||||||
|
if (umod == 1) {
|
||||||
|
((mca_coll_adapt_module_t *) (up_comm->c_coll->coll_ibcast_module))->adapt_component->
|
||||||
|
adapt_ibcast_algorithm = ualg;
|
||||||
|
((mca_coll_adapt_module_t *) (up_comm->c_coll->coll_ibcast_module))->adapt_component->
|
||||||
|
adapt_ibcast_algorithm = ualg;
|
||||||
|
((mca_coll_adapt_module_t *) (up_comm->c_coll->coll_ibcast_module))->adapt_component->
|
||||||
|
adapt_ibcast_segment_size = us;
|
||||||
|
((mca_coll_adapt_module_t *) (up_comm->c_coll->coll_ibcast_module))->adapt_component->
|
||||||
|
adapt_ibcast_segment_size = us;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
low_comm = han_module->cached_low_comms[mca_coll_han_component.han_bcast_low_module];
|
||||||
|
up_comm = han_module->cached_up_comms[mca_coll_han_component.han_bcast_up_module];
|
||||||
|
COLL_BASE_COMPUTED_SEGCOUNT(mca_coll_han_component.han_allreduce_segsize, typelng,
|
||||||
|
seg_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine number of elements sent per task. */
|
||||||
|
OPAL_OUTPUT_VERBOSE((10, mca_coll_han_component.han_output,
|
||||||
|
"In HAN Allreduce seg_size %d seg_count %d count %d\n",
|
||||||
|
mca_coll_han_component.han_allreduce_segsize, seg_count, count));
|
||||||
|
int num_segments = (count + seg_count - 1) / seg_count;
|
||||||
|
|
||||||
|
int low_rank = ompi_comm_rank(low_comm);
|
||||||
|
int root_up_rank = 0;
|
||||||
|
int root_low_rank = 0;
|
||||||
|
/* Create t0 task for the first segment */
|
||||||
|
mca_coll_task_t *t0 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t0 task arguments */
|
||||||
|
int *completed = (int *) malloc(sizeof(int));
|
||||||
|
completed[0] = 0;
|
||||||
|
mca_allreduce_argu_t *t = malloc(sizeof(mca_allreduce_argu_t));
|
||||||
|
mac_coll_han_set_allreduce_argu(t, t0, (char *) sbuf, (char *) rbuf, seg_count, dtype, op,
|
||||||
|
root_up_rank, root_low_rank, up_comm, low_comm, num_segments, 0,
|
||||||
|
w_rank, count - (num_segments - 1) * seg_count,
|
||||||
|
low_rank != root_low_rank, NULL, completed);
|
||||||
|
/* Init t0 task */
|
||||||
|
init_task(t0, mca_coll_han_allreduce_t0_task, (void *) (t));
|
||||||
|
/* Issure t0 task */
|
||||||
|
issue_task(t0);
|
||||||
|
|
||||||
|
/* Create t1 tasks for the current segment */
|
||||||
|
mca_coll_task_t *t1 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t1 task arguments */
|
||||||
|
t->cur_task = t1;
|
||||||
|
/* Init t1 task */
|
||||||
|
init_task(t1, mca_coll_han_allreduce_t1_task, (void *) t);
|
||||||
|
/* Issue t1 task */
|
||||||
|
issue_task(t1);
|
||||||
|
|
||||||
|
/* Create t2 tasks for the current segment */
|
||||||
|
mca_coll_task_t *t2 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t2 task arguments */
|
||||||
|
t->cur_task = t2;
|
||||||
|
/* Init t2 task */
|
||||||
|
init_task(t2, mca_coll_han_allreduce_t2_task, (void *) t);
|
||||||
|
issue_task(t2);
|
||||||
|
|
||||||
|
/* Create t3 tasks for the current segment */
|
||||||
|
mca_coll_task_t *t3 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t3 task arguments */
|
||||||
|
t->cur_task = t3;
|
||||||
|
/* Init t3 task */
|
||||||
|
init_task(t3, mca_coll_han_allreduce_t3_task, (void *) t);
|
||||||
|
issue_task(t3);
|
||||||
|
|
||||||
|
while (t->completed[0] != t->num_segments) {
|
||||||
|
/* Create t3 tasks for the current segment */
|
||||||
|
mca_coll_task_t *t3 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t3 task arguments */
|
||||||
|
t->cur_task = t3;
|
||||||
|
t->sbuf = (char *) t->sbuf + extent * t->seg_count;
|
||||||
|
t->rbuf = (char *) t->rbuf + extent * t->seg_count;
|
||||||
|
t->cur_seg = t->cur_seg + 1;
|
||||||
|
/* Init t3 task */
|
||||||
|
init_task(t3, mca_coll_han_allreduce_t3_task, (void *) t);
|
||||||
|
issue_task(t3);
|
||||||
|
}
|
||||||
|
if (t->completed != NULL) {
|
||||||
|
free(t->completed);
|
||||||
|
t->completed = NULL;
|
||||||
|
}
|
||||||
|
free(t);
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t0 task */
|
||||||
|
int mca_coll_han_allreduce_t0_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_allreduce_argu_t *t = (mca_allreduce_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] HAN Allreduce: t0 %d r_buf %d\n", t->w_rank, t->cur_seg,
|
||||||
|
((int *) t->rbuf)[0]));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(t->dtype, &lb, &extent);
|
||||||
|
t->low_comm->c_coll->coll_reduce((char *) t->sbuf, (char *) t->rbuf, t->seg_count, t->dtype,
|
||||||
|
t->op, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_reduce_module);
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t1 task */
|
||||||
|
int mca_coll_han_allreduce_t1_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_allreduce_argu_t *t = (mca_allreduce_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] HAN Allreduce: t1 %d r_buf %d\n", t->w_rank, t->cur_seg,
|
||||||
|
((int *) t->rbuf)[0]));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(t->dtype, &lb, &extent);
|
||||||
|
ompi_request_t *ireduce_req;
|
||||||
|
int tmp_count = t->seg_count;
|
||||||
|
if (!t->noop) {
|
||||||
|
int up_rank = ompi_comm_rank(t->up_comm);
|
||||||
|
/* ur of cur_seg */
|
||||||
|
if (up_rank == t->root_up_rank) {
|
||||||
|
t->up_comm->c_coll->coll_ireduce(MPI_IN_PLACE, (char *) t->rbuf, t->seg_count, t->dtype,
|
||||||
|
t->op, t->root_up_rank, t->up_comm, &ireduce_req,
|
||||||
|
t->up_comm->c_coll->coll_ireduce_module);
|
||||||
|
} else {
|
||||||
|
t->up_comm->c_coll->coll_ireduce((char *) t->rbuf, (char *) t->rbuf, t->seg_count,
|
||||||
|
t->dtype, t->op, t->root_up_rank, t->up_comm,
|
||||||
|
&ireduce_req, t->up_comm->c_coll->coll_ireduce_module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* lr of cur_seg+1 */
|
||||||
|
if (t->cur_seg <= t->num_segments - 2) {
|
||||||
|
if (t->cur_seg == t->num_segments - 2 && t->last_seg_count != t->seg_count) {
|
||||||
|
tmp_count = t->last_seg_count;
|
||||||
|
}
|
||||||
|
t->low_comm->c_coll->coll_reduce((char *) t->sbuf + extent * t->seg_count,
|
||||||
|
(char *) t->rbuf + extent * t->seg_count, tmp_count,
|
||||||
|
t->dtype, t->op, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_reduce_module);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!t->noop) {
|
||||||
|
ompi_request_wait(&ireduce_req, MPI_STATUSES_IGNORE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t2 task */
|
||||||
|
int mca_coll_han_allreduce_t2_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_allreduce_argu_t *t = (mca_allreduce_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] HAN Allreduce: t2 %d r_buf %d\n", t->w_rank, t->cur_seg,
|
||||||
|
((int *) t->rbuf)[0]));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(t->dtype, &lb, &extent);
|
||||||
|
ompi_request_t *reqs[2];
|
||||||
|
int req_count = 0;
|
||||||
|
int tmp_count = t->seg_count;
|
||||||
|
if (!t->noop) {
|
||||||
|
int up_rank = ompi_comm_rank(t->up_comm);
|
||||||
|
/* ub of cur_seg */
|
||||||
|
t->up_comm->c_coll->coll_ibcast((char *) t->rbuf, t->seg_count, t->dtype, t->root_up_rank,
|
||||||
|
t->up_comm, &(reqs[0]),
|
||||||
|
t->up_comm->c_coll->coll_ibcast_module);
|
||||||
|
req_count++;
|
||||||
|
/* ur of cur_seg+1 */
|
||||||
|
if (t->cur_seg <= t->num_segments - 2) {
|
||||||
|
if (t->cur_seg == t->num_segments - 2 && t->last_seg_count != t->seg_count) {
|
||||||
|
tmp_count = t->last_seg_count;
|
||||||
|
}
|
||||||
|
if (up_rank == t->root_up_rank) {
|
||||||
|
t->up_comm->c_coll->coll_ireduce(MPI_IN_PLACE,
|
||||||
|
(char *) t->rbuf + extent * t->seg_count,
|
||||||
|
tmp_count, t->dtype, t->op, t->root_up_rank,
|
||||||
|
t->up_comm, &(reqs[1]),
|
||||||
|
t->up_comm->c_coll->coll_ireduce_module);
|
||||||
|
} else {
|
||||||
|
t->up_comm->c_coll->coll_ireduce((char *) t->rbuf + extent * t->seg_count,
|
||||||
|
(char *) t->rbuf + extent * t->seg_count,
|
||||||
|
tmp_count, t->dtype, t->op, t->root_up_rank,
|
||||||
|
t->up_comm, &(reqs[1]),
|
||||||
|
t->up_comm->c_coll->coll_ireduce_module);
|
||||||
|
}
|
||||||
|
req_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* lr of cur_seg+2 */
|
||||||
|
if (t->cur_seg <= t->num_segments - 3) {
|
||||||
|
if (t->cur_seg == t->num_segments - 3 && t->last_seg_count != t->seg_count) {
|
||||||
|
tmp_count = t->last_seg_count;
|
||||||
|
}
|
||||||
|
t->low_comm->c_coll->coll_reduce((char *) t->sbuf + 2 * extent * t->seg_count,
|
||||||
|
(char *) t->rbuf + 2 * extent * t->seg_count, tmp_count,
|
||||||
|
t->dtype, t->op, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_reduce_module);
|
||||||
|
}
|
||||||
|
if (!t->noop && req_count > 0) {
|
||||||
|
ompi_request_wait_all(req_count, reqs, MPI_STATUSES_IGNORE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t3 task */
|
||||||
|
int mca_coll_han_allreduce_t3_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_allreduce_argu_t *t = (mca_allreduce_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] HAN Allreduce: t3 %d r_buf %d\n", t->w_rank, t->cur_seg,
|
||||||
|
((int *) t->rbuf)[0]));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(t->dtype, &lb, &extent);
|
||||||
|
ompi_request_t *reqs[2];
|
||||||
|
int req_count = 0;
|
||||||
|
int tmp_count = t->seg_count;
|
||||||
|
if (!t->noop) {
|
||||||
|
int up_rank = ompi_comm_rank(t->up_comm);
|
||||||
|
/* ub of cur_seg+1 */
|
||||||
|
if (t->cur_seg <= t->num_segments - 2) {
|
||||||
|
if (t->cur_seg == t->num_segments - 2 && t->last_seg_count != t->seg_count) {
|
||||||
|
tmp_count = t->last_seg_count;
|
||||||
|
}
|
||||||
|
t->up_comm->c_coll->coll_ibcast((char *) t->rbuf + extent * t->seg_count, t->seg_count,
|
||||||
|
t->dtype, t->root_up_rank, t->up_comm, &(reqs[0]),
|
||||||
|
t->up_comm->c_coll->coll_ibcast_module);
|
||||||
|
req_count++;
|
||||||
|
}
|
||||||
|
/* ur of cur_seg+2 */
|
||||||
|
if (t->cur_seg <= t->num_segments - 3) {
|
||||||
|
if (t->cur_seg == t->num_segments - 3 && t->last_seg_count != t->seg_count) {
|
||||||
|
tmp_count = t->last_seg_count;
|
||||||
|
}
|
||||||
|
if (up_rank == t->root_up_rank) {
|
||||||
|
t->up_comm->c_coll->coll_ireduce(MPI_IN_PLACE,
|
||||||
|
(char *) t->rbuf + 2 * extent * t->seg_count,
|
||||||
|
tmp_count, t->dtype, t->op, t->root_up_rank,
|
||||||
|
t->up_comm, &(reqs[1]),
|
||||||
|
t->up_comm->c_coll->coll_ireduce_module);
|
||||||
|
} else {
|
||||||
|
t->up_comm->c_coll->coll_ireduce((char *) t->rbuf + 2 * extent * t->seg_count,
|
||||||
|
(char *) t->rbuf + 2 * extent * t->seg_count,
|
||||||
|
tmp_count, t->dtype, t->op, t->root_up_rank,
|
||||||
|
t->up_comm, &(reqs[1]),
|
||||||
|
t->up_comm->c_coll->coll_ireduce_module);
|
||||||
|
}
|
||||||
|
req_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* lr of cur_seg+3 */
|
||||||
|
if (t->cur_seg <= t->num_segments - 4) {
|
||||||
|
if (t->cur_seg == t->num_segments - 4 && t->last_seg_count != t->seg_count) {
|
||||||
|
tmp_count = t->last_seg_count;
|
||||||
|
}
|
||||||
|
t->low_comm->c_coll->coll_reduce((char *) t->sbuf + 3 * extent * t->seg_count,
|
||||||
|
(char *) t->rbuf + 3 * extent * t->seg_count, tmp_count,
|
||||||
|
t->dtype, t->op, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_reduce_module);
|
||||||
|
}
|
||||||
|
/* lb of cur_seg */
|
||||||
|
t->low_comm->c_coll->coll_bcast((char *) t->rbuf, t->seg_count, t->dtype, t->root_low_rank,
|
||||||
|
t->low_comm, t->low_comm->c_coll->coll_bcast_module);
|
||||||
|
if (!t->noop && req_count > 0) {
|
||||||
|
ompi_request_wait_all(req_count, reqs, MPI_STATUSES_IGNORE);
|
||||||
|
}
|
||||||
|
|
||||||
|
t->completed[0]++;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] HAN Allreduce: t3 %d total %d\n", t->w_rank, t->cur_seg,
|
||||||
|
t->completed[0]));
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
222
ompi/mca/coll/han/coll_han_bcast.c
Обычный файл
222
ompi/mca/coll/han/coll_han_bcast.c
Обычный файл
@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "coll_han.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_base_functions.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_tags.h"
|
||||||
|
#include "ompi/mca/pml/pml.h"
|
||||||
|
#include "coll_han_trigger.h"
|
||||||
|
|
||||||
|
void mac_coll_han_set_bcast_argu(mca_bcast_argu_t * argu, mca_coll_task_t * cur_task, void *buff,
|
||||||
|
int seg_count, struct ompi_datatype_t *dtype,
|
||||||
|
int root_up_rank, int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int num_segments, int cur_seg, int w_rank, int last_seg_count,
|
||||||
|
bool noop)
|
||||||
|
{
|
||||||
|
argu->cur_task = cur_task;
|
||||||
|
argu->buff = buff;
|
||||||
|
argu->seg_count = seg_count;
|
||||||
|
argu->dtype = dtype;
|
||||||
|
argu->root_low_rank = root_low_rank;
|
||||||
|
argu->root_up_rank = root_up_rank;
|
||||||
|
argu->up_comm = up_comm;
|
||||||
|
argu->low_comm = low_comm;
|
||||||
|
argu->num_segments = num_segments;
|
||||||
|
argu->cur_seg = cur_seg;
|
||||||
|
argu->w_rank = w_rank;
|
||||||
|
argu->last_seg_count = last_seg_count;
|
||||||
|
argu->noop = noop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each segment of the messsage needs to go though 2 steps to perform MPI_Bcast:
|
||||||
|
* ub: upper level (inter-node) bcast
|
||||||
|
* lb: low level (shared-memory or intra-node) bcast.
|
||||||
|
* Hence, in each iteration, there is a combination of collective operations which is called a task.
|
||||||
|
* | seg 0 | seg 1 | seg 2 | seg 3 |
|
||||||
|
* iter 0 | ub | | | | task: t0, contains ub
|
||||||
|
* iter 1 | lb | ub | | | task: t1, contains ub and lb
|
||||||
|
* iter 2 | | lb | ub | | task: t1, contains ub and lb
|
||||||
|
* iter 3 | | | lb | ub | task: t1, contains ub and lb
|
||||||
|
* iter 4 | | | | lb | task: t1, contains lb
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
mca_coll_han_bcast_intra(void *buff,
|
||||||
|
int count,
|
||||||
|
struct ompi_datatype_t *dtype,
|
||||||
|
int root,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module)
|
||||||
|
{
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(dtype, &lb, &extent);
|
||||||
|
int w_rank;
|
||||||
|
w_rank = ompi_comm_rank(comm);
|
||||||
|
int seg_count = count;
|
||||||
|
size_t typelng;
|
||||||
|
ompi_datatype_type_size(dtype, &typelng);
|
||||||
|
|
||||||
|
/* Create the subcommunicators */
|
||||||
|
mca_coll_han_module_t *han_module = (mca_coll_han_module_t *) module;
|
||||||
|
mca_coll_han_comm_create(comm, han_module);
|
||||||
|
ompi_communicator_t *low_comm;
|
||||||
|
ompi_communicator_t *up_comm;
|
||||||
|
/* Auto tune is enabled */
|
||||||
|
if (mca_coll_han_component.han_auto_tune && mca_coll_han_component.han_auto_tuned != NULL) {
|
||||||
|
uint32_t n = han_auto_tuned_get_n(ompi_comm_size(han_module->cached_up_comms[0]));
|
||||||
|
uint32_t c = han_auto_tuned_get_c(ompi_comm_size(han_module->cached_low_comms[0]));
|
||||||
|
uint32_t m = han_auto_tuned_get_m(typelng * count);
|
||||||
|
uint32_t id =
|
||||||
|
n * mca_coll_han_component.han_auto_tune_c * mca_coll_han_component.han_auto_tune_m +
|
||||||
|
c * mca_coll_han_component.han_auto_tune_m + m;
|
||||||
|
uint32_t umod = mca_coll_han_component.han_auto_tuned[id].umod;
|
||||||
|
uint32_t lmod = mca_coll_han_component.han_auto_tuned[id].lmod;
|
||||||
|
uint32_t fs = mca_coll_han_component.han_auto_tuned[id].fs;
|
||||||
|
/* ualg and us are only available when using ADAPT */
|
||||||
|
/*
|
||||||
|
uint32_t ualg = mca_coll_han_component.han_auto_tuned[id].ualg;
|
||||||
|
uint32_t us = mca_coll_han_component.han_auto_tuned[id].us;
|
||||||
|
*/
|
||||||
|
/* Set up umod */
|
||||||
|
up_comm = han_module->cached_up_comms[umod];
|
||||||
|
/* Set up lmod */
|
||||||
|
low_comm = han_module->cached_low_comms[lmod];
|
||||||
|
/* Set up fs */
|
||||||
|
COLL_BASE_COMPUTED_SEGCOUNT((size_t) fs, typelng, seg_count);
|
||||||
|
/* Set up ualg and us, which is only available when using ADAPT */
|
||||||
|
/*
|
||||||
|
if (umod == 1) {
|
||||||
|
((mca_coll_adapt_module_t *) (up_comm->c_coll->coll_ibcast_module))->adapt_component->
|
||||||
|
adapt_ibcast_algorithm = ualg;
|
||||||
|
((mca_coll_adapt_module_t *) (up_comm->c_coll->coll_ibcast_module))->adapt_component->
|
||||||
|
adapt_ibcast_segment_size = us;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* If auto tune is disabled, use MCA parameters */
|
||||||
|
low_comm = han_module->cached_low_comms[mca_coll_han_component.han_bcast_low_module];
|
||||||
|
up_comm = han_module->cached_up_comms[mca_coll_han_component.han_bcast_up_module];
|
||||||
|
COLL_BASE_COMPUTED_SEGCOUNT(mca_coll_han_component.han_bcast_segsize, typelng,
|
||||||
|
seg_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_segments = (count + seg_count - 1) / seg_count;
|
||||||
|
OPAL_OUTPUT_VERBOSE((20, mca_coll_han_component.han_output,
|
||||||
|
"In HAN seg_count %d count %d num_seg %d\n",
|
||||||
|
seg_count, count, num_segments));
|
||||||
|
|
||||||
|
int *vranks = han_module->cached_vranks;
|
||||||
|
int low_rank = ompi_comm_rank(low_comm);
|
||||||
|
int low_size = ompi_comm_size(low_comm);
|
||||||
|
|
||||||
|
int root_low_rank;
|
||||||
|
int root_up_rank;
|
||||||
|
mca_coll_han_get_ranks(vranks, root, low_size, &root_low_rank, &root_up_rank);
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: root_low_rank %d root_up_rank %d\n", w_rank, root_low_rank,
|
||||||
|
root_up_rank));
|
||||||
|
|
||||||
|
/* Create t0 tasks for the first segment */
|
||||||
|
mca_coll_task_t *t0 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t0 task arguments */
|
||||||
|
mca_bcast_argu_t *t = malloc(sizeof(mca_bcast_argu_t));
|
||||||
|
mac_coll_han_set_bcast_argu(t, t0, (char *) buff, seg_count, dtype,
|
||||||
|
root_up_rank, root_low_rank, up_comm, low_comm,
|
||||||
|
num_segments, 0, w_rank, count - (num_segments - 1) * seg_count,
|
||||||
|
low_rank != root_low_rank);
|
||||||
|
/* Init the first task */
|
||||||
|
init_task(t0, mca_coll_han_bcast_t0_task, (void *) t);
|
||||||
|
issue_task(t0);
|
||||||
|
|
||||||
|
/* Create t1 task */
|
||||||
|
mca_coll_task_t *t1 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t1 task arguments */
|
||||||
|
t->cur_task = t1;
|
||||||
|
/* Init the t1 task */
|
||||||
|
init_task(t1, mca_coll_han_bcast_t1_task, (void *) t);
|
||||||
|
issue_task(t1);
|
||||||
|
|
||||||
|
while (t->cur_seg <= t->num_segments - 2) {
|
||||||
|
/* Create t1 task */
|
||||||
|
mca_coll_task_t *t1 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t1 task arguments */
|
||||||
|
t->cur_task = t1;
|
||||||
|
t->buff = (char *) t->buff + extent * seg_count;
|
||||||
|
t->cur_seg = t->cur_seg + 1;
|
||||||
|
/* Init the t1 task */
|
||||||
|
init_task(t1, mca_coll_han_bcast_t1_task, (void *) t);
|
||||||
|
issue_task(t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(t);
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t0 task: issue and wait for the upper level ibcast of segment 0 */
|
||||||
|
int mca_coll_han_bcast_t0_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_bcast_argu_t *t = (mca_bcast_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d]: in t0 %d\n", t->w_rank,
|
||||||
|
t->cur_seg));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
if (t->noop) {
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
} else {
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(t->dtype, &lb, &extent);
|
||||||
|
ompi_request_t *ibcast_req;
|
||||||
|
t->up_comm->c_coll->coll_ibcast((char *) t->buff, t->seg_count, t->dtype, t->root_up_rank,
|
||||||
|
t->up_comm, &ibcast_req, t->up_comm->c_coll->coll_ibcast_module);
|
||||||
|
ompi_request_wait(&ibcast_req, MPI_STATUSES_IGNORE);
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t1 task:
|
||||||
|
* 1. issue the upper level ibcast of segment cur_seg + 1
|
||||||
|
* 2. issue the low level bcast of segment cur_seg
|
||||||
|
* 3. wait for the completion of the ibcast
|
||||||
|
*/
|
||||||
|
int mca_coll_han_bcast_t1_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_bcast_argu_t *t = (mca_bcast_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d]: in t1 %d\n", t->w_rank,
|
||||||
|
t->cur_seg));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(t->dtype, &lb, &extent);
|
||||||
|
ompi_request_t *ibcast_req = NULL;
|
||||||
|
int tmp_count = t->seg_count;
|
||||||
|
if (!t->noop) {
|
||||||
|
if (t->cur_seg <= t->num_segments - 2 ) {
|
||||||
|
if (t->cur_seg == t->num_segments - 2 && t->last_seg_count != t->seg_count) {
|
||||||
|
tmp_count = t->last_seg_count;
|
||||||
|
}
|
||||||
|
t->up_comm->c_coll->coll_ibcast((char *) t->buff + extent * t->seg_count,
|
||||||
|
tmp_count, t->dtype, t->root_up_rank,
|
||||||
|
t->up_comm, &ibcast_req,
|
||||||
|
t->up_comm->c_coll->coll_ibcast_module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t->low_comm->c_coll->coll_bcast((char *) t->buff,
|
||||||
|
t->seg_count, t->dtype, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_bcast_module);
|
||||||
|
|
||||||
|
if (!t->noop && ibcast_req != NULL) {
|
||||||
|
ompi_request_wait(&ibcast_req, MPI_STATUSES_IGNORE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
279
ompi/mca/coll/han/coll_han_component.c
Обычный файл
279
ompi/mca/coll/han/coll_han_component.c
Обычный файл
@ -0,0 +1,279 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* Most of the description of the data layout is in the
|
||||||
|
* coll_han_module.c file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include "opal/util/show_help.h"
|
||||||
|
#include "ompi/constants.h"
|
||||||
|
#include "ompi/mca/coll/coll.h"
|
||||||
|
#include "coll_han.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Public string showing the coll ompi_han component version number
|
||||||
|
*/
|
||||||
|
const char *mca_coll_han_component_version_string =
|
||||||
|
"Open MPI han collective MCA component version " OMPI_VERSION;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local functions
|
||||||
|
*/
|
||||||
|
static int han_open(void);
|
||||||
|
static int han_close(void);
|
||||||
|
static int han_register(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Instantiate the public struct with all of our public information
|
||||||
|
* and pointers to our public functions in it
|
||||||
|
*/
|
||||||
|
|
||||||
|
mca_coll_han_component_t mca_coll_han_component = {
|
||||||
|
|
||||||
|
/* First, fill in the super */
|
||||||
|
|
||||||
|
{
|
||||||
|
/* First, the mca_component_t struct containing meta
|
||||||
|
information about the component itself */
|
||||||
|
|
||||||
|
.collm_version = {
|
||||||
|
MCA_COLL_BASE_VERSION_2_0_0,
|
||||||
|
|
||||||
|
/* Component name and version */
|
||||||
|
.mca_component_name = "han",
|
||||||
|
MCA_BASE_MAKE_VERSION(component, OMPI_MAJOR_VERSION, OMPI_MINOR_VERSION,
|
||||||
|
OMPI_RELEASE_VERSION),
|
||||||
|
|
||||||
|
/* Component functions */
|
||||||
|
.mca_open_component = han_open,
|
||||||
|
.mca_close_component = han_close,
|
||||||
|
.mca_register_component_params = han_register,
|
||||||
|
},
|
||||||
|
.collm_data = {
|
||||||
|
/* The component is not checkpoint ready */
|
||||||
|
MCA_BASE_METADATA_PARAM_NONE},
|
||||||
|
|
||||||
|
/* Initialization / querying functions */
|
||||||
|
|
||||||
|
.collm_init_query = mca_coll_han_init_query,
|
||||||
|
.collm_comm_query = mca_coll_han_comm_query,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* han-component specifc information */
|
||||||
|
|
||||||
|
/* (default) priority */
|
||||||
|
20,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init the component
|
||||||
|
*/
|
||||||
|
static int han_open(void)
|
||||||
|
{
|
||||||
|
mca_coll_han_component_t *cs = &mca_coll_han_component;
|
||||||
|
if (cs->han_auto_tune) {
|
||||||
|
cs->han_auto_tuned =
|
||||||
|
(selection *) malloc(2 * cs->han_auto_tune_n * cs->han_auto_tune_c *
|
||||||
|
cs->han_auto_tune_m * sizeof(selection));
|
||||||
|
char *filename = "/home/dycz0fx/results/auto/auto_tuned.bin";
|
||||||
|
FILE *file = fopen(filename, "r");
|
||||||
|
fread(cs->han_auto_tuned, sizeof(selection),
|
||||||
|
2 * cs->han_auto_tune_n * cs->han_auto_tune_c * cs->han_auto_tune_m, file);
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shut down the component
|
||||||
|
*/
|
||||||
|
static int han_close(void)
|
||||||
|
{
|
||||||
|
mca_coll_han_component_t *cs = &mca_coll_han_component;
|
||||||
|
if (cs->han_auto_tune && cs->han_auto_tuned != NULL) {
|
||||||
|
free(cs->han_auto_tuned);
|
||||||
|
cs->han_auto_tuned = NULL;
|
||||||
|
}
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register MCA params
|
||||||
|
*/
|
||||||
|
static int han_register(void)
|
||||||
|
{
|
||||||
|
mca_base_component_t *c = &mca_coll_han_component.super.collm_version;
|
||||||
|
mca_coll_han_component_t *cs = &mca_coll_han_component;
|
||||||
|
|
||||||
|
cs->han_priority = 50;
|
||||||
|
(void) mca_base_component_var_register(c, "priority", "Priority of the han coll component",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_priority);
|
||||||
|
|
||||||
|
int coll_han_verbose = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "verbose",
|
||||||
|
"Verbose level",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &coll_han_verbose);
|
||||||
|
cs->han_output = opal_output_open(NULL);
|
||||||
|
opal_output_set_verbosity(cs->han_output, coll_han_verbose);
|
||||||
|
|
||||||
|
cs->han_bcast_segsize = 65536;
|
||||||
|
(void) mca_base_component_var_register(c, "bcast_segsize",
|
||||||
|
"segment size for bcast",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_bcast_segsize);
|
||||||
|
|
||||||
|
cs->han_bcast_up_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "bcast_up_module",
|
||||||
|
"up level module for bcast, 0 libnbc, 1 adapt",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_bcast_up_module);
|
||||||
|
|
||||||
|
cs->han_bcast_low_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "bcast_low_module",
|
||||||
|
"low level module for bcast, 0 sm, 1 solo",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_bcast_low_module);
|
||||||
|
|
||||||
|
cs->han_reduce_segsize = 524288;
|
||||||
|
(void) mca_base_component_var_register(c, "reduce_segsize",
|
||||||
|
"segment size for reduce",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_reduce_segsize);
|
||||||
|
|
||||||
|
cs->han_reduce_up_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "reduce_up_module",
|
||||||
|
"up level module for allreduce, 0 libnbc, 1 adapt",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY,
|
||||||
|
&cs->han_reduce_up_module);
|
||||||
|
|
||||||
|
cs->han_reduce_low_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "reduce_low_module",
|
||||||
|
"low level module for allreduce, 0 sm, 1 shared",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY,
|
||||||
|
&cs->han_reduce_low_module);
|
||||||
|
cs->han_allreduce_segsize = 524288;
|
||||||
|
(void) mca_base_component_var_register(c, "allreduce_segsize",
|
||||||
|
"segment size for allreduce",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_allreduce_segsize);
|
||||||
|
|
||||||
|
cs->han_allreduce_up_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "allreduce_up_module",
|
||||||
|
"up level module for allreduce, 0 libnbc, 1 adapt",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY,
|
||||||
|
&cs->han_allreduce_up_module);
|
||||||
|
|
||||||
|
cs->han_allreduce_low_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "allreduce_low_module",
|
||||||
|
"low level module for allreduce, 0 sm, 1 shared",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY,
|
||||||
|
&cs->han_allreduce_low_module);
|
||||||
|
|
||||||
|
cs->han_allgather_up_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "allgather_up_module",
|
||||||
|
"up level module for allgather, 0 libnbc, 1 adapt",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY,
|
||||||
|
&cs->han_allgather_up_module);
|
||||||
|
|
||||||
|
cs->han_allgather_low_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "allgather_low_module",
|
||||||
|
"low level module for allgather, 0 sm, 1 shared",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY,
|
||||||
|
&cs->han_allgather_low_module);
|
||||||
|
|
||||||
|
cs->han_gather_up_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "gather_up_module",
|
||||||
|
"up level module for gather, 0 libnbc, 1 adapt",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_gather_up_module);
|
||||||
|
|
||||||
|
cs->han_gather_low_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "gather_low_module",
|
||||||
|
"low level module for gather, 0 sm, 1 shared",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_gather_low_module);
|
||||||
|
|
||||||
|
cs->han_scatter_up_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "scatter_up_module",
|
||||||
|
"up level module for scatter, 0 libnbc, 1 adapt",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_scatter_up_module);
|
||||||
|
|
||||||
|
cs->han_scatter_low_module = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "scatter_low_module",
|
||||||
|
"low level module for scatter, 0 sm, 1 shared",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY,
|
||||||
|
&cs->han_scatter_low_module);
|
||||||
|
|
||||||
|
cs->han_auto_tune = 0;
|
||||||
|
(void) mca_base_component_var_register(c, "auto_tune",
|
||||||
|
"whether enable auto tune, 0 disable, 1 enable, default 0",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_auto_tune);
|
||||||
|
|
||||||
|
cs->han_auto_tune_n = 5;
|
||||||
|
(void) mca_base_component_var_register(c, "auto_tune_n",
|
||||||
|
"auto tune n",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_auto_tune_n);
|
||||||
|
|
||||||
|
cs->han_auto_tune_c = 3;
|
||||||
|
(void) mca_base_component_var_register(c, "auto_tune_c",
|
||||||
|
"auto tune c",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_auto_tune_c);
|
||||||
|
|
||||||
|
cs->han_auto_tune_m = 21;
|
||||||
|
(void) mca_base_component_var_register(c, "auto_tune_m",
|
||||||
|
"auto tune n",
|
||||||
|
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
|
||||||
|
OPAL_INFO_LVL_9,
|
||||||
|
MCA_BASE_VAR_SCOPE_READONLY, &cs->han_auto_tune_m);
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
224
ompi/mca/coll/han/coll_han_gather.c
Обычный файл
224
ompi/mca/coll/han/coll_han_gather.c
Обычный файл
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "coll_han.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_base_functions.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_tags.h"
|
||||||
|
#include "ompi/mca/pml/pml.h"
|
||||||
|
#include "coll_han_trigger.h"
|
||||||
|
|
||||||
|
/* only work with regular situation (each node has equal number of processes) */
|
||||||
|
|
||||||
|
void mac_coll_han_set_gather_argu(mca_gather_argu_t * argu,
|
||||||
|
mca_coll_task_t * cur_task,
|
||||||
|
void *sbuf,
|
||||||
|
void *sbuf_inter_free,
|
||||||
|
int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf,
|
||||||
|
int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root,
|
||||||
|
int root_up_rank,
|
||||||
|
int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int w_rank, bool noop, ompi_request_t * req)
|
||||||
|
{
|
||||||
|
argu->cur_task = cur_task;
|
||||||
|
argu->sbuf = sbuf;
|
||||||
|
argu->sbuf_inter_free = sbuf_inter_free;
|
||||||
|
argu->scount = scount;
|
||||||
|
argu->sdtype = sdtype;
|
||||||
|
argu->rbuf = rbuf;
|
||||||
|
argu->rcount = rcount;
|
||||||
|
argu->rdtype = rdtype;
|
||||||
|
argu->root = root;
|
||||||
|
argu->root_up_rank = root_up_rank;
|
||||||
|
argu->root_low_rank = root_low_rank;
|
||||||
|
argu->up_comm = up_comm;
|
||||||
|
argu->low_comm = low_comm;
|
||||||
|
argu->w_rank = w_rank;
|
||||||
|
argu->noop = noop;
|
||||||
|
argu->req = req;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mca_coll_han_gather_intra(const void *sbuf, int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf, int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
int w_rank, w_size;
|
||||||
|
w_rank = ompi_comm_rank(comm);
|
||||||
|
w_size = ompi_comm_size(comm);
|
||||||
|
/* Create the subcommunicators */
|
||||||
|
mca_coll_han_module_t *han_module = (mca_coll_han_module_t *) module;
|
||||||
|
mca_coll_han_comm_create(comm, han_module);
|
||||||
|
ompi_communicator_t *low_comm =
|
||||||
|
han_module->cached_low_comms[mca_coll_han_component.han_gather_low_module];
|
||||||
|
ompi_communicator_t *up_comm =
|
||||||
|
han_module->cached_up_comms[mca_coll_han_component.han_gather_up_module];
|
||||||
|
int *vranks = han_module->cached_vranks;
|
||||||
|
int low_rank = ompi_comm_rank(low_comm);
|
||||||
|
int low_size = ompi_comm_size(low_comm);
|
||||||
|
int up_size = ompi_comm_size(up_comm);
|
||||||
|
|
||||||
|
ompi_request_t *temp_request = NULL;
|
||||||
|
/* Set up request */
|
||||||
|
temp_request = OBJ_NEW(ompi_request_t);
|
||||||
|
OMPI_REQUEST_INIT(temp_request, false);
|
||||||
|
temp_request->req_state = OMPI_REQUEST_ACTIVE;
|
||||||
|
temp_request->req_type = 0;
|
||||||
|
temp_request->req_free = han_request_free;
|
||||||
|
temp_request->req_status.MPI_SOURCE = 0;
|
||||||
|
temp_request->req_status.MPI_TAG = 0;
|
||||||
|
temp_request->req_status.MPI_ERROR = 0;
|
||||||
|
temp_request->req_status._cancelled = 0;
|
||||||
|
temp_request->req_status._ucount = 0;
|
||||||
|
|
||||||
|
int root_low_rank;
|
||||||
|
int root_up_rank;
|
||||||
|
mca_coll_han_get_ranks(vranks, root, low_size, &root_low_rank, &root_up_rank);
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: Future Gather root %d root_low_rank %d root_up_rank %d\n", w_rank,
|
||||||
|
root, root_low_rank, root_up_rank));
|
||||||
|
|
||||||
|
char *reorder_buf = NULL;
|
||||||
|
char *reorder_rbuf = NULL;
|
||||||
|
ptrdiff_t rsize, rgap = 0, rextent;
|
||||||
|
ompi_datatype_type_extent(rdtype, &rextent);
|
||||||
|
int *topo = mca_coll_han_topo_init(comm, han_module, 2);
|
||||||
|
if (w_rank == root) {
|
||||||
|
/* If the processes are mapped-by core, no need to reorder */
|
||||||
|
if (han_module->is_mapbycore) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: Future Gather is_bycore: ", w_rank));
|
||||||
|
reorder_rbuf = (char *) rbuf;
|
||||||
|
} else {
|
||||||
|
rsize = opal_datatype_span(&rdtype->super, (int64_t) rcount * w_size, &rgap);
|
||||||
|
reorder_buf = (char *) malloc(rsize); //TODO:free
|
||||||
|
reorder_rbuf = reorder_buf - rgap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Create lg task */
|
||||||
|
mca_coll_task_t *lg = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup lg task arguments */
|
||||||
|
mca_gather_argu_t *lg_argu = malloc(sizeof(mca_gather_argu_t));
|
||||||
|
mac_coll_han_set_gather_argu(lg_argu, lg, (char *) sbuf, NULL, scount, sdtype, reorder_rbuf,
|
||||||
|
rcount, rdtype, root, root_up_rank, root_low_rank, up_comm,
|
||||||
|
low_comm, w_rank, low_rank != root_low_rank, temp_request);
|
||||||
|
/* Init lg task */
|
||||||
|
init_task(lg, mca_coll_han_gather_lg_task, (void *) (lg_argu));
|
||||||
|
/* Issure lg task */
|
||||||
|
issue_task(lg);
|
||||||
|
|
||||||
|
ompi_request_wait(&temp_request, MPI_STATUS_IGNORE);
|
||||||
|
|
||||||
|
/* Reorder rbuf based on rank.
|
||||||
|
* Suppose, message is 0 1 2 3 4 5 6 7,
|
||||||
|
* and the processes are mapped on 2 nodes (the processes on the node 0 is 0 2 4 6 and the processes on the node 1 is 1 3 5 7),
|
||||||
|
* so the message needs to be reordered to 0 2 4 6 1 3 5 7
|
||||||
|
*/
|
||||||
|
if (w_rank == root && !han_module->is_mapbycore) {
|
||||||
|
for (i = 0; i < up_size; i++) {
|
||||||
|
for (j = 0; j < low_size; j++) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: Future Gather copy from %d %d\n", w_rank,
|
||||||
|
(i * low_size + j) * 2 + 1, topo[(i * low_size + j) * 2 + 1]));
|
||||||
|
ompi_datatype_copy_content_same_ddt(rdtype, (ptrdiff_t) rcount,
|
||||||
|
(char *) rbuf +
|
||||||
|
rextent * (ptrdiff_t) topo[(i * low_size + j) *
|
||||||
|
2 +
|
||||||
|
1] *
|
||||||
|
(ptrdiff_t) rcount,
|
||||||
|
reorder_rbuf + rextent * (i * low_size +
|
||||||
|
j) *
|
||||||
|
(ptrdiff_t) rcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(reorder_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lg: lower level (shared memory) gather task */
|
||||||
|
int mca_coll_han_gather_lg_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_gather_argu_t *t = (mca_gather_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d] Future Gather: lg\n",
|
||||||
|
t->w_rank));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
|
||||||
|
/* If the process is one of the node leader */
|
||||||
|
char *tmp_buf = NULL;
|
||||||
|
char *tmp_rbuf = NULL;
|
||||||
|
if (!t->noop) {
|
||||||
|
int low_size = ompi_comm_size(t->low_comm);
|
||||||
|
ptrdiff_t rsize, rgap = 0;
|
||||||
|
rsize = opal_datatype_span(&t->rdtype->super, (int64_t) t->rcount * low_size, &rgap);
|
||||||
|
tmp_buf = (char *) malloc(rsize);
|
||||||
|
tmp_rbuf = tmp_buf - rgap;
|
||||||
|
}
|
||||||
|
/* Shared memory gather */
|
||||||
|
t->low_comm->c_coll->coll_gather((char *) t->sbuf, t->scount, t->sdtype, tmp_rbuf, t->rcount,
|
||||||
|
t->rdtype, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_gather_module);
|
||||||
|
t->sbuf = tmp_rbuf;
|
||||||
|
t->sbuf_inter_free = tmp_buf;
|
||||||
|
|
||||||
|
/* Create ug (upper level all-gather) task */
|
||||||
|
mca_coll_task_t *ug = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup ug task arguments */
|
||||||
|
t->cur_task = ug;
|
||||||
|
/* Init ug task */
|
||||||
|
init_task(ug, mca_coll_han_gather_ug_task, (void *) t);
|
||||||
|
/* Issure ug task */
|
||||||
|
issue_task(ug);
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ug: upper level (intra-node) gather task */
|
||||||
|
int mca_coll_han_gather_ug_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_gather_argu_t *t = (mca_gather_argu_t *) task_argu;
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
|
||||||
|
if (t->noop) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] Future Gather: ug noop\n", t->w_rank));
|
||||||
|
} else {
|
||||||
|
int low_size = ompi_comm_size(t->low_comm);
|
||||||
|
/* Inter node gather */
|
||||||
|
t->up_comm->c_coll->coll_gather((char *) t->sbuf, t->scount * low_size, t->sdtype,
|
||||||
|
(char *) t->rbuf, t->rcount * low_size, t->rdtype,
|
||||||
|
t->root_up_rank, t->up_comm,
|
||||||
|
t->up_comm->c_coll->coll_gather_module);
|
||||||
|
|
||||||
|
if (t->sbuf_inter_free != NULL) {
|
||||||
|
free(t->sbuf_inter_free);
|
||||||
|
t->sbuf_inter_free = NULL;
|
||||||
|
}
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] Future Gather: ug gather finish\n", t->w_rank));
|
||||||
|
}
|
||||||
|
ompi_request_t *temp_req = t->req;
|
||||||
|
free(t);
|
||||||
|
ompi_request_complete(temp_req, 1);
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
468
ompi/mca/coll/han/coll_han_module.c
Обычный файл
468
ompi/mca/coll/han/coll_han_module.c
Обычный файл
@ -0,0 +1,468 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef HAVE_SCHED_H
|
||||||
|
#include <sched.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_SYS_MMAN_H
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif /* HAVE_SYS_MMAN_H */
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif /* HAVE_UNISTD_H */
|
||||||
|
|
||||||
|
#include "mpi.h"
|
||||||
|
#include "opal_stdint.h"
|
||||||
|
#include "opal/mca/hwloc/base/base.h"
|
||||||
|
#include "opal/util/os_path.h"
|
||||||
|
|
||||||
|
#include "ompi/communicator/communicator.h"
|
||||||
|
#include "ompi/group/group.h"
|
||||||
|
#include "ompi/mca/coll/coll.h"
|
||||||
|
#include "ompi/mca/coll/base/base.h"
|
||||||
|
#include "ompi/proc/proc.h"
|
||||||
|
#include "coll_han.h"
|
||||||
|
|
||||||
|
#include "ompi/mca/coll/base/coll_tags.h"
|
||||||
|
#include "ompi/mca/pml/pml.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local functions
|
||||||
|
*/
|
||||||
|
static int han_module_enable(mca_coll_base_module_t * module, struct ompi_communicator_t *comm);
|
||||||
|
static int mca_coll_han_module_disable(mca_coll_base_module_t * module,
|
||||||
|
struct ompi_communicator_t *comm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module constructor
|
||||||
|
*/
|
||||||
|
static void mca_coll_han_module_construct(mca_coll_han_module_t * module)
|
||||||
|
{
|
||||||
|
module->enabled = false;
|
||||||
|
module->super.coll_module_disable = mca_coll_han_module_disable;
|
||||||
|
module->cached_comm = NULL;
|
||||||
|
module->cached_low_comms = NULL;
|
||||||
|
module->cached_up_comms = NULL;
|
||||||
|
module->cached_vranks = NULL;
|
||||||
|
module->cached_topo = NULL;
|
||||||
|
module->is_mapbycore = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module destructor
|
||||||
|
*/
|
||||||
|
static void mca_coll_han_module_destruct(mca_coll_han_module_t * module)
|
||||||
|
{
|
||||||
|
module->enabled = false;
|
||||||
|
if (module->cached_low_comms != NULL) {
|
||||||
|
ompi_comm_free(&(module->cached_low_comms[0]));
|
||||||
|
ompi_comm_free(&(module->cached_low_comms[1]));
|
||||||
|
module->cached_low_comms[0] = NULL;
|
||||||
|
module->cached_low_comms[1] = NULL;
|
||||||
|
free(module->cached_low_comms);
|
||||||
|
module->cached_low_comms = NULL;
|
||||||
|
}
|
||||||
|
if (module->cached_up_comms != NULL) {
|
||||||
|
ompi_comm_free(&(module->cached_up_comms[0]));
|
||||||
|
ompi_comm_free(&(module->cached_up_comms[1]));
|
||||||
|
module->cached_up_comms[0] = NULL;
|
||||||
|
module->cached_up_comms[1] = NULL;
|
||||||
|
free(module->cached_up_comms);
|
||||||
|
module->cached_up_comms = NULL;
|
||||||
|
}
|
||||||
|
if (module->cached_vranks != NULL) {
|
||||||
|
free(module->cached_vranks);
|
||||||
|
module->cached_vranks = NULL;
|
||||||
|
}
|
||||||
|
if (module->cached_topo != NULL) {
|
||||||
|
free(module->cached_topo);
|
||||||
|
module->cached_topo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module disable
|
||||||
|
*/
|
||||||
|
static int mca_coll_han_module_disable(mca_coll_base_module_t * module,
|
||||||
|
struct ompi_communicator_t *comm)
|
||||||
|
{
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OBJ_CLASS_INSTANCE(mca_coll_han_module_t,
|
||||||
|
mca_coll_base_module_t,
|
||||||
|
mca_coll_han_module_construct, mca_coll_han_module_destruct);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initial query function that is invoked during MPI_INIT, allowing
|
||||||
|
* this component to disqualify itself if it doesn't support the
|
||||||
|
* required level of thread support. This function is invoked exactly
|
||||||
|
* once.
|
||||||
|
*/
|
||||||
|
int mca_coll_han_init_query(bool enable_progress_threads, bool enable_mpi_threads)
|
||||||
|
{
|
||||||
|
opal_output_verbose(10, ompi_coll_base_framework.framework_output,
|
||||||
|
"coll:han:init_query: pick me! pick me!");
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invoked when there's a new communicator that has been created.
|
||||||
|
* Look at the communicator and decide which set of functions and
|
||||||
|
* priority we want to return.
|
||||||
|
*/
|
||||||
|
mca_coll_base_module_t *mca_coll_han_comm_query(struct ompi_communicator_t * comm, int *priority)
|
||||||
|
{
|
||||||
|
mca_coll_han_module_t *han_module;
|
||||||
|
|
||||||
|
/* If we're intercomm, or if there's only one process in the
|
||||||
|
communicator */
|
||||||
|
if (OMPI_COMM_IS_INTER(comm) || 1 == ompi_comm_size(comm)
|
||||||
|
|| !ompi_group_have_remote_peers(comm->c_local_group)) {
|
||||||
|
opal_output_verbose(10, ompi_coll_base_framework.framework_output,
|
||||||
|
"coll:han:comm_query (%d/%s): intercomm, comm is too small, only on one node; disqualifying myself",
|
||||||
|
comm->c_contextid, comm->c_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the priority level attached to this module. If priority is less
|
||||||
|
* than or equal to 0, then the module is unavailable. */
|
||||||
|
*priority = mca_coll_han_component.han_priority;
|
||||||
|
if (mca_coll_han_component.han_priority <= 0) {
|
||||||
|
opal_output_verbose(10, ompi_coll_base_framework.framework_output,
|
||||||
|
"coll:han:comm_query (%d/%s): priority too low; disqualifying myself",
|
||||||
|
comm->c_contextid, comm->c_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
han_module = OBJ_NEW(mca_coll_han_module_t);
|
||||||
|
if (NULL == han_module) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All is good -- return a module */
|
||||||
|
han_module->super.coll_module_enable = han_module_enable;
|
||||||
|
han_module->super.ft_event = NULL;
|
||||||
|
han_module->super.coll_allgather = NULL; //mca_coll_han_allgather_intra;
|
||||||
|
han_module->super.coll_allgatherv = NULL;
|
||||||
|
han_module->super.coll_allreduce = mca_coll_han_allreduce_intra;
|
||||||
|
han_module->super.coll_alltoall = NULL;
|
||||||
|
han_module->super.coll_alltoallv = NULL;
|
||||||
|
han_module->super.coll_alltoallw = NULL;
|
||||||
|
han_module->super.coll_barrier = NULL;
|
||||||
|
han_module->super.coll_bcast = mca_coll_han_bcast_intra;
|
||||||
|
han_module->super.coll_exscan = NULL;
|
||||||
|
han_module->super.coll_gather = mca_coll_han_gather_intra;
|
||||||
|
han_module->super.coll_gatherv = NULL;
|
||||||
|
han_module->super.coll_reduce = mca_coll_han_reduce_intra;
|
||||||
|
han_module->super.coll_reduce_scatter = NULL;
|
||||||
|
han_module->super.coll_scan = NULL;
|
||||||
|
han_module->super.coll_scatter = mca_coll_han_scatter_intra;
|
||||||
|
han_module->super.coll_scatterv = NULL;
|
||||||
|
|
||||||
|
opal_output_verbose(10, ompi_coll_base_framework.framework_output,
|
||||||
|
"coll:han:comm_query (%d/%s): pick me! pick me!",
|
||||||
|
comm->c_contextid, comm->c_name);
|
||||||
|
return &(han_module->super);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init module on the communicator
|
||||||
|
*/
|
||||||
|
static int han_module_enable(mca_coll_base_module_t * module, struct ompi_communicator_t *comm)
|
||||||
|
{
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the han request
|
||||||
|
*/
|
||||||
|
int han_request_free(ompi_request_t ** request)
|
||||||
|
{
|
||||||
|
(*request)->req_state = OMPI_REQUEST_INVALID;
|
||||||
|
OBJ_RELEASE(*request);
|
||||||
|
*request = MPI_REQUEST_NULL;
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the communicators used in the HAN module */
|
||||||
|
void mca_coll_han_comm_create(struct ompi_communicator_t *comm, mca_coll_han_module_t * han_module)
|
||||||
|
{
|
||||||
|
/* Use cached communicators if possible */
|
||||||
|
if (han_module->cached_comm == comm && han_module->cached_low_comms != NULL
|
||||||
|
&& han_module->cached_up_comms != NULL && han_module->cached_vranks != NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Create communicators if there is no cached communicator */
|
||||||
|
else {
|
||||||
|
int low_rank, low_size;
|
||||||
|
int up_rank;
|
||||||
|
int w_rank = ompi_comm_rank(comm);
|
||||||
|
int w_size = ompi_comm_size(comm);
|
||||||
|
ompi_communicator_t **low_comms =
|
||||||
|
(struct ompi_communicator_t **) malloc(sizeof(struct ompi_communicator_t *) * 2);
|
||||||
|
ompi_communicator_t **up_comms =
|
||||||
|
(struct ompi_communicator_t **) malloc(sizeof(struct ompi_communicator_t *) * 2);
|
||||||
|
/* Create low_comms which contain all the process on a node */
|
||||||
|
const int *origin_priority = NULL;
|
||||||
|
/* Lower the priority of HAN module */
|
||||||
|
int han_var_id;
|
||||||
|
int tmp_han_priority = 0;
|
||||||
|
int tmp_han_origin = 0;
|
||||||
|
mca_base_var_find_by_name("coll_han_priority", &han_var_id);
|
||||||
|
mca_base_var_get_value(han_var_id, &origin_priority, NULL, NULL);
|
||||||
|
tmp_han_origin = *origin_priority;
|
||||||
|
mca_base_var_set_flag(han_var_id, MCA_BASE_VAR_FLAG_SETTABLE, true);
|
||||||
|
mca_base_var_set_value(han_var_id, &tmp_han_priority, sizeof(int), MCA_BASE_VAR_SOURCE_SET,
|
||||||
|
NULL);
|
||||||
|
comm->c_coll->coll_allreduce = ompi_coll_base_allreduce_intra_recursivedoubling;
|
||||||
|
comm->c_coll->coll_allgather = ompi_coll_base_allgather_intra_bruck;
|
||||||
|
|
||||||
|
int var_id;
|
||||||
|
int tmp_priority = 100;
|
||||||
|
int tmp_origin = 0;
|
||||||
|
/* Set up low_comms[0] with sm module */
|
||||||
|
mca_base_var_find_by_name("coll_sm_priority", &var_id);
|
||||||
|
mca_base_var_get_value(var_id, &origin_priority, NULL, NULL);
|
||||||
|
tmp_origin = *origin_priority;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] sm_priority origin %d %d\n", w_rank, *origin_priority,
|
||||||
|
tmp_origin));
|
||||||
|
mca_base_var_set_flag(var_id, MCA_BASE_VAR_FLAG_SETTABLE, true);
|
||||||
|
mca_base_var_set_value(var_id, &tmp_priority, sizeof(int), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||||
|
ompi_comm_split_type(comm, MPI_COMM_TYPE_SHARED, 0, (opal_info_t *) (&ompi_mpi_info_null),
|
||||||
|
&(low_comms[0]));
|
||||||
|
mca_base_var_set_value(var_id, &tmp_origin, sizeof(int), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||||
|
low_size = ompi_comm_size(low_comms[0]);
|
||||||
|
low_rank = ompi_comm_rank(low_comms[0]);
|
||||||
|
|
||||||
|
/* Set up low_comms[1] with solo module */
|
||||||
|
mca_base_var_find_by_name("coll_solo_priority", &var_id);
|
||||||
|
mca_base_var_get_value(var_id, &origin_priority, NULL, NULL);
|
||||||
|
tmp_origin = *origin_priority;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] solo_priority origin %d %d\n", w_rank, *origin_priority,
|
||||||
|
tmp_origin));
|
||||||
|
mca_base_var_set_flag(var_id, MCA_BASE_VAR_FLAG_SETTABLE, true);
|
||||||
|
mca_base_var_set_value(var_id, &tmp_priority, sizeof(int), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||||
|
ompi_comm_split_type(comm, MPI_COMM_TYPE_SHARED, 0, (opal_info_t *) (&ompi_mpi_info_null),
|
||||||
|
&(low_comms[1]));
|
||||||
|
mca_base_var_set_value(var_id, &tmp_origin, sizeof(int), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||||
|
|
||||||
|
/* Create up_comms[0] with libnbc which contain one process per node (across nodes) */
|
||||||
|
mca_base_var_find_by_name("coll_libnbc_priority", &var_id);
|
||||||
|
mca_base_var_get_value(var_id, &origin_priority, NULL, NULL);
|
||||||
|
tmp_origin = *origin_priority;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] libnbc_priority origin %d %d\n", w_rank, *origin_priority,
|
||||||
|
tmp_origin));
|
||||||
|
mca_base_var_set_flag(var_id, MCA_BASE_VAR_FLAG_SETTABLE, true);
|
||||||
|
mca_base_var_set_value(var_id, &tmp_priority, sizeof(int), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||||
|
ompi_comm_split(comm, low_rank, w_rank, &(up_comms[0]), false);
|
||||||
|
mca_base_var_set_value(var_id, &tmp_origin, sizeof(int), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||||
|
up_rank = ompi_comm_rank(up_comms[0]);
|
||||||
|
|
||||||
|
/* Create up_comms[1] with adapt which contain one process per node (across nodes) */
|
||||||
|
mca_base_var_find_by_name("coll_adapt_priority", &var_id);
|
||||||
|
mca_base_var_get_value(var_id, &origin_priority, NULL, NULL);
|
||||||
|
tmp_origin = *origin_priority;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] adapt_priority origin %d %d\n", w_rank, *origin_priority,
|
||||||
|
tmp_origin));
|
||||||
|
mca_base_var_set_flag(var_id, MCA_BASE_VAR_FLAG_SETTABLE, true);
|
||||||
|
mca_base_var_set_value(var_id, &tmp_priority, sizeof(int), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||||
|
ompi_comm_split(comm, low_rank, w_rank, &(up_comms[1]), false);
|
||||||
|
mca_base_var_set_value(var_id, &tmp_origin, sizeof(int), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||||
|
|
||||||
|
int *vranks = malloc(sizeof(int) * w_size);
|
||||||
|
/* Do allgather to gather vrank from each process so every process knows other processes' vrank */
|
||||||
|
int vrank = low_size * up_rank + low_rank;
|
||||||
|
ompi_coll_base_allgather_intra_bruck(&vrank, 1, MPI_INT, vranks, 1, MPI_INT, comm,
|
||||||
|
comm->c_coll->coll_allgather_module);
|
||||||
|
han_module->cached_comm = comm;
|
||||||
|
han_module->cached_low_comms = low_comms;
|
||||||
|
han_module->cached_up_comms = up_comms;
|
||||||
|
han_module->cached_vranks = vranks;
|
||||||
|
|
||||||
|
mca_base_var_set_value(han_var_id, &tmp_han_origin, sizeof(int), MCA_BASE_VAR_SOURCE_SET,
|
||||||
|
NULL);
|
||||||
|
comm->c_coll->coll_allreduce = mca_coll_han_allreduce_intra;
|
||||||
|
comm->c_coll->coll_allgather = mca_coll_han_allgather_intra;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mca_coll_han_pow10_int(int pow_value)
|
||||||
|
{
|
||||||
|
int i, result = 1;
|
||||||
|
for (i = 0; i < pow_value; i++) {
|
||||||
|
result *= 10;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mca_coll_han_hostname_to_number(char *hostname, int size)
|
||||||
|
{
|
||||||
|
int i = 0, j = 0;
|
||||||
|
char *number_array = (char *) malloc(sizeof(char) * size);
|
||||||
|
while (hostname[i] != '\0') {
|
||||||
|
if (hostname[i] >= '0' && hostname[i] <= '9') {
|
||||||
|
number_array[j++] = hostname[i];
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
int number = 0;
|
||||||
|
for (i = 0; i < j; i++) {
|
||||||
|
number += (number_array[i] - '0') * mca_coll_han_pow10_int(j - 1 - i);
|
||||||
|
}
|
||||||
|
free(number_array);
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mca_coll_han_topo_get(int *topo, struct ompi_communicator_t *comm, int num_topo_level)
|
||||||
|
{
|
||||||
|
int *self_topo = (int *) malloc(sizeof(int) * num_topo_level);
|
||||||
|
/* Set daemon vpid */
|
||||||
|
char hostname[1024];
|
||||||
|
gethostname(hostname, 1024);
|
||||||
|
self_topo[0] = mca_coll_han_hostname_to_number(hostname, 1024);
|
||||||
|
/* Set core id */
|
||||||
|
self_topo[1] = ompi_comm_rank(comm);
|
||||||
|
|
||||||
|
/* Allgather all the topology information */
|
||||||
|
ompi_coll_base_allgather_intra_bruck(self_topo, num_topo_level, MPI_INT, topo, num_topo_level,
|
||||||
|
MPI_INT, comm, comm->c_coll->coll_allgather_module);
|
||||||
|
free(self_topo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mca_coll_han_topo_sort(int *topo, int start, int end, int size, int level, int num_topo_level)
|
||||||
|
{
|
||||||
|
if (level > num_topo_level - 1 || start >= end) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int i, j;
|
||||||
|
int min = INT_MAX;
|
||||||
|
int min_loc = -1;
|
||||||
|
for (i = start; i <= end; i++) {
|
||||||
|
/* Find min */
|
||||||
|
for (j = i; j <= end; j++) {
|
||||||
|
if (topo[j * num_topo_level + level] < min) {
|
||||||
|
min = topo[j * num_topo_level + level];
|
||||||
|
min_loc = j;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Swap i and min_loc */
|
||||||
|
int temp;
|
||||||
|
for (j = 0; j < num_topo_level; j++) {
|
||||||
|
temp = topo[i * num_topo_level + j];
|
||||||
|
topo[i * num_topo_level + j] = topo[min_loc * num_topo_level + j];
|
||||||
|
topo[min_loc * num_topo_level + j] = temp;
|
||||||
|
}
|
||||||
|
min = INT_MAX;
|
||||||
|
min_loc = -1;
|
||||||
|
}
|
||||||
|
int last = 0;
|
||||||
|
int new_start = 0;
|
||||||
|
int new_end = 0;
|
||||||
|
for (i = start; i <= end; i++) {
|
||||||
|
if (i == start) {
|
||||||
|
last = topo[i * num_topo_level + level];
|
||||||
|
new_start = start;
|
||||||
|
} else if (i == end) {
|
||||||
|
new_end = end;
|
||||||
|
mca_coll_han_topo_sort(topo, new_start, new_end, size, level + 1, num_topo_level);
|
||||||
|
} else if (last != topo[i * num_topo_level + level]) {
|
||||||
|
new_end = i - 1;
|
||||||
|
mca_coll_han_topo_sort(topo, new_start, new_end, size, level + 1, num_topo_level);
|
||||||
|
new_start = i;
|
||||||
|
last = topo[i * num_topo_level + level];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the current processes are mapped by core */
|
||||||
|
bool mca_coll_han_topo_is_mapbycore(int *topo, struct ompi_communicator_t * comm,
|
||||||
|
int num_topo_level)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int size = ompi_comm_size(comm);
|
||||||
|
for (i = 1; i < size; i++) {
|
||||||
|
if (topo[(i - 1) * num_topo_level] > topo[i * num_topo_level]
|
||||||
|
|| topo[(i - 1) * num_topo_level + 1] > topo[i * num_topo_level + 1]) {
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *mca_coll_han_topo_init(struct ompi_communicator_t *comm, mca_coll_han_module_t * han_module,
|
||||||
|
int num_topo_level)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
size = ompi_comm_size(comm);
|
||||||
|
int *topo;
|
||||||
|
if ((han_module->cached_topo != NULL) && (han_module->cached_comm == comm)) {
|
||||||
|
topo = han_module->cached_topo;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (han_module->cached_topo != NULL) {
|
||||||
|
free(han_module->cached_topo);
|
||||||
|
han_module->cached_topo = NULL;
|
||||||
|
}
|
||||||
|
topo = (int *) malloc(sizeof(int) * size * num_topo_level);
|
||||||
|
/* Get topo infomation */
|
||||||
|
mca_coll_han_topo_get(topo, comm, num_topo_level);
|
||||||
|
mca_coll_han_topo_print(topo, comm, num_topo_level);
|
||||||
|
|
||||||
|
/* Check if the processes are mapped by core */
|
||||||
|
han_module->is_mapbycore = mca_coll_han_topo_is_mapbycore(topo, comm, num_topo_level);
|
||||||
|
/* Sort the topo such that each group is contiguous */
|
||||||
|
if (!han_module->is_mapbycore) {
|
||||||
|
mca_coll_han_topo_sort(topo, 0, size - 1, size, 0, num_topo_level);
|
||||||
|
}
|
||||||
|
han_module->cached_topo = topo;
|
||||||
|
han_module->cached_comm = comm;
|
||||||
|
}
|
||||||
|
|
||||||
|
mca_coll_han_topo_print(topo, comm, num_topo_level);
|
||||||
|
return topo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print out the topology info, for debugging purpose */
|
||||||
|
void mca_coll_han_topo_print(int *topo, struct ompi_communicator_t *comm, int num_topo_level)
|
||||||
|
{
|
||||||
|
int rank = ompi_comm_rank(comm);
|
||||||
|
int size = ompi_comm_size(comm);
|
||||||
|
|
||||||
|
if (rank == 0) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d]: HAN topo: ", rank));
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < size * num_topo_level; i++) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "%d ", topo[i]));
|
||||||
|
}
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "\n"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
192
ompi/mca/coll/han/coll_han_reduce.c
Обычный файл
192
ompi/mca/coll/han/coll_han_reduce.c
Обычный файл
@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "coll_han.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_base_functions.h"
|
||||||
|
#include "ompi/mca/pml/pml.h"
|
||||||
|
#include "coll_han_trigger.h"
|
||||||
|
|
||||||
|
void mac_coll_han_set_reduce_argu(mca_reduce_argu_t * argu, mca_coll_task_t * cur_task, void *sbuf, void *rbuf,
|
||||||
|
int seg_count, struct ompi_datatype_t *dtype, struct ompi_op_t *op,
|
||||||
|
int root_up_rank, int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int num_segments, int cur_seg, int w_rank, int last_seg_count,
|
||||||
|
bool noop)
|
||||||
|
{
|
||||||
|
argu->cur_task = cur_task;
|
||||||
|
argu->sbuf = sbuf;
|
||||||
|
argu->rbuf = rbuf;
|
||||||
|
argu->seg_count = seg_count;
|
||||||
|
argu->dtype = dtype;
|
||||||
|
argu->op = op;
|
||||||
|
argu->root_low_rank = root_low_rank;
|
||||||
|
argu->root_up_rank = root_up_rank;
|
||||||
|
argu->up_comm = up_comm;
|
||||||
|
argu->low_comm = low_comm;
|
||||||
|
argu->num_segments = num_segments;
|
||||||
|
argu->cur_seg = cur_seg;
|
||||||
|
argu->w_rank = w_rank;
|
||||||
|
argu->last_seg_count = last_seg_count;
|
||||||
|
argu->noop = noop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each segment of the messsage needs to go though 2 steps to perform MPI_Reduce:
|
||||||
|
* lb: low level (shared-memory or intra-node) reduce.
|
||||||
|
* ub: upper level (inter-node) reduce
|
||||||
|
* Hence, in each iteration, there is a combination of collective operations which is called a task.
|
||||||
|
* | seg 0 | seg 1 | seg 2 | seg 3 |
|
||||||
|
* iter 0 | lr | | | | task: t0, contains lr
|
||||||
|
* iter 1 | ur | lr | | | task: t1, contains ur and lr
|
||||||
|
* iter 2 | | ur | lr | | task: t1, contains ur and lr
|
||||||
|
* iter 3 | | | ur | lr | task: t1, contains ur and lr
|
||||||
|
* iter 4 | | | | ur | task: t1, contains ur
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
mca_coll_han_reduce_intra(const void *sbuf,
|
||||||
|
void *rbuf,
|
||||||
|
int count,
|
||||||
|
struct ompi_datatype_t *dtype,
|
||||||
|
ompi_op_t* op,
|
||||||
|
int root,
|
||||||
|
struct ompi_communicator_t *comm,
|
||||||
|
mca_coll_base_module_t * module)
|
||||||
|
{
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(dtype, &lb, &extent);
|
||||||
|
int w_rank;
|
||||||
|
w_rank = ompi_comm_rank(comm);
|
||||||
|
int seg_count = count;
|
||||||
|
size_t typelng;
|
||||||
|
ompi_datatype_type_size(dtype, &typelng);
|
||||||
|
|
||||||
|
/* Create the subcommunicators */
|
||||||
|
mca_coll_han_module_t *han_module = (mca_coll_han_module_t *) module;
|
||||||
|
mca_coll_han_comm_create(comm, han_module);
|
||||||
|
ompi_communicator_t *low_comm;
|
||||||
|
ompi_communicator_t *up_comm;
|
||||||
|
|
||||||
|
/* use MCA parameters for now */
|
||||||
|
low_comm = han_module->cached_low_comms[mca_coll_han_component.han_reduce_low_module];
|
||||||
|
up_comm = han_module->cached_up_comms[mca_coll_han_component.han_reduce_up_module];
|
||||||
|
COLL_BASE_COMPUTED_SEGCOUNT(mca_coll_han_component.han_reduce_segsize, typelng,
|
||||||
|
seg_count);
|
||||||
|
|
||||||
|
int num_segments = (count + seg_count - 1) / seg_count;
|
||||||
|
OPAL_OUTPUT_VERBOSE((20, mca_coll_han_component.han_output,
|
||||||
|
"In HAN seg_count %d count %d num_seg %d\n",
|
||||||
|
seg_count, count, num_segments));
|
||||||
|
|
||||||
|
int *vranks = han_module->cached_vranks;
|
||||||
|
int low_rank = ompi_comm_rank(low_comm);
|
||||||
|
int low_size = ompi_comm_size(low_comm);
|
||||||
|
|
||||||
|
int root_low_rank;
|
||||||
|
int root_up_rank;
|
||||||
|
mca_coll_han_get_ranks(vranks, root, low_size, &root_low_rank, &root_up_rank);
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: root_low_rank %d root_up_rank %d\n", w_rank, root_low_rank,
|
||||||
|
root_up_rank));
|
||||||
|
|
||||||
|
/* Create t0 tasks for the first segment */
|
||||||
|
mca_coll_task_t *t0 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t0 task arguments */
|
||||||
|
mca_reduce_argu_t *t = malloc(sizeof(mca_reduce_argu_t));
|
||||||
|
mac_coll_han_set_reduce_argu(t, t0, (char *) sbuf, (char *) rbuf, seg_count, dtype,
|
||||||
|
op, root_up_rank, root_low_rank, up_comm, low_comm,
|
||||||
|
num_segments, 0, w_rank, count - (num_segments - 1) * seg_count,
|
||||||
|
low_rank != root_low_rank);
|
||||||
|
/* Init the first task */
|
||||||
|
init_task(t0, mca_coll_han_reduce_t0_task, (void *) t);
|
||||||
|
issue_task(t0);
|
||||||
|
|
||||||
|
/* Create t1 task */
|
||||||
|
mca_coll_task_t *t1 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t1 task arguments */
|
||||||
|
t->cur_task = t1;
|
||||||
|
/* Init the t1 task */
|
||||||
|
init_task(t1, mca_coll_han_reduce_t1_task, (void *) t);
|
||||||
|
issue_task(t1);
|
||||||
|
|
||||||
|
while (t->cur_seg <= t->num_segments - 2) {
|
||||||
|
/* Create t1 task */
|
||||||
|
mca_coll_task_t *t1 = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up t1 task arguments */
|
||||||
|
t->cur_task = t1;
|
||||||
|
t->sbuf = (char *) t->sbuf + extent * t->seg_count;
|
||||||
|
t->rbuf = (char *) t->rbuf + extent * t->seg_count;
|
||||||
|
t->cur_seg = t->cur_seg + 1;
|
||||||
|
/* Init the t1 task */
|
||||||
|
init_task(t1, mca_coll_han_reduce_t1_task, (void *) t);
|
||||||
|
issue_task(t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(t);
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t0 task: issue and wait for the low level reduce of segment 0 */
|
||||||
|
int mca_coll_han_reduce_t0_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_reduce_argu_t *t = (mca_reduce_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d]: in t0 %d\n", t->w_rank,
|
||||||
|
t->cur_seg));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(t->dtype, &lb, &extent);
|
||||||
|
t->low_comm->c_coll->coll_reduce((char *) t->sbuf, (char *) t->rbuf, t->seg_count, t->dtype,
|
||||||
|
t->op, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_reduce_module);
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t1 task */
|
||||||
|
int mca_coll_han_reduce_t1_task(void *task_argu) {
|
||||||
|
mca_reduce_argu_t *t = (mca_reduce_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d]: in t1 %d\n", t->w_rank,
|
||||||
|
t->cur_seg));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
ptrdiff_t extent, lb;
|
||||||
|
ompi_datatype_get_extent(t->dtype, &lb, &extent);
|
||||||
|
ompi_request_t *ireduce_req = NULL;
|
||||||
|
int tmp_count = t->seg_count;
|
||||||
|
if (!t->noop) {
|
||||||
|
int up_rank = ompi_comm_rank(t->up_comm);
|
||||||
|
/* ur of cur_seg */
|
||||||
|
if (up_rank == t->root_up_rank) {
|
||||||
|
t->up_comm->c_coll->coll_ireduce(MPI_IN_PLACE, (char *) t->rbuf, t->seg_count, t->dtype,
|
||||||
|
t->op, t->root_up_rank, t->up_comm, &ireduce_req,
|
||||||
|
t->up_comm->c_coll->coll_ireduce_module);
|
||||||
|
} else {
|
||||||
|
t->up_comm->c_coll->coll_ireduce((char *) t->rbuf, (char *) t->rbuf, t->seg_count,
|
||||||
|
t->dtype, t->op, t->root_up_rank, t->up_comm,
|
||||||
|
&ireduce_req, t->up_comm->c_coll->coll_ireduce_module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* lr of cur_seg+1 */
|
||||||
|
if (t->cur_seg <= t->num_segments - 2) {
|
||||||
|
if (t->cur_seg == t->num_segments - 2 && t->last_seg_count != t->seg_count) {
|
||||||
|
tmp_count = t->last_seg_count;
|
||||||
|
}
|
||||||
|
t->low_comm->c_coll->coll_reduce((char *) t->sbuf + extent * t->seg_count,
|
||||||
|
(char *) t->rbuf + extent * t->seg_count, tmp_count,
|
||||||
|
t->dtype, t->op, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_reduce_module);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!t->noop && ireduce_req) {
|
||||||
|
ompi_request_wait(&ireduce_req, MPI_STATUSES_IGNORE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
222
ompi/mca/coll/han/coll_han_scatter.c
Обычный файл
222
ompi/mca/coll/han/coll_han_scatter.c
Обычный файл
@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "coll_han.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_base_functions.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_tags.h"
|
||||||
|
#include "ompi/mca/pml/pml.h"
|
||||||
|
#include "coll_han_trigger.h"
|
||||||
|
|
||||||
|
/* Only work with regular situation (each node has equal number of processes) */
|
||||||
|
|
||||||
|
void mac_coll_han_set_scatter_argu(mca_scatter_argu_t * argu,
|
||||||
|
mca_coll_task_t * cur_task,
|
||||||
|
void *sbuf,
|
||||||
|
void *sbuf_inter_free,
|
||||||
|
void *sbuf_reorder_free,
|
||||||
|
int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf,
|
||||||
|
int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root,
|
||||||
|
int root_up_rank,
|
||||||
|
int root_low_rank,
|
||||||
|
struct ompi_communicator_t *up_comm,
|
||||||
|
struct ompi_communicator_t *low_comm,
|
||||||
|
int w_rank, bool noop, ompi_request_t * req)
|
||||||
|
{
|
||||||
|
argu->cur_task = cur_task;
|
||||||
|
argu->sbuf = sbuf;
|
||||||
|
argu->sbuf_inter_free = sbuf_inter_free;
|
||||||
|
argu->sbuf_reorder_free = sbuf_reorder_free;
|
||||||
|
argu->scount = scount;
|
||||||
|
argu->sdtype = sdtype;
|
||||||
|
argu->rbuf = rbuf;
|
||||||
|
argu->rcount = rcount;
|
||||||
|
argu->rdtype = rdtype;
|
||||||
|
argu->root = root;
|
||||||
|
argu->root_up_rank = root_up_rank;
|
||||||
|
argu->root_low_rank = root_low_rank;
|
||||||
|
argu->up_comm = up_comm;
|
||||||
|
argu->low_comm = low_comm;
|
||||||
|
argu->w_rank = w_rank;
|
||||||
|
argu->noop = noop;
|
||||||
|
argu->req = req;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mca_coll_han_scatter_intra(const void *sbuf, int scount,
|
||||||
|
struct ompi_datatype_t *sdtype,
|
||||||
|
void *rbuf, int rcount,
|
||||||
|
struct ompi_datatype_t *rdtype,
|
||||||
|
int root,
|
||||||
|
struct ompi_communicator_t *comm, mca_coll_base_module_t * module)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
int w_rank, w_size;
|
||||||
|
w_rank = ompi_comm_rank(comm);
|
||||||
|
w_size = ompi_comm_size(comm);
|
||||||
|
|
||||||
|
/* Create the subcommunicators */
|
||||||
|
mca_coll_han_module_t *han_module = (mca_coll_han_module_t *) module;
|
||||||
|
mca_coll_han_comm_create(comm, han_module);
|
||||||
|
ompi_communicator_t *low_comm =
|
||||||
|
han_module->cached_low_comms[mca_coll_han_component.han_scatter_low_module];
|
||||||
|
ompi_communicator_t *up_comm =
|
||||||
|
han_module->cached_up_comms[mca_coll_han_component.han_scatter_up_module];
|
||||||
|
int *vranks = han_module->cached_vranks;
|
||||||
|
int low_rank = ompi_comm_rank(low_comm);
|
||||||
|
int low_size = ompi_comm_size(low_comm);
|
||||||
|
int up_size = ompi_comm_size(up_comm);
|
||||||
|
|
||||||
|
ompi_request_t *temp_request = NULL;
|
||||||
|
/* Set up request */
|
||||||
|
temp_request = OBJ_NEW(ompi_request_t);
|
||||||
|
OMPI_REQUEST_INIT(temp_request, false);
|
||||||
|
temp_request->req_state = OMPI_REQUEST_ACTIVE;
|
||||||
|
temp_request->req_type = 0;
|
||||||
|
temp_request->req_free = han_request_free;
|
||||||
|
temp_request->req_status.MPI_SOURCE = 0;
|
||||||
|
temp_request->req_status.MPI_TAG = 0;
|
||||||
|
temp_request->req_status.MPI_ERROR = 0;
|
||||||
|
temp_request->req_status._cancelled = 0;
|
||||||
|
temp_request->req_status._ucount = 0;
|
||||||
|
|
||||||
|
int root_low_rank;
|
||||||
|
int root_up_rank;
|
||||||
|
mca_coll_han_get_ranks(vranks, root, low_size, &root_low_rank, &root_up_rank);
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: Han Scatter root %d root_low_rank %d root_up_rank %d\n", w_rank,
|
||||||
|
root, root_low_rank, root_up_rank));
|
||||||
|
|
||||||
|
/* Reorder sbuf based on rank.
|
||||||
|
* Suppose, message is 0 1 2 3 4 5 6 7
|
||||||
|
* and the processes are mapped on 2 nodes (the processes on the node 0 is 0 2 4 6 and the processes on the node 1 is 1 3 5 7),
|
||||||
|
* so the message needs to be reordered to 0 2 4 6 1 3 5 7
|
||||||
|
*/
|
||||||
|
char *reorder_buf = NULL;
|
||||||
|
char *reorder_sbuf = NULL;
|
||||||
|
int *topo = mca_coll_han_topo_init(comm, han_module, 2);
|
||||||
|
|
||||||
|
if (w_rank == root) {
|
||||||
|
/* If the processes are mapped-by core, no need to reorder */
|
||||||
|
if (han_module->is_mapbycore) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: Han Scatter is_bycore: ", w_rank));
|
||||||
|
reorder_sbuf = (char *) sbuf;
|
||||||
|
} else {
|
||||||
|
ptrdiff_t ssize, sgap = 0, sextent;
|
||||||
|
ompi_datatype_type_extent(sdtype, &sextent);
|
||||||
|
ssize = opal_datatype_span(&sdtype->super, (int64_t) scount * w_size, &sgap);
|
||||||
|
reorder_buf = (char *) malloc(ssize);
|
||||||
|
reorder_sbuf = reorder_buf - sgap;
|
||||||
|
for (i = 0; i < up_size; i++) {
|
||||||
|
for (j = 0; j < low_size; j++) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d]: Han Scatter copy from %d %d\n", w_rank,
|
||||||
|
(i * low_size + j) * 2 + 1,
|
||||||
|
topo[(i * low_size + j) * 2 + 1]));
|
||||||
|
ompi_datatype_copy_content_same_ddt(sdtype, (ptrdiff_t) scount,
|
||||||
|
reorder_sbuf + sextent * (i * low_size +
|
||||||
|
j) *
|
||||||
|
(ptrdiff_t) scount,
|
||||||
|
(char *) sbuf +
|
||||||
|
sextent *
|
||||||
|
(ptrdiff_t) topo[(i * low_size + j) * 2 +
|
||||||
|
1] * (ptrdiff_t) scount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create us task */
|
||||||
|
mca_coll_task_t *us = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup us task arguments */
|
||||||
|
mca_scatter_argu_t *us_argu = malloc(sizeof(mca_scatter_argu_t));
|
||||||
|
mac_coll_han_set_scatter_argu(us_argu, us, reorder_sbuf, NULL, reorder_buf, scount, sdtype,
|
||||||
|
(char *) rbuf, rcount, rdtype, root, root_up_rank, root_low_rank,
|
||||||
|
up_comm, low_comm, w_rank, low_rank != root_low_rank,
|
||||||
|
temp_request);
|
||||||
|
/* Init us task */
|
||||||
|
init_task(us, mca_coll_han_scatter_us_task, (void *) (us_argu));
|
||||||
|
/* Issure us task */
|
||||||
|
issue_task(us);
|
||||||
|
|
||||||
|
ompi_request_wait(&temp_request, MPI_STATUS_IGNORE);
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* us: upper level (intra-node) scatter task */
|
||||||
|
int mca_coll_han_scatter_us_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_scatter_argu_t *t = (mca_scatter_argu_t *) task_argu;
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
|
||||||
|
if (t->noop) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d] Han Scatter: us noop\n",
|
||||||
|
t->w_rank));
|
||||||
|
} else {
|
||||||
|
int low_size = ompi_comm_size(t->low_comm);
|
||||||
|
ptrdiff_t rsize, rgap = 0;
|
||||||
|
rsize = opal_datatype_span(&t->rdtype->super, (int64_t) t->rcount * low_size, &rgap);
|
||||||
|
char *tmp_buf = (char *) malloc(rsize);
|
||||||
|
char *tmp_rbuf = tmp_buf - rgap;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output,
|
||||||
|
"[%d] Han Scatter: us scatter\n", t->w_rank));
|
||||||
|
/* Inter node scatter */
|
||||||
|
t->up_comm->c_coll->coll_scatter((char *) t->sbuf, t->scount * low_size, t->sdtype,
|
||||||
|
tmp_rbuf, t->rcount * low_size, t->rdtype, t->root_up_rank,
|
||||||
|
t->up_comm, t->up_comm->c_coll->coll_scatter_module);
|
||||||
|
t->sbuf = tmp_rbuf;
|
||||||
|
t->sbuf_inter_free = tmp_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->sbuf_reorder_free != NULL && t->root == t->w_rank) {
|
||||||
|
free(t->sbuf_reorder_free);
|
||||||
|
t->sbuf_reorder_free = NULL;
|
||||||
|
}
|
||||||
|
/* Create ls tasks for the current union segment */
|
||||||
|
mca_coll_task_t *ls = OBJ_NEW(mca_coll_task_t);
|
||||||
|
/* Setup up ls task arguments */
|
||||||
|
t->cur_task = ls;
|
||||||
|
/* Init ls task */
|
||||||
|
init_task(ls, mca_coll_han_scatter_ls_task, (void *) t);
|
||||||
|
/* Issure ls task */
|
||||||
|
issue_task(ls);
|
||||||
|
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ls: lower level (shared memory) scatter task */
|
||||||
|
int mca_coll_han_scatter_ls_task(void *task_argu)
|
||||||
|
{
|
||||||
|
mca_scatter_argu_t *t = (mca_scatter_argu_t *) task_argu;
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d] Han Scatter: ls\n",
|
||||||
|
t->w_rank));
|
||||||
|
OBJ_RELEASE(t->cur_task);
|
||||||
|
/* Shared memory scatter */
|
||||||
|
t->low_comm->c_coll->coll_scatter((char *) t->sbuf, t->scount, t->sdtype, (char *) t->rbuf,
|
||||||
|
t->rcount, t->rdtype, t->root_low_rank, t->low_comm,
|
||||||
|
t->low_comm->c_coll->coll_scatter_module);
|
||||||
|
|
||||||
|
if (t->sbuf_inter_free != NULL && t->noop != true) {
|
||||||
|
free(t->sbuf_inter_free);
|
||||||
|
t->sbuf_inter_free = NULL;
|
||||||
|
}
|
||||||
|
OPAL_OUTPUT_VERBOSE((30, mca_coll_han_component.han_output, "[%d] Han Scatter: ls finish\n",
|
||||||
|
t->w_rank));
|
||||||
|
ompi_request_t *temp_req = t->req;
|
||||||
|
free(t);
|
||||||
|
ompi_request_complete(temp_req, 1);
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
42
ompi/mca/coll/han/coll_han_trigger.c
Обычный файл
42
ompi/mca/coll/han/coll_han_trigger.c
Обычный файл
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "coll_han_trigger.h"
|
||||||
|
|
||||||
|
static void mca_coll_task_constructor(mca_coll_task_t * t)
|
||||||
|
{
|
||||||
|
t->func_ptr = NULL;
|
||||||
|
t->func_argu = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mca_coll_task_destructor(mca_coll_task_t * t)
|
||||||
|
{
|
||||||
|
t->func_ptr = NULL;
|
||||||
|
t->func_argu = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBJ_CLASS_INSTANCE(mca_coll_task_t, opal_object_t, mca_coll_task_constructor,
|
||||||
|
mca_coll_task_destructor);
|
||||||
|
|
||||||
|
/* Init task */
|
||||||
|
int init_task(mca_coll_task_t * t, task_func_ptr func_ptr, void *func_argu)
|
||||||
|
{
|
||||||
|
t->func_ptr = func_ptr;
|
||||||
|
t->func_argu = func_argu;
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Issue the task */
|
||||||
|
int issue_task(mca_coll_task_t * t)
|
||||||
|
{
|
||||||
|
t->func_ptr(t->func_argu);
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
46
ompi/mca/coll/han/coll_han_trigger.h
Обычный файл
46
ompi/mca/coll/han/coll_han_trigger.h
Обычный файл
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MCA_COLL_HAN_TRIGGER_EXPORT_H
|
||||||
|
#define MCA_COLL_HAN_TRIGGER_EXPORT_H
|
||||||
|
|
||||||
|
#include "ompi_config.h"
|
||||||
|
#include "mpi.h"
|
||||||
|
#include "ompi/mca/mca.h"
|
||||||
|
#include "ompi/mca/coll/coll.h"
|
||||||
|
#include "ompi/communicator/communicator.h"
|
||||||
|
#include "ompi/win/win.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_base_functions.h"
|
||||||
|
#include "opal/util/info.h"
|
||||||
|
#include "ompi/op/op.h"
|
||||||
|
#include "opal/runtime/opal_progress.h"
|
||||||
|
#include "ompi/mca/pml/pml.h"
|
||||||
|
#include "ompi/mca/coll/base/coll_tags.h"
|
||||||
|
|
||||||
|
typedef int (*task_func_ptr) (void *);
|
||||||
|
|
||||||
|
struct mca_coll_task_s {
|
||||||
|
opal_object_t super;
|
||||||
|
task_func_ptr func_ptr;
|
||||||
|
void *func_argu;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct mca_coll_task_s mca_coll_task_t;
|
||||||
|
|
||||||
|
OBJ_CLASS_DECLARATION(mca_coll_task_t);
|
||||||
|
|
||||||
|
/* Init task */
|
||||||
|
int init_task(mca_coll_task_t * t, task_func_ptr func_ptr, void *func_argu);
|
||||||
|
|
||||||
|
/* Issue the task */
|
||||||
|
int issue_task(mca_coll_task_t * t);
|
||||||
|
|
||||||
|
#endif /* MCA_COLL_HAN_TRIGGER_EXPORT_H */
|
58
ompi/mca/coll/han/coll_han_utils.c
Обычный файл
58
ompi/mca/coll/han/coll_han_utils.c
Обычный файл
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "coll_han.h"
|
||||||
|
|
||||||
|
/* Get root's low_rank and up_rank from vranks array */
|
||||||
|
void mca_coll_han_get_ranks(int *vranks, int root, int low_size, int *root_low_rank,
|
||||||
|
int *root_up_rank)
|
||||||
|
{
|
||||||
|
*root_up_rank = vranks[root] / low_size;
|
||||||
|
*root_low_rank = vranks[root] % low_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t han_auto_tuned_get_n(uint32_t n)
|
||||||
|
{
|
||||||
|
uint32_t avail[5] = { 4, 8, 16, 32, 64 };
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < 5; i++) {
|
||||||
|
if (avail[i] >= n) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t han_auto_tuned_get_c(uint32_t c)
|
||||||
|
{
|
||||||
|
uint32_t avail[3] = { 4, 8, 12 };
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
if (avail[i] >= c) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t han_auto_tuned_get_m(uint32_t m)
|
||||||
|
{
|
||||||
|
uint32_t avail[21] =
|
||||||
|
{ 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072,
|
||||||
|
262144, 524288, 1048576, 2097152, 4194304 };
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < 21; i++) {
|
||||||
|
if (avail[i] >= m) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i - 1;
|
||||||
|
}
|
Загрузка…
x
Ссылка в новой задаче
Block a user