| 246 | |
| 247 | |
| 248 | qindex mem_getTotalGlobalMemoryUsed(Qureg qureg) { |
| 249 | |
| 250 | /// @todo |
| 251 | /// if sizeof(qcomp) is a power of 2 (which it almost always is, c'mon now), |
| 252 | /// then we could instead return the LOG of the total memory and always |
| 253 | /// avoid overflow, permitting reporters to display mem=2^exp. |
| 254 | /// it would also make changing units (e.g. to GB) easier. |
| 255 | |
| 256 | // work out individual array costs |
| 257 | qindex memLocalArray = (qindex) mem_getLocalQuregMemoryRequired(qureg.numAmpsPerNode); // never overflows |
| 258 | int numLocalArrays = |
| 259 | mem_isAllocated(qureg.cpuAmps) + mem_isAllocated(qureg.cpuCommBuffer) + |
| 260 | mem_isAllocated(qureg.gpuAmps) + mem_isAllocated(qureg.gpuCommBuffer); // but 4*memLocalArray might overflow |
| 261 | |
| 262 | // if total local costs would overflow qindex, return 0 |
| 263 | qindex maxQindex = std::numeric_limits<qindex>::max(); |
| 264 | qindex maxLocalArrayMem = maxQindex / numLocalArrays; // floors |
| 265 | if (memLocalArray > maxLocalArrayMem) |
| 266 | return 0; |
| 267 | |
| 268 | // if qureg is non-distributed, compute local CPU+GPU+buffers costs and return |
| 269 | qindex memLocalTotal = numLocalArrays * memLocalArray; |
| 270 | if (!qureg.isDistributed) |
| 271 | return memLocalTotal; |
| 272 | |
| 273 | // else if total global costs would overflow qindex, return 0 |
| 274 | qindex maxLocalTotalMem = maxQindex / qureg.numNodes; // floors |
| 275 | if (memLocalTotal > maxLocalTotalMem) |
| 276 | return 0; |
| 277 | |
| 278 | // else compute total costs between all nodes |
| 279 | qindex memGlobalTotal = memLocalTotal * qureg.numNodes; |
| 280 | return memGlobalTotal; |
| 281 | } |
| 282 | |
| 283 | |
| 284 |
no test coverage detected