Skip to content

Commit

Permalink
Merge pull request tensorflow#278 from tensorflow/pauli_parse
Browse files Browse the repository at this point in the history
Add pauli parsing for new qsim.
  • Loading branch information
jaeyoo authored Jun 24, 2020
2 parents c9564b2 + 59314fb commit 55d2177
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 0 deletions.
2 changes: 2 additions & 0 deletions tensorflow_quantum/core/src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ cc_library(
srcs = ["circuit_parser_qsim.cc"],
hdrs = ["circuit_parser_qsim.h"],
deps = [
"//tensorflow_quantum/core/proto:pauli_sum_cc_proto",
"//tensorflow_quantum/core/proto:program_cc_proto",
"@com_google_absl//absl/container:flat_hash_map",
"@local_config_tf//:libtensorflow_framework",
Expand All @@ -63,6 +64,7 @@ cc_test(
linkstatic = 0,
deps = [
":circuit_parser_qsim",
"//tensorflow_quantum/core/proto:pauli_sum_cc_proto",
"//tensorflow_quantum/core/proto:program_cc_proto",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
Expand Down
30 changes: 30 additions & 0 deletions tensorflow_quantum/core/src/circuit_parser_qsim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ limitations under the License.
#include "absl/strings/numbers.h"
#include "cirq/google/api/v2/program.pb.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow_quantum/core/proto/pauli_sum.pb.h"

namespace tfq {

using ::cirq::google::api::v2::Moment;
using ::cirq::google::api::v2::Operation;
using ::cirq::google::api::v2::Program;
using ::tensorflow::Status;
using ::tfq::proto::PauliTerm;

namespace {

Expand Down Expand Up @@ -374,4 +376,32 @@ tensorflow::Status QsimCircuitFromProgram(
return Status::OK();
}

Status QsimCircuitFromPauliTerm(
const PauliTerm& term, const int num_qubits, QsimCircuit* circuit,
std::vector<qsim::GateFused<QsimGate>>* fused_circuit) {
Program measurement_program;
SymbolMap empty_map;
measurement_program.mutable_circuit()->set_scheduling_strategy(
cirq::google::api::v2::Circuit::MOMENT_BY_MOMENT);
Moment* term_moment = measurement_program.mutable_circuit()->add_moments();
for (const tfq::proto::PauliQubitPair& pair : term.paulis()) {
Operation* new_op = term_moment->add_operations();

// create corresponding eigen gate op.
new_op->add_qubits()->set_id(pair.qubit_id());
new_op->mutable_gate()->set_id(pair.pauli_type() + "P");
(*new_op->mutable_args())["exponent"].mutable_arg_value()->set_float_value(
1.0);
(*new_op->mutable_args())["global_shift"]
.mutable_arg_value()
->set_float_value(0.0);
(*new_op->mutable_args())["exponent_scalar"]
.mutable_arg_value()
->set_float_value(1.0);
}

return QsimCircuitFromProgram(measurement_program, empty_map, num_qubits,
circuit, fused_circuit);
}

} // namespace tfq
8 changes: 8 additions & 0 deletions tensorflow_quantum/core/src/circuit_parser_qsim.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ limitations under the License.
#include "absl/container/flat_hash_map.h"
#include "cirq/google/api/v2/program.pb.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow_quantum/core/proto/pauli_sum.pb.h"

namespace tfq {

Expand All @@ -37,6 +38,13 @@ tensorflow::Status QsimCircuitFromProgram(
const int num_qubits, qsim::Circuit<qsim::Cirq::GateCirq<float>>* circuit,
std::vector<qsim::GateFused<qsim::Cirq::GateCirq<float>>>* fused_circuit);

// parse a serialized pauliTerm from a larger cirq.Paulisum proto
// into a qsim Circuit and fused circuit.
tensorflow::Status QsimCircuitFromPauliTerm(
const tfq::proto::PauliTerm& term, const int num_qubits,
qsim::Circuit<qsim::Cirq::GateCirq<float>>* circuit,
std::vector<qsim::GateFused<qsim::Cirq::GateCirq<float>>>* fused_circuit);

} // namespace tfq

#endif // TFQ_CORE_SRC_CIRCUIT_PARSER_QSIM_H_
35 changes: 35 additions & 0 deletions tensorflow_quantum/core/src/circuit_parser_qsim_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -555,5 +555,40 @@ TEST(QsimCircuitParserTest, EmptyTest) {
ASSERT_EQ(fused_circuit.size(), 0);
}

TEST(QsimCircuitParserTest, CircuitFromPauliTermPauli) {
tfq::proto::PauliTerm pauli_proto;
// The created circuit should not depend on the coefficient
pauli_proto.set_coefficient_real(3.14);
tfq::proto::PauliQubitPair* pair_proto = pauli_proto.add_paulis();
pair_proto->set_qubit_id("0");
pair_proto->set_pauli_type("X");

// Build the corresponding correct circuit
auto reference = qsim::Cirq::XPowGate<float>::Create(0, 0, 1.0, 0.0);
QsimCircuit test_circuit;
std::vector<qsim::GateFused<QsimGate>> fused_circuit;
tensorflow::Status status;

// Check conversion
status =
QsimCircuitFromPauliTerm(pauli_proto, 1, &test_circuit, &fused_circuit);
ASSERT_EQ(status, tensorflow::Status::OK());
ASSERT_EQ(test_circuit.num_qubits, 1);
ASSERT_EQ(test_circuit.gates.size(), 1);
AssertOneQubitEqual(test_circuit.gates[0], reference);
}

TEST(QsimCircuitParserTest, CircuitFromPauliTermEmpty) {
tfq::proto::PauliTerm pauli_proto;
tensorflow::Status status;
QsimCircuit test_circuit;
std::vector<qsim::GateFused<QsimGate>> fused_circuit;
status =
QsimCircuitFromPauliTerm(pauli_proto, 0, &test_circuit, &fused_circuit);
ASSERT_EQ(status, tensorflow::Status::OK());
ASSERT_EQ(test_circuit.num_qubits, 0);
ASSERT_EQ(test_circuit.gates.size(), 0);
}

} // namespace
} // namespace tfq

0 comments on commit 55d2177

Please sign in to comment.