43 |
|
#include <algorithm> |
44 |
|
#include <cassert> |
45 |
|
#include <string> |
46 |
+ |
#include <iterator> |
47 |
|
|
48 |
|
#include "utils/OpenMDBitSet.hpp" |
49 |
|
#include "utils/Algorithm.hpp" |
50 |
+ |
#ifdef IS_MPI |
51 |
+ |
#include <mpi.h> |
52 |
+ |
#endif |
53 |
|
|
54 |
|
namespace OpenMD { |
55 |
|
int OpenMDBitSet::countBits() { |
68 |
|
assert(fromIndex <= toIndex); |
69 |
|
assert(fromIndex >=0); |
70 |
|
assert(toIndex <= size()); |
71 |
< |
std::vector<char>::iterator first = bitset_.begin() + fromIndex; |
72 |
< |
std::vector<char>::iterator last = bitset_.begin() + toIndex; |
71 |
> |
std::vector<bool>::iterator first = bitset_.begin() + fromIndex; |
72 |
> |
std::vector<bool>::iterator last = bitset_.begin() + toIndex; |
73 |
|
|
74 |
|
std::transform(first, last, first, std::logical_not<bool>()); |
75 |
|
|
79 |
|
assert(fromIndex <= toIndex); |
80 |
|
assert(fromIndex >=0); |
81 |
|
assert(toIndex <= size()); |
82 |
< |
std::vector<char>::iterator first = bitset_.begin() + fromIndex; |
83 |
< |
std::vector<char>::iterator last = bitset_.begin() + toIndex; |
82 |
> |
std::vector<bool>::iterator first = bitset_.begin() + fromIndex; |
83 |
> |
std::vector<bool>::iterator last = bitset_.begin() + toIndex; |
84 |
|
|
85 |
|
OpenMDBitSet result; |
86 |
|
std::copy(first, last, std::back_inserter(result.bitset_)); |
88 |
|
} |
89 |
|
|
90 |
|
bool OpenMDBitSet::none() { |
91 |
< |
std::vector<char>::iterator i = std::find(bitset_.begin(), bitset_.end(), true); |
91 |
> |
std::vector<bool>::iterator i = std::find(bitset_.begin(), bitset_.end(), true); |
92 |
|
return i == bitset_.end() ? true : false; |
93 |
|
} |
94 |
|
|
146 |
|
assert(fromIndex <= toIndex); |
147 |
|
assert(fromIndex >=0); |
148 |
|
assert(toIndex <= size()); |
149 |
< |
std::vector<char>::iterator first = bitset_.begin() + fromIndex; |
150 |
< |
std::vector<char>::iterator last = bitset_.begin() + toIndex; |
149 |
> |
std::vector<bool>::iterator first = bitset_.begin() + fromIndex; |
150 |
> |
std::vector<bool>::iterator last = bitset_.begin() + toIndex; |
151 |
|
std::fill(first, last, value); |
152 |
|
} |
153 |
|
|
194 |
|
bool operator== (const OpenMDBitSet & bs1, const OpenMDBitSet &bs2) { |
195 |
|
assert(bs1.size() == bs2.size()); |
196 |
|
return std::equal(bs1.bitset_.begin(), bs1.bitset_.end(), bs2.bitset_.begin()); |
197 |
+ |
} |
198 |
+ |
|
199 |
+ |
OpenMDBitSet OpenMDBitSet::parallelReduce() { |
200 |
+ |
OpenMDBitSet result; |
201 |
+ |
|
202 |
+ |
#ifdef IS_MPI |
203 |
+ |
|
204 |
+ |
// This is necessary because std::vector<bool> isn't really a |
205 |
+ |
// std::vector, so we can't pass the address of the first element |
206 |
+ |
// to the MPI call that follows. We first have to convert to a |
207 |
+ |
// std::vector<int> to do the logical_or Allreduce call, then back |
208 |
+ |
// convert it into the vector<bool>. |
209 |
+ |
|
210 |
+ |
std::vector<int> bsInt(bitset_.begin(), bitset_.end()); |
211 |
+ |
|
212 |
+ |
MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &bsInt[0], |
213 |
+ |
bsInt.size(), MPI::INT, MPI::LOR); |
214 |
+ |
|
215 |
+ |
std::transform(bsInt.begin(), bsInt.end(), |
216 |
+ |
std::back_inserter( result.bitset_ ), to_bool<int>()); |
217 |
+ |
#else |
218 |
+ |
|
219 |
+ |
// Not in MPI? Just return a copy of the current bitset: |
220 |
+ |
std::copy(bitset_.begin(), bitset_.end(), |
221 |
+ |
std::back_inserter( result.bitset_ )); |
222 |
+ |
#endif |
223 |
+ |
|
224 |
+ |
return result; |
225 |
|
} |
226 |
|
|
227 |
|
//std::istream& operator>> ( std::istream& is, const OpenMDBitSet& bs) { |
230 |
|
//} |
231 |
|
|
232 |
|
std::ostream& operator<< ( std::ostream& os, const OpenMDBitSet& bs) { |
233 |
< |
for (int i = 0; i < bs.bitset_.size(); ++i) { |
233 |
> |
for (unsigned int i = 0; i < bs.bitset_.size(); ++i) { |
234 |
|
std::string val = bs[i] ? "true" : "false"; |
235 |
|
os << "OpenMDBitSet[" << i <<"] = " << val << std::endl; |
236 |
|
} |