コード例 #1
0
ファイル: coll_fca_ops.c プロジェクト: bringhurst/ompi
/*
 *  Allreduce
 *
 *  Function:   - allreduce
 *  Accepts:    - same as MPI_Allreduce()
 *  Returns:    - MPI_SUCCESS or error code
 */
int mca_coll_fca_allreduce(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)
{
    mca_coll_fca_module_t *fca_module = (mca_coll_fca_module_t*)module;
    fca_reduce_spec_t spec;
    int ret;

    spec.sbuf = sbuf;
    spec.rbuf = rbuf;
    if (mca_coll_fca_fill_reduce_spec(count, dtype, op, &spec,
                                      fca_module->fca_comm_caps.max_payload)
            != OMPI_SUCCESS) {
        FCA_VERBOSE(5, "Unsupported allreduce operation %s, using fallback\n", op->o_name);
        goto orig_allreduce;
    }

    FCA_VERBOSE(5,"Using FCA Allreduce");
    ret = mca_coll_fca_component.fca_ops.do_all_reduce(fca_module->fca_comm, &spec);
    if (ret < 0) {
        if (ret == -EUSEMPI) {
            goto orig_allreduce;
        }
        FCA_ERROR("Allreduce failed: %s", mca_coll_fca_component.fca_ops.strerror(ret));
        return OMPI_ERROR;
    }
    return OMPI_SUCCESS;

orig_allreduce:
    return fca_module->previous_allreduce(sbuf, rbuf, count, dtype, op, comm,
                                          fca_module->previous_allreduce_module);
}
コード例 #2
0
ファイル: coll_fca_module.c プロジェクト: 00datman/ompi
static void mca_coll_fca_module_destruct(mca_coll_fca_module_t *fca_module)
{
    FCA_VERBOSE(5, "==>");
    if(mca_coll_fca_component.fca_enable_cache == 0) {

        if (fca_module->fca_comm) {
            __destroy_fca_comm(fca_module);
        }
    }

    OBJ_RELEASE(fca_module->previous_barrier_module);
    OBJ_RELEASE(fca_module->previous_bcast_module);
    OBJ_RELEASE(fca_module->previous_reduce_module);
    OBJ_RELEASE(fca_module->previous_allreduce_module);
    OBJ_RELEASE(fca_module->previous_allgather_module);
    OBJ_RELEASE(fca_module->previous_allgatherv_module);
    OBJ_RELEASE(fca_module->previous_gather_module);
    OBJ_RELEASE(fca_module->previous_gatherv_module);
    OBJ_RELEASE(fca_module->previous_alltoall_module);
    OBJ_RELEASE(fca_module->previous_alltoallv_module);
    OBJ_RELEASE(fca_module->previous_alltoallw_module);
    OBJ_RELEASE(fca_module->previous_reduce_scatter_module);
#if OMPI_FCA_VERSION >= 30
    OBJ_RELEASE(fca_module->previous_scatter_module);
#endif

    free(fca_module->local_ranks);
    mca_coll_fca_module_clear(fca_module);
}
コード例 #3
0
ファイル: coll_fca_ops.c プロジェクト: bringhurst/ompi
static mca_coll_fca_op_info_t *mca_coll_fca_get_op(ompi_op_t *op)
{
    mca_coll_fca_op_info_t *op_info;
    int i, fca_op;

    /*
     * Find 'op' in the array by exhaustive search. We assume all valid ops are
     * in the beginning. If we stumble on a MPI_OP_NULL, we try to resolve the FCA
     * operation code and store it in the array.
     */
    op_info = mca_coll_fca_component.fca_reduce_ops;
    for (i = 0; i < FCA_MAX_OPS; ++i, ++op_info) {
        if (op_info->mpi_op == op) {
            return op_info;
        } else if (op_info->mpi_op == MPI_OP_NULL) {
            fca_op = mca_coll_fca_component.fca_ops.translate_mpi_op(op->o_name);
            if (fca_op < 0)
                return NULL;
            op_info->mpi_op = op;
            op_info->fca_op = fca_op;
            FCA_VERBOSE(2, "Added new op[%d]: %s fca id: %d", i, op->o_name, fca_op);
            return op_info;
        }
    }
    /* assert the array does not overflow */
    /*assert(mca_coll_fca_component.fca_reduce_ops[FCA_MAX_OPS - 1] == MPI_OP_NULL);*/
    return NULL;
}
コード例 #4
0
ファイル: coll_fca_ops.c プロジェクト: bringhurst/ompi
static int mca_coll_fca_fill_reduce_spec(int count, ompi_datatype_t *dtype,
                                         ompi_op_t *op, fca_reduce_spec_t *spec,
                                         int max_fca_payload)
{
    mca_coll_fca_dtype_info_t *dtype_info;
    mca_coll_fca_op_info_t *op_info;

    /* Check dtype */
    dtype_info = mca_coll_fca_get_dtype(dtype);
    if (!dtype_info) {
        FCA_VERBOSE(10, "Unsupported dtype: %s", dtype->name);
        return OMPI_ERROR;
    }

    /* Check FCA size */
    if ((int)(dtype_info->fca_dtype_extent * count) > max_fca_payload) {
        FCA_VERBOSE(10, "Unsupported buffer size: %lu", dtype_info->fca_dtype_extent * count);
        return OMPI_ERROR;
    }

    /* Check operation */
    op_info = mca_coll_fca_get_op(op);
    if (!op_info) {
        FCA_VERBOSE(10, "Unsupported op: %s", op->o_name);
        return OMPI_ERROR;
    }

    /* Fill spec */
    spec->dtype = dtype_info->fca_dtype;
    spec->op = op_info->fca_op;
    spec->length = count;
    spec->buf_size = dtype_info->mpi_dtype_extent * count;
    if (MPI_IN_PLACE == spec->sbuf) {
        FCA_VERBOSE(10, "Using MPI_IN_PLACE for sbuf");
        spec->sbuf = spec->rbuf;
    } else if (MPI_IN_PLACE == spec->rbuf) {
        FCA_VERBOSE(10, "Using MPI_IN_PLACE for rbuf");
        spec->rbuf = spec->sbuf;
    }
    return OMPI_SUCCESS;
}
コード例 #5
0
ファイル: scoll_fca_module.c プロジェクト: Benguang/ompi
static void mca_scoll_fca_module_destruct(mca_scoll_fca_module_t *fca_module)
{
    FCA_VERBOSE(5, "==>");
    OBJ_RELEASE(fca_module->previous_barrier_module);
    OBJ_RELEASE(fca_module->previous_broadcast_module);
    OBJ_RELEASE(fca_module->previous_collect_module);
    OBJ_RELEASE(fca_module->previous_reduce_module);
    if (fca_module->fca_comm)
        _destroy_fca_comm(fca_module);
    free(fca_module->local_ranks);
    mca_scoll_fca_module_clear(fca_module);
}
コード例 #6
0
ファイル: coll_fca_module.c プロジェクト: 00datman/ompi
/*
 * 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_fca_comm_query(struct ompi_communicator_t *comm, int *priority)
{
    mca_coll_base_module_t *module;
    int size = ompi_comm_size(comm);
    int local_peers = 0;
    mca_coll_fca_module_t *fca_module;

    *priority = 0;
    module = NULL;

    if (!mca_coll_fca_component.fca_enable)
        goto exit;

    if (size < mca_coll_fca_component.fca_np)
        goto exit;

    if (!ompi_group_have_remote_peers(comm->c_local_group) || OMPI_COMM_IS_INTER(comm))
        goto exit;

    fca_module = OBJ_NEW(mca_coll_fca_module_t);
    if (!fca_module)
        goto exit;

    fca_module->super.coll_module_enable = mca_coll_fca_module_enable;
    fca_module->super.ft_event        = mca_coll_fca_ft_event;
    fca_module->super.coll_allgather  = mca_coll_fca_component.fca_enable_allgather?  mca_coll_fca_allgather  : NULL;
    fca_module->super.coll_allgatherv = mca_coll_fca_component.fca_enable_allgatherv? mca_coll_fca_allgatherv : NULL;
    fca_module->super.coll_allreduce  = mca_coll_fca_component.fca_enable_allreduce?  mca_coll_fca_allreduce  : NULL;
    fca_module->super.coll_alltoall   = mca_coll_fca_component.fca_enable_alltoall?   mca_coll_fca_alltoall   : NULL;
    fca_module->super.coll_alltoallv  = mca_coll_fca_component.fca_enable_alltoallv?  mca_coll_fca_alltoallv  : NULL;
    fca_module->super.coll_alltoallw  = mca_coll_fca_component.fca_enable_alltoallw?  mca_coll_fca_alltoallw  : NULL;
    fca_module->super.coll_barrier    = mca_coll_fca_component.fca_enable_barrier?    mca_coll_fca_barrier    : NULL;
    fca_module->super.coll_bcast      = mca_coll_fca_component.fca_enable_bcast?      mca_coll_fca_bcast      : NULL;
    fca_module->super.coll_exscan     = NULL;
    fca_module->super.coll_gather     = mca_coll_fca_component.fca_enable_gather?     mca_coll_fca_gather     : NULL;
    fca_module->super.coll_gatherv    = mca_coll_fca_component.fca_enable_gatherv?    mca_coll_fca_gatherv    : NULL;
    fca_module->super.coll_reduce     = mca_coll_fca_component.fca_enable_reduce?     mca_coll_fca_reduce     : NULL;
    fca_module->super.coll_reduce_scatter = mca_coll_fca_component.fca_enable_reduce_scatter? mca_coll_fca_reduce_scatter  : NULL;
    fca_module->super.coll_scan       = NULL;
    fca_module->super.coll_scatter    = NULL;
    fca_module->super.coll_scatterv   = NULL;

    *priority = mca_coll_fca_component.fca_priority;
    module = &fca_module->super;

exit:
    FCA_VERBOSE(4, "Query FCA module for comm %p size %d rank %d local_peers=%d: priority=%d %s",
                (void *)comm, size, ompi_comm_rank(comm), local_peers,
                *priority, module ? "enabled" : "disabled");
    return module;
}
コード例 #7
0
ファイル: coll_fca_ops.c プロジェクト: bringhurst/ompi
/*
 *  Function:   - barrier
 *  Returns:    - MPI_SUCCESS or error code
 */
