The Quantum Exact Simulation Toolkit v4.3.0
Loading...
Searching...
No Matches

Functions for seeding QuEST's random generators. More...

Functions

int getQuESTNumSeeds ()
 
void getQuESTSeeds (unsigned *seeds)
 
void setQuESTSeeds (unsigned *seeds, int numSeeds)
 
void setQuESTSeedsToDefault ()
 

Detailed Description

Functions for seeding QuEST's random generators.

Re-seeding with identical seeds will determine all of QuEST's subsequent random outputs (such as measurement and random state preparation), and can be done at any stage of execution. When seeding is not explicitly performed, QuEST will attempt to use a cryptographically secure pseudorandom number generator (CSPRNG) if locally available, else fall back to a standard PRNG, via using the standard C++ random_device class.

Function Documentation

◆ getQuESTNumSeeds()

int getQuESTNumSeeds ( )

Returns the number of seeds used by QuEST in its latest round of random number generator seeding.

This is the length of the list output by getQuESTSeeds().

Returns
the number of seeds.
Exceptions
error
  • if the QuEST environment has not been initialised via initQuESTEnv().
See also
Author
Tyson Jones

Definition at line 52 of file debug.cpp.

52 {
53 validate_envIsInit(__func__);
54
55 return rand_getNumSeeds();
56}

◆ getQuESTSeeds()

void getQuESTSeeds ( unsigned * seeds)

Populates seeds with those which last seeded QuEST's random number generation.

This will return the last seeds passed to setQuESTSeeds(), or those internally chosen within setQuESTSeedsToDefault() (and equivalently, those initially chosen during the QuEST environment initialisation). The number of seeds, which informs the necessary capacity of seeds, is obtained by getQuESTNumSeeds().

Example
int numSeeds = getQuESTNumSeeds();
unsigned *seeds = malloc(numSeeds * sizeof *seeds);
printf("seeds[%d] = { ", numSeeds);
for (int i=0; i<numSeeds; i++)
printf("%u ", seeds[i]);
printf("} \n");
free(seeds);
int getQuESTNumSeeds()
Definition debug.cpp:52
void getQuESTSeeds(unsigned *seeds)
Definition debug.cpp:58

may output

seeds[4] = { 3674477761 2499034318 2614242128 475980445 }

See setQuESTSeedsToDefault() for an example of how getQuESTSeeds() interacts with other seeding calls.

Parameters
[out]seedsthe list of seeds
Exceptions
error
  • if the QuEST environment has not been initialised via initQuESTEnv().
  • if seeds is a nullptr.
seg-fault
  • if seeds does not have capacity to write as many unsigned as getQuESTNumSeeds() returns.
See also
Author
Tyson Jones

Definition at line 58 of file debug.cpp.

58 {
59 validate_envIsInit(__func__);
60
61 auto vec = rand_getSeeds();
62 auto num = rand_getNumSeeds();
63
64 for (int i=0; i<num; i++)
65 seeds[i] = vec[i];
66}

Referenced by setRandomTestStateSeeds().

◆ setQuESTSeeds()

void setQuESTSeeds ( unsigned * seeds,
int numSeeds )

Sets the seeds used by QuEST's random number generation.

This affects and determines all pseudorandom decisions made the QuEST library, such as qubit measurement outcomes and random state preparation. The seeds are passed without modification to QuEST's 19,937-bit Mersenne Twister generator. As such, fully specifying the generator's initial state requires 19,937 seed bits, or 623 unsigned integers, although this is rarely necessary.

Seeding can be performed at any time before a random decision (such as measurement); no random outcomes/state is stored on any object beforehand.

Note
In distributed simulation, only the root node's seeds are consulted (and broadcast to all nodes) while those passed on all other nodes are ignored.
Example
// make report() print only one trailing newline
// seed
unsigned seeds[] = {123456789u, 987654321u, 546372819u};
setQuESTSeeds(seeds, 3);
// randomly collapse the plus state
reportScalar("outcome 0", applyQubitMeasurement(qureg, 0));
reportScalar("outcome 1", applyQubitMeasurement(qureg, 1));
reportScalar("outcome 2", applyQubitMeasurement(qureg, 2));
// restore RNG to state prior to collapse
setQuESTSeeds(seeds, 3);
// randomly collapse the plus state again, obtaining same outcomes
reportScalar("outcome 0", applyQubitMeasurement(qureg, 0));
reportScalar("outcome 1", applyQubitMeasurement(qureg, 1));
reportScalar("outcome 2", applyQubitMeasurement(qureg, 2));
void setQuESTNumReportedNewlines(int numNewlines)
Definition debug.cpp:150
void setQuESTSeeds(unsigned *seeds, int numSeeds)
Definition debug.cpp:37
void initPlusState(Qureg qureg)
int applyQubitMeasurement(Qureg qureg, int target)
void reportStr(const char *str)
Definition types.cpp:33
void reportScalar(const char *label, qcomp num)
Definition types.cpp:55
Example output:
outcome 0: 0
outcome 1: 1
outcome 2: 1
outcome 0: 0
outcome 1: 1
outcome 2: 1
Parameters
[in]seedsa list of seeds.
[in]numSeedsthe length of seeds.
Exceptions
error
  • if seeds is a null pointer.
  • if numSeeds is less than one.
