From b50615ffd596c39da3e4037dbb65536f3e08bfa0 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Sat, 8 Jun 2024 17:54:33 +0500 Subject: [PATCH 01/18] [Feature]: Support for Braket Direct reservations --- src/device.jl | 44 ++++++++++++++++++++++++++++++++++++++++++++ test/device.jl | 25 +++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/device.jl b/src/device.jl index 2926a1fe..c337417e 100644 --- a/src/device.jl +++ b/src/device.jl @@ -336,3 +336,47 @@ function get_devices(; arns::Vector{String}=String[], names::Vector{String}=Stri end return sort(collect(values(device_map)), by=(x->getproperty(x, Symbol("_"*order_by)))) end + +# DirectReservation structure +mutable struct DirectReservation + device_arn::String + reservation_arn::String + is_active::Bool +end + +function DirectReservation(device_arn::String, reservation_arn::String) + return DirectReservation(device_arn, reservation_arn, false) +end + +# Start reservation function +function start_reservation!(state::DirectReservation) + if state.is_active + error("Another reservation is already active.") + end + state.is_active = true + ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] = state.device_arn + ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] = state.reservation_arn +end + +# Stop reservation function +function stop_reservation!(state::DirectReservation) + if !state.is_active + @warn "Reservation is not active." + end + state.is_active = false + delete!(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") + delete!(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") +end + +# Direct reservation function +function direct_reservation(reservation::DirectReservation, func::Function) + env_vars = mock_env_vars() + withenv(env_vars) do + start_reservation!(reservation) + try + func() + finally + stop_reservation!(reservation) + end + end +end diff --git a/test/device.jl b/test/device.jl index 09d64aba..7183596a 100644 --- a/test/device.jl +++ b/test/device.jl @@ -268,3 +268,28 @@ MOCK_DWAVE_QPU() = """{ end end end + +@testset "DirectReservation Tests" begin + # Creating a DirectReservation + @testset "Creating DirectReservation" begin + reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) + @test reservation.device_arn == DEVICE_ARN + @test reservation.reservation_arn == RESERVATION_ARN + @test reservation.is_active == false + end + + # Starting and stopping a reservation + @testset "Starting and Stopping Reservation" begin + reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) + # Start reservation + Braket.start_reservation!(reservation) + @test reservation.is_active == true + @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN + @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN + # Stop reservation + Braket.stop_reservation!(reservation) + @test reservation.is_active == false + @test !haskey(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") + @test !haskey(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") + end +end From 42a507581d6bb746a4f568e806f79d194c597e06 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Sat, 8 Jun 2024 18:12:27 +0500 Subject: [PATCH 02/18] [Feature]: Support for Braket Direct reservations - adding docstrings and tests --- src/device.jl | 18 +++++++++++++++++- test/device.jl | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/device.jl b/src/device.jl index c337417e..d2ca8d1e 100644 --- a/src/device.jl +++ b/src/device.jl @@ -337,7 +337,23 @@ function get_devices(; arns::Vector{String}=String[], names::Vector{String}=Stri return sort(collect(values(device_map)), by=(x->getproperty(x, Symbol("_"*order_by)))) end -# DirectReservation structure +""" + DirectReservation(device::Union{Device, String, Nothing}, reservation_arn::Union{String, Nothing}) + +A context manager that adjusts AwsQuantumTasks generated within the context to utilize a reservation ARN +for all tasks targeting the designated device. Notably, this manager permits only one reservation +at a time. + +Reservations are specific to AWS accounts and devices. Only the AWS account that initiated the +reservation can utilize the reservation ARN. Moreover, the reservation ARN is solely valid on the +reserved device within the specified start and end times. + +Arguments: +- device (Device | str | Nothing): The Braket device for which you possess a reservation ARN, or + alternatively, the device ARN. +- reservation_arn (str | Nothing): The Braket Direct reservation ARN to be implemented for all + quantum tasks executed within the contex +""" mutable struct DirectReservation device_arn::String reservation_arn::String diff --git a/test/device.jl b/test/device.jl index 7183596a..db2340e8 100644 --- a/test/device.jl +++ b/test/device.jl @@ -269,6 +269,10 @@ MOCK_DWAVE_QPU() = """{ end end +# Constants +RESERVATION_ARN = "arn:aws:braket:us-east-1:123456789:reservation/uuid" +DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" + @testset "DirectReservation Tests" begin # Creating a DirectReservation @testset "Creating DirectReservation" begin From c6a2bb386419d2bfb9057861aefe8e00d6436a5e Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Sat, 8 Jun 2024 18:51:57 +0500 Subject: [PATCH 03/18] [Feature]: Support for Braket Direct reservations - minor cleanup --- src/device.jl | 18 +++--------------- test/device.jl | 2 ++ 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/device.jl b/src/device.jl index d2ca8d1e..c09f546c 100644 --- a/src/device.jl +++ b/src/device.jl @@ -344,8 +344,9 @@ A context manager that adjusts AwsQuantumTasks generated within the context to u for all tasks targeting the designated device. Notably, this manager permits only one reservation at a time. -Reservations are specific to AWS accounts and devices. Only the AWS account that initiated the -reservation can utilize the reservation ARN. Moreover, the reservation ARN is solely valid on the +[Reservations](https://docs.aws.amazon.com/braket/latest/developerguide/braket-reservations.html) +are specific to AWS accounts and devices. Only the AWS account that initiated the reservation +can utilize the reservation ARN. Moreover, the reservation ARN is solely valid on the reserved device within the specified start and end times. Arguments: @@ -383,16 +384,3 @@ function stop_reservation!(state::DirectReservation) delete!(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") delete!(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") end - -# Direct reservation function -function direct_reservation(reservation::DirectReservation, func::Function) - env_vars = mock_env_vars() - withenv(env_vars) do - start_reservation!(reservation) - try - func() - finally - stop_reservation!(reservation) - end - end -end diff --git a/test/device.jl b/test/device.jl index db2340e8..ce45ca03 100644 --- a/test/device.jl +++ b/test/device.jl @@ -285,11 +285,13 @@ DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" # Starting and stopping a reservation @testset "Starting and Stopping Reservation" begin reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) + # Start reservation Braket.start_reservation!(reservation) @test reservation.is_active == true @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN + # Stop reservation Braket.stop_reservation!(reservation) @test reservation.is_active == false From c5c72540edb0c4e193c3b4ecff873e25db140b5b Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Sat, 8 Jun 2024 20:13:56 +0500 Subject: [PATCH 04/18] [Feature]: Support for Braket Direct reservations - Adding more tests --- src/device.jl | 15 +++++++++++++++ test/device.jl | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/device.jl b/src/device.jl index c09f546c..669bfdf2 100644 --- a/src/device.jl +++ b/src/device.jl @@ -384,3 +384,18 @@ function stop_reservation!(state::DirectReservation) delete!(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") delete!(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") end + +function direct_reservation(reservation::DirectReservation, func::Function) + env_vars = Dict( + "AMZN_BRAKET_RESERVATION_DEVICE_ARN" => reservation.device_arn, + "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN" => reservation.reservation_arn + ) + withenv(pairs(env_vars)...) do + start_reservation!(reservation) + try + func() + finally + stop_reservation!(reservation) + end + end +end diff --git a/test/device.jl b/test/device.jl index ce45ca03..be8f73a2 100644 --- a/test/device.jl +++ b/test/device.jl @@ -297,5 +297,23 @@ DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" @test reservation.is_active == false @test !haskey(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") @test !haskey(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") + end + + function test_func() + println("Executing within reservation context") + # Add actions as needed + @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN + @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN + end + + @testset "Direct Reservation Function" begin + @test Braket.direct_reservation(reservation, test_func) + end + + @testset "Invalid Device Type" begin + invalid_device = 12345 # Not a valid device type + @test_throws UndefVarError DirectReservation(invalid_device, RESERVATION_ARN) + end + end From 4365624b0253cbee9335ee8a2a8015dd2c73ef2a Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Sat, 8 Jun 2024 20:31:57 +0500 Subject: [PATCH 05/18] [Feature]: Support for Braket Direct reservations - Final Polish --- test/device.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/device.jl b/test/device.jl index be8f73a2..65995675 100644 --- a/test/device.jl +++ b/test/device.jl @@ -302,13 +302,15 @@ DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" function test_func() println("Executing within reservation context") + return 5 # Add actions as needed @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN end @testset "Direct Reservation Function" begin - @test Braket.direct_reservation(reservation, test_func) + reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) + @test Braket.direct_reservation(reservation, test_func) == 5 end @testset "Invalid Device Type" begin From 16b0d90e2007e7253850d3e5673f76b9f617ff0f Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Sat, 8 Jun 2024 20:34:55 +0500 Subject: [PATCH 06/18] [Feature]: Support for Braket Direct reservations - Improving Indentation --- test/device.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/device.jl b/test/device.jl index 65995675..ef89dd88 100644 --- a/test/device.jl +++ b/test/device.jl @@ -302,7 +302,7 @@ DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" function test_func() println("Executing within reservation context") - return 5 + return 5 # Add actions as needed @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN From 082ece3c366d2e1627f6a40e3b977abc32ed316b Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Wed, 12 Jun 2024 23:47:10 +0500 Subject: [PATCH 07/18] [Feature]: Support for Braket Direct reservations - codereview --- src/device.jl | 10 ++--- test/integ_tests/direct_reservtions.jl | 54 ++++++++++++++++++++++++++ test/integ_tests/runtests.jl | 1 + 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 test/integ_tests/direct_reservtions.jl diff --git a/src/device.jl b/src/device.jl index 669bfdf2..3748f08c 100644 --- a/src/device.jl +++ b/src/device.jl @@ -350,10 +350,10 @@ can utilize the reservation ARN. Moreover, the reservation ARN is solely valid o reserved device within the specified start and end times. Arguments: -- device (Device | str | Nothing): The Braket device for which you possess a reservation ARN, or +- device (Device | string | Nothing): The Braket device for which you possess a reservation ARN, or alternatively, the device ARN. - reservation_arn (str | Nothing): The Braket Direct reservation ARN to be implemented for all - quantum tasks executed within the contex + quantum tasks executed within the startreservation and stopreservation """ mutable struct DirectReservation device_arn::String @@ -361,9 +361,7 @@ mutable struct DirectReservation is_active::Bool end -function DirectReservation(device_arn::String, reservation_arn::String) - return DirectReservation(device_arn, reservation_arn, false) -end +DirectReservation(device_arn::String, reservation_arn::String) = DirectReservation(device_arn, reservation_arn, false) # Start reservation function function start_reservation!(state::DirectReservation) @@ -394,6 +392,8 @@ function direct_reservation(reservation::DirectReservation, func::Function) start_reservation!(reservation) try func() + catch e + error("Error during reservation with device ARN $(reservation.device_arn): $(e)") finally stop_reservation!(reservation) end diff --git a/test/integ_tests/direct_reservtions.jl b/test/integ_tests/direct_reservtions.jl new file mode 100644 index 00000000..db8567b7 --- /dev/null +++ b/test/integ_tests/direct_reservtions.jl @@ -0,0 +1,54 @@ +using Braket, Test, Mocking, JSON3, Dates, Graphs +using Braket: status +Mocking.activate() + +# Constants +RESERVATION_ARN = "arn:aws:braket:us-east-1:123456789:reservation/uuid" +DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" + +@testset "DirectReservation Tests" begin + # Creating a DirectReservation + @testset "Creating DirectReservation" begin + reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) + @test reservation.device_arn == DEVICE_ARN + @test reservation.reservation_arn == RESERVATION_ARN + @test reservation.is_active == false + end + + # Starting and stopping a reservation + @testset "Starting and Stopping Reservation" begin + reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) + + # Start reservation + Braket.start_reservation!(reservation) + @test reservation.is_active == true + @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN + @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN + + # Stop reservation + Braket.stop_reservation!(reservation) + @test reservation.is_active == false + @test !haskey(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") + @test !haskey(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") + + end + + function test_func() + println("Executing within reservation context") + return 5 + # Add actions as needed + @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN + @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN + end + + @testset "Direct Reservation Function" begin + reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) + @test Braket.direct_reservation(reservation, test_func) == 5 + end + + @testset "Invalid Device Type" begin + invalid_device = 12345 # Not a valid device type + @test_throws UndefVarError DirectReservation(invalid_device, RESERVATION_ARN) + end + +end diff --git a/test/integ_tests/runtests.jl b/test/integ_tests/runtests.jl index 233e718d..d324c1fb 100644 --- a/test/integ_tests/runtests.jl +++ b/test/integ_tests/runtests.jl @@ -6,6 +6,7 @@ s3_destination_folder = Braket.default_task_bucket() include("adjoint_gradient.jl") include("create_local_quantum_job.jl") include("create_quantum_job.jl") +include("direct_reservtions.jl") include("job_macro.jl") include("measure.jl") include("cost_tracking.jl") From 3db59121b1cfcf7d81ecb989335788ed2ba5600b Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Thu, 13 Jun 2024 00:05:46 +0500 Subject: [PATCH 08/18] [Feature]: Support for Braket Direct reservations - codereview --- test/device.jl | 4 ++++ test/integ_tests/direct_reservtions.jl | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/test/device.jl b/test/device.jl index ef89dd88..6ddbb6b7 100644 --- a/test/device.jl +++ b/test/device.jl @@ -286,6 +286,10 @@ DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" @testset "Starting and Stopping Reservation" begin reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) + # Start reservation + @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == nothing || ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN + @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == nothing || ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN + # Start reservation Braket.start_reservation!(reservation) @test reservation.is_active == true diff --git a/test/integ_tests/direct_reservtions.jl b/test/integ_tests/direct_reservtions.jl index db8567b7..43462e4b 100644 --- a/test/integ_tests/direct_reservtions.jl +++ b/test/integ_tests/direct_reservtions.jl @@ -19,6 +19,10 @@ DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" @testset "Starting and Stopping Reservation" begin reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) + # Start reservation + @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == nothing || ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN + @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == nothing || ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN + # Start reservation Braket.start_reservation!(reservation) @test reservation.is_active == true From b67791cd539d7c9bec241bf827d7dffd9be7ddc9 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Thu, 13 Jun 2024 00:07:35 +0500 Subject: [PATCH 09/18] [Feature]: Support for Braket Direct reservations - codereview --- .../{direct_reservtions.jl => direct_reservations.jl} | 0 test/integ_tests/runtests.jl | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename test/integ_tests/{direct_reservtions.jl => direct_reservations.jl} (100%) diff --git a/test/integ_tests/direct_reservtions.jl b/test/integ_tests/direct_reservations.jl similarity index 100% rename from test/integ_tests/direct_reservtions.jl rename to test/integ_tests/direct_reservations.jl diff --git a/test/integ_tests/runtests.jl b/test/integ_tests/runtests.jl index d324c1fb..9023de91 100644 --- a/test/integ_tests/runtests.jl +++ b/test/integ_tests/runtests.jl @@ -6,7 +6,7 @@ s3_destination_folder = Braket.default_task_bucket() include("adjoint_gradient.jl") include("create_local_quantum_job.jl") include("create_quantum_job.jl") -include("direct_reservtions.jl") +include("direct_reservations.jl") include("job_macro.jl") include("measure.jl") include("cost_tracking.jl") From e127c8e97997e9f5bebda873118aaad7affc54d5 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Thu, 13 Jun 2024 07:04:58 +0500 Subject: [PATCH 10/18] [Feature]: Support for Braket Direct reservations - codereview suggestions --- src/device.jl | 12 ++++-- test/device.jl | 55 ------------------------- test/integ_tests/direct_reservations.jl | 4 -- 3 files changed, 8 insertions(+), 63 deletions(-) diff --git a/src/device.jl b/src/device.jl index 3748f08c..4d0350d2 100644 --- a/src/device.jl +++ b/src/device.jl @@ -352,8 +352,8 @@ reserved device within the specified start and end times. Arguments: - device (Device | string | Nothing): The Braket device for which you possess a reservation ARN, or alternatively, the device ARN. -- reservation_arn (str | Nothing): The Braket Direct reservation ARN to be implemented for all - quantum tasks executed within the startreservation and stopreservation +- reservation_arn (string | Nothing): The Braket Direct reservation ARN to be implemented for all + quantum tasks executed within the startreservation and stopreservation. """ mutable struct DirectReservation device_arn::String @@ -379,8 +379,12 @@ function stop_reservation!(state::DirectReservation) @warn "Reservation is not active." end state.is_active = false - delete!(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") - delete!(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") + if haskey(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") + delete!(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") + end + if haskey(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") + delete!(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") + end end function direct_reservation(reservation::DirectReservation, func::Function) diff --git a/test/device.jl b/test/device.jl index 6ddbb6b7..09d64aba 100644 --- a/test/device.jl +++ b/test/device.jl @@ -268,58 +268,3 @@ MOCK_DWAVE_QPU() = """{ end end end - -# Constants -RESERVATION_ARN = "arn:aws:braket:us-east-1:123456789:reservation/uuid" -DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" - -@testset "DirectReservation Tests" begin - # Creating a DirectReservation - @testset "Creating DirectReservation" begin - reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) - @test reservation.device_arn == DEVICE_ARN - @test reservation.reservation_arn == RESERVATION_ARN - @test reservation.is_active == false - end - - # Starting and stopping a reservation - @testset "Starting and Stopping Reservation" begin - reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) - - # Start reservation - @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == nothing || ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN - @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == nothing || ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN - - # Start reservation - Braket.start_reservation!(reservation) - @test reservation.is_active == true - @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN - @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN - - # Stop reservation - Braket.stop_reservation!(reservation) - @test reservation.is_active == false - @test !haskey(ENV, "AMZN_BRAKET_RESERVATION_DEVICE_ARN") - @test !haskey(ENV, "AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN") - - end - - function test_func() - println("Executing within reservation context") - return 5 - # Add actions as needed - @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN - @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN - end - - @testset "Direct Reservation Function" begin - reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) - @test Braket.direct_reservation(reservation, test_func) == 5 - end - - @testset "Invalid Device Type" begin - invalid_device = 12345 # Not a valid device type - @test_throws UndefVarError DirectReservation(invalid_device, RESERVATION_ARN) - end - -end diff --git a/test/integ_tests/direct_reservations.jl b/test/integ_tests/direct_reservations.jl index 43462e4b..db8567b7 100644 --- a/test/integ_tests/direct_reservations.jl +++ b/test/integ_tests/direct_reservations.jl @@ -19,10 +19,6 @@ DEVICE_ARN = "arn:aws:braket:us-east-1:123456789:device/qpu/ionq/Forte-1" @testset "Starting and Stopping Reservation" begin reservation = Braket.DirectReservation(DEVICE_ARN, RESERVATION_ARN) - # Start reservation - @test ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == nothing || ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] == DEVICE_ARN - @test ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == nothing || ENV["AMZN_BRAKET_RESERVATION_TIME_WINDOW_ARN"] == RESERVATION_ARN - # Start reservation Braket.start_reservation!(reservation) @test reservation.is_active == true From 815bf29c42806b7a7b12cd88dc859c53887d19a4 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Thu, 13 Jun 2024 07:07:22 +0500 Subject: [PATCH 11/18] [Feature]: Support for Braket Direct reservations - formatting --- src/device.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device.jl b/src/device.jl index 4d0350d2..f2f633af 100644 --- a/src/device.jl +++ b/src/device.jl @@ -350,9 +350,9 @@ can utilize the reservation ARN. Moreover, the reservation ARN is solely valid o reserved device within the specified start and end times. Arguments: -- device (Device | string | Nothing): The Braket device for which you possess a reservation ARN, or +- device (Device | String | Nothing): The Braket device for which you possess a reservation ARN, or alternatively, the device ARN. -- reservation_arn (string | Nothing): The Braket Direct reservation ARN to be implemented for all +- reservation_arn (String | Nothing): The Braket Direct reservation ARN to be implemented for all quantum tasks executed within the startreservation and stopreservation. """ mutable struct DirectReservation From 5b22d5a48deeba6460b78b9a1faff19fa37d99f7 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Thu, 13 Jun 2024 08:34:24 +0500 Subject: [PATCH 12/18] [Feature]: Support for Braket Direct reservations - formatting --- src/device.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device.jl b/src/device.jl index f2f633af..4a133815 100644 --- a/src/device.jl +++ b/src/device.jl @@ -353,7 +353,7 @@ Arguments: - device (Device | String | Nothing): The Braket device for which you possess a reservation ARN, or alternatively, the device ARN. - reservation_arn (String | Nothing): The Braket Direct reservation ARN to be implemented for all - quantum tasks executed within the startreservation and stopreservation. + quantum tasks executed within the context. """ mutable struct DirectReservation device_arn::String From 1b2b57292471b712322a27cf210288403f5a8092 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Wed, 19 Jun 2024 09:31:00 +0500 Subject: [PATCH 13/18] Adding codereview suggestions --- docs/src/device.md | 2 ++ docs/src/reservations.md | 7 +++++++ src/device.jl | 14 +++++++------- 3 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 docs/src/reservations.md diff --git a/docs/src/device.md b/docs/src/device.md index f1bab3a6..3aa26832 100644 --- a/docs/src/device.md +++ b/docs/src/device.md @@ -7,4 +7,6 @@ Braket.BraketDevice isavailable search_devices get_devices +Braket.AwsQuantumTask +DirectReservation ``` diff --git a/docs/src/reservations.md b/docs/src/reservations.md new file mode 100644 index 00000000..08ab5904 --- /dev/null +++ b/docs/src/reservations.md @@ -0,0 +1,7 @@ +# Reservations +```@docs +Braket.DirectReservation +Braket.start_reservation! +Braket.stop_reservation! +Braket.direct_reservation +``` \ No newline at end of file diff --git a/src/device.jl b/src/device.jl index 4a133815..8f1ba532 100644 --- a/src/device.jl +++ b/src/device.jl @@ -338,9 +338,9 @@ function get_devices(; arns::Vector{String}=String[], names::Vector{String}=Stri end """ - DirectReservation(device::Union{Device, String, Nothing}, reservation_arn::Union{String, Nothing}) + DirectReservation(device_arn::String, reservation_arn::String) -A context manager that adjusts AwsQuantumTasks generated within the context to utilize a reservation ARN +A context manager that adjusts [`AwsQuantumTask`](@refs)s generated within the context to utilize a reservation ARN for all tasks targeting the designated device. Notably, this manager permits only one reservation at a time. @@ -350,9 +350,9 @@ can utilize the reservation ARN. Moreover, the reservation ARN is solely valid o reserved device within the specified start and end times. Arguments: -- device (Device | String | Nothing): The Braket device for which you possess a reservation ARN, or - alternatively, the device ARN. -- reservation_arn (String | Nothing): The Braket Direct reservation ARN to be implemented for all +- device_arn: The [`BraketDevice`](@ref) for which you possess a reservation ARN, or + alternatively, the [`Device`](@ref) ARN. +- reservation_arn: The Braket [`DirectReservation`](@ref) ARN to be implemented for all quantum tasks executed within the context. """ mutable struct DirectReservation @@ -366,7 +366,7 @@ DirectReservation(device_arn::String, reservation_arn::String) = DirectReservati # Start reservation function function start_reservation!(state::DirectReservation) if state.is_active - error("Another reservation is already active.") + error("Another reservation is already active. Reservation ARN: $reservation_arn") end state.is_active = true ENV["AMZN_BRAKET_RESERVATION_DEVICE_ARN"] = state.device_arn @@ -397,7 +397,7 @@ function direct_reservation(reservation::DirectReservation, func::Function) try func() catch e - error("Error during reservation with device ARN $(reservation.device_arn): $(e)") + error("Error during reservation with device ARN $(reservation.device_arn) and reservation ARN $(reservation.reservation_arn): $(e)") finally stop_reservation!(reservation) end From 8d73982bf3d96743941c80950afe3fcd7951671f Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Wed, 19 Jun 2024 09:34:49 +0500 Subject: [PATCH 14/18] Minor Formatting --- docs/src/reservations.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/reservations.md b/docs/src/reservations.md index 08ab5904..d0b3a4c3 100644 --- a/docs/src/reservations.md +++ b/docs/src/reservations.md @@ -1,4 +1,5 @@ # Reservations + ```@docs Braket.DirectReservation Braket.start_reservation! From 9d0d8af79a1c0055de2c4e6348e739de034b44d3 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Wed, 19 Jun 2024 09:37:18 +0500 Subject: [PATCH 15/18] Minor Formatting --- src/device.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/device.jl b/src/device.jl index 8f1ba532..9fe1a610 100644 --- a/src/device.jl +++ b/src/device.jl @@ -340,9 +340,9 @@ end """ DirectReservation(device_arn::String, reservation_arn::String) -A context manager that adjusts [`AwsQuantumTask`](@refs)s generated within the context to utilize a reservation ARN -for all tasks targeting the designated device. Notably, this manager permits only one reservation -at a time. +A context manager that adjusts [`AwsQuantumTask`](@ref) generated within the context to utilize a +reservation ARN for all tasks targeting the designated device. Notably, this manager permits only +one reservation at a time. [Reservations](https://docs.aws.amazon.com/braket/latest/developerguide/braket-reservations.html) are specific to AWS accounts and devices. Only the AWS account that initiated the reservation From 7fa635a25c9d213fa881f0ff6e2aefc89cc6b1c0 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Thu, 20 Jun 2024 01:32:27 +0500 Subject: [PATCH 16/18] adding direct reservation details in docstring --- docs/src/reservations.md | 21 +++++++++++++++++++++ src/device.jl | 11 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/docs/src/reservations.md b/docs/src/reservations.md index d0b3a4c3..019cd86c 100644 --- a/docs/src/reservations.md +++ b/docs/src/reservations.md @@ -1,5 +1,26 @@ # Reservations +[Reservations](https://docs.aws.amazon.com/braket/latest/developerguide/braket-reservations.html) grant exclusive access to a specific quantum device for a predetermined time slot. This control over execution windows offers several advantages to users: + +Reservations provide exclusive access to a chosen quantum device for a predetermined time slot. This grants you complete control over when your quantum workload starts and finishes execution. Reservations offer several advantages: + + * **Predictability:** Users have guaranteed knowledge of precisely when their tasks will be executed, eliminating scheduling uncertainties. + * **Prioritization:** During the reservation window, the user's workloads take precedence over others, avoiding queueing delays and potential bottlenecks. + * **Efficiency:** The cost is based solely on the reserved duration, irrespective of the number of tasks the user runs within that window. + +# Why Use Reservations? + +In certain scenarios, reservations provide significant benefits over on-demand access: + +- **Production Runs**: When finalizing research or performing critical computations, reservations guarantee timely completion, ensuring adherence to deadlines. +- **Live Demos or Workshops**: Reservations secure exclusive device access for showcasing work or conducting workshops at specific times. +- **Streamlined Workflows**: Users can schedule reservations for tasks requiring execution at particular moments within their workflows, optimizing their overall process. + +# Reservations vs. On-Demand Access + +On-demand access is better suited for the initial development and prototyping stages of a quantum project. This method allows for rapid iterations without the need for pre-scheduled reservations, facilitating agile development. However, once the project progresses towards final production runs requiring guaranteed execution times, reservations become the preferred choice. +""" + ```@docs Braket.DirectReservation Braket.start_reservation! diff --git a/src/device.jl b/src/device.jl index 9fe1a610..b659a0c4 100644 --- a/src/device.jl +++ b/src/device.jl @@ -364,6 +364,12 @@ end DirectReservation(device_arn::String, reservation_arn::String) = DirectReservation(device_arn, reservation_arn, false) # Start reservation function +""" + start_reservation!(state::DirectReservation) + +[`start_reservation!`](@ref) activates a [`DirectReservation`](@ref) object, granting exclusive access to the +specified quantum device for the reserved time window. +""" function start_reservation!(state::DirectReservation) if state.is_active error("Another reservation is already active. Reservation ARN: $reservation_arn") @@ -374,6 +380,11 @@ function start_reservation!(state::DirectReservation) end # Stop reservation function +""" + stop_reservation!(state::DirectReservation) + +[`stop_reservation!`](@ref) deactivates a [`DirectReservation`](@ref) object, releasing exclusive access to the quantum device. +""" function stop_reservation!(state::DirectReservation) if !state.is_active @warn "Reservation is not active." From 226c0dab4dfb4b2b4c48f853e445a9521f614b34 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Thu, 20 Jun 2024 01:42:05 +0500 Subject: [PATCH 17/18] Minor formatting and cleanup --- docs/src/reservations.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/src/reservations.md b/docs/src/reservations.md index 019cd86c..733c4b07 100644 --- a/docs/src/reservations.md +++ b/docs/src/reservations.md @@ -2,8 +2,6 @@ [Reservations](https://docs.aws.amazon.com/braket/latest/developerguide/braket-reservations.html) grant exclusive access to a specific quantum device for a predetermined time slot. This control over execution windows offers several advantages to users: -Reservations provide exclusive access to a chosen quantum device for a predetermined time slot. This grants you complete control over when your quantum workload starts and finishes execution. Reservations offer several advantages: - * **Predictability:** Users have guaranteed knowledge of precisely when their tasks will be executed, eliminating scheduling uncertainties. * **Prioritization:** During the reservation window, the user's workloads take precedence over others, avoiding queueing delays and potential bottlenecks. * **Efficiency:** The cost is based solely on the reserved duration, irrespective of the number of tasks the user runs within that window. From 04a5253282ebd87e159f447a0eb05fe4d07bb78a Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Thu, 20 Jun 2024 23:58:17 +0500 Subject: [PATCH 18/18] CI documentation fix --- docs/src/device.md | 8 +++++--- src/device.jl | 11 +++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/src/device.md b/docs/src/device.md index 3aa26832..052635e9 100644 --- a/docs/src/device.md +++ b/docs/src/device.md @@ -7,6 +7,8 @@ Braket.BraketDevice isavailable search_devices get_devices -Braket.AwsQuantumTask -DirectReservation -``` +Braket.DirectReservation +Braket.start_reservation! +Braket.stop_reservation! +Braket.direct_reservation +``` \ No newline at end of file diff --git a/src/device.jl b/src/device.jl index b659a0c4..8c529295 100644 --- a/src/device.jl +++ b/src/device.jl @@ -398,6 +398,17 @@ function stop_reservation!(state::DirectReservation) end end +""" + direct_reservation(reservation::DirectReservation, func::Function) + +Runs a function within the context of an AWS Braket [`DirectReservation`](@ref). This function sets +the necessary environment variables, starts the reservation, executes the provided function, +and then stops the reservation, ensuring proper resource management. + +Arguments: +- reservation::DirectReservation: The reservation details, including device ARN and reservation ARN. +- func::Function: The function to run within the reservation context. +""" function direct_reservation(reservation::DirectReservation, func::Function) env_vars = Dict( "AMZN_BRAKET_RESERVATION_DEVICE_ARN" => reservation.device_arn,