root/oshmem/mca/scoll/basic/scoll_basic_alltoall.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mca_scoll_basic_alltoall
  2. get_stride_elem
  3. get_dst_pe
  4. a2as_alg_simple
  5. a2a_alg_simple

   1 /*
   2  * Copyright (c) 2016      Mellanox Technologies, Inc.
   3  *                         All rights reserved.
   4  * $COPYRIGHT$
   5  *
   6  * Additional copyrights may follow
   7  *
   8  * $HEADER$
   9  */
  10 
  11 #include "oshmem_config.h"
  12 #include <stdio.h>
  13 #include <stdlib.h>
  14 
  15 #include "oshmem/constants.h"
  16 #include "oshmem/op/op.h"
  17 #include "oshmem/mca/spml/spml.h"
  18 #include "oshmem/mca/scoll/scoll.h"
  19 #include "oshmem/mca/scoll/base/base.h"
  20 #include "scoll_basic.h"
  21 
  22 static int a2a_alg_simple(struct oshmem_group_t *group,
  23                           void *target,
  24                           const void *source,
  25                           size_t nelems,
  26                           size_t element_size);
  27 
  28 static int a2as_alg_simple(struct oshmem_group_t *group,
  29                            void *target,
  30                            const void *source,
  31                            ptrdiff_t dst, ptrdiff_t sst,
  32                            size_t nelems,
  33                            size_t element_size);
  34 
  35 
  36 int mca_scoll_basic_alltoall(struct oshmem_group_t *group,
  37                              void *target,
  38                              const void *source,
  39                              ptrdiff_t dst, ptrdiff_t sst,
  40                              size_t nelems,
  41                              size_t element_size,
  42                              long *pSync,
  43                              int alg)
  44 {
  45     int rc;
  46     int i;
  47 
  48     /* Arguments validation */
  49     if (!group) {
  50         SCOLL_ERROR("Active set (group) of PE is not defined");
  51         return OSHMEM_ERR_BAD_PARAM;
  52     }
  53 
  54     /* Check if this PE is part of the group */
  55     if (!oshmem_proc_group_is_member(group)) {
  56         return OSHMEM_SUCCESS;
  57     }
  58 
  59     if (!pSync) {
  60         SCOLL_ERROR("Incorrect argument pSync");
  61         return OSHMEM_ERR_BAD_PARAM;
  62     }
  63 
  64     /* Do nothing on zero-length request */
  65     if (OPAL_UNLIKELY(!nelems)) {
  66         return OPAL_SUCCESS;
  67     }
  68 
  69     if ((sst == 1) && (dst == 1)) {
  70         rc = a2a_alg_simple(group, target, source, nelems, element_size);
  71     } else {
  72         rc = a2as_alg_simple(group, target, source, dst, sst, nelems,
  73                              element_size);
  74     }
  75 
  76     if (rc != OSHMEM_SUCCESS) {
  77        return rc;
  78     }
  79 
  80     /* quiet is needed because scoll level barrier does not
  81      * guarantee put completion
  82      */
  83     MCA_SPML_CALL(quiet(oshmem_ctx_default));
  84 
  85     /* Wait for operation completion */
  86     SCOLL_VERBOSE(14, "[#%d] Wait for operation completion", group->my_pe);
  87     rc = BARRIER_FUNC(group, pSync, SCOLL_DEFAULT_ALG);
  88 
  89     /* Restore initial values */
  90     SCOLL_VERBOSE(12, "PE#%d Restore special synchronization array",
  91                   group->my_pe);
  92 
  93     for (i = 0; pSync && (i < _SHMEM_ALLTOALL_SYNC_SIZE); i++) {
  94         pSync[i] = _SHMEM_SYNC_VALUE;
  95     }
  96 
  97     return rc;
  98 }
  99 
 100 
 101 static inline void *
 102 get_stride_elem(const void *base, ptrdiff_t sst, size_t nelems, size_t elem_size,
 103                 int block_idx, int elem_idx)
 104 {
 105     /*
 106      * j th block starts at: nelems * element_size * sst * j
 107      * offset of the l th element in the block is: element_size * sst * l
 108      */
 109     return (char *)base + elem_size * sst * (nelems * block_idx + elem_idx);
 110 }
 111 
 112 static inline int
 113 get_dst_pe(struct oshmem_group_t *group, int src_blk_idx, int dst_blk_idx, int *dst_pe_idx)
 114 {
 115     /* index permutation for better distribution of traffic */
 116     (*dst_pe_idx) = (dst_blk_idx + src_blk_idx) % group->proc_count;
 117 
 118     /* convert to the global pe */
 119     return oshmem_proc_pe(group->proc_array[*dst_pe_idx]);
 120 }
 121 
 122 static int a2as_alg_simple(struct oshmem_group_t *group,
 123                            void *target,
 124                            const void *source,
 125                            ptrdiff_t tst, ptrdiff_t sst,
 126                            size_t nelems,
 127                            size_t element_size)
 128 {
 129     int rc;
 130     int dst_pe;
 131     int src_blk_idx;
 132     int dst_blk_idx;
 133     int dst_pe_idx;
 134     size_t elem_idx;
 135 
 136     SCOLL_VERBOSE(14,
 137                   "[#%d] send data to all PE in the group",
 138                   group->my_pe);
 139 
 140     dst_blk_idx = oshmem_proc_group_find_id(group, group->my_pe);
 141 
 142     for (src_blk_idx = 0; src_blk_idx < group->proc_count; src_blk_idx++) {
 143 
 144         dst_pe = get_dst_pe(group, src_blk_idx, dst_blk_idx, &dst_pe_idx);
 145         for (elem_idx = 0; elem_idx < nelems; elem_idx++) {
 146             rc = MCA_SPML_CALL(put(oshmem_ctx_default, 
 147                         get_stride_elem(target, tst, nelems, element_size,
 148                                         dst_blk_idx, elem_idx),
 149                         element_size,
 150                         get_stride_elem(source, sst, nelems, element_size,
 151                                         dst_pe_idx, elem_idx),
 152                         dst_pe));
 153             if (OSHMEM_SUCCESS != rc) {
 154                 return rc;
 155             }
 156         }
 157     }
 158     return OSHMEM_SUCCESS;
 159 }
 160 
 161 static int a2a_alg_simple(struct oshmem_group_t *group,
 162                            void *target,
 163                            const void *source,
 164                            size_t nelems,
 165                            size_t element_size)
 166 {
 167     int rc;
 168     int dst_pe;
 169     int src_blk_idx;
 170     int dst_blk_idx;
 171     int dst_pe_idx;
 172     void *dst_blk;
 173 
 174     SCOLL_VERBOSE(14,
 175                   "[#%d] send data to all PE in the group",
 176                   group->my_pe);
 177 
 178     dst_blk_idx = oshmem_proc_group_find_id(group, group->my_pe);
 179 
 180     /* block start at stride 1 first elem */
 181     dst_blk = get_stride_elem(target, 1, nelems, element_size, dst_blk_idx, 0);
 182 
 183     for (src_blk_idx = 0; src_blk_idx < group->proc_count; src_blk_idx++) {
 184 
 185         dst_pe = get_dst_pe(group, src_blk_idx, dst_blk_idx, &dst_pe_idx);
 186         rc = MCA_SPML_CALL(put(oshmem_ctx_default, dst_blk,
 187                                 nelems * element_size,
 188                                 get_stride_elem(source, 1, nelems,
 189                                                 element_size, dst_pe_idx, 0),
 190                                 dst_pe));
 191         if (OSHMEM_SUCCESS != rc) {
 192             return rc;
 193         }
 194     }
 195     return OSHMEM_SUCCESS;
 196 }

/* [<][>][^][v][top][bottom][index][help] */