Skip to content

Commit ca6e9f8

Browse files
committed
made createPauliStrSum validate enough RAM
since the same facilities are anyway needed (with much better motivation) by Lindblad evolution
1 parent b2240e1 commit ca6e9f8

File tree

4 files changed

+38
-7
lines changed

4 files changed

+38
-7
lines changed

quest/src/core/memory.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,15 @@ bool mem_canSuperOpFitInMemory(int numQubits, qindex numBytesPerNode) {
388388
}
389389

390390

391+
bool mem_canPauliStrSumFitInMemory(qindex numTerms, qindex numBytesPerNode) {
392+
393+
// awkwardly arranged to avoid overflow when numTerms is too large
394+
size_t numBytesPerTerm = sizeof(PauliStr) + sizeof(qcomp);
395+
qindex maxNumTerms = numBytesPerNode / numBytesPerTerm; // floors
396+
return numTerms <= maxNumTerms;
397+
}
398+
399+
391400

392401
/*
393402
* MEMORY ALLOCATION SUCCESS

quest/src/core/memory.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ bool mem_canMatrixFitInMemory(int numQubits, bool isDense, int numNodes, qindex
101101

102102
bool mem_canSuperOpFitInMemory(int numQubits, qindex numBytesPerNode);
103103

104+
bool mem_canPauliStrSumFitInMemory(qindex numTerms, qindex numBytesPerNode);
105+
104106

105107

106108
/*

quest/src/core/validation.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,9 @@ namespace report {
693693
string NEW_PAULI_STR_SUM_DIFFERENT_NUM_STRINGS_AND_COEFFS =
694694
"Given a different number of Pauli strings (${NUM_STRS}) and coefficients ${NUM_COEFFS}.";
695695

696+
string NEW_PAULI_STR_SUM_CANNOT_FIT_INTO_CPU_MEM =
697+
"A PauliStrSum containing ${NUM_TERMS} terms cannot fit in the available RAM of ${NUM_BYTES} bytes.";
698+
696699
string NEW_PAULI_STR_SUM_STRINGS_ALLOC_FAILED =
697700
"Attempted allocation of the PauliStrSum's ${NUM_TERMS}-term array of Pauli strings (${NUM_BYTES} bytes total) unexpectedly failed.";
698701

@@ -3190,14 +3193,25 @@ void validate_controlAndPauliStrTargets(Qureg qureg, int ctrl, PauliStr str, con
31903193

31913194
void validate_newPauliStrSumParams(qindex numTerms, const char* caller) {
31923195

3193-
// note we do not bother checking whether RAM has enough memory to contain
3194-
// the new Pauli sum, because the caller to this function has already
3195-
// been passed data of the same size (and it's unlikely the user is about
3196-
// to max RAM), and the memory requirements scale only linearly with the
3197-
// parameters (e.g. numTerms), unlike the exponential scaling of the memory
3198-
// of Qureg and CompMatr, for example
3199-
32003196
assertThat(numTerms > 0, report::NEW_PAULI_STR_SUM_NON_POSITIVE_NUM_STRINGS, {{"${NUM_TERMS}", numTerms}}, caller);
3197+
3198+
// attempt to fetch RAM, and simply return if we fail; if we unknowingly
3199+
// didn't have enough RAM, then alloc validation will trigger later
3200+
size_t memPerNode = 0;
3201+
try {
3202+
memPerNode = mem_tryGetLocalRamCapacityInBytes();
3203+
} catch(mem::COULD_NOT_QUERY_RAM e) {
3204+
return;
3205+
}
3206+
3207+
// pedantically check whether the PauliStrSum fits in memory. This seems
3208+
// ridiculous/pointless because the user is expected to have already prepared
3209+
// data of an equivalent size (which is passed), but checking means we catch
3210+
// when the user has passed an erroneous 'numTerms' which is way too large,
3211+
// avoiding a seg fault
3212+
3213+
bool fits = mem_canPauliStrSumFitInMemory(numTerms, memPerNode);
3214+
assertThat(fits, report::NEW_PAULI_STR_SUM_CANNOT_FIT_INTO_CPU_MEM, {{"${NUM_TERMS}", numTerms}, {"${NUM_BYTES}", memPerNode}}, caller);
32013215
}
32023216

32033217
void validate_newPauliStrSumMatchingListLens(qindex numStrs, qindex numCoeffs, const char* caller) {

tests/unit/paulis.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ TEST_CASE( "createPauliStrSum", TEST_CATEGORY ) {
328328
REQUIRE_THROWS_WITH( createPauliStrSum(nullptr, nullptr, numTerms), ContainsSubstring("number of terms must be a positive integer") );
329329
}
330330

331+
SECTION( "exceeds memory" ) {
332+
333+
// can choose even a number of terms so large that its size (in bytes) overflows
334+
REQUIRE_THROWS_WITH( createPauliStrSum(nullptr, nullptr, 1LL << 60), ContainsSubstring("cannot fit in the available RAM") );
335+
}
336+
331337
SECTION( "mismatching lengths" ) {
332338

333339
// specific to the C++ interface

0 commit comments

Comments
 (0)