See also
Author
Tyson Jones

Definition at line 37 of file debug.cpp.

37 {
38 validate_envIsInit(__func__);
39 validate_randomSeeds(seeds, numSeeds, __func__);
40
41 // consults only root-node seeds
42 rand_setSeeds(vector<unsigned>(seeds, seeds+numSeeds));
43}

Referenced by setRandomTestStateSeeds().

◆ setQuESTSeedsToDefault()

void setQuESTSeedsToDefault ( )

Re-randomizes QuEST, seeding its random number generator with new seeds as pseudorandomly produced by the C++ std::random_device @a function, potentially using a hardware RNG. Similar to setQuESTSeeds(), this affects all pseudorandom decisions made the QuEST library, such as qubit measurement outcomes and random state preparation. Unlike setQuESTSeeds() however, repeated calls will not guarantee identical random generation; the internally processed seeds may differ at each invocation. This is, in fact, the function first internally called during QuEST environment initialisation. Seeding can be performed at any time after QuEST library initialisation, before a random decision (such as measurement); no random outcomes/state is stored on any object beforehand. This function consults std::random_device to produce DEFAULT_NUM_RNG_SEEDS=4 seeds, which is infact insufficient to fully specify an initial state of QuEST's 19,937-bit Mersenne Twister generator. Presently, DEFAULT_NUM_RNG_SEEDS cannot be changed except through manual modification and recompilation.

Note
In distributed simulation, only the root node's seeds are consulted (and broadcast to all nodes) while those passed on all other nodes are ignored.

Note that many data structures (e.g. CompMatr, DiagMatr, KrausMap) will assess epsilon-dependent validation properties such as unitarity once, recording the result in a persistent heap field (like KrausMap.isApproxCPTP) to avoid superfluous re-calculation. Updating the global validation epsilon via this function will update all persistent heap fields, marking epsilon-dependent properties as "unknown", which will be lazily re-evaluated when validation is next performed. Ergo, calling this function can cause later additional function overheads.

Example
// make report() print only one trailing newline
// randomise the RNG state
// randomly collapse the plus state
reportScalar("outcome 0", applyQubitMeasurement(qureg, 0));
reportScalar("outcome 1", applyQubitMeasurement(qureg, 1));
reportScalar("outcome 2", applyQubitMeasurement(qureg, 2));
// re-randomise the RNG state
// randomly collapse the plus state again, obtaining new outcomes
reportScalar("outcome 0", applyQubitMeasurement(qureg, 0));
reportScalar("outcome 1", applyQubitMeasurement(qureg, 1));
reportScalar("outcome 2", applyQubitMeasurement(qureg, 2));
void setQuESTSeedsToDefault()
Definition debug.cpp:45
Example output:
outcome 0: 0
outcome 1: 1
outcome 2: 0
outcome 0: 1
outcome 1: 1
outcome 2: 1
We can view the random seeds chosen by QuEST using getQuESTSeeds():
int numSeeds = getQuESTNumSeeds(); // fixed=4
unsigned seeds[1000]; // lazily/dangerously assume num<=1000
for (int i=0; i<numSeeds; i++)
printf("%u ", seeds[i]);
printf("\n\n");
for (int i=0; i<numSeeds; i++)
printf("%u ", seeds[i]);
printf("\n");
Example output:
766738893 3449946700 2005286535 3261547242
3996404805 474611433 1261615115 3403708295
Exceptions
error
  • if the QuEST environment has not been initialised via initQuESTEnv().
See also
Author
Tyson Jones

Definition at line 45 of file debug.cpp.

45 {
46 validate_envIsInit(__func__);
47
48 rand_setSeedsToDefault();
49}