int mca_coll_fca_barrier(struct ompi_communicator_t *comm,
                         mca_coll_base_module_t *module)
{
    mca_coll_fca_module_t *fca_module = (mca_coll_fca_module_t*)module;
    int ret;

    FCA_VERBOSE(5,"Using FCA Barrier");
    ret = mca_coll_fca_component.fca_ops.do_barrier(fca_module->fca_comm);
    if (ret < 0) {
        if (ret == -EUSEMPI) {
            goto orig_barrier;
        }
        FCA_ERROR("Barrier failed: %s", mca_coll_fca_component.fca_ops.strerror(ret));
        return OMPI_ERROR;
    }
    return OMPI_SUCCESS;

orig_barrier:
    return fca_module->previous_barrier(comm, fca_module->previous_barrier_module);

}
コード例 #8
0
ファイル: coll_fca_ops.c プロジェクト: bringhurst/ompi
static mca_coll_fca_dtype_info_t* mca_coll_fca_get_dtype(ompi_datatype_t *dtype)
{
    mca_coll_fca_dtype_info_t *dtype_info;
    ptrdiff_t lb, extent;
    int id = dtype->id;
    int fca_dtype;

    if (id < 0 || id >= FCA_DT_MAX_PREDEFINED) {
        return NULL;
    }

    /* Different dtype structures may have the same id. In that case, we assume
     * they are aliases.
     */
    dtype_info = &mca_coll_fca_component.fca_dtypes[id];
    if (dtype_info->mpi_dtype->id == id) {
        return dtype_info;
    }

    /* assert we don't overwrite another datatype */
    assert(dtype_info->mpi_dtype == MPI_DATATYPE_NULL);

    fca_dtype = mca_coll_fca_component.fca_ops.translate_mpi_dtype(dtype->name);
    if (fca_dtype < 0) {
        return NULL;
    }

    FCA_DT_GET_TRUE_EXTENT(dtype, &lb, &extent);
    dtype_info->mpi_dtype = dtype;
    dtype_info->mpi_dtype_extent = extent;
    dtype_info->fca_dtype = fca_dtype;
    dtype_info->fca_dtype_extent = mca_coll_fca_component.fca_ops.get_dtype_size(fca_dtype);
    FCA_VERBOSE(2, "Added new dtype[%d]: %s fca id: %d, mpi size: %lu, fca size: %lu",
                id, dtype->name, dtype_info->fca_dtype, dtype_info->mpi_dtype_extent,
                dtype_info->fca_dtype_extent);
    return dtype_info;
}
コード例 #9
0
ファイル: coll_fca_ops.c プロジェクト: bringhurst/ompi
/*
 * Prepare a send buffer for allgather/allgatherv, handle packing and MPI_IN_PLACE.
 */
