]> foleosoft.com Git - QAnsel.git/commitdiff
Sun Mar 10 06:43:42 AM EDT 2024
authormiha-q <>
Sun, 10 Mar 2024 10:43:42 +0000 (06:43 -0400)
committermiha-q <>
Sun, 10 Mar 2024 10:43:42 +0000 (06:43 -0400)
src/bytecode.c

index 63cf248ae3c1ec5a40142da47e659753cafa9251..ffc0a59f4d552049d710e5bcdad8ef26bd302e77 100644 (file)
@@ -195,6 +195,74 @@ float* qansel_unitary(float theta, float phi, float lambda)
        return m.ptr;
 }
 
+void qansel_queue_init
+(
+       cpx_mtx_t* queueVectors,
+       int qubitCount,
+       int dofree
+)
+{
+       for (int i = 0; i < qubitCount; i++)
+       {
+               if (dofree) free(queueVectors[i].ptr);
+               int vectLen = queueVectors[i].rows * (queueVectors[i].cols * 2) + queueVectors[i].cols * 2;
+               queueVectors[i].rows = 2;
+               queueVectors[i].cols = 2;
+               queueVectors[i].ptr = malloc(vectLen);
+               memcpy(queueVectors[i].ptr, Identity, vectLen);
+       }
+}
+
+void qansel_instruction_queue
+(
+       cpx_mtx_t** queueVectors,
+       int qubitCount,
+       unsigned char instr,
+       unsigned char index, 
+       float arg0,
+       float arg1,
+       float arg2
+)
+{
+       cpx_mtx_t gate, tmp;
+       gate.rows = 2;
+       gate.cols = 2;
+       float* gate_ptr;
+       int needToFreeGate = 0;
+       switch (instr)
+       {
+               case QANSEL_INSTRUCTION_H: gate_ptr = Hadamard; break;
+               case QANSEL_INSTRUCTION_X: gate_ptr = PauliX; break;
+               case QANSEL_INSTRUCTION_Y: gate_ptr = PauliY; break;
+               case QANSEL_INSTRUCTION_Z: gate_ptr = PauliZ; break;
+               case QANSEL_INSTRUCTION_S: gate_ptr = PhaseS; break;
+               case QANSEL_INSTRUCTION_T: gate_ptr = PhaseT; break;
+               case QANSEL_INSTRUCTION_RX:
+               case QANSEL_INSTRUCTION_RY:
+               case QANSEL_INSTRUCTION_RZ:
+               case QANSEL_INSTRUCTION_U1:
+               case QANSEL_INSTRUCTION_U2:
+               case QANSEL_INSTRUCTION_U3:
+                       gate_ptr = qansel_unitary(arg0, arg1, arg2);
+                       needToFreeGate = 1;
+                       break;
+               default: gate_ptr = Identity; break;
+       }
+       unsigned char qubit = qubitCount - (index) - 1;
+       gate.rows = 2;
+       gate.cols = 2;
+       gate.ptr = gate_ptr;
+       tmp.rows = 1;
+       tmp.cols = 2;
+       tmp.ptr = malloc(tmp.rows * (tmp.cols * 2) * sizeof(float));
+       cpx_mtx_dot(tmp.ptr, queueVectors[index]->ptr, gate_ptr, queueVectors[index]->rows, queueVectors[index]->cols, 2, 2);
+       free(queueVectors[index]->ptr);
+       queueVectors[index]->rows = tmp.rows;
+       queueVectors[index]->cols = tmp.cols;
+       queueVectors[index]->ptr = tmp.ptr;
+       if (needToFreeGate) free(gate);
+}
+
 void qansel_instruction
 (
        cpx_mtx_t* stateVector,
@@ -203,14 +271,19 @@ void qansel_instruction
        unsigned char index, 
        float arg0,
        float arg1,
-       float arg2
+       float arg2,
+       //if using gate queueing
+       cpx_mtx_t* queueVectors,
+       int queueStatus
 )
 {
+       if (queueStatus == 0) queueVectors = NULL;
        cpx_mtx_t tmp;
        cpx_mtx_t gate;
        gate.rows = 2;
        gate.cols = 2;
        float* gate_ptr;
+       int needToFreeGate = 0;
        switch (instr)
        {
                case QANSEL_INSTRUCTION_H: gate_ptr = Hadamard; break;
@@ -226,6 +299,7 @@ void qansel_instruction
                case QANSEL_INSTRUCTION_U2:
                case QANSEL_INSTRUCTION_U3:
                        gate_ptr = qansel_unitary(arg0, arg1, arg2);
+                       needToFreeGate = 1;
                        break;
                default: gate_ptr = Identity; break;
        }
@@ -233,19 +307,23 @@ void qansel_instruction
        cpx_t n;
        cpx_mtx_t filter;
        cpx_mtx_init(&filter, 2, 2);
-       unsigned char qubit = qubitCount - (index) - 1;
-       if (qubit == 0)
+       unsigned char qubit = qubitCount - (queueVectors == NULL ? index : 0) - 1;
+       if (qubit == 0 && queueVectors == NULL)
        {
                memcpy(filter.ptr, gate_ptr, 8 * sizeof(float));
        }
-       else
+       else if (queueVectors == NULL)
        {
                memcpy(filter.ptr, Identity, 8 * sizeof(float));
        }
+       else
+       {
+               memcpy(filter.ptr, queueVectors[0].ptr, 8 * sizeof(float));
+       }
 
        for (unsigned char i = 1; i < qubitCount; i++)
        {
-               if (index != 0x0F)
+               if (index != 0x0F && queueVectors == NULL)
                {
                        if (qubit == i)
                        {
@@ -256,10 +334,14 @@ void qansel_instruction
                                gate.ptr = Identity;
                        }
                }
-               else
+               else if (queueVectors == NULL)
                {
                        gate.ptr = gate_ptr;
                }
+               else
+               {
+                       gate.ptr = queueVectors[i].ptr;
+               }
 
                tmp.rows = filter.rows * gate.rows;
                tmp.cols = filter.cols * gate.cols;
@@ -352,10 +434,7 @@ void qansel_instruction
        free(stateVector->ptr);
        stateVector->ptr = tmp.ptr;
        free(filter.ptr);
-       if (instr == QANSEL_INSTRUCTION_U1 || instr == QANSEL_INSTRUCTION_U2 || instr == QANSEL_INSTRUCTION_U3)
-       {
-               free(gate_ptr);
-       }
+       if (needToFreeGate) free(gate_ptr);
 }
 
 unsigned char qansel_measure(cpx_mtx_t* stateVector, unsigned char qubitCount, unsigned char qubit)
@@ -717,7 +796,7 @@ void qansel_reset(cpx_mtx_t* stateVector, unsigned char* bitVector, int qubitCou
                unsigned char bit = qansel_measure(stateVector, qubitCount, q0);
                if (bit)
                {
-                       qansel_instruction(stateVector, qubitCount, QANSEL_INSTRUCTION_X, q0, 0, 0, 0);
+                       qansel_instruction(stateVector, qubitCount, QANSEL_INSTRUCTION_X, q0, 0, 0, 0, NULL, 0);
                }
        }
        else if (q0 >= 0x10 && q0 <= 0x1D)
@@ -795,13 +874,25 @@ int qansel_crawl(unsigned char* program, int programSize, int* qubitCount, int*
 
 void qansel_run(unsigned char* program, int programSize, int qubitCount, int bitCount, unsigned char* outputBitVector)
 {
+       int useQueue = 0;
        int PC = 0;
        unsigned int qubitCountPow2 = (unsigned int)pow(2, qubitCount);
        unsigned char bitVector[bitCount];
        memset(bitVector, 0, bitCount);
        cpx_mtx_t stateVector;
+       cpx_mtx_t* queueVector = NULL;
+       int queueStatus = 0;
        cpx_mtx_init(&stateVector, 1, qubitCountPow2);
        cpx_mtx_set2(&stateVector, 0, 0, 1, 0);
+       if (useQueue)
+       {
+               queueVector = malloc(qubitCount * sizeof(cpx_mtx_t));
+               for (int i = 0; i < qubitCount; i++)
+               {
+                       cpx_mtx_init(&(queueVector[i]), 1, 2);
+                       cpx_mtx_set2(&(queueVector[i]), 0, 0, 1, 0);
+               }
+       }
        if (QANSEL_USE_DISPLAY) { QANSEL_USE_DISPLAY = display(&stateVector, qubitCount, QANSEL_USE_DISPLAY); }
        unsigned char skip = 0, a0 = 0, a1 = 0, a2 = 0;
        unsigned char flags = 0;
@@ -831,14 +922,15 @@ void qansel_run(unsigned char* program, int programSize, int qubitCount, int bit
                                case QANSEL_INSTRUCTION_S:
                                case QANSEL_INSTRUCTION_T:
                                        a0 = program[PC + 1];
-                                       qansel_instruction(&stateVector, qubitCount, instr, program[PC + 1], 0, 0, 0);
+                                       qansel_instruction(&stateVector, qubitCount, instr, program[PC + 1], 0, 0, 0, queueVector, queueStatus);
                                        break;
                                case QANSEL_INSTRUCTION_RX:
                                        a0 = program[PC + 1];
                                        qansel_instruction
                                        (
                                                &stateVector, qubitCount, instr, a0,
-                                               M_PI / 2, -M_PI / 2, qansel_get_float(program, PC + 2) - (M_PI / 2)
+                                               M_PI / 2, -M_PI / 2, qansel_get_float(program, PC + 2) - (M_PI / 2),
+                                               queueVector, queueStatus
                                        );
                                        break;
                                case QANSEL_INSTRUCTION_RY:
@@ -847,7 +939,8 @@ void qansel_run(unsigned char* program, int programSize, int qubitCount, int bit
                                        qansel_instruction
                                        (
                                                &stateVector, qubitCount, instr, a0,
-                                               qansel_get_float(program, PC + 2), 0, 0
+                                               qansel_get_float(program, PC + 2), 0, 0,
+                                               queueVector, queueStatus
                                        );
                                        break;
                                case QANSEL_INSTRUCTION_RZ:
@@ -855,7 +948,8 @@ void qansel_run(unsigned char* program, int programSize, int qubitCount, int bit
                                        qansel_instruction
                                        (
                                                &stateVector, qubitCount, instr, a0,
-                                               0, 0, qansel_get_float(program, PC + 2)
+                                               0, 0, qansel_get_float(program, PC + 2),
+                                               queueVector, queueStatus
                                        );
                                        break;
                                case QANSEL_INSTRUCTION_U2:
@@ -865,7 +959,7 @@ void qansel_run(unsigned char* program, int programSize, int qubitCount, int bit
                                                &stateVector, qubitCount, instr, a0,
                                                qansel_get_float(program, PC + 2), 
                                                qansel_get_float(program, PC + 2 + sizeof(float)),
-                                               0
+                                               0, queueVector, queueStatus
                                        );
                                        break;
                                case QANSEL_INSTRUCTION_U3:
@@ -875,7 +969,8 @@ void qansel_run(unsigned char* program, int programSize, int qubitCount, int bit
                                                &stateVector, qubitCount, instr, a0,
                                                qansel_get_float(program, PC + 2), 
                                                qansel_get_float(program, PC + 2 + sizeof(float)),
-                                               qansel_get_float(program, PC + 2 + sizeof(float) * 2)
+                                               qansel_get_float(program, PC + 2 + sizeof(float) * 2),
+                                               queueVector, queueStatus
                                        );
                                        break;
                                case QANSEL_INSTRUCTION_CX:
@@ -985,6 +1080,14 @@ void qansel_run(unsigned char* program, int programSize, int qubitCount, int bit
                }
        }
        cpx_mtx_free(&stateVector);
+       if (useQueue)
+       {
+               for (int i = 0; i < qubitCount; i++)
+               {
+                       cpx_mtx_free(&(queueVector[i]));
+               }
+               free(queueVector);
+       }
        if (QANSEL_USE_DISPLAY) { display(NULL, 0, 0); }
 
 }