18 _gatheredDataPointer(nullptr),
19 _globalMemoryPage(UndefinedMemoryPage) {
25 if (_gatheredDataPointer!=
nullptr and not container.empty()) {
26 logDebug(
"scatter()",
"scatter " << container.size() <<
" element(s) from heap" );
28 const int oldSize = container.size();
30 for (
int i=0; i<oldSize; i++) {
31 container.push_back(
new T( _gatheredDataPointer[i]) );
35 _gatheredDataPointer =
nullptr;
37 else if (_globalMemoryPage!=UndefinedMemoryPage and not container.empty()) {
38 logDebug(
"scatter()",
"scatter " << container.size() <<
" element(s) from large continuous memory" );
39 assertion1( _globalMemory.pages[ _globalMemoryPage ].used, _globalMemoryPage );
41 const int size = _globalMemory.pages[ _globalMemoryPage ].size;
42 const int first = _globalMemory.pages[ _globalMemoryPage ].startIndex;
44 logDebug(
"scatter()",
"page size is " << size <<
" starting at index " << first );
47 for (
int i=0; i<size; i++) {
48 container.push_back(
new T( _globalMemory.data[ first+i ] ) );
51 _globalMemory.freePage( _globalMemoryPage );
52 _globalMemoryPage = UndefinedMemoryPage;
60 _gatheredDataPointer =
nullptr;
61 _globalMemoryPage = UndefinedMemoryPage;
68 assertion( not container.empty() or not isGathered() );
69 if (not isGathered()) {
72 else if (_gatheredDataPointer!=
nullptr) {
73 logDebug(
"scatterAndUpdateIterator()",
"scatter " << container.size() <<
" element(s) currently held on heap" );
76 typename Container::iterator result;
78 for (
auto oldContainerIterator: container) {
79 newContainer.push_back(
new T(*oldContainerIterator) );
80 if (oldContainerIterator==*p) {
81 result = newContainer.end();
87 container.splice( container.begin(), newContainer );
90 _gatheredDataPointer =
nullptr;
95 logDebug(
"scatterAndUpdateIterator()",
"scatter " << container.size() <<
" element(s) currently held within page of continuous memory" );
98 typename Container::iterator result;
100 for (
auto oldContainerIterator: container) {
101 newContainer.push_back(
new T(*oldContainerIterator) );
102 if (oldContainerIterator==*p) {
103 result = newContainer.end();
109 container.splice( container.begin(), newContainer );
111 _globalMemory.freePage(_globalMemoryPage);
112 _globalMemoryPage = UndefinedMemoryPage;
121 assertion( not container.empty() or not isGathered() );
122 if ( not isGathered() and not container.empty()) {
123 logDebug(
"gather()",
"gather " << container.size() <<
" element(s)" );
125 _globalMemoryPage = _globalMemory.addPage( container.size() );
127 if ( _globalMemoryPage==UndefinedMemoryPage) {
128 logDebug(
"gather()",
"have not been able to book page in continuous memory, so gather " << container.size() <<
" element(s) on heap" );
131 for (
auto& p: container) {
132 _gatheredDataPointer[entry] = *p;
137 typename Container::iterator p = container.begin();
138 for (
int entry=0; entry<container.size(); entry++) {
139 *p = _gatheredDataPointer + entry;
144 logDebug(
"gather()",
"gather " << container.size() <<
" element(s) into page " << _globalMemoryPage );
146 const int first = _globalMemory.pages[ _globalMemoryPage ].startIndex;
149 for (
auto& p: container) {
150 _globalMemory.data[first+entry] = *p;
155 typename Container::iterator p = container.begin();
156 for (
int entry=0; entry<container.size(); entry++) {
157 assertion( first+entry<_globalMemory.data.size() );
158 *p = &( _globalMemory.data[first+entry] );
168 assertion( not( _gatheredDataPointer!=
nullptr and _globalMemoryPage!=UndefinedMemoryPage ));
169 return _gatheredDataPointer!=
nullptr or _globalMemoryPage!=UndefinedMemoryPage;
175 assertion( not container.empty() or _gatheredDataPointer==
nullptr );
176 if ( isGathered() ) {
182 container.push_back(newCopy);
189 data(initialCapacity),
191 additionalEntriesRequested(0) {
206 if ( not pages[currentPage].used and pages[currentPage].size==size ) {
207 freePage = currentPage;
213 logInfo(
"addPage(int)",
"global memory seems not to be used at all, but is to small to accommodate first page of size " << size <<
". Increase capacity to be able accommodate page" );
219 "addPage(int)",
"global memory had no free page of size " << size <<
220 ". Add new page, as capacity is available (used size=" << totalUsedSize() <<
" vs capacity=" <<
228 pages.push_back( newPage );
230 freePage = pages.size()-1;
233 if (additionalEntriesRequested==0) {
236 "global memory had no free page of size " << size <<
" and we cannot accommodate an additional page of size " <<
237 size <<
" (currently used size=" << totalUsedSize() <<
" vs available capacity of " <<
238 data.size() <<
"). Will not report on further requests unless global memory space has grown"
241 additionalEntriesRequested += size;
242 logDebug(
"addPage(int)",
"additional-entries-requested=" << additionalEntriesRequested );
260 assertion1( pageNumber<pages.size(), pageNumber );
264 pages[pageNumber].used =
false;
266 while ( not pages.empty() and not pages[pages.size()-1].used ) {
270 if (pages.empty() and additionalEntriesRequested>0) {
273 "global memory is completely empty, so use opportunity to increase total size from " <<
274 data.size() <<
" to " << ( data.size() + additionalEntriesRequested )
276 assertion3( data.size() + additionalEntriesRequested <= data.max_size(), data.size(), additionalEntriesRequested, data.max_size() );
277 data.resize( data.size() + additionalEntriesRequested );
278 additionalEntriesRequested = 0;
287 : pages[pages.size()-1].startIndex + pages[pages.size()-1].size;
#define assertion3(expr, param0, param1, param2)
#define assertion1(expr, param)
#define logDebug(methodName, logMacroMessageStream)
#define logTraceOutWith1Argument(methodName, argument0)
#define logTraceInWith1Argument(methodName, argument0)
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Create a lock around a boolean semaphore region.
Memory pool offering continuous global memory for a particle species.
static bool requestCompleteScatter()
Recommend complete scatter.
static tarch::logging::Log _log
void gather()
Gather the particle.
void clearAndReset()
Clear dataset tied to one vertex.
GlobalContinuousMemoryPool()
Container::iterator scatterAndUpdateIterator(const typename Container::iterator &p)
bool isGathered() const
Is the vertex data gathered.
void replace(typename Container::iterator p, T *newCopy)
Replace particle.
std::list< T * > Container
static constexpr int UndefinedMemoryPage
void scatter()
Scatter the data.
static GlobalMemory _globalMemory
This class attribute represents the global data space for all of the particles.
void freeMemory(void *data, MemoryLocation location, int device=accelerator::Device::HostDevice)
Free memory.
@ Heap
Create data on the heap of the local device.
Represents the global memory.
GlobalMemory(int initialSize)
void freePage(int pageNumber)
Free a page.
int totalUsedSize() const
Take last page's start index, add its size and you get the result.
int additionalEntriesRequested
Number of entries that we would have liked to have.
int addPage(int size)
Add a new page of size size.