From: miha-q <> Date: Sun, 10 Mar 2024 10:43:42 +0000 (-0400) Subject: Sun Mar 10 06:43:42 AM EDT 2024 X-Git-Url: http://www.foleosoft.com/?a=commitdiff_plain;h=ff43cf5baad29659684baa90027beae76badc870;p=QAnsel.git Sun Mar 10 06:43:42 AM EDT 2024 --- diff --git a/src/bytecode.c b/src/bytecode.c index 63cf248..ffc0a59 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -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); } }