static size_t __setup_gather_sendbuf(void *sbuf, void *inplace_sbuf, int scount,
                                     struct ompi_datatype_t *sdtype,
                                     struct mca_coll_fca_convertor *sconv,
                                     void **real_sendbuf)
{
    size_t gap, ssize;

    if (mca_coll_fca_array_size(sdtype, scount, &gap, &ssize)) {
        *real_sendbuf = ((MPI_IN_PLACE == sbuf) ? inplace_sbuf : sbuf) + gap;
    } else {
        FCA_VERBOSE(5, "Packing send buffer");
        if (MPI_IN_PLACE == sbuf) {
            mca_coll_fca_convertor_create(sconv, sdtype, scount, inplace_sbuf,
                                          MCA_COLL_FCA_CONV_SEND, real_sendbuf,
                                          &ssize);
        } else {
            mca_coll_fca_convertor_create(sconv, sdtype, scount, sbuf,
                                          MCA_COLL_FCA_CONV_SEND, real_sendbuf,
                                          &ssize);
        }
        mca_coll_fca_convertor_process(sconv, 0);
    }
    return ssize;
}
コード例 #10
0
ファイル: coll_fca_module.c プロジェクト: 00datman/ompi
static void mca_coll_fca_module_construct(mca_coll_fca_module_t *fca_module)
{
    FCA_VERBOSE(5, "==>");
    mca_coll_fca_module_clear(fca_module);
}
コード例 #11
0
ファイル: scoll_fca_module.c プロジェクト: Benguang/ompi
/*
 *  * 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_scoll_base_module_t *
mca_scoll_fca_comm_query(struct oshmem_group_t *comm, int *priority)
{
    mca_scoll_base_module_t *module;
    int size = comm->proc_count;
    int local_peers = 0;

    mca_scoll_fca_module_t *fca_module;

    *priority = 0;
    module = NULL;

    if (!mca_scoll_fca_component.fca_enable) {
        FCA_VERBOSE(20, "FCA is disable on user request => exiting");
        goto exit;
    }

    if (mca_memheap.memheap_component == NULL ) {
        FCA_VERBOSE(20, "No memheap => exiting");
        goto exit;
    }

    if (NULL == mca_scoll_fca_component.ret) {
        MCA_MEMHEAP_CALL(private_alloc(sizeof(int),(void **)&mca_scoll_fca_component.ret));
        MCA_MEMHEAP_CALL(private_alloc(oshmem_group_all->proc_count*sizeof(*mca_scoll_fca_component.rcounts), (void **)&mca_scoll_fca_component.rcounts ));
        MCA_MEMHEAP_CALL(private_alloc(/*info_size*/20,&mca_scoll_fca_component.my_info_exchangeable));
        MCA_MEMHEAP_CALL(private_alloc(sizeof(fca_comm_desc_t), &mca_scoll_fca_component.fca_comm_desc_exchangeable));
    }
    if (size < mca_scoll_fca_component.fca_np) {
        FCA_VERBOSE(20,
                    "size(%d) < fca_np(%d)",
                    size, mca_scoll_fca_component.fca_np);
        goto exit;
    }

    if (size < 2) {
        FCA_VERBOSE(20, "size(%d) < 2", size);
        goto exit;
    }

    if (!have_remote_peers(comm,
                           size,
                           &local_peers) /* || OMPI_COMM_IS_INTER(comm)*/) {
        FCA_VERBOSE(1,
                    "all peers in group are on the same node, fca disabled\n");
        goto exit;
    }

    fca_module = OBJ_NEW(mca_scoll_fca_module_t);
    if (!fca_module) {
        goto exit_fatal;
    }
    fca_module->super.scoll_module_enable = mca_scoll_fca_module_enable;
    fca_module->super.scoll_collect =
            mca_scoll_fca_component.fca_enable_allgather ?
                    mca_scoll_fca_collect : NULL;
    fca_module->super.scoll_reduce =
            mca_scoll_fca_component.fca_enable_allreduce ?
                    mca_scoll_fca_reduce : NULL;
    fca_module->super.scoll_barrier =
            mca_scoll_fca_component.fca_enable_barrier ? mca_scoll_fca_barrier :
                                                         NULL;
    fca_module->super.scoll_broadcast =
            mca_scoll_fca_component.fca_enable_bcast ? mca_scoll_fca_broadcast :
                                                       NULL;

    *priority = mca_scoll_fca_component.fca_priority;
    module = &fca_module->super;

    exit:
    FCA_VERBOSE(4,
                "Query FCA module for comm %p size %d rank %d local_peers=%d: priority=%d %s",
                (void *)comm, size, comm->my_pe, local_peers, *priority, module ? "enabled" : "disabled");
    return module;

    exit_fatal:
    /* it is possible that other pe(s) succesfully initialized fca.
     * So differnt frameworks will be used for collective ops
     */
    FCA_ERROR("FCA module query failed - aborting");
    oshmem_shmem_abort(-1);
    return NULL ;
}
コード例 #12
0
ファイル: coll_fca_ops.c プロジェクト: bringhurst/ompi
int mca_coll_fca_allgatherv(void *sbuf, int scount,
                           struct ompi_datatype_t *sdtype,
                           void *rbuf, int *rcounts, int *disps,
                           struct ompi_datatype_t *rdtype,
                           struct ompi_communicator_t *comm,
                           mca_coll_base_module_t *module)
{
    mca_coll_fca_module_t *fca_module = (mca_coll_fca_module_t*)module;
#if OMPI_FCA_ALLGATHER == 1
    MCA_COLL_FCA_DECLARE_CONVERTOR(sconv);
    MCA_COLL_FCA_DECLARE_CONVERTOR(rconv);
    fca_gatherv_spec_t spec;
    size_t rgap, rsize;
    int sum_rcounts;
    ptrdiff_t rdtype_extent;
    int comm_size;
    int relemsize;
    size_t displ;
    int i, ret;

    comm_size = ompi_comm_size(fca_module->comm);
    FCA_DT_EXTENT(rdtype, &rdtype_extent);

    /* Setup send buffer */
    spec.sendsize =
            __setup_gather_sendbuf(sbuf, (char *)rbuf + disps[fca_module->rank] * rdtype_extent,
                                   scount, sdtype, &sconv, &spec.sbuf);

    /* Allocate alternative recvsizes/displs on the stack, which will be in bytes */
    spec.recvsizes = alloca(sizeof *spec.recvsizes * comm_size);
    spec.displs = alloca(sizeof *spec.displs * comm_size);

    /* Calculate the size of receive buffer */
    sum_rcounts = 0;
    for (i = 0; i < comm_size; ++i) {
        sum_rcounts += rcounts[i];
    }

    /* convert MPI counts which depend on dtype) to FCA sizes (which are in bytes) */
    if (mca_coll_fca_array_size(rdtype, sum_rcounts, &rgap, &rsize) && rgap == 0) {
        spec.rbuf = rbuf;
        for (i = 0; i < comm_size; ++i) {
            spec.recvsizes[i] = rcounts[i] * rdtype_extent;
            spec.displs[i] = disps[i] * rdtype_extent;
        }
    } else {
        /*
         * Reorder and remove gaps in displs - we want to allocate as little memory
         * as possible, and we should unpack one-by-one anyway.
         */
        FCA_VERBOSE(5, "Reordering AllgatherV displacements");
        mca_coll_fca_convertor_create(&rconv, rdtype, sum_rcounts, rbuf,
                                      MCA_COLL_FCA_CONV_RECV, &spec.rbuf, &rsize);
        assert(rsize % sum_rcounts == 0);
        relemsize = rsize / sum_rcounts;

        displ = 0;
        for (i = 0; i < comm_size; ++i) {
            spec.recvsizes[i] = rcounts[i] * relemsize;
            spec.displs[i] = displ;
            displ += spec.recvsizes[i];
        }
        assert(displ == rsize);
    }

    /* Call FCA AllgatherV */
    FCA_VERBOSE(5,"Using FCA Allgatherv");
    ret = mca_coll_fca_component.fca_ops.do_allgatherv(fca_module->fca_comm, &spec);

    /* Destroy convertors if operation failed */
    if (ret < 0) {
        mca_coll_fca_convertor_destroy(&sconv);
        mca_coll_fca_convertor_destroy(&rconv);
        if (ret == -EUSEMPI) {
            goto orig_allgatherv;
        }
        FCA_ERROR("Allgatherv failed: %s", mca_coll_fca_component.fca_ops.strerror(ret));
        return OMPI_ERROR;
    }

    /* Unpack data and clean up convertor */
    mca_coll_fca_convertor_destroy(&sconv);
    if (mca_coll_fca_convertor_valid(&rconv)) {
        FCA_VERBOSE(5, "Unpacking AllgatherV receive buffer rdtype_extent=%ld",
                    rdtype_extent);
        for (i = 0; i < comm_size; ++i) {
            mca_coll_fca_convertor_set(&rconv, rdtype,
                                       (char*)rbuf + disps[i] * rdtype_extent,
                                       rcounts[i]);
            mca_coll_fca_convertor_process(&rconv, spec.displs[i]);
        }
        mca_coll_fca_convertor_destroy(&rconv);
    }
    return OMPI_SUCCESS;

orig_allgatherv:
#endif
    return fca_module->previous_allgatherv(sbuf, scount, sdtype, rbuf, rcounts,
                                           disps, rdtype, comm,
                                           fca_module->previous_allgatherv_module);
}
コード例 #13
0
ファイル: coll_fca_ops.c プロジェクト: bringhurst/ompi
/*
 *  Allgather
 *
 *  Function:   - allgather
 *  Accepts:    - same as MPI_Allgather()
 *  Returns:    - MPI_SUCCESS or error code
 */
