-#include "../colls_private.h"
+/* Copyright (c) 2011-2021. The SimGrid Team. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "../colls_private.hpp"
+#include "smpi_status.hpp"
+
namespace simgrid{
namespace smpi{
processes may not get any data. For example if bufsize = 97 and
nprocs = 16, ranks 15 and 16 will get 0 data. On each process, the
scattered data is stored at the same offset in the buffer as it is
- on the root process. */
+ on the root process. */
scatter_size = (nbytes + comm_size - 1)/comm_size; /* ceiling division */
curr_size = (rank == root) ? nbytes : 0; /* root starts with all the
{
if (relative_rank & mask)
{
- src = rank - mask;
+ src = rank - mask;
if (src < 0) src += comm_size;
recv_size = nbytes - relative_rank*scatter_size;
/* recv_size is larger than what might actually be sent by the
sender. We don't need compute the exact value because MPI
- allows you to post a larger recv.*/
+ allows you to post a larger recv.*/
if (recv_size <= 0)
{
curr_size = 0; /* this process doesn't receive any data
}
/* This process is responsible for all processes that have bits
- set from the LSB upto (but not including) mask. Because of
+ set from the LSB up to (but not including) mask. Because of
the "not including", we start by shifting mask back down
one. */
{
if (relative_rank + mask < comm_size)
{
- send_size = curr_size - scatter_size * mask;
+ send_size = curr_size - scatter_size * mask;
/* mask is also the size of this process's subtree */
if (send_size > 0)
}
-int
-Coll_bcast_scatter_rdb_allgather::bcast (
- void *buffer,
- int count,
- MPI_Datatype datatype,
- int root,
+int bcast__scatter_rdb_allgather(
+ void *buffer,
+ int count,
+ MPI_Datatype datatype,
+ int root,
MPI_Comm comm)
{
MPI_Status status;
int relative_rank, mask;
int mpi_errno = MPI_SUCCESS;
int scatter_size, curr_size, recv_size = 0;
- int j, k, i, tmp_mask, is_contig, is_homogeneous;
+ int j, k, i, tmp_mask;
+ bool is_contig, is_homogeneous;
MPI_Aint type_size = 0, nbytes = 0;
int relative_dst, dst_tree_root, my_tree_root, send_offset;
int recv_offset, tree_root, nprocs_completed, offset;
if (comm_size == 1) goto fn_exit;
//if (HANDLE_GET_KIND(datatype) == HANDLE_KIND_BUILTIN)
- if(datatype->flags() & DT_FLAG_CONTIGUOUS)
- is_contig = 1;
- else {
- is_contig = 0;
- }
+ is_contig = ((datatype->flags() & DT_FLAG_CONTIGUOUS) != 0);
- is_homogeneous = 1;
+ is_homogeneous = true;
/* MPI_Type_size() might not give the accurate size of the packed
* datatype for heterogeneous systems (because of padding, encoding,
}
else
{
- tmp_buf=(void*)xbt_malloc(nbytes);
-
- /* TODO: Pipeline the packing and communication */
- position = 0;
- if (rank == root) {
- mpi_errno = datatype->pack(buffer, count, tmp_buf, nbytes,
- &position, comm);
- if (mpi_errno) xbt_die("crash while packing %d", mpi_errno);
- }
+ tmp_buf = new unsigned char[nbytes];
+
+ /* TODO: Pipeline the packing and communication */
+ position = 0;
+ if (rank == root) {
+ mpi_errno = datatype->pack(buffer, count, tmp_buf, nbytes, &position, comm);
+ xbt_assert(mpi_errno == 0, "crash while packing %d", mpi_errno);
+ }
}
mpi_errno = scatter_for_bcast(root, comm,
nbytes, tmp_buf);
- if (mpi_errno) {
- xbt_die("crash while scattering %d", mpi_errno);
- }
+ xbt_assert(mpi_errno == 0, "crash while scattering %d", mpi_errno);
/* curr_size is the amount of data that this process now has stored in
* buffer at byte offset (relative_rank*scatter_size) */
{
relative_dst = relative_rank ^ mask;
- dst = (relative_dst + root) % comm_size;
+ dst = (relative_dst + root) % comm_size;
/* find offset into send and recv buffers.
zero out the least significant "i" bits of relative_rank and
relative_dst to find root of src and dst
subtrees. Use ranks of roots as index to send from
- and recv into buffer */
+ and recv into buffer */
dst_tree_root = relative_dst >> i;
dst_tree_root <<= i;
if (relative_dst < comm_size)
{
Request::sendrecv(((char *)tmp_buf + send_offset),
- curr_size, MPI_BYTE, dst, COLL_TAG_BCAST,
+ curr_size, MPI_BYTE, dst, COLL_TAG_BCAST,
((char *)tmp_buf + recv_offset),
- (nbytes-recv_offset < 0 ? 0 : nbytes-recv_offset),
+ (nbytes-recv_offset < 0 ? 0 : nbytes-recv_offset),
MPI_BYTE, dst, COLL_TAG_BCAST, comm, &status);
recv_size=Status::get_count(&status, MPI_BYTE);
curr_size += recv_size;
/* This part of the code will not currently be
executed because we are not using recursive
doubling for non power of two. Mark it as experimental
- so that it doesn't show up as red in the coverage tests. */
+ so that it doesn't show up as red in the coverage tests. */
/* --BEGIN EXPERIMENTAL-- */
if (dst_tree_root + mask > comm_size)
in a tree fashion. First find root of current tree
that is being divided into two. k is the number of
least-significant bits in this process's rank that
- must be zeroed out to find the rank of the root */
+ must be zeroed out to find the rank of the root */
j = mask;
k = 0;
while (j)
while (tmp_mask)
{
relative_dst = relative_rank ^ tmp_mask;
- dst = (relative_dst + root) % comm_size;
+ dst = (relative_dst + root) % comm_size;
tree_root = relative_rank >> k;
tree_root <<= k;
/* send only if this proc has data and destination
doesn't have data. */
- /* if (rank == 3) {
+ /* if (rank == 3) {
printf("rank %d, dst %d, root %d, nprocs_completed %d\n", relative_rank, relative_dst, tree_root, nprocs_completed);
fflush(stdout);
}*/
- if ((relative_dst > relative_rank) &&
+ if ((relative_dst > relative_rank) &&
(relative_rank < tree_root + nprocs_completed)
&& (relative_dst >= tree_root + nprocs_completed))
{
}
/* recv only if this proc. doesn't have data and sender
has data */
- else if ((relative_dst < relative_rank) &&
+ else if ((relative_dst < relative_rank) &&
(relative_dst < tree_root + nprocs_completed) &&
(relative_rank >= tree_root + nprocs_completed))
{
/* printf("Rank %d waiting to recv from rank %d\n",
relative_rank, dst); */
Request::recv(((char *)tmp_buf + offset),
- nbytes - offset,
+ nbytes - offset,
MPI_BYTE, dst, COLL_TAG_BCAST,
comm, &status);
/* nprocs_completed is also equal to the no. of processes
/* check that we received as much as we expected */
/* recvd_size may not be accurate for packed heterogeneous data */
- if (is_homogeneous && curr_size != nbytes) {
- xbt_die("we didn't receive enough !");
- }
-
- if (!is_contig || !is_homogeneous)
- {
- if (rank != root)
- {
- position = 0;
- mpi_errno = MPI_Unpack(tmp_buf, nbytes, &position, buffer,
- count, datatype, comm);
- if (mpi_errno) xbt_die("error when unpacking %d", mpi_errno);
- }
+ xbt_assert(not is_homogeneous || curr_size == nbytes, "we didn't receive enough !");
+
+ if (not is_contig || not is_homogeneous) {
+ if (rank != root) {
+ position = 0;
+ mpi_errno = MPI_Unpack(tmp_buf, nbytes, &position, buffer, count, datatype, comm);
+ xbt_assert(mpi_errno == 0, "error when unpacking %d", mpi_errno);
+ }
}
fn_exit:
-/* xbt_free(tmp_buf);*/
- return mpi_errno;
+ /* delete[] static_cast<unsigned char*>(tmp_buf); */
+ return mpi_errno;
}
}