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

Use a different default location for mediating ancilla states in CNOTs when the layout does not supply one #115

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions include/lsqecc/gates/gates.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ std::optional<CNOTType> CNOTType_fromString(std::string_view s);

enum class CNOTAncillaPlacement
{
ANCILLA_FREE_PLACEMENT,
USE_DEDICATED_CELL,
ANCILLA_NEXT_TO_CONTROL,
ANCILLA_NEXT_TO_TARGET
};
Expand All @@ -85,7 +85,10 @@ struct ControlledGate
CNOTAncillaPlacement cnot_ancilla_placement;

static constexpr CNOTType default_cnot_type = CNOTType::ZX_WITH_MBM_CONTROL_FIRST;
static constexpr CNOTAncillaPlacement default_ancilla_placement = CNOTAncillaPlacement::ANCILLA_FREE_PLACEMENT;

// Initialized in source file. This value is updated depending on the type of layout.
// TODO consider using a more robust pattern if we have to support multiple layouts per lsqecc_slicer execution.
static CNOTAncillaPlacement default_ancilla_placement;
};


Expand Down
2 changes: 1 addition & 1 deletion include/lsqecc/layout/ascii_layout_spec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class LayoutFromSpec : public Layout{
const std::vector<SurfaceCodeTimestep>& distillation_times() const override {return cached_distillation_times_;};
const std::vector<Cell>& ancilla_location() const override {return cached_ancilla_locations_;}
const std::vector<Cell>& dead_location() const override {return cached_dead_cells_;}
const std::vector<Cell>& predistilled_y_states() const override {return cached_y_states_;}
const std::vector<Cell>& predistilled_y_states() const override {return cached_y_states_;}
const std::vector<Cell>& distilled_state_locations(size_t distillation_region_idx) const override
{
return cached_distilled_state_locations_[distillation_region_idx];
Expand Down
1 change: 1 addition & 0 deletions include/lsqecc/layout/layout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace lsqecc {
using SurfaceCodeTimestep = uint32_t;
using DistillationTimeMap = std::vector<SurfaceCodeTimestep>;


struct Layout {

virtual const std::vector<SparsePatch>& core_patches() const = 0;
Expand Down
10 changes: 7 additions & 3 deletions src/gates/gates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ std::string_view CNOTAncillaPlacement_toString(CNOTAncillaPlacement v)
using namespace std::string_view_literals;
switch (v)
{
case CNOTAncillaPlacement::ANCILLA_FREE_PLACEMENT:
case CNOTAncillaPlacement::USE_DEDICATED_CELL:
return "AncillaFreePlacement"sv;
case CNOTAncillaPlacement::ANCILLA_NEXT_TO_CONTROL:
return "AncillaNextToControl"sv;
Expand All @@ -130,8 +130,8 @@ std::string_view CNOTAncillaPlacement_toString(CNOTAncillaPlacement v)

std::optional<CNOTAncillaPlacement> CNOTAncillaPlacement_fromString(std::string_view s)
{
if (s == CNOTAncillaPlacement_toString(CNOTAncillaPlacement::ANCILLA_FREE_PLACEMENT))
return CNOTAncillaPlacement::ANCILLA_FREE_PLACEMENT;
if (s == CNOTAncillaPlacement_toString(CNOTAncillaPlacement::USE_DEDICATED_CELL))
return CNOTAncillaPlacement::USE_DEDICATED_CELL;
if (s == CNOTAncillaPlacement_toString(CNOTAncillaPlacement::ANCILLA_NEXT_TO_CONTROL))
return CNOTAncillaPlacement::ANCILLA_NEXT_TO_CONTROL;
if (s == CNOTAncillaPlacement_toString(CNOTAncillaPlacement::ANCILLA_NEXT_TO_TARGET))
Expand Down Expand Up @@ -176,6 +176,10 @@ tsl::ordered_set<QubitNum> get_operating_qubits(const Gate& gate)
return res;
}


CNOTAncillaPlacement ControlledGate::default_ancilla_placement = CNOTAncillaPlacement::USE_DEDICATED_CELL;


} // namespace lsqecc::gates

namespace lsqecc {
Expand Down
1 change: 1 addition & 0 deletions src/gates/parse_gates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <iostream>
#include <vector>
#include <stdexcept>
#include <iostream>

namespace lsqecc {

Expand Down
2 changes: 1 addition & 1 deletion src/ls_instructions/ls_instructions_from_gates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ std::queue<LSInstruction> LSIinstructionFromGatesGenerator::make_t_gate_instruct
target_id,
new_magic_state_id,
gates::CNOTType::BELL_BASED,
gates::CNOTAncillaPlacement::ANCILLA_FREE_PLACEMENT,
gates::CNOTAncillaPlacement::USE_DEDICATED_CELL,
CNOTCorrectionMode::NEVER);
lstk::queue_extend(next_instructions, instructions);
next_instructions.push({.operation={SinglePatchMeasurement{new_magic_state_id, PauliOperator::Z, false}}});
Expand Down
60 changes: 46 additions & 14 deletions src/pipelines/slicer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ namespace lsqecc
Local, Nonlocal
};

enum class AutoLayoutMode // Layouts specified with -L
{
Compact, CompactNoClogging, Edpc
};

using LayoutMode = std::variant<AutoLayoutMode, std::unique_ptr<LayoutFromSpec>>; // LayoutFromSpec is for -l

DistillationOptions make_distillation_options(argparse::ArgumentParser& parser)
{
DistillationOptions distillation_options;
Expand Down Expand Up @@ -199,6 +206,34 @@ namespace lsqecc
return 0;
}

DistillationOptions distillation_options = make_distillation_options(parser);

LayoutMode layout_mode = AutoLayoutMode::Compact;
if (parser.exists("layoutgenerator"))
{
if (parser.get<std::string>("layoutgenerator") == "compact")
{
layout_mode = AutoLayoutMode::Compact;
} else if (parser.get<std::string>("layoutgenerator") == "compact_no_clogging")
{
layout_mode = AutoLayoutMode::CompactNoClogging;
}
else if (parser.get<std::string>("layoutgenerator") == "edpc")
{
layout_mode = AutoLayoutMode::Edpc;
}
else
{
err_stream << "Unknown layout generator: " << parser.get<std::string>("layoutgenerator") << std::endl;
return -1;
}
}
else if(parser.exists("l"))
layout_mode = std::make_unique<LayoutFromSpec>(file_to_string(parser.get<std::string>("l")), distillation_options);
else {
// Default to Litinsiki's compact layout
}

std::reference_wrapper<std::ostream> bulk_output_stream = std::ref(out_stream);
std::unique_ptr<std::ostream> _ofstream_store;
if(parser.exists("o"))
Expand Down Expand Up @@ -334,21 +369,20 @@ namespace lsqecc


std::unique_ptr<Layout> layout;
DistillationOptions distillation_options = make_distillation_options(parser);
if (parser.exists("layoutgenerator"))
if (AutoLayoutMode* auto_layout_mode = std::get_if<AutoLayoutMode>(&layout_mode))
{
if (parser.get<std::string>("layoutgenerator") == "compact")
if (*auto_layout_mode == AutoLayoutMode::Compact)
{
layout = make_compact_layout(instruction_stream->core_qubits().size(), distillation_options);
instruction_stream = std::make_unique<TeleportedSGateInjectionStream>(std::move(instruction_stream), id_generator);
instruction_stream = std::make_unique<BoundaryRotationInjectionStream>(std::move(instruction_stream), *layout);
} else if (parser.get<std::string>("layoutgenerator") == "compact_no_clogging")
} else if (*auto_layout_mode == AutoLayoutMode::CompactNoClogging)
{
layout = make_compact_layout(instruction_stream->core_qubits().size(), distillation_options, true);
instruction_stream = std::make_unique<TeleportedSGateInjectionStream>(std::move(instruction_stream), id_generator);
instruction_stream = std::make_unique<BoundaryRotationInjectionStream>(std::move(instruction_stream), *layout);
}
else if (parser.get<std::string>("layoutgenerator") == "edpc")
else if (*auto_layout_mode == AutoLayoutMode::Edpc)
{
size_t num_lanes = 1;
bool condensed = false;
Expand All @@ -364,18 +398,16 @@ namespace lsqecc
}
else
{
err_stream << "Unknown layout generator: " << parser.get<std::string>("layoutgenerator") << std::endl;
return -1;
LSTK_NOT_IMPLEMENTED;
}
}
else if(parser.exists("l"))
layout = std::make_unique<LayoutFromSpec>(file_to_string(parser.get<std::string>("l")), distillation_options);
else
else if(std::unique_ptr<LayoutFromSpec>* custom_layout_path = std::get_if<std::unique_ptr<LayoutFromSpec>>(&layout_mode))
layout = std::move(*custom_layout_path);

// Override the choice of ancilla placements when no location is provided
if(layout->ancilla_location().empty())
{
// Default to Litinsiki's compact layout
layout = make_compact_layout(instruction_stream->core_qubits().size(), distillation_options);
instruction_stream = std::make_unique<TeleportedSGateInjectionStream>(std::move(instruction_stream), id_generator);
instruction_stream = std::make_unique<BoundaryRotationInjectionStream>(std::move(instruction_stream), *layout);
gates::ControlledGate::default_ancilla_placement = gates::CNOTAncillaPlacement::ANCILLA_NEXT_TO_TARGET;
}

LLIPrintMode lli_print_mode = LLIPrintMode::None;
Expand Down
Loading