Skip to content

Commit

Permalink
Merge branch 'develop' into conditional-barrier
Browse files Browse the repository at this point in the history
  • Loading branch information
sjdilkes committed Aug 31, 2023
2 parents fe39c11 + ada0a12 commit 016ae57
Show file tree
Hide file tree
Showing 130 changed files with 4,020 additions and 1,106 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ jobs:
- uses: actions/checkout@v3
- name: Install conan
uses: turtlebrowser/[email protected]
with:
version: '2.0.9'
- name: Set up conan
id: conan-setup
run: |
Expand Down Expand Up @@ -424,11 +426,13 @@ jobs:
cd pytket/tests
pip install -r requirements.txt
pytest --ignore=simulator/
- name: Run mypy
- name: Check type stubs are up-to-date and run mypy
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
run: |
pip install -U mypy
cd pytket
./stub_generation/regenerate_stubs
git diff --quiet pytket/_tket && echo "Stubs are up-to-date" || exit 1 # fail if stubs change after regeneration
mypy --config-file=mypy.ini --no-incremental -p pytket -p tests
- name: Upload package
if: github.event_name == 'push' && github.ref == 'refs/heads/develop' && needs.check_changes.outputs.tket_changed == 'true'
Expand Down
8 changes: 2 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
[tool.black]
# ignore auto generated qasm include definitions
exclude = '''
/(
pytket/pytket/qasm/includes
)/
'''
# ignore auto generated qasm include definitions, installed packages, auto-generated stubfiles
exclude = 'pytket/pytket/qasm/includes|^.+\.pyi$'
53 changes: 37 additions & 16 deletions pytket/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,76 +93,97 @@ if (WIN32)
list(APPEND lib_deps bcrypt) # For boost::uuid
endif()

set(HEADER_FILES
binders/include/add_gate.hpp
binders/include/binder_json.hpp
binders/include/binder_utils.hpp
binders/include/deleted_hash.hpp
binders/include/py_operators.hpp
binders/include/typecast.hpp
binders/include/unit_downcast.hpp
binders/include/UnitRegister.hpp
)

pybind11_add_module(circuit
binders/circuit/main.cpp
binders/circuit/unitid.cpp
binders/circuit/boxes.cpp
binders/circuit/classical.cpp
binders/circuit/library.cpp
binders/circuit/Circuit/main.cpp
binders/circuit/Circuit/add_op.cpp
binders/circuit/Circuit/add_classical_op.cpp)
binders/circuit/Circuit/add_classical_op.cpp
${HEADER_FILES})
target_include_directories(circuit PRIVATE binders/include)
target_link_libraries(circuit PRIVATE ${lib_deps})

pybind11_add_module(mapping binders/mapping.cpp)
pybind11_add_module(circuit_library binders/circuit_library.cpp ${HEADER_FILES})
target_include_directories(circuit_library PRIVATE binders/include)
target_link_libraries(circuit_library PRIVATE ${lib_deps})

pybind11_add_module(unit_id binders/unitid.cpp ${HEADER_FILES})
target_include_directories(unit_id PRIVATE binders/include)
target_link_libraries(unit_id PRIVATE ${lib_deps})

pybind11_add_module(mapping binders/mapping.cpp ${HEADER_FILES})
target_include_directories(mapping PRIVATE binders/include)
target_link_libraries(mapping PRIVATE ${lib_deps})

pybind11_add_module(transform binders/transform.cpp)
pybind11_add_module(transform binders/transform.cpp ${HEADER_FILES})
target_include_directories(transform PRIVATE binders/include)
target_link_libraries(transform PRIVATE ${lib_deps})

pybind11_add_module(predicates binders/predicates.cpp)
pybind11_add_module(predicates binders/predicates.cpp ${HEADER_FILES})
target_include_directories(predicates PRIVATE binders/include)
target_link_libraries(predicates PRIVATE ${lib_deps})

pybind11_add_module(passes binders/passes.cpp)
pybind11_add_module(passes binders/passes.cpp ${HEADER_FILES})
target_include_directories(passes PRIVATE binders/include)
target_link_libraries(passes PRIVATE ${lib_deps})

pybind11_add_module(architecture binders/architecture.cpp)
pybind11_add_module(architecture binders/architecture.cpp ${HEADER_FILES})
target_include_directories(architecture PRIVATE binders/include)
target_link_libraries(architecture PRIVATE ${lib_deps})

pybind11_add_module(placement binders/placement.cpp)
pybind11_add_module(placement binders/placement.cpp ${HEADER_FILES})
target_include_directories(placement PRIVATE binders/include)
target_link_libraries(placement PRIVATE ${lib_deps})

pybind11_add_module(partition binders/partition.cpp)
pybind11_add_module(partition binders/partition.cpp ${HEADER_FILES})
target_include_directories(partition PRIVATE binders/include)
target_link_libraries(partition PRIVATE ${lib_deps})

