diff --git a/CondaPkg.toml b/CondaPkg.toml index 3dc251e50..b4d9a9447 100644 --- a/CondaPkg.toml +++ b/CondaPkg.toml @@ -1,4 +1,5 @@ [deps] +qibo = "" qiskit = "" [pip.deps] diff --git a/ext/TenetPythonCallExt/Qibo.jl b/ext/TenetPythonCallExt/Qibo.jl new file mode 100644 index 000000000..2c7a5c987 --- /dev/null +++ b/ext/TenetPythonCallExt/Qibo.jl @@ -0,0 +1,40 @@ +function Tenet.Quantum(::Val{:qibo}, pyobj::Py) + qibo = pyimport("qibo") + qibo.set_backend("numpy") + if !pyissubclass(pytype(pyobj), qibo.models.circuit.Circuit) + throw(ArgumentError("Expected a qibo.models.circuit.Circuit object, got $(pyfullyqualname(pyobj))")) + end + + n = pyconvert(Int, pyobj.nqubits) + gen = Tenet.IndexCounter() + + wire = [[Tenet.nextindex!(gen)] for _ in 1:n] + tn = TensorNetwork() + circgates = pyobj.queue + + for gate in circgates + matrix = pyconvert(Array, gate.matrix()) + + qubits = map(x -> pyconvert(Int, x), gate.qubits) + array = reshape(matrix, fill(2, 2 * length(qubits))...) + + inds = (x -> collect(Iterators.flatten(zip(x...))))( + map(qubits) do l + l += 1 + from, to = last(wire[l]), Tenet.nextindex!(gen) + push!(wire[l], to) + (from, to) + end, + ) + + tensor = Tensor(array, Tuple(inds)) + push!(tn, tensor) + end + + sites = merge( + Dict([Site(site; dual=true) => first(index) for (site, index) in enumerate(wire) if first(index) ∈ tn]), + Dict([Site(site; dual=false) => last(index) for (site, index) in enumerate(wire) if last(index) ∈ tn]), + ) + + return Quantum(tn, sites) +end diff --git a/ext/TenetPythonCallExt/TenetPythonCallExt.jl b/ext/TenetPythonCallExt/TenetPythonCallExt.jl index 836cae6c9..f85f5303a 100644 --- a/ext/TenetPythonCallExt/TenetPythonCallExt.jl +++ b/ext/TenetPythonCallExt/TenetPythonCallExt.jl @@ -18,5 +18,6 @@ end include("Qiskit.jl") include("Quimb.jl") +include("Qibo.jl") end diff --git a/test/integration/python/test_qibo.jl b/test/integration/python/test_qibo.jl new file mode 100644 index 000000000..e130df76e --- /dev/null +++ b/test/integration/python/test_qibo.jl @@ -0,0 +1,18 @@ +@testset "qibo" begin + using PythonCall + qibo = pyimport("qibo") + + circuit = qibo.Circuit(3) + circuit.add(qibo.gates.H(0)) + circuit.add(qibo.gates.H(1)) + circuit.add(qibo.gates.CNOT(1, 2)) + circuit.add(qibo.gates.CNOT(0, 2)) + circuit.add(qibo.gates.H(0)) + circuit.add(qibo.gates.H(1)) + circuit.add(qibo.gates.H(2)) + + tn = Tenet.Quantum(circuit) + @test issetequal(sites(tn; set=:inputs), adjoint.(Site.([1, 2, 3]))) + @test issetequal(sites(tn; set=:outputs), Site.([1, 2, 3])) + @test Tenet.ntensors(tn) == 7 +end diff --git a/test/runtests.jl b/test/runtests.jl index e830be926..9867e8c48 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -29,6 +29,7 @@ if VERSION >= v"1.10" @testset "Python" begin include("integration/python/test_quimb.jl") include("integration/python/test_qiskit.jl") + include("integration/python/test_qibo.jl") end end end