Skip to content
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
57 changes: 32 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,20 @@ To build `qsyn`, follow the instructions below:

<details>
<summary>For Linux Users</summary>

You'll probably need to install `OpenBLAS` and `LAPACK` libraries. For Ubuntu, you can install them by running

```sh
sudo apt install libopenblas-dev
sudo apt install liblapack-dev
```
You'll probably need to install `OpenBLAS` and `LAPACK` libraries.
- For Ubuntu, you can install them by running
```sh
sudo apt install libopenblas-dev
sudo apt install liblapack-dev
```
- For Fedora, you can install them by running
```sh
sudo dnf install openblas-devel
sudo dnf install lapack-devel
```
- For openSUSE, you can read [this wiki page](https://en.opensuse.org/openSUSE:Science_Linear_algebra_libraries).
- For other distros, you might be interested in [OpenBLAS install.md](https://github.com/OpenMathLib/OpenBLAS/blob/develop/docs/install.md).

If you are tech-savvy enough to be using a different Linux distribution, we're confident that you can figure out how to install these libraries 😉

Expand All @@ -97,7 +104,7 @@ This uses the default compiler (gcc/g++) and triggers the CMake build. To overri

<details>
<summary>For MacOS Users</summary>

Since Qsyn uses C++20 features not fully supported by Apple Clang, install a C++20-capable compiler. Options:

1. **LLVM (clang++)** via Homebrew:
Expand Down Expand Up @@ -332,26 +339,26 @@ This architecture is central to qsyn’s flexibility and extensibility. It segre
### Data Access and Utilities

`qsyn` provides various data representations for quantum logic. `<dt>` stands for any data representation type, including quantum circuits, ZX diagrams, Tableau, etc.
| Command | Description |
| :----- | :---- |
| `<dt>` list | list all `<dt>`s |
| `<dt>` checkout | switch focus between `<dt>`s |
| `<dt>` print | print `<dt>` information |
| `<dt>` <new \| delete> | add a new/delete a `<dt>` |
| `<dt>` <read \| write> | read and write `<dt>` |
| `<dt>` equiv | verify equivalence of two `<dt>`s |
| `<dt>` draw | render visualization of `<dt>` |
| convert `<dt1>` `<dt2>` | convert from `<dt1>` to `<dt2>` |
| Command | Description |
| :---------------------- | :-------------------------------- |
| `<dt>` list | list all `<dt>`s |
| `<dt>` checkout | switch focus between `<dt>`s |
| `<dt>` print | print `<dt>` information |
| `<dt>` <new \| delete> | add a new/delete a `<dt>` |
| `<dt>` <read \| write> | read and write `<dt>` |
| `<dt>` equiv | verify equivalence of two `<dt>`s |
| `<dt>` draw | render visualization of `<dt>` |
| convert `<dt1>` `<dt2>` | convert from `<dt1>` to `<dt2>` |

There are also some extra utilities:
| Command | Description |
| :----- | :---- |
| alias | set or unset aliases |
| help | display helps to commands |
| Command | Description |
| :------ | :----------------------------- |
| alias | set or unset aliases |
| help | display helps to commands |
| history | show or export command history |
| logger | control log levels |
| set | set or unset variables |
| usage | show time/memory usage |
| logger | control log levels |
| set | set or unset variables |
| usage | show time/memory usage |

## License

Expand All @@ -363,7 +370,7 @@ Certain functions of `qsyn` is enabled by a series of third-party libraries. For
## Resources

* Quantum circuit benchmark: [qsyn-benchmark](https://github.com/DVLab-NTU/qsyn-benchmark)

## Reference
If you are using Qsyn for your research, it will be greatly appreciated if you cite this publication:

Expand Down
4 changes: 3 additions & 1 deletion src/argparse/arg_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ bool SubParsers::is_required() const noexcept {
return _pimpl->required;
}

SubParsers::MapType& SubParsers::get_subparsers() { return _pimpl->subparsers; }
SubParsers::MapType const& SubParsers::get_subparsers() const { return _pimpl->subparsers; }
std::string const& SubParsers::get_help() const { return _pimpl->help; }
std::string const& SubParsers::get_dest() const { return _pimpl->dest; }
Expand Down Expand Up @@ -487,8 +488,9 @@ bool ArgumentParser::_parse_positional_arguments(TokensSpan tokens, std::vector<
fmt::println(stderr, "Error: missing argument \"{}\": expected {}{} arguments!!",
arg.get_name(), (lower < upper ? "at least " : ""), lower);
return false;
} else
} else {
continue;
}
}

if (!arg.take_action(parse_range)) return false;
Expand Down
1 change: 1 addition & 0 deletions src/argparse/arg_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class SubParsers {

size_t size() const noexcept;

SubParsers::MapType& get_subparsers();
SubParsers::MapType const& get_subparsers() const;
std::string const& get_help() const;
std::string const& get_dest() const;
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/conversion_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,9 @@ Command convert_from_zx_cmd(zx::ZXGraphMgr& zxgraph_mgr, QCirMgr& qcir_mgr, tens
zxgraph_mgr.add(zxgraph_mgr.get_next_id(), std::make_unique<zx::ZXGraph>(std::move(target)));
zxgraph_mgr.get()->add_procedure("ZX2QC-Unpermuted");
qcir_mgr.get()->add_procedure("ZX2QC-Unpermuted");
} else
} else {
qcir_mgr.get()->add_procedure("ZX2QC");
}

assert(std::ranges::all_of(qcir_mgr.get()->get_gates(), [&](auto* gate) { return gate->get_id() == qcir_mgr.get()->get_gate(gate->get_id())->get_id(); }));
}
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/qcir_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,13 +322,13 @@ dvlab::Command qcir_print_cmd(QCirMgr const& qcir_mgr) {
if (parser.parsed("--gate")) {
auto gate_ids = parser.get<std::vector<size_t>>("--gate");
qcir_mgr.get()->print_gates(parser.parsed("--verbose"), gate_ids);
} else if (parser.parsed("--diagram"))
} else if (parser.parsed("--diagram")) {
if (parser.parsed("--verbose")) {
qcir_mgr.get()->draw(QCirDrawerType::text);
} else {
qcir_mgr.get()->print_circuit_diagram();
}
else if (parser.parsed("--statistics")) {
} else if (parser.parsed("--statistics")) {
qcir_mgr.get()->print_qcir();
qcir_mgr.get()->print_gate_statistics(parser.parsed("--verbose"));
fmt::println("Depth : {}", qcir_mgr.get()->calculate_depth());
Expand Down
4 changes: 2 additions & 2 deletions src/device/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,9 +735,9 @@ void Device::print_path(QubitIdType src, QubitIdType dest) const {
}
}
std::vector<PhysicalQubit> const& path = get_path(src, dest);
if (path.front().get_id() != src && path.back().get_id() != dest)
if (path.front().get_id() != src && path.back().get_id() != dest) {
fmt::println("No path between {} and {}", src, dest);
else {
} else {
fmt::println("Path from {} to {}:", src, dest);
size_t cnt = 0;
for (auto& v : path) {
Expand Down
6 changes: 4 additions & 2 deletions src/duostra/mapping_eqv_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ MappingEquivalenceChecker::MappingEquivalenceChecker(QCir* phy, QCir* log, Devic
if (init.empty()) {
auto placer = get_placer(placer_type);
init = placer->place_and_assign(_device);
} else
} else {
_device.place(init);
}
for (auto const& [i, qubit] : tl::views::enumerate(_logical->get_qubits())) {
_dependency[i] = _reverse ? qubit.get_last_gate() : qubit.get_first_gate();
}
Expand Down Expand Up @@ -63,8 +64,9 @@ bool MappingEquivalenceChecker::check() {
}
} else if (phys_gate->get_num_qubits() > 1) {
return false;
} else if (!execute_single(phys_gate))
} else if (!execute_single(phys_gate)) {
return false;
}
}
// REVIEW - check remaining gates in logical are swaps
check_remaining();
Expand Down
2 changes: 2 additions & 0 deletions src/duostra/placer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ std::vector<QubitIdType> BasePlacer::place_and_assign(Device& device) {
*/
std::vector<QubitIdType> RandomPlacer::_place(Device& device) const {
std::vector<QubitIdType> assign;
assign.reserve(device.get_num_qubits());
for (size_t i = 0; i < device.get_num_qubits(); ++i)
assign.emplace_back(i);

Expand All @@ -76,6 +77,7 @@ std::vector<QubitIdType> RandomPlacer::_place(Device& device) const {
*/
std::vector<QubitIdType> StaticPlacer::_place(Device& device) const {
std::vector<QubitIdType> assign;
assign.reserve(device.get_num_qubits());
for (size_t i = 0; i < device.get_num_qubits(); ++i)
assign.emplace_back(i);

Expand Down
2 changes: 1 addition & 1 deletion src/qcir/oracle/pebble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ std::optional<DepGraph> from_xag_cuts(XAG const& xag, std::map<XAGNodeID, XAGCut
};

std::vector<XAGNodeID> optimal_cone_tips = optimal_cut |
views::filter([&is_input](auto const entry) { return !is_input(entry.first); }) |
views::filter([&is_input](auto const& entry) { return !is_input(entry.first); }) |
views::keys |
tl::to<std::vector>();

Expand Down
10 changes: 5 additions & 5 deletions src/qcir/qcir_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ namespace qsyn::qcir {
std::optional<QCir> from_file(std::filesystem::path const& filepath) {
auto const extension = filepath.extension();

if (extension == ".qasm")
if (extension == ".qasm") {
return qcir::from_qasm(filepath);
else if (extension == ".qc")
} else if (extension == ".qc") {
return qcir::from_qc(filepath);
else {
} else {
spdlog::error("File format \"{}\" is not supported!!", extension);
return std::nullopt;
}
Expand Down Expand Up @@ -159,9 +159,9 @@ std::optional<QCir> from_qc(std::filesystem::path const& filepath) {
n_qubit++;
}
}
} else if (line.find('#') == 0 || line.empty())
} else if (line.find('#') == 0 || line.empty()) {
continue;
else if (line.find("BEGIN") == 0 || line.find("begin") == 0) {
} else if (line.find("BEGIN") == 0 || line.find("begin") == 0) {
qcir.add_qubits(n_qubit);
} else if (line.find("END") == 0 || line.find("end") == 0) {
return qcir;
Expand Down
4 changes: 2 additions & 2 deletions src/qsyn/qsyn_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void create_default_qsynrc(dvlab::CommandLineInterface& cli, std::filesystem::pa
namespace fs = std::filesystem;

if (!fs::is_directory(qsynrc_path.parent_path()) && !fs::create_directories(qsynrc_path.parent_path())) {
spdlog::critical("Cannot create directory {}", qsynrc_path.parent_path());
spdlog::critical("Cannot create directory {}", qsynrc_path.parent_path().string());
return;
}
// clang-format off
Expand Down Expand Up @@ -115,7 +115,7 @@ bool read_qsynrc_file(dvlab::CommandLineInterface& cli, std::filesystem::path qs
cli.clear_history();

if (result == dvlab::CmdExecResult::error) {
spdlog::critical("Some errors occurred while reading the qsynrc file from {}", qsynrc_path);
spdlog::critical("Some errors occurred while reading the qsynrc file from {}", qsynrc_path.string());
return false;
}

Expand Down
20 changes: 16 additions & 4 deletions src/tableau/pauli_rotation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,14 @@ struct fmt::formatter<qsyn::experimental::PauliProduct> {

constexpr auto parse(format_parse_context& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == '+' || *it == '-' || *it == ' ')) signedness = *it++;
if (it != end && (*it == 'c' || *it == 'b')) presentation = *it++;
if (it != end && (*it == '+' || *it == '-' || *it == ' ')) {
signedness = *it;
it = std::next(it);
}
if (it != end && (*it == 'c' || *it == 'b')) {
presentation = *it;
it = std::next(it);
}
if (it != end && *it != '}') detail::throw_format_error("invalid format");
return it;
}
Expand All @@ -383,8 +389,14 @@ struct fmt::formatter<qsyn::experimental::PauliRotation> {

constexpr auto parse(format_parse_context& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == '+' || *it == '-' || *it == ' ')) signedness = *it++;
if (it != end && (*it == 'c' || *it == 'b')) presentation = *it++;
if (it != end && (*it == '+' || *it == '-' || *it == ' ')) {
signedness = *it;
it = std::next(it);
}
if (it != end && (*it == 'c' || *it == 'b')) {
presentation = *it;
it = std::next(it);
}
if (it != end && *it != '}') detail::throw_format_error("invalid format");
return it;
}
Expand Down
8 changes: 6 additions & 2 deletions src/tableau/stabilizer_tableau.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,12 @@ struct fmt::formatter<qsyn::experimental::StabilizerTableau> {
char presentation = 'c';
constexpr auto parse(format_parse_context& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == 'c' || *it == 'b')) presentation = *it++;
if (it != end && *it != '}') detail::throw_format_error("invalid format");
if (it != end && (*it == 'c' || *it == 'b')) {
presentation = *it;
it = std::next(it);
}
if (it != end && *it != '}')
detail::throw_format_error("invalid format");
return it;
}

Expand Down
14 changes: 12 additions & 2 deletions src/tableau/tableau.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ class Tableau : public PauliProductTrait<Tableau> {
// FIXME - check if the subtableau has the same number of qubits
_subtableaux.push_back(subtableau);
}
auto push_back(SubTableau&& subtableau) {
// FIXME - check if the subtableau has the same number of qubits
_subtableaux.push_back(std::move(subtableau));
}

template <typename... Args>
auto emplace_back(Args&&... args) {
Expand Down Expand Up @@ -159,7 +163,10 @@ struct fmt::formatter<qsyn::experimental::SubTableau> {
char presentation = 'c';
constexpr auto parse(format_parse_context& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == 'c' || *it == 'b')) presentation = *it++;
if (it != end && (*it == 'c' || *it == 'b')) {
presentation = *it;
it = std::next(it);
}
if (it != end && *it != '}') detail::throw_format_error("invalid format");
return it;
}
Expand Down Expand Up @@ -188,7 +195,10 @@ struct fmt::formatter<qsyn::experimental::Tableau> {
char presentation = 'c';
constexpr auto parse(format_parse_context& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == 'c' || *it == 'b')) presentation = *it++;
if (it != end && (*it == 'c' || *it == 'b')) {
presentation = *it;
it = std::next(it);
}
if (it != end && *it != '}') detail::throw_format_error("invalid format");
return it;
}
Expand Down
1 change: 1 addition & 0 deletions src/tensor/tensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ Tensor<U> operator/(Tensor<U> lhs, Tensor<U> const& rhs) {
template <typename DT>
std::vector<size_t> Tensor<DT>::shape() const {
std::vector<size_t> shape;
shape.reserve(dimension());
for (size_t i = 0; i < dimension(); ++i) {
shape.emplace_back(_tensor.shape(i));
}
Expand Down
3 changes: 2 additions & 1 deletion src/util/data_structure_manager_common_cmd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ Command mgr_delete_cmd(DataStructureManager<T>& mgr) {
mgr.clear();
} else if (!parser.parsed("id")) {
mgr.remove(SIZE_MAX);
} else
} else {
mgr.remove(parser.get<size_t>("id"));
}

return CmdExecResult::done;
}};
Expand Down
Loading