static void como_compile_ast(ast_node *p, const char *filename) { Object *main_code = newArray(4); global_frame = create_frame(main_code); global_frame->filename = newString(filename); mapInsertEx(global_frame->cf_symtab, "__FUNCTION__", newString("__main__")); (void)como_compile(p, global_frame); arrayPushEx(main_code, newPointer((void *)create_op(HALT, NULL))); (void)como_execute(global_frame, NULL); }
static void como_compile(ast_node* p, ComoFrame *frame) { assert(p); switch(p->type) { default: printf("%s(): invalid node type(%d)\n", __func__, p->type); exit(1); break; case AST_NODE_TYPE_STRING: arrayPushEx(frame->code, newPointer((void *)create_op(LOAD_CONST, newString(p->u1.string_value.value)))); break; case AST_NODE_TYPE_PRINT: como_compile(p->u1.print_node.expr, frame); arrayPushEx(frame->code, newPointer((void *)create_op(IPRINT, NULL))); break; case AST_NODE_TYPE_NUMBER: arrayPushEx(frame->code, newPointer((void *)create_op(LOAD_CONST, newLong((long)p->u1.number_value)))); break; case AST_NODE_TYPE_ID: arrayPushEx(frame->code, newPointer((void *)create_op(LOAD_NAME, newString(p->u1.string_value.value)))); break; case AST_NODE_TYPE_RET: if(p->u1.return_node.expr != NULL) { como_compile(p->u1.return_node.expr, frame); arrayPushEx(frame->code, newPointer((void *)create_op(IRETURN, newLong(1L)))); } else { arrayPushEx(frame->code, newPointer((void *)create_op(IRETURN, newLong(0L)))); } break; case AST_NODE_TYPE_STATEMENT_LIST: { size_t i; for(i = 0; i < p->u1.statements_node.count; i++) { ast_node* stmt = p->u1.statements_node.statement_list[i]; como_compile(stmt, frame); } } break; case AST_NODE_TYPE_WHILE: { Object *l = newLong((long)(O_AVAL(frame->code)->size)); arrayPushEx(frame->code, newPointer((void *)create_op(LABEL, l))); Object *l2 = newLong(0); como_compile(p->u1.while_node.condition, frame); arrayPushEx(frame->code, newPointer((void *)create_op(JZ, l2))); como_compile(p->u1.while_node.body, frame); arrayPushEx(frame->code, newPointer((void *)create_op(JMP, newLong(O_LVAL(l))))); Object *l3 = newLong((long)(O_AVAL(frame->code)->size)); arrayPushEx(frame->code, newPointer((void *)create_op(LABEL, l3))); O_LVAL(l2) = O_LVAL(l3); } break; case AST_NODE_TYPE_FOR: { Object *l = newLong((long)(O_AVAL(frame->code)->size)); arrayPushEx(frame->code, newPointer((void *)create_op(LABEL, l))); Object *l2 = newLong(0); como_compile(p->u1.for_node.initialization, frame); como_compile(p->u1.for_node.condition, frame); arrayPushEx(frame->code, newPointer((void *)create_op(JZ, l2))); Object *l4 = newLong((long)(O_AVAL(frame->code)->size)); /* label for the body */ arrayPushEx(frame->code, newPointer((void *)create_op(LABEL, l4))); como_compile(p->u1.for_node.body, frame); como_compile(p->u1.for_node.final_expression, frame); como_compile(p->u1.for_node.condition, frame); arrayPushEx(frame->code, newPointer((void *)create_op(JZ, l2))); arrayPushEx(frame->code, newPointer((void *)create_op(JMP, newLong(O_LVAL(l4))))); Object *l3 = newLong((long)(O_AVAL(frame->code)->size)); arrayPushEx(frame->code, newPointer((void *)create_op(LABEL, l3))); O_LVAL(l2) = O_LVAL(l3); } break; case AST_NODE_TYPE_IF: { Object *l2 = newLong(0); Object *l4 = newLong(0); como_compile(p->u1.if_node.condition, frame); arrayPushEx(frame->code, newPointer((void *)create_op(JZ, l2))); como_compile(p->u1.if_node.b1, frame); arrayPushEx(frame->code, newPointer((void *)create_op(JMP, l4))); Object *l3 = newLong((long)(O_AVAL(frame->code)->size)); arrayPushEx(frame->code, newPointer((void *)create_op(LABEL, l3))); if(p->u1.if_node.b2 != NULL) { como_compile(p->u1.if_node.b2, frame); } O_LVAL(l2) = O_LVAL(l3); O_LVAL(l4) = (long)(O_AVAL(frame->code)->size); arrayPushEx(frame->code, newPointer((void *)create_op(LABEL, newLong((long)(O_AVAL(frame->code)->size))))); } break; case AST_NODE_TYPE_FUNC_DECL: { const char *name = p->u1.function_node.name; Object *func_decl = newArray(4); Object *func_decl_parameters = newArray(2); ComoFrame *func_decl_frame = create_frame(func_decl); func_decl_frame->namedparameters = func_decl_parameters; if(frame->filename != NULL) { func_decl_frame->filename = copyObject(frame->filename); } else { func_decl_frame->filename = newString("<unknown>"); } size_t i; ast_node_statements *parameters = &p->u1.function_node .parameter_list->u1 .statements_node; for(i = 0; i < parameters->count; i++) { arrayPushEx(func_decl_parameters, newString( AST_NODE_AS_ID( parameters->statement_list[i] ) ) ); } arrayPushEx(func_decl_frame->code, newPointer((void *)create_op(LOAD_CONST, newString(name)))); arrayPushEx(func_decl_frame->code, newPointer((void *)create_op(STORE_NAME, newString("__FUNCTION__")))); como_compile(p->u1.function_node.body, func_decl_frame); Array *temp = O_AVAL(func_decl_frame->code); Object *temp2 = temp->table[temp->size - 1]; ComoOpCode *opcode = (ComoOpCode *)(O_PTVAL(temp2)); if(opcode->op_code != IRETURN) { //como_debug("automatically inserting IRETURN for function %s", name); arrayPushEx(func_decl_frame->code, newPointer( (void *)create_op(LOAD_CONST, newLong(0L)))); arrayPushEx(func_decl_frame->code, newPointer( (void *)create_op(IRETURN, newLong(1L)))); } mapInsertEx(global_frame->cf_symtab, name, newPointer( (void *)func_decl_frame)); break; } case AST_NODE_TYPE_CALL: { const char *name = p->u1.call_node.id->u1.id_node.name; const long argcount = (long)p->u1 .call_node .arguments->u1 .statements_node .count; como_compile(p->u1.call_node.arguments, frame); arrayPushEx(frame->code, newPointer( (void *)create_op(LOAD_CONST, newLong(argcount)))); arrayPushEx(frame->code, newPointer( (void *)create_op(LOAD_NAME, newString(name)))); arrayPushEx(frame->code, newPointer( (void *)create_op(CALL_FUNCTION, newString(name)))); break; } case AST_NODE_TYPE_POSTFIX: { Object *name = newString(AST_NODE_AS_ID(p->u1.postfix_node.expr)); switch(p->u1.postfix_node.type) { case AST_POSTFIX_OP_INC: arrayPushEx(frame->code, newPointer( (void *)create_op(POSTFIX_INC, name))); break; case AST_POSTFIX_OP_DEC: arrayPushEx(frame->code, newPointer( (void *)create_op(POSTFIX_DEC, name))); break; } break; } case AST_NODE_TYPE_UNARY_OP: { switch(p->u1.unary_node.type) { case AST_UNARY_OP_MINUS: como_compile(p->u1.unary_node.expr, frame); arrayPushEx(frame->code, newPointer( (void *)create_op(UNARY_MINUS, NULL))); break; } } break; case AST_NODE_TYPE_BIN_OP: { if(p->u1.binary_node.type != AST_BINARY_OP_ASSIGN) { como_compile(p->u1.binary_node.left, frame); como_compile(p->u1.binary_node.right, frame); } switch(p->u1.binary_node.type) { case AST_BINARY_OP_REM: arrayPushEx(frame->code, newPointer( (void *)create_op(IREM, NULL))); break; case AST_BINARY_OP_LTE: arrayPushEx(frame->code, newPointer( (void *)create_op(IS_LESS_THAN_OR_EQUAL, NULL))); break; case AST_BINARY_OP_GTE: arrayPushEx(frame->code, newPointer( (void *)create_op(IS_GREATER_THAN_OR_EQUAL, NULL))); break; case AST_BINARY_OP_LT: arrayPushEx(frame->code, newPointer( (void *)create_op(IS_LESS_THAN, NULL))); break; case AST_BINARY_OP_GT: arrayPushEx(frame->code, newPointer( (void *)create_op(IS_GREATER_THAN, NULL))); break; case AST_BINARY_OP_CMP: arrayPushEx(frame->code, newPointer( (void *)create_op(IS_EQUAL, NULL))); break; case AST_BINARY_OP_NEQ: arrayPushEx(frame->code, newPointer( (void *)create_op(IS_NOT_EQUAL, NULL))); break; case AST_BINARY_OP_MINUS: arrayPushEx(frame->code, newPointer( (void *)create_op(IMINUS, NULL))); break; case AST_BINARY_OP_DIV: arrayPushEx(frame->code, newPointer( (void *)create_op(IDIV, NULL))); break; case AST_BINARY_OP_ADD: arrayPushEx(frame->code, newPointer( (void *)create_op(IADD, NULL))); break; case AST_BINARY_OP_TIMES: arrayPushEx(frame->code, newPointer( (void *)create_op(ITIMES, NULL))); break; case AST_BINARY_OP_ASSIGN: como_compile(p->u1.binary_node.right, frame); arrayPushEx(frame->code, newPointer( (void *)create_op(STORE_NAME, newString( p->u1.binary_node.left->u1.id_node.name)))); break; } } break; } }
int main(int argc,char **args){ PetscReal time_max,dt,*gamma_1,*gamma_2; PetscReal gate_time_step,theta,fidelity,t1,t2; PetscScalar mat_val; PetscInt steps_max,num_qubits; Vec rho,rho_base,rho_base2,rho_base3; int i,j,h_dim,system,dm_place,logical_qubits,prev_qb,prev_qb2,num_qubits2; circuit qiskit_read; Mat encoder_mat; char string[10],filename[128]; stabilizer S1,S2,S3,S4; PetscReal *r_str,gam,dep,noise; char encoder_str[128]; encoder_type encoder_type0,encoder_type1,encoder_type2,encoder_type3; struct quantum_gate_struct *gate_list; /* Initialize QuaC */ QuaC_initialize(argc,args); num_qubits = 0; strcpy(filename,"NULL"); PetscOptionsGetString(NULL,NULL,"-file_circ",filename,sizeof(filename),NULL); qiskit_qasm_read(filename,&num_qubits,&qiskit_read); strcpy(filename,"NULL"); PetscOptionsGetString(NULL,NULL,"-file_ev",filename,sizeof(filename),NULL); qubits = malloc(num_qubits*sizeof(struct operator)); gamma_1 = malloc(num_qubits*sizeof(PetscReal)); gamma_2 = malloc(num_qubits*sizeof(PetscReal)); for (i=0;i<num_qubits;i++){ create_op(2,&qubits[i]); gamma_1[i] = 0; gamma_2[i] = 0; printf("MY_OP_TYPE op %d qubits[i]->dag %d qubits[i]->dag->dag %d\n",qubits[i]->my_op_type,qubits[i]->dag->my_op_type,qubits[i]->dag->dag->my_op_type); } gam = 1.0; dep = 1.0; noise = 0; PetscOptionsGetReal(NULL,NULL,"-noise",&noise,NULL); for (i=0; i<num_qubits;i++){ gamma_1[i] = gam*noise; gamma_2[i] = dep*noise; } //Add lindblad terms for (i=0;i<num_qubits;i++){ if (gamma_1[i]>0){ //Spontaneous emission add_lin(gamma_1[i],qubits[i]); } if (gamma_2[i]>0){ //Dephasing add_lin(gamma_2[i],qubits[i]->n); } } time_max = qiskit_read.num_gates + 1; dt = 1; steps_max = 10000000; /* Set the ts_monitor to print results at each time step */ set_ts_monitor(ts_monitor); /* Open file that we will print to in ts_monitor */ if (nid==0){ f_pop = fopen("pop","w"); fprintf(f_pop,"#Time Populations\n"); } create_full_dm(&rho); mat_val = 1.0; add_value_to_dm(rho,0,0,mat_val); assemble_dm(rho); if (nid==0){ printf("num_gates: %ld \n",qiskit_read.num_gates); } start_circuit_at_time(&qiskit_read,0.0); time_step(rho,0.0,time_max,dt,steps_max); /* get_expectation_value(rho,&mat_val,2,qubits[0]->sig_z,qubits[0]->sig_z); */ qiskit_vqe_get_expectation(filename,rho,&mat_val); if (nid==0) printf("Energy: %.18lf\n",PetscRealPart(mat_val)); //print_psi(rho,16); for (i=0;i<num_qubits;i++){ destroy_op(&qubits[i]); } destroy_dm(rho); QuaC_finalize(); return 0; }
int main(int argc,char **args){ PetscReal time_max,dt,*gamma_1,*gamma_2; PetscScalar mat_val; PetscInt steps_max,num_qubits; int i; Vec rho; circuit projectq_read; char string[10],filename[128],file_dm[128]; /* Initialize QuaC */ QuaC_initialize(argc,args); num_qubits = 0; /* Get the encoding strategies for each qubit */ strcpy(filename,"NULL"); strcpy(file_dm,"dm.dat"); PetscOptionsGetString(NULL,NULL,"-file_circ",filename,sizeof(filename),NULL); PetscOptionsGetString(NULL,NULL,"-file_dm",file_dm,sizeof(file_dm),NULL); quil_read(filename,&num_qubits,&projectq_read); // Read the file qubits = malloc(num_qubits*sizeof(struct operator)); //Allocate structure to store qubits gamma_1 = malloc(num_qubits*sizeof(PetscReal)); //Allocate array for qubit error rates gamma_2 = malloc(num_qubits*sizeof(PetscReal)); for (i=0;i<num_qubits;i++){ create_op(2,&qubits[i]); //create qubit gamma_1[i] = 0; gamma_2[i] = 0; } for (i=0; i<num_qubits;i++){ //Read errors from command line using -gam0, -gam1, etc sprintf(string, "-gam%d",i); PetscOptionsGetReal(NULL,NULL,string,&gamma_1[i],NULL); sprintf(string, "-dep%d",i); PetscOptionsGetReal(NULL,NULL,string,&gamma_2[i],NULL); } //Add errors to lindblad term for (i=0;i<num_qubits;i++){ add_lin(gamma_1[i]/2,qubits[i]); add_lin(gamma_2[i]*2,qubits[i]->n); } if (nid==0){ // Print read in variables printf("qubit gam dep\n"); for (i=0;i<num_qubits;i++){ printf("%d %f %f \n",i,gamma_1[i],gamma_2[i]); } } //Time step until 1 after the last gate; gates are applied every 1.0 time unit time_max = projectq_read.num_gates+1; dt = 0.01; steps_max = 100000; /* Set the ts_monitor to print results at each time step, if desired */ set_ts_monitor(ts_monitor); /* Open file that we will print to in ts_monitor */ if (nid==0){ f_pop = fopen("pop","w"); fprintf(f_pop,"#Time Populations\n"); } create_full_dm(&rho); //Allocate and set our initial density matrix mat_val = 1.0; add_value_to_dm(rho,0,0,mat_val); assemble_dm(rho); if (nid==0){ //Print number of gates printf("num_gates: %ld\n",projectq_read.num_gates); } //Start out circuit at time 0.0, first gate will be at 1.0 start_circuit_at_time(&projectq_read,0.0); //Run the evolution, with error and with the circuit time_step(rho,0.0,time_max,dt,steps_max); print_dm_sparse_to_file(rho,pow(2,num_qubits),file_dm); //Clean up memory for (i=0;i<num_qubits;i++){ destroy_op(&qubits[i]); } destroy_dm(rho); QuaC_finalize(); return 0; }