Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
69f40d1
Extend auto-multithreading
TysonRayJones Oct 1, 2026
12fcd07
Patch distributed error propagation
TysonRayJones Oct 1, 2026
9850367
Add missing validation
TysonRayJones Oct 1, 2026
66c2878
Correct validation throwing function names
TysonRayJones Oct 1, 2026
51c42ba
Include max nqubits in auto-deploy report
TysonRayJones Oct 1, 2026
a4ed26e
Patch C++ setDensityQuregAmps
TysonRayJones Oct 1, 2026
baf63b2
Patch NUMA-aware destroyQureg
TysonRayJones Oct 1, 2026
3b35c11
Avoid overflows with safer types
TysonRayJones Oct 1, 2026
0cd68f4
Correct internal error typo
TysonRayJones Oct 1, 2026
8788034
Patch multi-GPU oversubscription check
TysonRayJones Oct 4, 2026
bd56928
Patch Hermiticity validation
TysonRayJones Oct 4, 2026
bd78749
Patch CPTP validation
TysonRayJones Oct 4, 2026
6798e3a
Forbid zero-prob zero sample
TysonRayJones Oct 4, 2026
701af92
Do not oversubscribe threads in AnyTargDenseMatr
TysonRayJones Oct 4, 2026
17a5b10
Patch seed validation error msg
TysonRayJones Oct 4, 2026
4692841
Patch setDensityQuregAmps dim validation
TysonRayJones Oct 4, 2026
eb08780
Extremely minor boundary changes
TysonRayJones Oct 4, 2026
9a07f3f
Correct validation error msgs
TysonRayJones Oct 4, 2026
610efe7
Patch maximally-distributed cuQuantum calcTotalProb
TysonRayJones Oct 4, 2026
99df89d
Patch two's complement matrix initialisation
TysonRayJones Oct 4, 2026
145320b
Handle maximally distributed dephasing edgecase
TysonRayJones Oct 4, 2026
fb2fe7f
Patch NUMA array allocation
TysonRayJones Oct 5, 2026
0715a68
Improve memory unit rounding
TysonRayJones Oct 5, 2026
d356355
Patch sufficient memory validations
TysonRayJones Oct 6, 2026
4c160b7
Patch KrausMap memory validation
TysonRayJones Oct 11, 2026
f39f0bc
Patch MPI request leak and defend overflows
TysonRayJones Oct 11, 2026
4e1ea7a
Patch MPI calcProbsOfAllMultiQubitOutcomes
TysonRayJones Oct 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions quest/src/api/calculations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,11 @@ qreal calcProbOfMultiQubitOutcome(Qureg qureg, vector<int> qubits, vector<int> o

vector<qreal> calcProbsOfAllMultiQubitOutcomes(Qureg qureg, vector<int> qubits) {

// validate before exponentiating the caller-controlled vector size
validate_quregFields(qureg, __func__);
validate_targets(qureg, qubits.data(), qubits.size(), __func__);
validate_measurementOutcomesFitInGpuMem(qureg, qubits.size(), __func__);

// allocate temp vector, and validate successful (since it's exponentially large!)
vector<qreal> out;
qindex numOut = powerOf2(qubits.size());
Expand Down
2 changes: 1 addition & 1 deletion quest/src/api/channels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void freeAllMemoryIfAnyAllocsFailed(T& obj) {
// determine whether any node experienced a failure
bool anyFail = didAnyLocalAllocsFail(obj);
if (comm_isActive())
anyFail = comm_isTrueOnAllNodes(anyFail);
anyFail = comm_isTrueOnAnyNode(anyFail);

// if so, free all memory before subsequent validation
if (anyFail)
Expand Down
1 change: 1 addition & 0 deletions quest/src/api/decoherence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ void mixQureg(Qureg outQureg, Qureg inQureg, qreal inProb) {

void mixSuperOp(Qureg qureg, int* targets, int numTargets, SuperOp superop) {
validate_quregFields(qureg, __func__);
validate_quregIsDensityMatrix(qureg, __func__);
validate_targets(qureg, targets, numTargets, __func__);
validate_superOpFields(superop, __func__);
validate_superOpIsSynced(superop, __func__);
Expand Down
2 changes: 1 addition & 1 deletion quest/src/api/environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ void printQuregAutoDeployments(bool isDensMatr) {
// auto-deploy will still try to deploy there to (then subsequent validation will fail)
int maxQubits = mem_getMaxNumQuregQubitsBeforeGlobalMemSizeofOverflow(isDensMatr, global_envPtr->numNodes);

for (int numQubits=1; numQubits<maxQubits; numQubits++) {
for (int numQubits=1; numQubits<=maxQubits; numQubits++) {

// re-choose auto deployment
useDistrib = modeflag::USE_AUTO;
Expand Down
3 changes: 2 additions & 1 deletion quest/src/api/initialisations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,8 @@ void setDensityQuregAmps(Qureg qureg, qindex startRow, qindex startCol, vector<v
ptrs[i] = amps[i].data();

// C function performs main validation
setDensityQuregAmps(qureg, startRow, startCol, ptrs.data(), len, (len>0)? len : 0); // avoid seg-fault
size_t numCols = (len > 0)? amps[0].size() : 0; // avoid seg-fault
setDensityQuregAmps(qureg, startRow, startCol, ptrs.data(), len, numCols);
}

void setQuregAmps(Qureg qureg, qindex startInd, vector<qcomp> amps) {
Expand Down
6 changes: 3 additions & 3 deletions quest/src/api/matrices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void freeAllMemoryIfAnyAllocsFailed(T matr) {
// ascertain whether any allocs failed on any node
bool anyFail = didAnyLocalAllocsFail(matr);
if (comm_isActive())
anyFail = comm_isTrueOnAllNodes(anyFail);
anyFail = comm_isTrueOnAnyNode(anyFail);

// if so, free all heap fields
if (anyFail)
Expand Down Expand Up @@ -310,7 +310,7 @@ FullStateDiagMatr validateAndCreateCustomFullStateDiagMatr(int numQubits, int us
out.cpuElems = cpu_allocArray(numElemsPerNode);
out.gpuElems = (useGpuAccel)? gpu_allocArray(numElemsPerNode) : nullptr;

validateMatrixAllocs(out, __func__);
validateMatrixAllocs(out, caller);
setInitialHeapFlags(out);
return out;
}
Expand Down Expand Up @@ -743,7 +743,7 @@ extern "C" void setFullStateDiagMatrFromMultiDimLists(FullStateDiagMatr out, voi
template<class T>
void validateAndPrintMatrix(T matr, const char* caller) {
validate_matrixFields(matr, caller);
validate_numReportedNewlinesAboveZero(__func__); // because trailing newline mandatory
validate_numReportedNewlinesAboveZero(caller); // because trailing newline mandatory

// syncable matrices must be synced before reporting (though only CPU elems are printed)
if constexpr (util_isHeapMatrixType<T>())
Expand Down
2 changes: 1 addition & 1 deletion quest/src/api/paulis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bool didAnyAllocsFailOnAnyNode(PauliStrSum sum) {
! mem_isAllocated(sum.isApproxHermitian) );

if (comm_isActive())
anyFail = comm_isTrueOnAllNodes(anyFail);
anyFail = comm_isTrueOnAnyNode(anyFail);

return anyFail;
}
Expand Down
18 changes: 14 additions & 4 deletions quest/src/api/qureg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ bool didAnyAllocsFailOnAnyNode(Qureg qureg) {

bool anyFail = didAnyLocalAllocsFail(qureg);
if (comm_isActive())
anyFail = comm_isTrueOnAllNodes(anyFail);
anyFail = comm_isTrueOnAnyNode(anyFail);

return anyFail;
}
Expand All @@ -130,7 +130,7 @@ void freeAllMemoryIfAnyAllocsFailed(Qureg qureg) {
return;

// otherwise, free everything that was successfully allocated (freeing nullptr is legal)
cpu_deallocArray(qureg.cpuAmps);
cpu_deallocNumaArray(qureg.cpuAmps, qureg.numAmpsPerNode);
cpu_deallocArray(qureg.cpuCommBuffer);

// although we avoid calling GPU deallocation in non-GPU mode
Expand Down Expand Up @@ -166,7 +166,7 @@ Qureg validateAndCreateCustomQureg(int numQubits, int isDensMatr, int useDistrib

// if any of the above mallocs failed, below validation will memory leak; so free first (but don't set to nullptr)
freeAllMemoryIfAnyAllocsFailed(qureg);
validate_newQuregAllocs(qureg, __func__);
validate_newQuregAllocs(qureg, caller);

// TODO / DEBUG:
// TEMPORARILY FORBID HIP GPU ACCELERATION OF > 2^32 AMPS PER NODE,
Expand Down Expand Up @@ -534,6 +534,11 @@ extern "C" void _wrap_getDensityQuregAmp(qcomp* out, Qureg qureg, qindex row, qi

vector<qcomp> getQuregAmps(Qureg qureg, qindex startInd, qindex numAmps) {

// validate before interpreting numAmps as an allocation size
validate_quregFields(qureg, __func__);
validate_quregIsStateVector(qureg, __func__);
validate_basisStateIndices(qureg, startInd, numAmps, __func__);

// allocate the output vector, and validate successful
vector<qcomp> out;
auto callback = [&]() { validate_tempListAllocSucceeded(false, numAmps, sizeof(qcomp), __func__); };
Expand All @@ -547,9 +552,14 @@ vector<qcomp> getQuregAmps(Qureg qureg, qindex startInd, qindex numAmps) {

vector<vector<qcomp>> getDensityQuregAmps(Qureg qureg, qindex startRow, qindex startCol, qindex numRows, qindex numCols) {

// validate before multiplying dimensions or interpreting them as allocation sizes
validate_quregFields(qureg, __func__);
validate_quregIsDensityMatrix(qureg, __func__);
validate_basisStateRowCols(qureg, startRow, startCol, numRows, numCols, __func__);

// allocate the output matrix, and validate successful
vector<vector<qcomp>> out;
qindex numElems = numRows * numCols; // never overflows (else Qureg alloc would fail)
qindex numElems = numRows * numCols;
auto callback1 = [&]() { validate_tempListAllocSucceeded(false, numElems, sizeof(qcomp), __func__); };
util_tryAllocMatrix(out, numRows, numCols, callback1);

Expand Down
2 changes: 1 addition & 1 deletion quest/src/api/trotterisation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void internal_applyFirstOrderTrotterRepetition(
) {
// apply each sum term as a gadget, in forward or reverse order
for (qindex i=0; i<sum.numTerms; i++) {
int j = reverse? sum.numTerms - i - 1 : i;
qindex j = reverse? sum.numTerms - i - 1 : i;
qindex k = (sumOrdering.empty())? j : sumOrdering[j];
qcomp coeff = sum.coeffs[k];
PauliStr str = sum.strings[k];
Expand Down
Loading
Loading