Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Surface Code #7

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

Conversation

justinlietz
Copy link
Collaborator

This PR adds the cudaq::qec::surface_code namespace which includes the surface_code type and the stabilizer_grid helper class. The stabilizer_grid generates the 2d layout of the stabilizers, and which data qubits each stabilizer has support on. Lastly it generates the stabilizers and observables as vectors of cudaq::spin_op which the qec::code expects.

Copy link

copy-pr-bot bot commented Nov 21, 2024

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

}

__qpu__ void prep1(patch logicalQubit) {
prep0(logicalQubit);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need this prep0 call?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not currently, but at the moment, all of our logical stateprep assumes starting from fresh qubits set to |0>. We should change the behavior of all of these so that they could work in the middle of an larger kernel execution. This means that the existing prep0 should all have a round of resets at the beginning, then prep1 should call prep0 then the logical X gate.

@boschmitt
Copy link
Collaborator

/ok to test

Copy link
Collaborator

@bmhowe23 bmhowe23 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Justin. I have a few comments/questions below.

void generate_stabilizers();

public:
/// @brief The distance of the code,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
/// @brief The distance of the code,
/// @brief The distance of the code


/// @brief enumerates the role of a grid site in the surface codes stabilizer
/// grid
enum surface_role { amx, amz, empty };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious: is this "a measure x" and "a measure z", or something else?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a fine interpretation, although in my head I was thinking "ancilla for mx/z".

public:
/// @brief The distance of the code,
// determines the number of data qubits per dimension
uint32_t distance;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to initialize this for cases where the default constructor is used.

Suggested change
uint32_t distance;
uint32_t distance = 0;

/// @brief length of the stabilizer grid
// for distance = d data qubits,
// the stabilizer grid has length d+1
uint32_t grid_length;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to initialize this for cases where the default constructor is used.

Suggested change
uint32_t grid_length;
uint32_t grid_length= 0;

Comment on lines +233 to +234
stabilizer(patch p, const std::vector<std::size_t> &x_stabilizers,
const std::vector<std::size_t> &z_stabilizers);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't think we supported pass-by-reference going into a __qpu__ function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the expected behavior of passing a ref in? This seems to work here as well as in the Steane code.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, either pass by value or pass by ref get you the same thing - a subtlety of the ASTBridge MLIR generation. No matter what the signature is, if you pass a std::vector it is modeled as a cc.stdvec which lowers to a span-like type (a pointer and a size). You are always passing by reference no matter what. Eric can elaborate more if needed.

cudaqx::tensor<uint8_t> Lz = surf_code->get_observables_z();

{
// This is just a regression check, this has not been hand tested
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly does this comment mean? Where did the data come from?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The data is only generated from itself, just scraped from the terminal and put into a vector here. Other instances of checking against hardcoded bit strings were hand checked to be correct. This one was not, as there are not printed instances of surface code PCMs I could find.

This comment is to make us aware that these are not magic numbers that we must always match. Various permutations would all be valid PCMs of the surface code.

EXPECT_EQ(t.at({i, j}), parity.at({i, j}));
}
{
// This is just a regression check, this has not been hand tested
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here.

EXPECT_EQ(t.at({i, j}), parity_x.at({i, j}));
}
{
// This is just a regression check, this has not been hand tested
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here.

Copy link
Collaborator

@bmhowe23 bmhowe23 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notes from our meeting today.


/// @brief Generates and keeps track of the 2d grid of stabilizers in the
/// rotated surface code
// Grid layout is arranged from left to right, top to bottom (row major storage)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to double check that the docs are rendering as desired for // vs ///.

Comment on lines +45 to +47
// The grid length of 4 corresponds to a distance 3 surface code, which results
// in: e(0,0) e(0,1) Z(0,2) e(0,3) X(1,0) Z(1,1) X(1,2) e(1,3) e(2,0)
// X(2,1) Z(2,2) X(2,3) e(3,0) Z(3,1) e(3,2) e(3,3)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double-check formatting.

//
// The data qubits are located at the four corners of each of the weight-4
// stabilizers. They are also organized with index increasing from left to
// right, top to bottom: d0 d1 d2 d3 d4 d5 d6 d7 d8
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double check formatting (two spaces vs single spac)

bool operator<(const vec2d &lhs, const vec2d &rhs);

/// @brief Generates and keeps track of the 2d grid of stabilizers in the
/// rotated surface code
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps consider adding link to a reference paper who's convention you're following w.r.t. the grid.

@@ -0,0 +1,396 @@
/****************************************************************-*- C++ -*-****
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
/****************************************************************-*- C++ -*-****
/*******************************************************************************

@@ -0,0 +1,87 @@
/****************************************************************-*- C++ -*-****
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
/****************************************************************-*- C++ -*-****
/*******************************************************************************

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants