Loading handlers/qcor_syntax_handler.cpp +36 −25 Original line number Diff line number Diff line Loading @@ -13,6 +13,9 @@ using namespace clang; namespace qcor { namespace __internal__developer__flags__ { bool add_predefines = true; } bool qrt = false; std::string qpu_name = "qpp"; Loading Loading @@ -331,9 +334,10 @@ void QCORSyntaxHandler::GetReplacement( OS << "}\n"; if (add_het_map_ctor) { // Remove "&" from type string before getting the Python variables in the HetMap. // Note: HetMap can't store references. const auto remove_ref_arg_type = [](const std::string &org_arg_type) -> std::string { // Remove "&" from type string before getting the Python variables in the // HetMap. Note: HetMap can't store references. const auto remove_ref_arg_type = [](const std::string &org_arg_type) -> std::string { // We intentially only support a very limited set of pass-by-ref types // from the HetMap. // Only do: double& and int& Loading Loading @@ -369,19 +373,23 @@ void QCORSyntaxHandler::GetReplacement( // If this is a *supported* ref types: double&, int&, etc. if (remove_ref_arg_type(program_arg_types[i]) != program_arg_types[i]) { // Generate a temp var const std::string new_var_name = "__temp_var__" + std::to_string(var_counter++); const std::string new_var_name = "__temp_var__" + std::to_string(var_counter++); // Copy the var from HetMap to the temp var ref_type_copy_decl_ss << remove_ref_arg_type(program_arg_types[i]) << " "<< new_var_name << " = " << "args.get<" << remove_ref_arg_type(program_arg_types[i]) << ">(\"" << program_parameters[i] << "\");\n"; ref_type_copy_decl_ss << remove_ref_arg_type(program_arg_types[i]) << " " << new_var_name << " = " << "args.get<" << remove_ref_arg_type(program_arg_types[i]) << ">(\"" << program_parameters[i] << "\");\n"; // We just pass this copied var to the ctor // where it expects a reference type. arg_ctor_list.emplace_back(new_var_name); } else { } else { // Otherwise, just unpack the arg inline in the ctor call. std::stringstream ss; ss << "args.get<" << program_arg_types[i] << ">(\""<< program_parameters[i] << "\")"; ss << "args.get<" << program_arg_types[i] << ">(\"" << program_parameters[i] << "\")"; arg_ctor_list.emplace_back(ss.str()); } } Loading @@ -394,8 +402,8 @@ void QCORSyntaxHandler::GetReplacement( // CTor call OS << "class " << kernel_name << " __ker__temp__("; // First arg: qreg OS << "args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; OS << "args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; // The rest: either inline unpacking or temp var names (ref type) for (const auto &arg_str : arg_ctor_list) { OS << ", " << arg_str; Loading @@ -404,14 +412,15 @@ void QCORSyntaxHandler::GetReplacement( OS << "}\n"; OS << "void " << kernel_name << "__with_parent_and_hetmap_args(std::shared_ptr<CompositeInstruction> parent, " << "__with_parent_and_hetmap_args(std::shared_ptr<CompositeInstruction> " "parent, " "HeterogeneousMap& args) {\n"; OS << ref_type_copy_decl_ss.str(); // CTor call with parent kernel OS << "class " << kernel_name << " __ker__temp__(parent, "; // Second arg: qreg OS << "args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; OS << "args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; // The rest: either inline unpacking or temp var names (ref type) for (const auto &arg_str : arg_ctor_list) { OS << ", " << arg_str; Loading @@ -425,10 +434,12 @@ void QCORSyntaxHandler::GetReplacement( } void QCORSyntaxHandler::AddToPredefines(llvm::raw_string_ostream &OS) { if (__internal__developer__flags__::add_predefines) { OS << "#include \"qcor.hpp\"\n"; OS << "using namespace qcor;\n"; OS << "using namespace xacc::internal_compiler;\n"; } } class DoNothingConsumer : public ASTConsumer { public: Loading handlers/qcor_syntax_handler.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,12 @@ namespace qcor { extern std::string qpu_name; extern int shots; // Add this for internal development, specifically JIT tests // where I don't want AddPredefines to add qcor.hpp. For example // where I want to compile a simple c++ code with no dependencies, // I don't want to include qcor.hpp bc it makes it much slower. namespace __internal__developer__flags__ { extern bool add_predefines;} class QCORSyntaxHandler : public SyntaxHandler { public: QCORSyntaxHandler() : SyntaxHandler("qcor") {} Loading mlir/CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ set(LIBS MLIRExecutionEngine MLIRStandard MLIRAffine LLVMLinker openqasm-mlir-generator openqasmv3-mlir-generator quantum-to-llvm-lowering Loading mlir/parsers/qasm3/examples/qpe.qasm +0 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ h counting; // Loop over and create ctrl-U**2k int repetitions = 1; for i in [0:n_counting] { print("i is ", i, repetitions); ctrl @ pow(repetitions) @ oracle counting[i], state; repetitions *= 2; } Loading mlir/parsers/qasm3/examples/qrng.qasm 0 → 100644 +44 −0 Original line number Diff line number Diff line OPENQASM 3; // Global constant, maximum bit size // for the random integer const max_bits = 4; // Generate a superposition and // measure to return a 50/50 random bit def random_bit() qubit:a -> bit { h a; return measure a; } // Generate a random integer of max_bits bit width // This will generate a random 0 or 1 // based on a single provided qubit put // in a superposition def generate_random_int() qubit:q -> int { // Create [0,0,0,...0] of size max_bits bit b[max_bits]; // Set every bit as a random 0 or 1 for i in [0:max_bits] { b[i] = random_bit() q; // reset qubit state for // next iteration reset q; } // Print the binary string print("random binary: ", b); // Cast to int and return return int[32](b); } // Allocate a single qubit qubit a; // Generate the random number // using the allocated qubit int n = generate_random_int() a; // print the random number print("Random int (lsb): ", n); No newline at end of file Loading
handlers/qcor_syntax_handler.cpp +36 −25 Original line number Diff line number Diff line Loading @@ -13,6 +13,9 @@ using namespace clang; namespace qcor { namespace __internal__developer__flags__ { bool add_predefines = true; } bool qrt = false; std::string qpu_name = "qpp"; Loading Loading @@ -331,9 +334,10 @@ void QCORSyntaxHandler::GetReplacement( OS << "}\n"; if (add_het_map_ctor) { // Remove "&" from type string before getting the Python variables in the HetMap. // Note: HetMap can't store references. const auto remove_ref_arg_type = [](const std::string &org_arg_type) -> std::string { // Remove "&" from type string before getting the Python variables in the // HetMap. Note: HetMap can't store references. const auto remove_ref_arg_type = [](const std::string &org_arg_type) -> std::string { // We intentially only support a very limited set of pass-by-ref types // from the HetMap. // Only do: double& and int& Loading Loading @@ -369,19 +373,23 @@ void QCORSyntaxHandler::GetReplacement( // If this is a *supported* ref types: double&, int&, etc. if (remove_ref_arg_type(program_arg_types[i]) != program_arg_types[i]) { // Generate a temp var const std::string new_var_name = "__temp_var__" + std::to_string(var_counter++); const std::string new_var_name = "__temp_var__" + std::to_string(var_counter++); // Copy the var from HetMap to the temp var ref_type_copy_decl_ss << remove_ref_arg_type(program_arg_types[i]) << " "<< new_var_name << " = " << "args.get<" << remove_ref_arg_type(program_arg_types[i]) << ">(\"" << program_parameters[i] << "\");\n"; ref_type_copy_decl_ss << remove_ref_arg_type(program_arg_types[i]) << " " << new_var_name << " = " << "args.get<" << remove_ref_arg_type(program_arg_types[i]) << ">(\"" << program_parameters[i] << "\");\n"; // We just pass this copied var to the ctor // where it expects a reference type. arg_ctor_list.emplace_back(new_var_name); } else { } else { // Otherwise, just unpack the arg inline in the ctor call. std::stringstream ss; ss << "args.get<" << program_arg_types[i] << ">(\""<< program_parameters[i] << "\")"; ss << "args.get<" << program_arg_types[i] << ">(\"" << program_parameters[i] << "\")"; arg_ctor_list.emplace_back(ss.str()); } } Loading @@ -394,8 +402,8 @@ void QCORSyntaxHandler::GetReplacement( // CTor call OS << "class " << kernel_name << " __ker__temp__("; // First arg: qreg OS << "args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; OS << "args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; // The rest: either inline unpacking or temp var names (ref type) for (const auto &arg_str : arg_ctor_list) { OS << ", " << arg_str; Loading @@ -404,14 +412,15 @@ void QCORSyntaxHandler::GetReplacement( OS << "}\n"; OS << "void " << kernel_name << "__with_parent_and_hetmap_args(std::shared_ptr<CompositeInstruction> parent, " << "__with_parent_and_hetmap_args(std::shared_ptr<CompositeInstruction> " "parent, " "HeterogeneousMap& args) {\n"; OS << ref_type_copy_decl_ss.str(); // CTor call with parent kernel OS << "class " << kernel_name << " __ker__temp__(parent, "; // Second arg: qreg OS << "args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; OS << "args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; // The rest: either inline unpacking or temp var names (ref type) for (const auto &arg_str : arg_ctor_list) { OS << ", " << arg_str; Loading @@ -425,10 +434,12 @@ void QCORSyntaxHandler::GetReplacement( } void QCORSyntaxHandler::AddToPredefines(llvm::raw_string_ostream &OS) { if (__internal__developer__flags__::add_predefines) { OS << "#include \"qcor.hpp\"\n"; OS << "using namespace qcor;\n"; OS << "using namespace xacc::internal_compiler;\n"; } } class DoNothingConsumer : public ASTConsumer { public: Loading
handlers/qcor_syntax_handler.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,12 @@ namespace qcor { extern std::string qpu_name; extern int shots; // Add this for internal development, specifically JIT tests // where I don't want AddPredefines to add qcor.hpp. For example // where I want to compile a simple c++ code with no dependencies, // I don't want to include qcor.hpp bc it makes it much slower. namespace __internal__developer__flags__ { extern bool add_predefines;} class QCORSyntaxHandler : public SyntaxHandler { public: QCORSyntaxHandler() : SyntaxHandler("qcor") {} Loading
mlir/CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ set(LIBS MLIRExecutionEngine MLIRStandard MLIRAffine LLVMLinker openqasm-mlir-generator openqasmv3-mlir-generator quantum-to-llvm-lowering Loading
mlir/parsers/qasm3/examples/qpe.qasm +0 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ h counting; // Loop over and create ctrl-U**2k int repetitions = 1; for i in [0:n_counting] { print("i is ", i, repetitions); ctrl @ pow(repetitions) @ oracle counting[i], state; repetitions *= 2; } Loading
mlir/parsers/qasm3/examples/qrng.qasm 0 → 100644 +44 −0 Original line number Diff line number Diff line OPENQASM 3; // Global constant, maximum bit size // for the random integer const max_bits = 4; // Generate a superposition and // measure to return a 50/50 random bit def random_bit() qubit:a -> bit { h a; return measure a; } // Generate a random integer of max_bits bit width // This will generate a random 0 or 1 // based on a single provided qubit put // in a superposition def generate_random_int() qubit:q -> int { // Create [0,0,0,...0] of size max_bits bit b[max_bits]; // Set every bit as a random 0 or 1 for i in [0:max_bits] { b[i] = random_bit() q; // reset qubit state for // next iteration reset q; } // Print the binary string print("random binary: ", b); // Cast to int and return return int[32](b); } // Allocate a single qubit qubit a; // Generate the random number // using the allocated qubit int n = generate_random_int() a; // print the random number print("Random int (lsb): ", n); No newline at end of file