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