Skip to content

Commit

Permalink
change: Remove PythonCall dep and extension (#51)
Browse files Browse the repository at this point in the history
* change: Remove PythonCall dep and extension
  • Loading branch information
kshyatt-aws authored Sep 24, 2024
1 parent 944f1fd commit 23991af
Show file tree
Hide file tree
Showing 16 changed files with 214 additions and 202 deletions.
8 changes: 3 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
Expand All @@ -21,12 +22,9 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[weakdeps]
Braket = "19504a0f-b47d-4348-9127-acc6cc69ef67"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"

[extensions]
BraketSimulatorBraketExt = "Braket"
BraketSimulatorPythonExt = ["JSON3", "PythonCall"]

[compat]
AbstractTrees = "=0.4.5"
Expand All @@ -43,7 +41,7 @@ LinearAlgebra = "1.6"
Logging = "1.6"
OrderedCollections = "=1.6.3"
PrecompileTools = "=1.2.1"
PythonCall = "=0.9.22"
PythonCall = "=0.9.23"
Random = "1.6"
StaticArrays = "1.9"
StatsBase = "0.34"
Expand All @@ -62,4 +60,4 @@ PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Aqua", "Braket", "JSON3", "Test", "Logging", "PythonCall"]
test = ["Aqua", "Braket", "JSON3", "PythonCall", "Test", "Logging"]
6 changes: 5 additions & 1 deletion coverage.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Coverage
# process '*.cov' files
coverage = process_folder()
coverage = append!(coverage, process_folder("ext/BraketSimulatorPythonExt/"))
coverage = append!(coverage, process_folder("ext/BraketSimulatorBraketExt/"))
coverage = merge_coverage_counts(coverage)
# Get total coverage for all Julia files
Expand All @@ -17,6 +16,11 @@ for fi in readdir("src")
println("Coverage for file $fi: $(get_summary(process_file(joinpath("src", fi))))")
end
end
for fi in readdir("ext/BraketSimulatorBraketExt")
if endswith(fi, ".jl")
println("Coverage for file $fi: $(get_summary(process_file(joinpath("ext/BraketSimulatorBraketExt", fi))))")
end
end

# uncomment this if you have `genhtml` installed
# to generate HTML coverage info
Expand Down
1 change: 0 additions & 1 deletion docs/src/circuits.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ BraketSimulator.FreeParameter
BraketSimulator.Measure
BraketSimulator.Instruction
BraketSimulator.QubitSet
BraketSimulator.Qubit
BraketSimulator.qubit_count
BraketSimulator.qubits
BraketSimulator.basis_rotation_instructions!
Expand Down
48 changes: 0 additions & 48 deletions ext/BraketSimulatorPythonExt/BraketSimulatorPythonExt.jl

This file was deleted.

104 changes: 88 additions & 16 deletions src/BraketSimulator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ using
Dates,
Combinatorics,
LinearAlgebra,
JSON3,
StaticArrays,
StatsBase,
UUIDs,
Expand Down Expand Up @@ -145,11 +146,7 @@ function _generate_results(
) where {D<:AbstractSimulator}
result_values = map(result_type -> calculate(result_type, simulator), result_types)
ir_results = map(StructTypes.lower, result_types)
results = map(zip(ir_results, result_values)) do (ir, val)
ir_val = complex_matrix_to_ir(val)
return ResultTypeValue(ir, ir_val)
end
return results
return [ResultTypeValue(ir_results[r_ix], complex_matrix_to_ir(result_values[r_ix])) for r_ix in 1:length(result_values)]
end

_translate_result_type(r::IR.Amplitude) = Amplitude(r.states)
Expand Down Expand Up @@ -202,8 +199,10 @@ parsing and the qubit count of the circuit.
"""
function _prepare_program(circuit_ir::OpenQasmProgram, inputs::Dict{String, <:Any}, shots::Int)
ir_inputs = isnothing(circuit_ir.inputs) ? Dict{String, Float64}() : circuit_ir.inputs
circuit = Circuit(circuit_ir.source, merge(ir_inputs, inputs))
n_qubits = qubit_count(circuit)
merged_inputs = merge(ir_inputs, inputs)
src = circuit_ir.source::String
circuit = Quasar.to_circuit(src, merged_inputs)
n_qubits = qubit_count(circuit)
if shots > 0
_verify_openqasm_shots_observables(circuit, n_qubits)
basis_rotation_instructions!(circuit)
Expand Down Expand Up @@ -381,6 +380,68 @@ function simulate(simulator::AbstractSimulator,
return results
end

# these functions are for calls from an "external" language
# like Python or Rust, when we're calling this package from a
# separate process and thus don't want to have to IPC large
# blobs of data back and forth/deal with having to serialize
# Julia objects
function create_sim(simulator_id::String, shots::Int)
return if simulator_id == "braket_sv_v2"
StateVectorSimulator(0, shots)
elseif simulator_id == "braket_dm_v2"
DensityMatrixSimulator(0, shots)
end
end

function _mmap_large_result_values(results)
to_mmap = findall(rt->sizeof(rt.value) > 2^20, results.resultTypes)
isempty(to_mmap) && return nothing, nothing
mmap_files = String[]
obj_lengths = Int[]
for r_ix in to_mmap
push!(obj_lengths, length(results.resultTypes[r_ix].value))
tmp_path, io = mktemp()
write(io, results.resultTypes[r_ix].value)
empty!(results.resultTypes[r_ix].value)
close(io)
push!(mmap_files, tmp_path)
end
py_paths = tuple(mmap_files...)
py_lens = tuple(obj_lengths...)
mmap_files = nothing
obj_lengths = nothing
return py_paths, py_lens
end

function BraketSimulator.simulate(simulator_id::String, task_spec::String, py_inputs::String, shots::Int; kwargs...)
inputs = JSON3.read(py_inputs, Dict{String, Any})
jl_spec = BraketSimulator.OpenQasmProgram(BraketSimulator.braketSchemaHeader("braket.ir.openqasm.program", "1"), task_spec, inputs)
simulator = create_sim(simulator_id, shots)
jl_results = simulate(simulator, jl_spec, shots; kwargs...)
py_paths, py_lens = _mmap_large_result_values(jl_results)
py_results = JSON3.write(jl_results)
simulator = nothing
inputs = nothing
jl_spec = nothing
jl_results = nothing
return py_results, py_paths, py_lens
end
function BraketSimulator.simulate(simulator_id::String, task_specs::AbstractVector, py_inputs::String, shots::Int; kwargs...)
inputs = JSON3.read(py_inputs, Vector{Dict{String, Any}})
jl_specs = map(zip(task_specs, inputs)) do (task_spec, input)
BraketSimulator.OpenQasmProgram(BraketSimulator.braketSchemaHeader("braket.ir.openqasm.program", "1"), task_spec, input)
end
simulator = create_sim(simulator_id, shots)
jl_results = simulate(simulator, jl_specs, shots; kwargs...)
paths_and_lens = JSON3.write(map(_mmap_large_result_values, jl_results))
jsons = JSON3.write(jl_results)
simulator = nothing
jl_results = nothing
inputs = nothing
jl_specs = nothing
return jsons, paths_and_lens
end

include("result_types.jl")
include("properties.jl")
include("sv_simulator.jl")
Expand Down Expand Up @@ -699,6 +760,7 @@ include("dm_simulator.jl")
#pragma braket result probability
#pragma braket result expectation x(q[0])
#pragma braket result variance x(q[0]) @ y(q[1])
#pragma braket result variance y(q[0])
"""
shots_results_qasm = """
OPENQASM 3.0;
Expand All @@ -714,48 +776,58 @@ include("dm_simulator.jl")
simulator = StateVectorSimulator(5, 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), custom_qasm, nothing)
simulate(simulator, oq3_program, 100)
simulate("braket_sv_v2", custom_qasm, "{}", 100)

simulator = DensityMatrixSimulator(2, 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), noise_qasm, nothing)
simulate(simulator, oq3_program, 100)
simulate(simulator, [oq3_program, oq3_program], 100)
simulate("braket_dm_v2", noise_qasm, "{}", 100)
simulate("braket_dm_v2", [noise_qasm, noise_qasm], "[{}, {}]", 100)

simulator = StateVectorSimulator(3, 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), unitary_qasm, nothing)
simulate(simulator, oq3_program, 100)
simulate(simulator, [oq3_program, oq3_program], 100)
simulate("braket_sv_v2", unitary_qasm, "{}", 100)
simulate("braket_sv_v2", [unitary_qasm, unitary_qasm], "[{}, {}]", 100)

simulator = StateVectorSimulator(6, 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), sv_adder_qasm, Dict("a_in"=>3, "b_in"=>7))
simulate(simulator, oq3_program, 0)

simulate("braket_sv_v2", sv_adder_qasm, "{\"a_in\":3,\"b_in\":7}", 100)

simulator = StateVectorSimulator(16, 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), grcs_16_qasm, nothing)
simulate(simulator, oq3_program, 0)
simulate("braket_sv_v2", grcs_16_qasm, "{}", 0)

simulator = StateVectorSimulator(2, 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), vqe_qasm, nothing)
simulate(simulator, oq3_program, 100)
simulate("braket_sv_v2", vqe_qasm, "{}", 100)

sv_simulator = StateVectorSimulator(3, 0)
dm_simulator = DensityMatrixSimulator(3, 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), all_gates_qasm, Dict("theta"=>0.665))
simulate(sv_simulator, oq3_program, 100)
simulate(dm_simulator, oq3_program, 100)
simulate("braket_sv_v2", all_gates_qasm, "{\"theta\":0.665}", 100)
simulate("braket_dm_v2", all_gates_qasm, "{\"theta\":0.665}", 100)

sv_simulator = StateVectorSimulator(2, 0)
dm_simulator = DensityMatrixSimulator(2, 0)
sv_oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), sv_exact_results_qasm, nothing)
dm_oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), dm_exact_results_qasm, nothing)
results = simulate(sv_simulator, sv_oq3_program, 0)
map(StructTypes.lower, results.resultTypes)
results = simulate(dm_simulator, dm_oq3_program, 0)
map(StructTypes.lower, results.resultTypes)
simulate(sv_simulator, sv_oq3_program, 0)
simulate("braket_sv_v2", sv_exact_results_qasm, "{}", 0)
simulate(dm_simulator, dm_oq3_program, 0)
simulate("braket_dm_v2", dm_exact_results_qasm, "{}", 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), shots_results_qasm, nothing)
results = simulate(sv_simulator, oq3_program, 10)
map(StructTypes.lower, results.resultTypes)
results = simulate(dm_simulator, oq3_program, 10)
map(StructTypes.lower, results.resultTypes)
simulate(sv_simulator, oq3_program, 10)
simulate(dm_simulator, oq3_program, 10)
simulate("braket_sv_v2", shots_results_qasm, "{}", 10)
simulate("braket_dm_v2", shots_results_qasm, "{}", 10)
end
end
end # module BraketSimulator
Loading

0 comments on commit 23991af

Please sign in to comment.