QuEST-Kit / QuEST

A multithreaded, distributed, GPU-accelerated simulator of quantum computers
https://quest.qtechtheory.org/
MIT License
392 stars 135 forks source link

Quantum register questions and MBQC #352

Closed fieldofnodes closed 1 year ago

fieldofnodes commented 1 year ago

I am trying to understand how the Qureg is designed, namely what is meant by a state vector. Can I think of it as a vector of states per qubit?

For example, if I call

Qureg createQureg(int numQubits, QuESTEnv env)

I understand that internally we call the following

https://github.com/QuEST-Kit/QuEST/blob/23a0a088dfd76d89f3252bffabda0387e880cda6/QuEST/src/CPU/QuEST_cpu.c#L1296

In this line we start this function:

void statevec_createQureg(Qureg *qureg, int numQubits, QuESTEnv env)
{
    long long int numAmps = 1LL << numQubits;
    long long int numAmpsPerRank = numAmps/env.numRanks;

    validateMemoryAllocationSize(numAmpsPerRank, __func__);

    size_t arrSize = (size_t) (numAmpsPerRank * sizeof(*(qureg->stateVec.real)));
    qureg->stateVec.real = malloc(arrSize);
    qureg->stateVec.imag = malloc(arrSize);
    if (env.numRanks>1){
        qureg->pairStateVec.real = malloc(arrSize);
        qureg->pairStateVec.imag = malloc(arrSize);
    }

    qureg->numQubitsInStateVec = numQubits;
    qureg->numAmpsTotal = numAmps;
    qureg->numAmpsPerChunk = numAmpsPerRank;
    qureg->chunkId = env.rank;
    qureg->numChunks = env.numRanks;
    qureg->isDensityMatrix = 0;

    validateQuregAllocation(qureg, env, __func__);
}

I assume that when we call sizeof(*(qureg->stateVec.real))) we are getting an integer which is the number of real elements in qureg->stateVec. Is this true?

The reason why I ask is I am working on using QuEST to do MBQC simulation and I think I need to initialise my MBQC graph through a single quantum register.

This brings me to my next question, when I measure a specific qubit, does QuEST project onto the existing quantum state a subspace as a result of that measurement?

Is this the best place to ask questions to the developers?

TysonRayJones commented 1 year ago

In C, sizeof(*array) will return the number of bytes dedicated to each element of array (because * deferences array to its first element type). Ergo,

numArrayElems * sizeof(*array)

yields the total memory size (in bytes) of the array.

Our statevector is a collection of complex amplitudes, but their real and imaginary components are stored in separate arrays. The i-th local amplitude is ergo represented with two floating point numbers; stateVec.real[i] and stateVec.imag[i]. When QuEST is run in distributed mode, each of env.numRanks computers store a uniform subset of the full collection of amplitudes; numAmpsPerRank.

The line

size_t arrSize = (size_t) (numAmpsPerRank * sizeof(*(qureg->stateVec.real)));

therefore evaluates the memory size (in bytes) of each of a single computer's stateVec.real and stateVec.imag arrays.

Yep, QuEST's measure function is destructive.

fieldofnodes commented 1 year ago

Thank you for the information. I am newish to C/C++ and there are certain fundamentals that I lack. Thank you. I am happy for this to be closed. Do you want me to do this?