5555 * to send the data in the correct order even if the process are NOT mapped by core.
5656 * 2. In the send buffer, other than the root's node, data destined to the same node are continuous
5757 * - it is ok if data to different nodes has gap.
58+ *
59+ * Limitation:
60+ * The node leader acts as a broker between the Root and node followers, but it cannot match the
61+ * exact type signature of the followers; instead it forwards the intermediate data from Root in its
62+ * packed form of MPI_BYTE type. This works for Gatherv but NOT for Scatterv provided that the Root
63+ * has a different architecture, e.g. endianness, integer representation, etc.
5864 */
5965int mca_coll_han_scatterv_intra (const void * sbuf , const int * scounts , const int * displs ,
6066 struct ompi_datatype_t * sdtype , void * rbuf , int rcount ,
@@ -94,6 +100,14 @@ int mca_coll_han_scatterv_intra(const void *sbuf, const int *scounts, const int
94100 return han_module -> previous_scatterv (sbuf , scounts , displs , sdtype , rbuf , rcount , rdtype ,
95101 root , comm , han_module -> previous_scatterv_module );
96102 }
103+ if (han_module -> is_heterogeneous ) {
104+ OPAL_OUTPUT_VERBOSE ((30 , mca_coll_han_component .han_output ,
105+ "han cannot handle scatterv with this communicator (heterogeneous). Fall "
106+ "back on another component\n" ));
107+ HAN_LOAD_FALLBACK_COLLECTIVE (han_module , comm , scatterv );
108+ return han_module -> previous_scatterv (sbuf , scounts , displs , sdtype , rbuf , rcount , rdtype ,
109+ root , comm , han_module -> previous_scatterv_module );
110+ }
97111
98112 w_rank = ompi_comm_rank (comm );
99113 w_size = ompi_comm_size (comm );
@@ -125,7 +139,6 @@ int mca_coll_han_scatterv_intra(const void *sbuf, const int *scounts, const int
125139 int need_bounce_buf = 0 , total_up_scounts = 0 , * up_displs = NULL , * up_scounts = NULL ,
126140 * up_peer_lb = NULL , * up_peer_ub = NULL ;
127141 char * reorder_sbuf = (char * ) sbuf , * bounce_buf = NULL ;
128- size_t sdsize ;
129142
130143 low_scounts = malloc (low_size * sizeof (int ));
131144 low_displs = malloc (low_size * sizeof (int ));
@@ -144,8 +157,6 @@ int mca_coll_han_scatterv_intra(const void *sbuf, const int *scounts, const int
144157 low_scounts [low_peer ] = scounts [w_peer ];
145158 }
146159
147- ompi_datatype_type_size (sdtype , & sdsize );
148-
149160 up_scounts = calloc (up_size , sizeof (int ));
150161 up_displs = malloc (up_size * sizeof (int ));
151162 up_peer_ub = calloc (up_size , sizeof (int ));
@@ -201,11 +212,14 @@ int mca_coll_han_scatterv_intra(const void *sbuf, const int *scounts, const int
201212 }
202213
203214 if (need_bounce_buf ) {
204- bounce_buf = malloc (sdsize * total_up_scounts );
215+ ptrdiff_t ssize , sgap ;
216+ ssize = opal_datatype_span (& rdtype -> super , total_up_scounts , & sgap );
217+ bounce_buf = malloc (ssize );
205218 if (!bounce_buf ) {
206219 err = OMPI_ERR_OUT_OF_RESOURCE ;
207220 goto root_out ;
208221 }
222+ reorder_sbuf = bounce_buf - sgap ;
209223
210224 /* Calculate displacements for the inter-node scatterv */
211225 for (up_peer = 0 ; up_peer < up_size ; ++ up_peer ) {
@@ -214,7 +228,8 @@ int mca_coll_han_scatterv_intra(const void *sbuf, const int *scounts, const int
214228 }
215229
216230 /* Use a temp buffer to reorder the send buffer if needed */
217- ptrdiff_t offset = 0 ;
231+ ptrdiff_t offset = 0 , sdext ;
232+ ompi_datatype_type_extent (sdtype , & sdext );
218233
219234 for (int i = 0 ; i < w_size ; ++ i ) {
220235 up_peer = topo [2 * i ];
@@ -225,13 +240,11 @@ int mca_coll_han_scatterv_intra(const void *sbuf, const int *scounts, const int
225240 w_peer = topo [2 * i + 1 ];
226241
227242 ompi_datatype_copy_content_same_ddt (sdtype , (size_t ) scounts [w_peer ],
228- bounce_buf + offset ,
243+ reorder_sbuf + offset ,
229244 (char * ) sbuf
230- + (size_t ) displs [w_peer ] * sdsize );
231- offset += sdsize * (size_t ) scounts [w_peer ];
245+ + (size_t ) displs [w_peer ] * sdext );
246+ offset += sdext * (size_t ) scounts [w_peer ];
232247 }
233-
234- reorder_sbuf = bounce_buf ;
235248 }
236249
237250 /* Up Iscatterv */
0 commit comments