Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Dr Ian Bush [consultant]
HPC

External contributors:
Mai Đức Khang
implemented RAM probe (for unitaryHACK issue #600)
James Richings
patched overflow in bitwise.hpp logic
Luc Jaulmes
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ See the [docs](docs/README.md) for enabling acceleration and running the unit te

In addition to QuEST's [authors](AUTHORS.txt), we sincerely thank the following external contributors to QuEST.

- [Mai Đức Khang](https://github.com/Roll249) for implementing a RAM probe (unitaryHACK 2025 [#600](https://github.com/QuEST-Kit/QuEST/issues/600)).
- [James Richings](https://github.com/JPRichings) for patching a v4 overflow bug.
- [Luc Jaulmes](https://github.com/lucjaulmes) for patching v4's CMake installation.
- [Jakub Adamski](https://github.com/jjacobx) for optimising distributed communication of max-size messages.
Expand Down
33 changes: 28 additions & 5 deletions quest/src/core/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@

#include <cstdlib>

// Platform-specific includes for RAM querying
#if defined(__linux__)
#include <sys/sysinfo.h>
#elif defined(__APPLE__)
#include <sys/types.h>
#include <sys/sysctl.h>
#elif defined(_WIN32)
#define NOMINMAX
#include <windows.h>
#endif



/*
Expand Down Expand Up @@ -196,11 +207,23 @@ qindex mem_getMaxNumKrausMapMatricesBeforeLocalMemSizeofOverflow(int numQubits)


qindex mem_tryGetLocalRamCapacityInBytes() {

/// @todo attempt to find total Ram

// if we're unable to find total RAM, throw an exception
// (which the caller should catch and gracefully continue)
#if defined(__linux__)
struct sysinfo info;
if (sysinfo(&info) == 0)
return (qindex) info.totalram * info.mem_unit;
#elif defined(__APPLE__)
int mib[2] = {CTL_HW, HW_MEMSIZE};
int64_t memsize = 0;
size_t len = sizeof(memsize);
if (sysctl(mib, 2, &memsize, &len, NULL, 0) == 0 && memsize > 0)
return (qindex) memsize;
#elif defined(_WIN32)
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
if (GlobalMemoryStatusEx(&statex))
return (qindex) statex.ullTotalPhys;
#endif
// fallback: throw exception
throw (mem::COULD_NOT_QUERY_RAM) false;
}

Expand Down
12 changes: 10 additions & 2 deletions tests/unit/channels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ TEST_CASE( "createKrausMap", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createKrausMap(12,1), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createKrausMap(12,1),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("exceeds the available memory") ||
ContainsSubstring("available GPU memory") );
#endif
}

Expand Down Expand Up @@ -512,7 +516,11 @@ TEST_CASE( "createSuperOp", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createSuperOp(12), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createSuperOp(12),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("exceeds that available") );
#endif
}
}
Expand Down
24 changes: 20 additions & 4 deletions tests/unit/matrices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,11 @@ TEST_CASE( "createCompMatr", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createCompMatr(25), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createCompMatr(25),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("exceeds the available RAM") );
#endif
}
}
Expand Down Expand Up @@ -529,7 +533,11 @@ TEST_CASE( "createDiagMatr", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createDiagMatr(50), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createDiagMatr(50),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("exceeds the available RAM") );
#endif
}
}
Expand Down Expand Up @@ -602,7 +610,11 @@ TEST_CASE( "createFullStateDiagMatr", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createFullStateDiagMatr(50), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createFullStateDiagMatr(50),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("exceeds the available RAM") );
#endif
}

Expand Down Expand Up @@ -698,7 +710,11 @@ TEST_CASE( "createCustomFullStateDiagMatr", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(50, mpi,gpu,omp), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(50, mpi,gpu,omp),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("exceeds the available RAM") );
#endif
}
}
Expand Down
36 changes: 30 additions & 6 deletions tests/unit/qureg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@ TEST_CASE( "createQureg", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createQureg(50), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createQureg(50),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("RAM") );
#endif
}
}
Expand Down Expand Up @@ -210,7 +214,11 @@ TEST_CASE( "createDensityQureg", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createDensityQureg(25), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createDensityQureg(25),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("RAM") );
#endif
}
}
Expand Down Expand Up @@ -302,7 +310,11 @@ TEST_CASE( "createForcedQureg", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createForcedQureg(50), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createForcedQureg(50),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("RAM") );
#endif
}
}
Expand Down Expand Up @@ -395,7 +407,11 @@ TEST_CASE( "createForcedDensityQureg", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createForcedDensityQureg(25), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createForcedDensityQureg(25),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("RAM") );
#endif
}
}
Expand Down Expand Up @@ -531,8 +547,16 @@ TEST_CASE( "createCustomQureg", TEST_CATEGORY ) {
// GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
// advance or whether it proceeded to malloc() which subsequently failed
#ifndef SANITIZER_IS_ACTIVE
REQUIRE_THROWS_WITH( createCustomQureg(50, 0, 0,0,0), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createCustomQureg(25, 1, 0,0,0), ContainsSubstring("failed") || ContainsSubstring("insufficient available memory") || ContainsSubstring("available GPU memory") );
REQUIRE_THROWS_WITH( createCustomQureg(50, 0, 0,0,0),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("RAM") );
REQUIRE_THROWS_WITH( createCustomQureg(25, 1, 0,0,0),
ContainsSubstring("failed") ||
ContainsSubstring("insufficient available memory") ||
ContainsSubstring("available GPU memory") ||
ContainsSubstring("RAM") );
#endif
}
}
Expand Down
Loading