From 9ceef8393a0bd54bdfa41ec13438b67d2836490c Mon Sep 17 00:00:00 2001 From: miha-q <> Date: Mon, 18 Mar 2024 19:31:21 -0400 Subject: [PATCH] Mon Mar 18 07:31:21 PM EDT 2024 --- examples/bb84.txt | 2 +- examples/encryption.txt | 2 +- examples/reordering.txt | 13 +++++++++++++ src/bytecode.c | 42 ++++++++++++++++++++++------------------- src/context.c | 4 ++-- src/main.c | 6 +++++- src/openqasm.c | 12 ++++++++---- src/qansel.h | 2 +- 8 files changed, 54 insertions(+), 29 deletions(-) create mode 100644 examples/reordering.txt diff --git a/examples/bb84.txt b/examples/bb84.txt index 60a44b3..d0cfe17 100644 --- a/examples/bb84.txt +++ b/examples/bb84.txt @@ -15,7 +15,7 @@ h q[1]; //The first should now be random noise // while the second unmeasured one // should be 0 -born; +born q; //In a full BB84 Alice would randomly // apply the gate or not apply the diff --git a/examples/encryption.txt b/examples/encryption.txt index 806578b..51f2460 100644 --- a/examples/encryption.txt +++ b/examples/encryption.txt @@ -29,5 +29,5 @@ cx q[3], q[7]; measure q[6] -> c[6]; measure q[7] -> c[7]; -print c; +sample c; diff --git a/examples/reordering.txt b/examples/reordering.txt new file mode 100644 index 0000000..2c23251 --- /dev/null +++ b/examples/reordering.txt @@ -0,0 +1,13 @@ +qreg q[13]; + +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; +h q[12]; cx q[1], q[2]; diff --git a/src/bytecode.c b/src/bytecode.c index 6db18a8..dd434ec 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1184,21 +1184,26 @@ void qansel_reorder(QAnselContext* ctx, unsigned char* program, int programSize) free(reordered[i]); } - int copyloc = 0; - for (int i = 0; i < ramInstrLen; i++) + if (best > efficiency) { - int next; - if (ramInstr[i].use_ifop) + int copyloc = 0; + besti = head[besti]; + for (int i = 0; i < ramInstrLen; i++) { - next = qansel_get_instruction_size(ramInstr[i].ifop[0]); - memcpy(program + copyloc, ramInstr[i].ifop, next); + int next; + if (ramInstr[besti].use_ifop) + { + next = qansel_get_instruction_size(ramInstr[besti].ifop[0]); + memcpy(program + copyloc, ramInstr[besti].ifop, next); + copyloc += next; + } + next = qansel_get_instruction_size(ramInstr[besti].op); + memcpy(program + copyloc, ramInstr[besti].bytes, next); + besti = ramInstr[besti].next; copyloc += next; } - next = qansel_get_instruction_size(ramInstr[i].op); - memcpy(program + copyloc, ramInstr[i].bytes, next); - copyloc += next; } - + if (ctx->verbose) { if (best > efficiency) @@ -1214,7 +1219,7 @@ void qansel_reorder(QAnselContext* ctx, unsigned char* program, int programSize) void qansel_run(QAnselContext* ctx, unsigned char* program, int programSize, int qubitCount, int bitCount, unsigned char* outputBitVector) { - int useQueue = ((ctx->optimization_level) & QANSEL_MODE_QUEUE) ? 1 : 0; + int useQueue = ((ctx->optimization_level) & QANSEL_MODE_SMART) ? 1 : 0; int PC = 0; unsigned int qubitCountPow2 = (unsigned int)pow(2, qubitCount); unsigned char bitVector[bitCount]; @@ -1252,10 +1257,6 @@ void qansel_run(QAnselContext* ctx, unsigned char* program, int programSize, int else { unsigned char instr = program[PC]; - //printf("-----------------------------------\n"); - //qansel_density_or_print(&stateVector, bitVector, 0, bitCount, qubitCount, QANSEL_ALL_QUANTUM); - //qansel_density_or_print(&stateVector, bitVector, 0, bitCount, qubitCount, QANSEL_ALL_CLASSIC); - //printf("%s(%i, %i, %i)(%f, %f, %f)\n", qansel_instruction_to_string(instr), program[PC+1], program[PC+2], program[PC], qansel_get_float(program, PC + 2), qansel_get_float(program, PC + 2 + sizeof(float)), qansel_get_float(program, PC + 2) + sizeof(float) * 2); //flush the queue if any non-single qubit instructions are called if (useQueue) @@ -1284,12 +1285,15 @@ void qansel_run(QAnselContext* ctx, unsigned char* program, int programSize, int case QANSEL_INSTRUCTION_IF_LE: break; default: - qansel_instruction(ctx, &stateVector, qubitCount, instr, 0, 0, 0, 0, &queueVector); - for (int i = 0; i < qubitCount; i++) + if (!queueFlushed) { - memcpy(queueVector[i].ptr, Identity, sizeof(Identity)); + qansel_instruction(ctx, &stateVector, qubitCount, instr, 0, 0, 0, 0, &queueVector); + for (int i = 0; i < qubitCount; i++) + { + memcpy(queueVector[i].ptr, Identity, sizeof(Identity)); + } + queueFlushed = 1; } - queueFlushed = 1; break; } } diff --git a/src/context.c b/src/context.c index 27528ce..e25abc8 100644 --- a/src/context.c +++ b/src/context.c @@ -17,7 +17,7 @@ int qanselContextValidate(QAnselContext* ctx) fprintf(stderr, "QAnsel: Invalid display settings.\n"); return 0; } - if (ctx->optimization_level < QANSEL_MODE_BARE || ctx->optimization_level > (QANSEL_MODE_THREADED | QANSEL_MODE_METAL | QANSEL_MODE_QUEUE)) + if (ctx->optimization_level < QANSEL_MODE_BARE || ctx->optimization_level > (QANSEL_MODE_THREADED | QANSEL_MODE_METAL | QANSEL_MODE_SMART)) { fprintf(stderr, "QAnsel: Invalid optimization settings.\n"); return 0; @@ -58,7 +58,7 @@ int qanselContextBegin(QAnselContext* ctx) fprintf(stderr, "QAnsel: Invalid display settings.\n"); return 0; } - if (ctx->optimization_level < QANSEL_MODE_BARE || ctx->optimization_level > (QANSEL_MODE_THREADED | QANSEL_MODE_METAL | QANSEL_MODE_QUEUE)) + if (ctx->optimization_level < QANSEL_MODE_BARE || ctx->optimization_level > (QANSEL_MODE_THREADED | QANSEL_MODE_METAL | QANSEL_MODE_SMART)) { fprintf(stderr, "QAnsel: Invalid optimization settings.\n"); return 0; diff --git a/src/main.c b/src/main.c index 675640c..e9fe93b 100644 --- a/src/main.c +++ b/src/main.c @@ -23,7 +23,7 @@ void display_help() printf(" -o1 Enables multithreading.\n"); printf(" -o2 Enables hardware acceleration (GPU).\n"); printf(" -o3 Combines -o1 and -o2.\n"); - printf(" -o4 Enables instruction queueing.\n"); + printf(" -o4 Enables smart optimizations.\n"); printf(" -o5 Combines -o1 and -o4.\n"); printf(" -o6 Combines -o2 and -o4.\n"); printf(" -o7 Combines -o3 and -o4.\n"); @@ -68,6 +68,10 @@ void main(int argc, char** argv) if (!qanselContextBegin(&ctx)) exit(1); if (qanselBuildFromSource(script, &bytecode, &bytecodeSize, &ctx)) { + for (int i = 0; i < bytecodeSize; i += qansel_get_instruction_size(bytecode[i])) + { + printf("%s(%i,%i)\n", qansel_instruction_to_string(bytecode[i]), bytecode[i + 1], bytecode[i + 2]); + } qanselExecuteBytecode(bytecode, bytecodeSize, &ctx); free(bytecode); } diff --git a/src/openqasm.c b/src/openqasm.c index 24b65bc..1cad5e1 100644 --- a/src/openqasm.c +++ b/src/openqasm.c @@ -476,7 +476,7 @@ int qansel_process_chunk(int index, char* chunk, int line, regmatch_t* regmatche } if (instr == 0x00) //sample { - if (a0 == QANSEL_ALL_QUANTUM) a0 = QANSEL_ALL; + if (a0 == QANSEL_ALL_CLASSIC) a0 = QANSEL_ALL; else a0 = a0 - QANSEL_CBOUND_LOWER; ctx->sampling_bit = a0; ctx->sampling_shots = samplingshots; @@ -722,6 +722,7 @@ int qansel_process_chunks(char** chunks, int* associatedLines, int count, unsign if (regcomp(®ex, regexes[j], REG_EXTENDED | REG_ICASE)) { printf("QAnsel: Regex fatal error.\n"); + free(binary); return 0; } ret = regexec(®ex, chunks[i], 10, regmatches, 0); @@ -737,6 +738,7 @@ int qansel_process_chunks(char** chunks, int* associatedLines, int count, unsign { regerror(ret, ®ex, errbuf, sizeof(errbuf)); fprintf(stderr, "QAnsel: %s.\n", errbuf); + free(binary); return 0; } } @@ -744,6 +746,7 @@ int qansel_process_chunks(char** chunks, int* associatedLines, int count, unsign if (!found) { fprintf(stderr, "QAnsel on line %i: Invalid syntax.\n", associatedLines[i]); + free(binary); return 0; } } @@ -770,11 +773,12 @@ int qanselBuildFromSource(char* source, unsigned char** binary, int* binarySize, if (!status) { *binarySize = 0; - free(*binary); return 0; } - - //qansel_reorder(ctx, *binary, *binarySize); + if (ctx->optimization_level & QANSEL_MODE_SMART) + { + qansel_reorder(ctx, *binary, *binarySize); + } return 1; } diff --git a/src/qansel.h b/src/qansel.h index 875e169..530c139 100644 --- a/src/qansel.h +++ b/src/qansel.h @@ -24,7 +24,7 @@ #define QANSEL_MODE_BARE 0 #define QANSEL_MODE_THREADED 1 #define QANSEL_MODE_METAL 2 -#define QANSEL_MODE_QUEUE 4 +#define QANSEL_MODE_SMART 4 //#define SPEED_TEST #define QANSEL_HARDWARE_NONE 0 -- 2.39.5