pybind11_add_module(pauli binders/pauli.cpp)
pybind11_add_module(pauli binders/pauli.cpp ${HEADER_FILES})
target_include_directories(pauli PRIVATE binders/include)
target_link_libraries(pauli PRIVATE ${lib_deps})

pybind11_add_module(logging binders/logging.cpp)
pybind11_add_module(logging binders/logging.cpp ${HEADER_FILES})
target_include_directories(logging PRIVATE binders/include)
target_link_libraries(logging PRIVATE ${lib_deps})

pybind11_add_module(utils_serialization binders/utils_serialization.cpp)
pybind11_add_module(utils_serialization binders/utils_serialization.cpp ${HEADER_FILES})
target_include_directories(utils_serialization PRIVATE binders/include)
target_link_libraries(utils_serialization PRIVATE ${lib_deps})

pybind11_add_module(tailoring binders/tailoring.cpp)
pybind11_add_module(tailoring binders/tailoring.cpp ${HEADER_FILES})
target_include_directories(tailoring PRIVATE binders/include)
target_link_libraries(tailoring PRIVATE ${lib_deps})

pybind11_add_module(tableau binders/tableau.cpp)
pybind11_add_module(tableau binders/tableau.cpp ${HEADER_FILES})
target_include_directories(tableau PRIVATE binders/include)
target_link_libraries(tableau PRIVATE ${lib_deps})

pybind11_add_module(zx
binders/zx/diagram.cpp
binders/zx/rewrite.cpp)
binders/zx/rewrite.cpp
${HEADER_FILES})
target_include_directories(zx PRIVATE binders/include)
target_link_libraries(zx PRIVATE ${lib_deps})

