v4 wishlist - contributors wanted! #496
TysonRayJones
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
QuEST v4 is almost ready 🎉 though there are lots of things which can be improved with the help of external contributions. If you are keen to become a contributor, check out the below feature wishlist. If you see something fun, comment that you'd like to try implementing it (so we don't duplicate efforts) and make a pull-request to the
v4
branch.Don't stress about getting it perfect - we will help you iteratively refine the PR 🙌
Self-contained
Add CPU memory querying.
Specifically, function stub
mem_tryGetLocalRamCapacityInBytes()
inmemory.cpp
needs an implementation. This is used by several user-input validators to attempt to check whether the user's data structure can principally fit into RAM. This avoids subsequent successful mallocs using intractably slow virtual memory.The function can return the total RAM capacity (as the name implies), or the remaining available memory if that is easier - the difference is not very important, because there already exists post-memory-allocation validation which is more robust. The function can safely throw an error (like in the existing stub) if it is unable to find the memory at runtime. Callers will handle the exception as the RAM capacity being unknown, and proceed to attempted allocation.
The challenge of this task is to implement a querier which is platform agnostic; it must compile on Windows, Linux and MacOS, and be compatible with all common C++ compilers (e.g. gcc, clang, icc, xlc, msvc). It is expected to make extensive use of compiler-guards to handle these scenarios, and gracefully fail on incompatible platforms (by throwing a runtime exception, rather than failing to compile).
Make reporting precision user-configurable.
Functions like
reportCompMatr()
involve printing many decimal scalars to the screen, which can quickly become visually untidy. A user may prefer to change the number of significant-figures displayed, similar to how they can already change the number of reported scalars through functionsetNumReportedItems()
. This task involves creating a new function indebug.cpp
such assetNumReportedSigFigs()
which changes the sig-figs of subsequently reported scalars. This would affect both the real and imaginary components of complex numbers separately.
Completing this task would involve adding a global variable like
maxNumPrintedSigFigs
toprinter.cpp
(similar to the existingmaxNumPrintedItems
), and extendingfloatToStr()
to return that many sig-figs.Extend memory-size reporting to use sensible units.
Specifically, functions which report quantities in bytes to the screen should be updated to use whatever unit (e.g. KiB, MiB, GiB, TiB) is most convenient to express the quantity.
Several QuEST functions like
reportQuregParams()
,reportQuESTEnv()
andreportCompMatr()
create and display strings containing memory quantities in units of bytes. For example,reportQuregParams(qureg)
may report (here, truncated):while
reportQuESTEnv()
may report:and
reportCompMatr()
might show:A string like
25622413312 bytes
is needlessly precise and is better communicated to the user as23.9 GiB
.This task involves modifying function
printer_getMemoryWithUnitStr()
insideprinter.cpp
to return astd::string
with a more sensible unit than "bytes| depending onnumBytes
passed.string printer_getMemoryWithUnitStr(size_t numBytes) {
}
```
It is acceptable to round to the nearest tenth-unit, e.g.
23.9 GiB
but not `23.86 GiB`, although an ideal solution would print as many significant figures as the user has currently configured (as related to the above task).Extend reporters to write to file.
Functions like...
reportQuregParams()
reportQuESTEnv()
reportCompMatr()
reportKrausMatr()
etc involve reporting data to the screen (standard output). However, in HPC settings, it is often preferred to log these to file.
This task involves defining new reporters like the above, but which accept an additional filename argument; all output is directed there and not printed. These should have the above names with a
ToFile
suffix, e.greportQuregParamsToFile(Qureg, char*)
. These functions will require new validation which checks that the destination file can be opened and overwritten, in a platform-agnostic manner.HPC
improve the custom CUDA kernel parallelisation granularity. Currently, we hardcode the number of threads per block here, and allocate as many blocks as necessary such that every thread modifies a single amplitude (when doing so is embarrassingly parallel). This was done for simplicity, and to maintain compatibility with many GPUs, but is far from optimal. Allocation may be improved using the occupancy API.
accelerate (via OpenMP and CUDA) the utility checks of unitarity, Hermiticity, and CPTP. These are noted with
TODO
comments inutilities.cpp
, e.g. here.test and implement the OpenMP and enumeration optimisations listed in
cpu_routines.cpp
asTODO
comments.test and implement the CUDA and Thrust optimisations listed in
gpu_routines.cpp
andgpu_kernels.cuh
asTODO
comments.Refactoring
Adding private namespaces.
So far, the v4 source-code uses lengthy underscore-joined function names for internal functions which are exposed to other internal functions and files. For example:
This communicates that this function is the
CPU
version of"subroutine B"
involved in computing theoneQubitPauliChannel
upon adensity matrix
. This function is exposed incpu_subroutines.hpp
.However, intendedly private internal functions which are not intendedly exposed to other files are given informative names without a prefix. For example,
assertValidCtrlStates
inlocaliser.cpp
. Alas, C++ functions use external linkage by default, so these private symbols can actually collide with user code when the QuEST library is statically linked! A user of QuEST who defines their ownassertValidCtrlStates()
function, despite knowing nothing about QuEST's internal functions, will encounter a symbol duplication error!To remedy this, we should make use of anonymous namespaces. Completing this task involves wrapping all private functions (those without a
prefix_
) in the source with an anonymous namespace to ensure they have only internal linkage.Extend user-validation error messages to contain arbitrary types.
Users love to make errors and pass erroneous inputs to functions, so
validation.cpp
contains many checks that function preconditions are satisfied. For example, a users invalidly duplicating a qubit in a target list...will see an error reporting the mistake:
Some error messages helpfully contain more specific information about the mistake. E.g.
will trigger
The numbers
-1
and3
were substituted into this string which originally resembled:string INVALID_TARGET_QUBIT = "Invalid target qubit (${QUBIT_IND}). Must be greater than or equal to zero, and less than the number of qubits in the Qureg (${NUM_QUBITS})."
This happened by invocation of
assertThat()
where we have aliased
The
vars
are substituted into the string viagetStringWithSubstitutedVars()
.This rudimentary method limits us to embedding only integer variables into validation messages (because
tokenSubs
is a map tolong long int
). Alas we should wish to embed other types like floating-point numbers and strings, to report messages like:This task involves refactoring
tokenSubs
to permit substitution of arbitrary types. This is not as simple as templatingtokenSubs
in its current form; we may wish to substitute different types into the same string, i.e. to produce strings like"The probability of dephasing (0.745) of the qubit of index 8 exceeds the maximum allowed."
The challenge is to do this in a way that is:
tokenSubs
so a big increase of boilerplate (e.g. explicitly templating every instance) is non-ideal. The existing implementation is already spaghetti!Beta Was this translation helpful? Give feedback.
All reactions