00001
00002 #ifdef __DEBUG__
00003 #ifndef __DEBUG_PAR__
00004 #define __DEBUG_PAR__
00005 #endif
00006 #endif
00007
00014 namespace par {
00015
00016 template <typename T>
00017 int maxLowerBound(const std::vector<T> & keys, const std::vector<T> & searchList,
00018 std::vector<T> & results, MPI_Comm comm) {
00019 PROF_SEARCH_BEGIN
00020
00021 int rank, npes;
00022
00023 MPI_Comm_size(comm, &npes);
00024 MPI_Comm_rank(comm, &rank);
00025
00026
00027 std::vector<T> mins (npes);
00028 assert(!searchList.empty());
00029
00030 par::MPI_Allgather<T>( &(*searchList.begin()), &(*mins.begin()), 1, comm);
00031
00032
00033 unsigned int *part = new unsigned int[keys.size()];
00034 for ( unsigned int i=0; i<keys.size(); i++ ) {
00035
00036 bool found = par::maxLowerBound<T>(mins,keys[i], part+i);
00037 if ( !found ) {
00038
00039
00040 part[i] = rank;
00041 }
00042 }
00043 mins.clear();
00044
00045 int *numKeysSend = new int[npes];
00046 int *numKeysRecv = new int[npes];
00047 for ( int i=0; i<npes; i++ )
00048 numKeysSend[i] = 0;
00049
00050 for ( unsigned int i=0; i<keys.size(); i++ )
00051 numKeysSend[part[i]]++;
00052
00053
00054 par::MPI_Alltoall(numKeysSend, 1, MPI_INT, numKeysRecv, 1, MPI_INT, comm);
00055
00056 unsigned int totalKeys=0;
00057 for ( int i=0; i<npes; i++ )
00058 totalKeys += numKeysRecv[i];
00059
00060
00061 std::vector<T> sendK (keys.size());
00062 std::vector<T> recvK (totalKeys);
00063
00064 unsigned int * comm_map = new unsigned int [keys.size()];
00065
00066
00067 int *sendOffsets = new int[npes]; sendOffsets[0] = 0;
00068 int *recvOffsets = new int[npes]; recvOffsets[0] = 0;
00069 int *numKeysTmp = new int[npes]; numKeysTmp[0] = 0;
00070
00071
00072 for ( int i=1; i<npes; i++ ) {
00073 sendOffsets[i] = sendOffsets[i-1] + numKeysSend[i-1];
00074 recvOffsets[i] = recvOffsets[i-1] + numKeysRecv[i-1];
00075 numKeysTmp[i] = 0;
00076 }
00077
00078 for ( unsigned int i=0; i< keys.size(); i++ ) {
00079 unsigned int ni = numKeysTmp[part[i]];
00080 numKeysTmp[part[i]]++;
00081
00082 sendK[sendOffsets[part[i]] + ni] = keys[i];
00083
00084 comm_map[i] = sendOffsets[part[i]] + ni;
00085 }
00086 delete [] part;
00087 delete [] numKeysTmp;
00088
00089
00090 par::MPI_Alltoallv_sparse((void *)&(*sendK.begin()), numKeysSend,
00091 sendOffsets,par::Mpi_datatype<T>::value(),
00092 &(*recvK.begin()), numKeysRecv, recvOffsets,
00093 par::Mpi_datatype<T>::value(), comm);
00094
00095
00096 std::vector<T> resSend (totalKeys);
00097 std::vector<T> resRecv (keys.size());
00098
00099
00100 for ( unsigned int i=0; i<totalKeys;i++) {
00101 unsigned int idx;
00102 bool found = par::maxLowerBound<T>( searchList, recvK[i], &idx );
00103 if(found) {
00104 resSend[i] = searchList[idx];
00105 }
00106 }
00107
00108
00109
00110 par::MPI_Alltoallv_sparse((void*)&(*resSend.begin()), numKeysRecv,
00111 recvOffsets,par::Mpi_datatype<T>::value(),
00112 &(*resRecv.begin()), numKeysSend, sendOffsets,
00113 par::Mpi_datatype<T>::value(), comm);
00114
00115 delete [] sendOffsets;
00116 delete [] recvOffsets;
00117 delete [] numKeysSend;
00118 delete [] numKeysRecv;
00119
00120 for ( unsigned int i=0; i < keys.size(); i++ ) {
00121 results[i] = resRecv[comm_map[i]];
00122 }
00123
00124
00125 delete [] comm_map;
00126
00127 PROF_SEARCH_END
00128 }
00129
00130
00131 }
00132