- int system_tag = 999; // used negative int but smpi_create_request() declares this illegal (to be checked)
- int rank;
- int retval = MPI_SUCCESS;
- int i;
- smpi_mpi_request_t request;
- smpi_mpi_request_t * requests;
-
- rank = smpi_mpi_comm_rank(comm);
-
- /* wait for data from my parent in the tree */
- if (!tree->isRoot) {
-#ifdef DEBUG_STEPH
- printf("[%d] recv(%d from %d, tag=%d)\n",rank,rank, tree->parent, system_tag+rank);
-#endif
- retval = smpi_create_request(buf, count, datatype,
- tree->parent, rank,
- system_tag + rank,
- comm, &request);
- if (MPI_SUCCESS != retval) {
- printf("** internal error: smpi_create_request() rank=%d returned retval=%d, %s:%d\n",
- rank,retval,__FILE__,__LINE__);
- }
- smpi_mpi_irecv(request);
-#ifdef DEBUG_STEPH
- printf("[%d] waiting on irecv from %d\n",rank , tree->parent);
-#endif
- smpi_mpi_wait(request, MPI_STATUS_IGNORE);
- xbt_mallocator_release(smpi_global->request_mallocator, request);
- }
-
- requests = xbt_malloc( tree->numChildren * sizeof(smpi_mpi_request_t));
-#ifdef DEBUG_STEPH
- printf("[%d] creates %d requests\n",rank,tree->numChildren);
-#endif
-
- /* iniates sends to ranks lower in the tree */
- for (i=0; i < tree->numChildren; i++) {
- if (tree->child[i] != -1) {
-#ifdef DEBUG_STEPH
- printf("[%d] send(%d->%d, tag=%d)\n",rank,rank, tree->child[i], system_tag+tree->child[i]);
-#endif
- retval = smpi_create_request(buf, count, datatype,
- rank, tree->child[i],
- system_tag + tree->child[i],
- comm, &(requests[i]));
-#ifdef DEBUG_STEPH
- printf("[%d] after create req[%d]=%p req->(src=%d,dst=%d)\n",rank , i, requests[i],requests[i]->src,requests[i]->dst );
-#endif
- if (MPI_SUCCESS != retval) {
- printf("** internal error: smpi_create_request() rank=%d returned retval=%d, %s:%d\n",
- rank,retval,__FILE__,__LINE__);
- }
- smpi_mpi_isend(requests[i]);
- /* FIXME : we should not wait immediately here. See next FIXME. */
- smpi_mpi_wait( requests[i], MPI_STATUS_IGNORE);
- xbt_mallocator_release(smpi_global->request_mallocator, requests[i]);
- }
- }
- /* FIXME : normally, we sould wait only once all isend have been issued:
- * this is the following commented code. It deadlocks, probably because
- * of a bug in the sender process */
-
- /* wait for completion of sends */
- /* printf("[%d] wait for %d send completions\n",rank,tree->numChildren);
- smpi_mpi_waitall( tree->numChildren, requests, MPI_STATUS_IGNORE);
- printf("[%d] reqs completed\n)",rank);
- */
-
- xbt_free(requests);
- return(retval);
- /* checked ok with valgrind --leak-check=full*/
+ int system_tag = COLL_TAG_BCAST;
+ int rank, i;
+ MPI_Request *requests;
+
+ rank = smpi_comm_rank(comm);
+ /* wait for data from my parent in the tree */
+ if (!tree->isRoot) {
+ XBT_DEBUG("<%d> tree_bcast(): i am not root: recv from %d, tag=%d)",
+ rank, tree->parent, system_tag + rank);
+ smpi_mpi_recv(buf, count, datatype, tree->parent, system_tag + rank,
+ comm, MPI_STATUS_IGNORE);
+ }
+ requests = xbt_new(MPI_Request, tree->numChildren);
+ XBT_DEBUG("<%d> creates %d requests (1 per child)", rank,
+ tree->numChildren);
+ /* iniates sends to ranks lower in the tree */
+ for (i = 0; i < tree->numChildren; i++) {
+ if (tree->child[i] == -1) {
+ requests[i] = MPI_REQUEST_NULL;
+ } else {
+ XBT_DEBUG("<%d> send to <%d>, tag=%d", rank, tree->child[i],
+ system_tag + tree->child[i]);
+ requests[i] =
+ smpi_isend_init(buf, count, datatype, tree->child[i],
+ system_tag + tree->child[i], comm);
+ }
+ }
+ smpi_mpi_startall(tree->numChildren, requests);
+ smpi_mpi_waitall(tree->numChildren, requests, MPI_STATUS_IGNORE);
+ xbt_free(requests);