Skip to content

Commit

Permalink
some bug fixes (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandrupaler committed Mar 8, 2024
1 parent 39d2bf0 commit 6801e68
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ build
*.a
*.vscode
tests_*
.DS_Store
.DS_Store
*.github
1 change: 1 addition & 0 deletions include/lsqecc/gates/gates.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ using ArbitraryPrecisionInteger = int64_t;
struct Fraction{
ArbitraryPrecisionInteger num;
ArbitraryPrecisionInteger den;
bool is_negative = false;//not used for the moment

bool operator==(const Fraction& other) const = default;
};
Expand Down
22 changes: 22 additions & 0 deletions include/lstk/lstk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
#include <chrono>
#include <sstream>

#include <algorithm>
#include <cctype>
#include <locale>

#define LSTK_UNREACHABLE throw std::logic_error(std::string{"Not meant to be unreachable: "}+__FILE__+":"+std::to_string(__LINE__))
#define LSTK_NOT_IMPLEMENTED throw std::logic_error(std::string{"Not implemented: "}+__FILE__+":"+std::to_string(__LINE__))

Expand Down Expand Up @@ -153,6 +157,24 @@ static inline bool contains(std::string_view s, char target)
return s.find(target) != std::string_view::npos;
}

// https://stackoverflow.com/questions/216823/how-to-trim-a-stdstring
// trim from start (in place)
inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
return !std::isspace(ch);
}));
}

// https://stackoverflow.com/questions/216823/how-to-trim-a-stdstring
// trim from end (in place)
inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
return !std::isspace(ch);
}).base(), s.end());
}



// String manipulation

template <typename, typename = void>
Expand Down
4 changes: 3 additions & 1 deletion src/gates/gate_approximator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

bool is_power_of_two(lsqecc::ArbitraryPrecisionInteger n)
{
if(n==1)
return true;
return (n & (n - 1)) == 0 && n != 0;
}

Expand Down Expand Up @@ -117,7 +119,7 @@ std::vector<Gate> approximate_RZ_gate_cached(const RZ rz_gate)
if ((rz_gate.pi_fraction.num == 1 || rz_gate.pi_fraction.num == -1) && is_power_of_two(rz_gate.pi_fraction.den))
{
// TODO Do the approximation
LSTK_NOT_IMPLEMENTED;
throw std::runtime_error{lstk::cat("Not implemented! No cached decompositions. We are working on this...")};
}
throw std::runtime_error{lstk::cat("Can only approximate pi/2^n phase gates in cached mode, got rz(", print_pi_fraction(rz_gate.pi_fraction),")\n"
"If you really need non pi/2^n gates consider enabling the gridsynth integration"
Expand Down
50 changes: 42 additions & 8 deletions src/gates/parse_gates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <lstk/lstk.hpp>

#include <iostream>
#include <vector>
#include <stdexcept>

Expand Down Expand Up @@ -112,17 +113,31 @@ gates::CNOTAncillaPlacement determine_cnot_ancilla_placement(const std::vector<s

Fraction parse_angle(std::string_view s)
{
bool is_negative = false;
// check if negative
if(s.starts_with("-")) {
is_negative = true;
s = s.substr(1);
}

if(s.starts_with("pi/"))
return Fraction{1,try_parse_int<ArbitraryPrecisionInteger>(s.substr(3))};
return Fraction{1,try_parse_int<ArbitraryPrecisionInteger>(s.substr(3)), is_negative};

// use split on with *pi/ as delimiter
auto split = lstk::split_on(s,"*pi/");
if(split.size() != 2)
throw GateParseException{lstk::cat("Could not parse angle ", s, " as n*pi/m")};
if(split.size() != 2) {
//Is this an angle of the form 3*pi?
// not sure why but maybe we need something like
std::string ns = std::string(s) + "/1";

split = lstk::split_on(ns,"*pi/");
if(split.size() != 2)
throw GateParseException{lstk::cat("Could not parse angle ", s, " as n*pi/m")};
}

return Fraction{
try_parse_int<ArbitraryPrecisionInteger>(split.at(0)),
try_parse_int<ArbitraryPrecisionInteger>(split.at(1))};
ArbitraryPrecisionInteger num = try_parse_int<ArbitraryPrecisionInteger>(split.at(0));
ArbitraryPrecisionInteger den = try_parse_int<ArbitraryPrecisionInteger>(split.at(1));
return Fraction{num, den, is_negative};
}

gates::Reset parse_reset(const std::vector<std::string_view>& args)
Expand Down Expand Up @@ -161,9 +176,18 @@ gates::Gate parse_qasm_gate(const Line& line)

if(line.instruction.substr(0,2) == "rz")
{
Fraction fraction = parse_angle(get_arg_in_brackets(line.instruction));

if(fraction.den == 1)
{
// Multiples of PI are Z with a global phase
return gates::Z(get_index_arg(line.args.at(0)));
}

return gates::RZ{
get_index_arg(line.args[0]),
parse_angle(get_arg_in_brackets(line.instruction))};
fraction
};
}
if(line.instruction.substr(0,3) == "crz")
{
Expand Down Expand Up @@ -216,6 +240,17 @@ Qreg parse_qreg(std::vector<std::string_view>& args)

ParseGateResult parse_gate(std::string_view str_line)
{
// trim
std::string sline {str_line};
lstk::ltrim(sline);
str_line = std::string_view { sline };

// check for comment at beginning of line
if (str_line[0]=='/' && str_line[1] == '/')
{
return IgnoredInstruction{};
}

Line line = split_instruction_and_args(str_line);
if (!is_ignored_instruction(line.instruction))
{
Expand All @@ -231,7 +266,6 @@ ParseGateResult parse_gate(std::string_view str_line)

void GateStreamFromFile::advance_gate()
{

ParseGateResult maybe_gate = IgnoredInstruction{};
while(!std::holds_alternative<gates::Gate>(maybe_gate))
{
Expand Down
2 changes: 2 additions & 0 deletions src/pipelines/slicer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <fstream>
#include <chrono>

#include <string>


#define CONSOLE_HELP_NEWLINE_ALIGN "\n "

Expand Down
7 changes: 3 additions & 4 deletions tests/gates/parse_gates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ TEST(parse_gates, rz_pi_over_1)
ParseGateResult res = parse_gate(gate);
ASSERT_TRUE(std::holds_alternative<gates::Gate>(res));
auto g = std::get<gates::Gate>(res);
ASSERT_TRUE(std::holds_alternative<gates::RZ>(g));
auto rz = std::get<gates::RZ>(g);
ASSERT_TRUE(std::holds_alternative<gates::BasicSingleQubitGate>(g));
auto rz = std::get<gates::BasicSingleQubitGate>(g);
ASSERT_EQ(22, rz.target_qubit);
ASSERT_EQ(1, rz.pi_fraction.num);
ASSERT_EQ(1, rz.pi_fraction.den);
ASSERT_EQ(gates::BasicSingleQubitGate::Type::Z, rz.gate_type);
}

TEST(parse_gates, rz_2_pi_over_7)
Expand Down

0 comments on commit 6801e68

Please sign in to comment.