Ejemplo n.º 1
0
bool FastQuery::getData(const std::string &varNameStr, void *data,
                        const std::string &varPathStr,
                        const bool collective, const bool bcast)
{
    if (! isValid("FastQuery::getData")) return false;

    std::vector<VarInfo> varInfoList;
    std::vector<VarSpace> varSpaceList;
    unsigned int numVar = metadataMgr->getAllVariables
        (varInfoList, varSpaceList, varPathStr, varNameStr);
    if (numVar == 0) {
        LOGGER(ibis::gVerbose > 0)
            << "Warning -- FastQuery::getData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") failed to find the named variable";
        return false;
    }
    int idx=0;
    if (numVar > 1) {
        // pick the best fit variable with the shortest length
        std::string varName = varInfoList[0].getPath();
        int len = varName.size();
        for (unsigned int i=1; i<numVar; i++) {
            if (len > varInfoList[i].getPath().size()) {
                idx = i;
                len = varInfoList[i].getPath().size();
            }
        }
        LOGGER(ibis::gVerbose > 2)
            << "Warning -- FastQuery::getData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") found multiple variables with the name, use \""
            << varInfoList[idx].getPath() << "\"";
    }

    VarInfo varInfo = varInfoList[idx];
    VarSpace varSpace = varSpaceList[idx];
    bool berr;
#ifndef FQ_NOMPI
    if (collective == false) {
#endif
    if (varInfo.getSize() == varSpace.getSize()) {
        berr = dataFile->getData(varInfo.getPath(), data);
    }
    else {
        berr = dataFile->getArrayData(varInfo.getPath(),
                                      varSpace.getOffsets(),
                                      varSpace.getCounts(),
                                      varSpace.getStrides(), data);
    }
#ifndef FQ_NOMPI
    } else {
    int mpi_dim = 0; // split data by the first dimension
    std::vector<uint64_t> offsets = varSpace.getOffsets();
    std::vector<uint64_t> counts = varSpace.getCounts();
    std::vector<uint64_t> strides = varSpace.getStrides();
    int nElements = varSpace.getSize();
    unsigned int totalCount = counts[mpi_dim];
    if (totalCount < mpi_size) {
        LOGGER(ibis::gVerbose > 0)
            << "Warning -- IndexBuilder::setData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << "): number of MPI tasks cannot be less than"
            << " the dimension length " << totalCount;
        return false;
    }
    int mpi_len = std::ceil((double)totalCount/(double)mpi_size);
    if (mpi_rank >= totalCount%mpi_len && totalCount%mpi_len != 0) {
        counts[mpi_dim] = mpi_len - 1;
        offsets[mpi_dim] += (mpi_len*mpi_rank -
                             (mpi_rank-totalCount%mpi_len)) *
            strides[mpi_dim];
    }
    else {
        counts[mpi_dim] = mpi_len;
        offsets[mpi_dim] += (mpi_len*mpi_rank)*strides[mpi_dim];
    }
    bool mpi_berr = false;
    FQ::DataType fqType = varInfo.getType();
    void* mpi_data;
    int data_len = counts[mpi_dim]*(nElements/totalCount);
    switch(fqType){
    case FQ::FQT_FLOAT: {
        mpi_data = new float[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_DOUBLE: {
        mpi_data = new double[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_BYTE: {
        mpi_data = new signed char[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_UBYTE: {
        mpi_data = new unsigned char[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_SHORT: {
        mpi_data = new int16_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_USHORT: {
        mpi_data = new uint16_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_INT: {
        mpi_data = new int32_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_UINT: {
        mpi_data = new uint32_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_LONG: {
        mpi_data = new int64_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_ULONG: {
        mpi_data = new uint64_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    default:
        LOGGER(ibis::gVerbose > 0)
            << "Warning -- FastQuery::setData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") can not handle FQ data type " << fqType;
        mpi_berr = false;
    }

    MPI_Allreduce(&mpi_berr, &berr, 1, MPI_BYTE, MPI_BAND, mpi_comm);

    if (berr) {
        int recvcounts[mpi_size];
        int displs[mpi_size];
        recvcounts[0] = mpi_len*(nElements/totalCount);
        displs[0] = 0;
        for(int i=1; i<mpi_size; i++) {
            if (i >= totalCount%mpi_len && totalCount%mpi_len != 0)
                recvcounts[i] = (mpi_len - 1)*(nElements/totalCount);
            else
                recvcounts[i] = mpi_len*(nElements/totalCount);
            displs[i] = displs[i-1] + recvcounts[i-1];
        }

        switch(fqType){
        case FQ::FQT_FLOAT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_FLOAT, data, recvcounts,
                           displs, MPI_FLOAT, mpi_comm);
            break;}
        case FQ::FQT_DOUBLE: {
            MPI_Allgatherv(mpi_data, data_len, MPI_DOUBLE, data,
                           recvcounts, displs, MPI_DOUBLE, mpi_comm);
            break;}
        case FQ::FQT_BYTE: {
            MPI_Allgatherv(mpi_data, data_len, MPI_CHAR, data, recvcounts,
                           displs, MPI_CHAR, mpi_comm);
            break;}
        case FQ::FQT_UBYTE: {
            MPI_Allgatherv(mpi_data, data_len, MPI_UNSIGNED_CHAR, data,
                           recvcounts, displs, MPI_UNSIGNED_CHAR, mpi_comm);
            break;}
        case FQ::FQT_SHORT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_SHORT, data,
                           recvcounts, displs, MPI_SHORT, mpi_comm);
            break;}
        case FQ::FQT_USHORT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_UNSIGNED_SHORT,
                           data, recvcounts, displs,
                           MPI_UNSIGNED_SHORT, mpi_comm);
            break;}
        case FQ::FQT_INT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_INT, data, recvcounts,
                           displs, MPI_INT, mpi_comm);
            break;}
        case FQ::FQT_UINT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_UNSIGNED, data,
                           recvcounts, displs, MPI_UNSIGNED, mpi_comm);
            break;}
        case FQ::FQT_LONG: {
            MPI_Allgatherv(mpi_data, data_len, MPI_LONG_LONG, data,
                           recvcounts, displs, MPI_LONG_LONG, mpi_comm);
            break;}
        case FQ::FQT_ULONG: {
            MPI_Allgatherv(mpi_data, data_len, MPI_UNSIGNED_LONG_LONG,
                           data, recvcounts, displs,
                           MPI_UNSIGNED_LONG_LONG, mpi_comm);
            break;}
        default:
            berr = false;
            break;
        }
    }
    }
#endif
    if (! berr) {
        LOGGER(ibis::gVerbose > 0)
            << "Warning -- FastQuery::getData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") failed to get data from dataset \""
            << varInfo.getPath().c_str() << "\"";
        return false;
    }
    else {
        LOGGER(ibis::gVerbose > 6)
            << "FastQuery::getData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") successfully retrieved data from dataset \""
            << varInfo.getPath().c_str() << "\"";
        return true;
    }
} // FastQuery::getData