Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Support for Braket Direct Reservations #87

Merged
merged 19 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
63 changes: 63 additions & 0 deletions src/device.jl
Original file line number Diff line number Diff line change
Expand Up @@ -336,3 +336,66 @@ 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(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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why no doc link here for AwsQuantumTask?

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
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
Fe-r-oz marked this conversation as resolved.
Show resolved Hide resolved
alternatively, the device ARN.
- reservation_arn (str | Nothing): The Braket Direct reservation ARN to be implemented for all
quantum tasks executed within the contex
Fe-r-oz marked this conversation as resolved.
Show resolved Hide resolved
"""
mutable struct DirectReservation
device_arn::String
reservation_arn::String
is_active::Bool
end

function DirectReservation(device_arn::String, reservation_arn::String)
Fe-r-oz marked this conversation as resolved.
Show resolved Hide resolved
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.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not include the reservation_arn in this error message?

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")
Fe-r-oz marked this conversation as resolved.
Show resolved Hide resolved
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()
Fe-r-oz marked this conversation as resolved.
Show resolved Hide resolved
finally
stop_reservation!(reservation)
end
end
end
51 changes: 51 additions & 0 deletions test/device.jl
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,54 @@ MOCK_DWAVE_QPU() = """{
end
end
end

# Constants
RESERVATION_ARN = "arn:aws:braket:us-east-1:123456789:reservation/uuid"
Fe-r-oz marked this conversation as resolved.
Show resolved Hide resolved
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