int mca_coll_fca_allgather(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)
{
    mca_coll_fca_module_t *fca_module = (mca_coll_fca_module_t*)module;
#if OMPI_FCA_ALLGATHER == 1
    MCA_COLL_FCA_DECLARE_CONVERTOR(sconv);
    MCA_COLL_FCA_DECLARE_CONVERTOR(rconv);
    fca_gather_spec_t spec = {0,};
    size_t rgap, rsize;
    ptrdiff_t rdtype_extent;
    ssize_t total_rcount;
    int ret;

    FCA_DT_EXTENT(rdtype, &rdtype_extent);

    /* Setup send buffer */
    spec.size =
            __setup_gather_sendbuf(sbuf, (char *)rbuf + rcount * fca_module->rank * rdtype_extent,
                                   scount, sdtype, &sconv, &spec.sbuf);

    /* Setup recv buffer */
    total_rcount = ompi_comm_size(comm) * rcount;
    if (mca_coll_fca_array_size(rdtype, total_rcount, &rgap, &rsize) && rgap == 0) {
        spec.rbuf = rbuf;
    } else {
        mca_coll_fca_convertor_create(&rconv, rdtype, total_rcount, rbuf,
                                      MCA_COLL_FCA_CONV_RECV, &spec.rbuf, &rsize);
    }


    /* Call FCA Allgather */
    FCA_VERBOSE(5,"Using FCA Allgather size");
    ret = mca_coll_fca_component.fca_ops.do_allgather(fca_module->fca_comm, &spec);

    /* Destroy convertors if operation failed */
    if (ret < 0) {
        mca_coll_fca_convertor_destroy(&sconv);
        mca_coll_fca_convertor_destroy(&rconv);
        if (ret == -EUSEMPI) {
            goto orig_allgather;
        }
        FCA_ERROR("Allgather failed: %s", mca_coll_fca_component.fca_ops.strerror(ret));
        return OMPI_ERROR;
    }

    /* Unpack data and clean up convertor */
    mca_coll_fca_convertor_destroy(&sconv);
    if (mca_coll_fca_convertor_valid(&rconv)) {
        FCA_VERBOSE(5, "Unpacking Allgather receive buffer");
        mca_coll_fca_convertor_process(&rconv, 0);
        mca_coll_fca_convertor_destroy(&rconv);
    }
    return OMPI_SUCCESS;

orig_allgather:
#endif
    return fca_module->previous_allgather(sbuf, scount, sdtype, rbuf, rcount, rdtype,
                                          comm, fca_module->previous_allgather_module);
}
コード例 #14
0
ファイル: coll_fca_ops.c プロジェクト: bringhurst/ompi
/*
 *  Function:   - broadcast
 *  Accepts:    - same arguments as MPI_Bcast()
 *  Returns:    - MPI_SUCCESS or error code
 */
