Say I have
std::vector<T, allocator1=default allocator in STL> A
std::vector<T, allocator2=some other allocator> B
I am using __offload::shared_allocator as allocator2 in Cilk Plus for offloading from Host CPU to Xeon Phi coprocessor
Can I construct A from B?
std::vector<T> A{B.begin(), B.end()};
And more general, for which kind of STL functions that different allocators will matter?
As noted in the comments, the constructor
std::vector<T> A{B.begin(), B.end()};
should work fine since it works for any two iterators. As for the question "for which kind of STL functions that different allocators will matter?", there's two kinds of "different":
For incompatibilities with respect to (1), you should see a compile-time error because the type system will catch it. For (2), I don't know if STL implementations catch the possible problems or not. The primary container/function to worry about in that regard are the splice
methods on class list
(and splice_after
methods on class forward_list
), because they move an object allocated in one container to another container. As footnote 265 of the C++11 standard notes, the STL containers require that allocators compare equal, so such movement should not be a problem.
With respect to offload issues, if A is allocated with a plain STL allocator, then it cannot be constructed on the host side and used on the coprocessor side. But B can be used on both sides. Here is an example that constructs B using an
offload::shared_allocator, and constructs
A` from it on the coprocessor side.
#pragma offload_attribute (push, _Cilk_shared)
#include <vector>
#include "offload.h"
#include <cstdio>
#pragma offload_attribute (pop)
_Cilk_shared std::vector<int, __offload::shared_allocator<int> > B;
_Cilk_shared void foo() {
#ifdef __MIC__
std::vector<int> A(B.begin(),B.end());
for( auto& x: A )
std::printf("%d\n", x);
#else
std::printf("Host\n");
#endif
}
int main() {
auto y = 1;
for( int i=0; i<10; ++i ) {
B.push_back(y);
y *= 10;
}
_Cilk_offload foo();
}
It should print:
1
10
100
1000
10000
100000
1000000
10000000
100000000
1000000000