install(TARGETS
logging
utils_serialization
circuit
circuit_library
unit_id
passes
predicates
partition
Expand Down
6 changes: 6 additions & 0 deletions pytket/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ To generate a test coverage report:
pytest --hypothesis-seed=1 --cov=../pytket --cov-branch --cov-report=html --cov-report=xml:htmlcov/cov.xml
```

## Stub generation

Python type stubs are generated from the `pybind11` modules using mypy's `stubgen`. Changes to the
binding code under [binders](binders) (or, in some cases, to `tket` itself) may require stub regeneration.
See [stub_generation/README.md](stub_generation/README.md) for more information.

## Building without conan

It is possible to build pytket without using conan at all: see
Expand Down
43 changes: 28 additions & 15 deletions pytket/binders/architecture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@

#include "tket/Architecture/Architecture.hpp"

#include <pybind11/eigen.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include "binder_json.hpp"
#include "binder_utils.hpp"
#include "tket/Circuit/Circuit.hpp"
#include "deleted_hash.hpp"
#include "py_operators.hpp"
#include "tket/Utils/Json.hpp"
#include "typecast.hpp"

Expand All @@ -31,9 +28,11 @@ using json = nlohmann::json;
namespace tket {

PYBIND11_MODULE(architecture, m) {
py::module::import("pytket._tket.unit_id");
py::class_<Architecture, std::shared_ptr<Architecture>>(
m, "Architecture",
"Class describing the connectivity of qubits on a general device.")
.def(py::init<>(), "Produces an empty architecture")
.def(
py::init([](const std::vector<std::pair<unsigned, unsigned>>
&connections) { return Architecture(connections); }),
Expand Down Expand Up @@ -77,25 +76,32 @@ PYBIND11_MODULE(architecture, m) {
"Returns the coupling map of the Architecture as "
"UnitIDs. ")
.def(
"to_dict", [](const Architecture &arch) { return json(arch); },
"to_dict",
[](const Architecture &arch) {
return py::object(json(arch)).cast<py::dict>();
},
"Return a JSON serializable dict representation of "
"the Architecture."
"\n\n:return: dict containing nodes and links.")
.def_static(
"from_dict", [](const json &j) { return j.get<Architecture>(); },
"from_dict",
[](const py::dict &architecture_dict) {
return json(architecture_dict).get<Architecture>();
},
"Construct Architecture instance from JSON serializable "
"dict representation of the Architecture.")
// as far as Python is concerned, Architectures are immutable
.def(
"__deepcopy__",
[](const Architecture &arc, py::dict = py::dict()) { return arc; })
"__deepcopy__", [](const Architecture &arc,
const py::dict & = py::dict()) { return arc; })
.def(
"__repr__",
[](const Architecture &arc) {
return "<tket::Architecture, nodes=" +
std::to_string(arc.n_nodes()) + ">";
})
.def(py::self == py::self);
.def("__eq__", &py_equals<Architecture>)
.def("__hash__", &deletedHash<Architecture>, deletedHashDocstring);
py::class_<SquareGrid, std::shared_ptr<SquareGrid>, Architecture>(
m, "SquareGrid",
"Inherited Architecture class for qubits arranged in a square lattice of "
Expand Down Expand Up @@ -182,25 +188,32 @@ PYBIND11_MODULE(architecture, m) {
"FullyConnected Architecture",
py::arg("n"), py::arg("label") = "fcNode")
.def(
"__deepcopy__",
[](const FullyConnected &arc, py::dict = py::dict()) { return arc; })
"__deepcopy__", [](const FullyConnected &arc,
const py::dict & = py::dict()) { return arc; })
.def(
"__repr__",
[](const FullyConnected &arc) {
return "<tket::FullyConnected, nodes=" +
std::to_string(arc.n_nodes()) + ">";
})
.def(py::self == py::self)
.def("__eq__", &py_equals<FullyConnected>)
.def("__hash__", &deletedHash<FullyConnected>, deletedHashDocstring)
.def_property_readonly(
"nodes", &FullyConnected::get_all_nodes_vec,
"All nodes of the architecture as :py:class:`Node` objects.")
.def(
"to_dict", [](const FullyConnected &arch) { return json(arch); },
"to_dict",
[](const FullyConnected &arch) {
return py::object(json(arch)).cast<py::dict>();
},
"JSON-serializable dict representation of the architecture."
"\n\n"
":return: dict containing nodes")
.def_static(
"from_dict", [](const json &j) { return j.get<FullyConnected>(); },
"from_dict",
[](const py::dict &fully_connected_dict) {
return json(fully_connected_dict).get<FullyConnected>();
},
"Construct FullyConnected instance from dict representation.");
}
} // namespace tket
20 changes: 9 additions & 11 deletions pytket/binders/circuit/Circuit/add_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <pybind11/eigen.h>
#include <pybind11/functional.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <optional>
#include <vector>

#include "UnitRegister.hpp"
#include "add_gate.hpp"
#include "binder_utils.hpp"
#include "tket/Circuit/Boxes.hpp"
#include "tket/Circuit/Circuit.hpp"
#include "tket/Circuit/ClassicalExpBox.hpp"
Expand All @@ -34,7 +31,6 @@
#include "tket/Circuit/ToffoliBox.hpp"
#include "tket/Converters/PhasePoly.hpp"
#include "tket/Gate/OpPtrFunctions.hpp"
#include "tket/Ops/Op.hpp"
#include "typecast.hpp"
namespace py = pybind11;

Expand Down Expand Up @@ -345,7 +341,7 @@ void init_circuit_add_op(py::class_<Circuit, std::shared_ptr<Circuit>> &c) {

.def(
"add_classicalexpbox_bit",
[](Circuit *circ, const py::object exp,
[](Circuit *circ, const py::object &exp,
const std::vector<Bit> &outputs, const py::kwargs &kwargs) {
auto inputs = exp.attr("all_inputs")().cast<std::set<Bit>>();
std::vector<Bit> o_vec, io_vec;
Expand Down Expand Up @@ -378,7 +374,7 @@ void init_circuit_add_op(py::class_<Circuit, std::shared_ptr<Circuit>> &c) {
py::arg("expression"), py::arg("target"))
.def(
"add_classicalexpbox_register",
[](Circuit *circ, const py::object exp,
[](Circuit *circ, const py::object &exp,
const std::vector<Bit> &outputs, const py::kwargs &kwargs) {
auto inputs =
exp.attr("all_inputs")().cast<std::set<BitRegister>>();
Expand Down Expand Up @@ -631,8 +627,9 @@ void init_circuit_add_op(py::class_<Circuit, std::shared_ptr<Circuit>> &c) {
const std::optional<unsigned> &ancilla,
const std::optional<std::string> &name) -> Circuit * {
std::vector<Qubit> qubits_;
for (unsigned i = 0; i < qubits.size(); ++i) {
qubits_.push_back(Qubit(qubits[i]));
qubits_.reserve(qubits.size());
for (unsigned int qubit : qubits) {
qubits_.emplace_back(qubit);
}
std::optional<Qubit> ancilla_;
if (ancilla == std::nullopt) {
Expand Down Expand Up @@ -674,8 +671,9 @@ void init_circuit_add_op(py::class_<Circuit, std::shared_ptr<Circuit>> &c) {
const std::vector<unsigned> &qubits, const unsigned &ancilla,
const std::optional<std::string> &name) -> Circuit * {
std::vector<Qubit> qubits_;
for (unsigned i = 0; i < qubits.size(); ++i) {
qubits_.push_back(Qubit(qubits[i]));
qubits_.reserve(qubits.size());
for (unsigned int qubit : qubits) {
qubits_.emplace_back(qubit);
}
Qubit ancilla_(ancilla);
circ->add_assertion(box, qubits_, ancilla_, name);
Expand Down
Loading

0 comments on commit 016ae57

Please sign in to comment.