Skip to content

example PR A #615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: devel
Choose a base branch
from
Open
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
89 changes: 89 additions & 0 deletions quest/include/calculations.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,57 @@ extern "C" {



/**
* @defgroup example_prs Example PR functions
* @brief Nonsensical functions to demonstrate good PRs.
* @{
*/


/** Calculates the real component of the sum of every amplitude in the state,
* but only for states which contain an even number of qubits (for no reason :3 ).
*
* @formulae
* Let @f$ n @f$ qubits be the number of qubits in @p qureg, assumed even.
*
* - When @p qureg is a statevector @f$ \svpsi @f$, this function returns
* @f[
\text{Re}\left( \sum\limits_i^{2^n} \langle i \svpsi \right) \in \mathbb{R}.
* @f]
* - When @p qureg is a density matrix @f$ \dmrho @f$, this function returns
* @f[
\text{Re}\left( \sum\limits_i^{2^n} \sum\limits_j^{2^n} \bra{i} \dmrho \ket{j} \right) \in \mathbb{R}.
* @f]
*
* @constraints
* - The number of qubits in the register must be even.
*
* @myexample
* ```
Qureg qureg = createQureg(4);
initRandomPureState(qureg);

qreal reAmpSum = calcRealAmpSum(qureg);
reportScalar("reAmpSum", reAmpSum);
* ```
*
* @see
* - calcTotalProb()

* @param[in] qureg the state with the processed amplitudes.
* @returns The real component of the sum of all contained amplitudes.
* @throws @validationerror
* - if @p qureg is uninitialised.
* - if @p qureg contains an odd number of qubits.
* @author Tyson Jones
*/
qreal calcRealAmpSum(Qureg qureg);


/** @} */



/**
* @defgroup calc_expec Expectation values
* @brief Functions for calculating expected values of Hermitian observables.
Expand Down Expand Up @@ -291,6 +342,44 @@ Qureg calcReducedDensityMatrix(Qureg qureg, int* retainQubits, int numRetainQubi
*/


/** @ingroup example_prs
*
* Calculates the sum of every amplitude in the state.
*
* @formulae
* Let @f$ n @f$ qubits be the number of qubits in @p qureg.
*
* - When @p qureg is a statevector @f$ \svpsi @f$, this function returns
* @f[
\sum\limits_i^{2^n} \langle i \svpsi \in \mathbb{C}.
* @f]
* - When @p qureg is a density matrix @f$ \dmrho @f$, this function returns
* @f[
\sum\limits_i^{2^n} \sum\limits_j^{2^n} \bra{i} \dmrho \ket{j} \in \mathbb{C}.
* @f]
*
* @myexample
* ```
Qureg qureg = createQureg(4);
initRandomPureState(qureg);

qcomp ampSum = calcAmpSum(qureg);
reportScalar("ampSum", ampSum);
* ```
*
* @see
* - calcRealAmpSum()

* @param[in] qureg the state with the processed amplitudes.
* @returns The the sum of all contained amplitudes.
* @throws @validationerror
* - if @p qureg is uninitialised.
* - if @p qureg contains an odd number of qubits.
* @author Tyson Jones
*/
qcomp calcAmpSum(Qureg qureg);


/// @ingroup calc_comparisons
/// @notdoced
/// @notvalidated
Expand Down
9 changes: 9 additions & 0 deletions quest/include/wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@
#ifndef __cplusplus


extern void _wrap_calcAmpSum(Qureg qureg, qcomp* out);

qcomp calcAmpSum(Qureg qureg) {

qcomp out;
_wrap_calcAmpSum(qureg, &out);
return out;
}


extern void _wrap_calcInnerProduct(Qureg bra, Qureg ket, qcomp* out);

Expand Down
28 changes: 28 additions & 0 deletions quest/src/api/calculations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ extern Qureg validateAndCreateCustomQureg(
*/


qcomp calcAmpSum(Qureg qureg) {
validate_quregFields(qureg, __func__);

return localiser_statevec_calcAmpSum(qureg);
}
extern "C" void _wrap_calcAmpSum(Qureg qureg, qcomp* out) {

*out = calcAmpSum(qureg);
}


qcomp calcInnerProduct(Qureg quregA, Qureg quregB) {
validate_quregFields(quregA, __func__);
validate_quregFields(quregB, __func__);
Expand Down Expand Up @@ -125,6 +136,23 @@ extern "C" {



/*
* PR DEMOS
*/


qreal calcRealAmpSum(Qureg qureg) {
validate_quregFields(qureg, __func__);
validate_quregHasEvenNumQubits(qureg, __func__);

// logic is identical for both statevectors and density matrices
qcomp value = localiser_statevec_calcAmpSum(qureg);

return std::real(value);
}



/*
* EXPECTED VALUES
*/
Expand Down
14 changes: 14 additions & 0 deletions quest/src/core/accelerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,20 @@ using std::min;



/*
* PR DEMOS
*/


qcomp accel_statevec_calcAmpSum(Qureg qureg) {

return (qureg.isGpuAccelerated)?
gpu_statevec_calcAmpSum(qureg):
cpu_statevec_calcAmpSum(qureg);
}



/*
* GETTERS
*/
Expand Down
7 changes: 7 additions & 0 deletions quest/src/core/accelerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ using std::vector;
name = compileval;


/*
* PR DEMOS
*/

qcomp accel_statevec_calcAmpSum(Qureg qureg);


/*
* GETTERS
*/
Expand Down
21 changes: 21 additions & 0 deletions quest/src/core/localiser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,27 @@ void exchangeAmpsToBuffersWhereQubitsAreInStates(Qureg qureg, int pairRank, vect



/*
* PR DEMOS
*/


qcomp localiser_statevec_calcAmpSum(Qureg qureg) {

// each node computes the sum of its local amps
// in an embarrassingly parallel fashion
qcomp out = accel_statevec_calcAmpSum(qureg);

// node partial sums are combined, and every
// node receives a copy of the full sum (consensus)
if (qureg.isDistributed)
comm_reduceAmp(&out);

return out;
}



/*
* GETTERS
*/
Expand Down
7 changes: 7 additions & 0 deletions quest/src/core/localiser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
using std::vector;


/*
* PR DEMOS
*/

qcomp localiser_statevec_calcAmpSum(Qureg qureg);


/*
* GETTERS
*/
Expand Down
23 changes: 23 additions & 0 deletions quest/src/core/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ using std::vector;
namespace report {


/*
* NONSENSE VALIDATION FOR DEMO PR
*/

string QUREG_HAS_ODD_NUM_QUBITS =
"The given Qureg contained ${NUM_QUBITS} qubits, but must contain an even number.";


/*
* ENVIRONMENT CREATION
*/
Expand Down Expand Up @@ -1306,6 +1314,21 @@ bool isIndexListUnique(int* list, int len) {



/*
* NONSENSE VALIDATION FOR DEMO PR
*/

void validate_quregHasEvenNumQubits(Qureg qureg, const char* caller) {

tokenSubs vars = {
{"${NUM_QUBITS}", qureg.numQubits}
};

assertThat(qureg.numQubits % 2 == 0, report::QUREG_HAS_ODD_NUM_QUBITS, vars, caller);
}



/*
* ENVIRONMENT CREATION
*/
Expand Down
8 changes: 8 additions & 0 deletions quest/src/core/validation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ qreal validateconfig_getEpsilon();



/*
* NONSENSE VALIDATION FOR DEMO PR
*/

void validate_quregHasEvenNumQubits(Qureg qureg, const char* caller);



/*
* ENVIRONMENT CREATION
*/
Expand Down
28 changes: 28 additions & 0 deletions quest/src/cpu/cpu_subroutines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,34 @@ using std::vector;



/*
* PR DEMOS
*/


qcomp cpu_statevec_calcAmpSum(Qureg qureg) {

// we brazenly perform this all-state reduction without
// a single thought to finite precision effects - arrest me!

// separately reduce real and imag components to make MSVC happy
qreal outRe = 0;
qreal outIm = 0;

// every local amplitude contributes to the sum
qindex numIts = qureg.numAmpsPerNode;

#pragma omp parallel for reduction(+:outRe,outIm) if(qureg.isMultithreaded)
for (qindex n=0; n<numIts; n++) {
outRe += std::real(qureg.cpuAmps[n]);
outIm += std::imag(qureg.cpuAmps[n]);
}

return qcomp(outRe, outIm);
}



/*
* GETTERS
*/
Expand Down
7 changes: 7 additions & 0 deletions quest/src/cpu/cpu_subroutines.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
using std::vector;


/*
* PR DEMOS
*/

qcomp cpu_statevec_calcAmpSum(Qureg qureg);


/*
* GETTERS
*/
Expand Down
26 changes: 26 additions & 0 deletions quest/src/gpu/gpu_subroutines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,32 @@ using std::vector;



/*
* PR DEMOS
*/


qcomp gpu_statevec_calcAmpSum(Qureg qureg) {

#if COMPILE_CUDA || COMPILE_CUQUANTUM

// there is no cuQuantum function for this facility,
// nor is there a need to implement a custom kernel;
// we will leverage an exting Thrust facility
cu_qcomp out = thrust_statevec_calcAmpSum(qureg);

// the GPU backend uses a CUDA-equivalent of 'qcomp'
// which we must cast back and forth between (ew!)
return toQcomp(out);

#else
error_gpuSimButGpuNotCompiled();
return -1;
#endif
}



/*
* GETTERS
*/
Expand Down
7 changes: 7 additions & 0 deletions quest/src/gpu/gpu_subroutines.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
using std::vector;


/*
* PR DEMOS
*/

qcomp gpu_statevec_calcAmpSum(Qureg qureg);


/*
* GETTERS
*/
Expand Down
Loading