int mca_coll_fca_bcast(void *buff, int count, struct ompi_datatype_t *datatype,
                       int root, struct ompi_communicator_t *comm,
                       mca_coll_base_module_t *module)
{
    mca_coll_fca_module_t *fca_module = (mca_coll_fca_module_t*)module;
    MCA_COLL_FCA_DECLARE_CONVERTOR(conv);
    fca_bcast_spec_t spec;
    size_t gap, size;
    int ret;

    FCA_VERBOSE(5, "[%d] Calling mca_coll_fca_bcast, root=%d, count=%d",
                ompi_comm_rank(comm), root, count);

    /* Setup exchange buffer */
    spec.root = root;
    if (mca_coll_fca_array_size(datatype, count, &gap, &size)) {
        spec.buf = buff + gap;
    } else {
        mca_coll_fca_convertor_create(&conv, datatype, count, buff,
                                      (root == fca_module->rank)
                                                    ? MCA_COLL_FCA_CONV_SEND
                                                    : MCA_COLL_FCA_CONV_RECV,
                                      &spec.buf, &size);
    }

    /* Check that operation size does not exceed limit */
    spec.size = size;
    if (spec.size > fca_module->fca_comm_caps.max_payload) {
         FCA_VERBOSE(5, "Unsupported bcast operation size %d, using fallback",
                     spec.size);
         if (spec.buf != buff) {
             mca_coll_fca_convertor_destroy(&conv);
         }
         goto orig_bcast;
    }

    /* Sender may pack data */
    if (spec.buf != buff && root == fca_module->rank) {
        mca_coll_fca_convertor_process(&conv, 0);
    }

    /* Call FCA Bcast */
    FCA_VERBOSE(5, "Using FCA Bcast");
    ret = mca_coll_fca_component.fca_ops.do_bcast(fca_module->fca_comm, &spec);

    /* Destroy convertor if operation failed */
    if (ret < 0) {
        mca_coll_fca_convertor_destroy(&conv);
        if (ret == -EUSEMPI) {
            goto orig_bcast;
        }
        FCA_ERROR("Bcast failed: %s", mca_coll_fca_component.fca_ops.strerror(ret));
        return OMPI_ERROR;
    }

    /* Unpack data and clean up convertor */
    if (mca_coll_fca_convertor_valid(&conv)) {
        if (root != fca_module->rank) {
            mca_coll_fca_convertor_process(&conv, 0);
        }
        mca_coll_fca_convertor_destroy(&conv);
    }
    return OMPI_SUCCESS;

orig_bcast:
    return fca_module->previous_bcast(buff, count, datatype, root, comm,
                                      fca_module->previous_bcast_module);
}