From 80c11d287641b0d15bcd372b68f01366b6b19e98 Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Thu, 7 Dec 2023 11:00:27 -0800 Subject: [PATCH 01/13] update: updating to py 3.10 so we can use decorator --- buildspec.yml | 2 +- testspec.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 8385db4a..7b6f0f6b 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -9,7 +9,7 @@ phases: pre_build: commands: - echo Logging in to Amazon ECR... - - $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION) + - $(aws ecr get-login-password --region $AWS_DEFAULT_REGION) - pip install -r src/requirements.txt - echo The following is only required if we use DLC images as our base 'FROM' images. - aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 763104351884.dkr.ecr.us-east-1.amazonaws.com diff --git a/testspec.yml b/testspec.yml index 45b6b3f9..9e868db1 100644 --- a/testspec.yml +++ b/testspec.yml @@ -8,7 +8,7 @@ phases: pre_build: commands: - echo Logging in to Amazon ECR... - - $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION) + - $(aws ecr get-login-password --region $AWS_DEFAULT_REGION) - pip install -r test/requirements.txt - echo Performing additional setup... - python test/perform_additional_setup.py From 2f24e2c3b44b876537d736e004b4eddccd9e7903 Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Thu, 7 Dec 2023 11:08:53 -0800 Subject: [PATCH 02/13] attempt 2 --- buildspec.yml | 2 +- testspec.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 7b6f0f6b..f2e8ef87 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -9,7 +9,7 @@ phases: pre_build: commands: - echo Logging in to Amazon ECR... - - $(aws ecr get-login-password --region $AWS_DEFAULT_REGION) + - $(aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com) - pip install -r src/requirements.txt - echo The following is only required if we use DLC images as our base 'FROM' images. - aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 763104351884.dkr.ecr.us-east-1.amazonaws.com diff --git a/testspec.yml b/testspec.yml index 9e868db1..e80acd92 100644 --- a/testspec.yml +++ b/testspec.yml @@ -8,7 +8,7 @@ phases: pre_build: commands: - echo Logging in to Amazon ECR... - - $(aws ecr get-login-password --region $AWS_DEFAULT_REGION) + - $(aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com) - pip install -r test/requirements.txt - echo Performing additional setup... - python test/perform_additional_setup.py From 5a8667d98fddf52e6afdce8e9f27c538413f2b6a Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Thu, 7 Dec 2023 11:16:43 -0800 Subject: [PATCH 03/13] attempt 3 --- buildspec.yml | 2 +- testspec.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index f2e8ef87..d7d111a1 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -9,7 +9,7 @@ phases: pre_build: commands: - echo Logging in to Amazon ECR... - - $(aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com) + - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - pip install -r src/requirements.txt - echo The following is only required if we use DLC images as our base 'FROM' images. - aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 763104351884.dkr.ecr.us-east-1.amazonaws.com diff --git a/testspec.yml b/testspec.yml index e80acd92..9b77ba14 100644 --- a/testspec.yml +++ b/testspec.yml @@ -8,7 +8,7 @@ phases: pre_build: commands: - echo Logging in to Amazon ECR... - - $(aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com) + - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - pip install -r test/requirements.txt - echo Performing additional setup... - python test/perform_additional_setup.py From 8198ae0cf43a737f99a6a4e8c48939a243f173c8 Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Thu, 7 Dec 2023 16:49:36 -0800 Subject: [PATCH 04/13] debugging issue --- test/resources/qaoa_entry_point.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index 11f589c8..36860f2e 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -21,7 +21,7 @@ from braket.jobs import get_job_device_arn, save_job_checkpoint, save_job_result from braket.jobs.metrics import log_metric -from . import qaoa_utils +import qaoa_utils def record_test_metrics(metric, start_time, interface): @@ -79,21 +79,24 @@ def entry_point( cost_h, mixer_h = qml.qaoa.maxcut(g) def qaoa_layer(gamma, alpha): + print(f"cost layer {gamma}, {alpha}") qml.qaoa.cost_layer(gamma, cost_h) qml.qaoa.mixer_layer(alpha, mixer_h) def circuit(params, **kwargs): + print(f"circuit {params}") for i in range(num_nodes): qml.Hadamard(wires=i) qml.layer(qaoa_layer, p, params[0], params[1]) - device_arn = get_job_device_arn() + device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" # get_job_device_arn() dev = init_pl_device(device_arn, num_nodes, shots, max_parallel) np.random.seed(seed) @qml.qnode(dev, interface=pl_interface) def cost_function(params): + print(f"cost func {params}") circuit(params) return qml.expval(cost_h) @@ -150,3 +153,7 @@ def cost_function(params): record_test_metrics('Total', start_time, pl_interface) print("Braket Container Run Success") + + +if __name__ == "__main__": + entry_point(2, 1967, 10, 5, 2, 1000, "autograd", time.time()) \ No newline at end of file From c5870391e7d742df4041bc8fe1cf0ef3301d380c Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Fri, 8 Dec 2023 09:32:47 -0800 Subject: [PATCH 05/13] fixing import --- test/resources/qaoa_entry_point.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index 36860f2e..c8e5065c 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -21,7 +21,7 @@ from braket.jobs import get_job_device_arn, save_job_checkpoint, save_job_result from braket.jobs.metrics import log_metric -import qaoa_utils +from . import qaoa_utils def record_test_metrics(metric, start_time, interface): From 76248e14c4e85fd3b64b77c47f33a4785c9d4d58 Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Fri, 8 Dec 2023 11:19:34 -0800 Subject: [PATCH 06/13] attempt again --- test/resources/qaoa_entry_point.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index c8e5065c..103094a4 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -83,13 +83,13 @@ def qaoa_layer(gamma, alpha): qml.qaoa.cost_layer(gamma, cost_h) qml.qaoa.mixer_layer(alpha, mixer_h) - def circuit(params, **kwargs): + def my_circuit(params, **kwargs): print(f"circuit {params}") for i in range(num_nodes): qml.Hadamard(wires=i) qml.layer(qaoa_layer, p, params[0], params[1]) - device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" # get_job_device_arn() + device_arn = get_job_device_arn() dev = init_pl_device(device_arn, num_nodes, shots, max_parallel) np.random.seed(seed) @@ -97,7 +97,7 @@ def circuit(params, **kwargs): @qml.qnode(dev, interface=pl_interface) def cost_function(params): print(f"cost func {params}") - circuit(params) + my_circuit(params) return qml.expval(cost_h) params = interface.initialize_params(0.01 * np.random.uniform(size=[2, p])) From 481cbae950f5ddcb7363594b5d203dda296d6cfb Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Fri, 8 Dec 2023 13:49:58 -0800 Subject: [PATCH 07/13] more print statements --- test/resources/qaoa_entry_point.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index 103094a4..3d10fe58 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -86,7 +86,9 @@ def qaoa_layer(gamma, alpha): def my_circuit(params, **kwargs): print(f"circuit {params}") for i in range(num_nodes): + print(f"wire {i}") qml.Hadamard(wires=i) + print(f"calling layer") qml.layer(qaoa_layer, p, params[0], params[1]) device_arn = get_job_device_arn() From 8235035a2db0a1e8282b5fc82e32b6013fd8c064 Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Fri, 8 Dec 2023 14:17:42 -0800 Subject: [PATCH 08/13] again --- test/resources/qaoa_entry_point.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index 3d10fe58..888d0cee 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -86,8 +86,9 @@ def qaoa_layer(gamma, alpha): def my_circuit(params, **kwargs): print(f"circuit {params}") for i in range(num_nodes): - print(f"wire {i}") + print(f"wire {i} of {num_nodes}") qml.Hadamard(wires=i) + print(f"done wire {i} of {num_nodes}") print(f"calling layer") qml.layer(qaoa_layer, p, params[0], params[1]) From 567886d100843fe08b181cec9b114c1960b84492 Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Fri, 8 Dec 2023 15:59:27 -0800 Subject: [PATCH 09/13] again 2 --- test/resources/qaoa_entry_point.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index 888d0cee..b07076d1 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -84,6 +84,7 @@ def qaoa_layer(gamma, alpha): qml.qaoa.mixer_layer(alpha, mixer_h) def my_circuit(params, **kwargs): + p = params.shape[1] print(f"circuit {params}") for i in range(num_nodes): print(f"wire {i} of {num_nodes}") From b0959c5805abe5af3cc5ca07a57ce554640ded74 Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Mon, 11 Dec 2023 09:46:11 -0800 Subject: [PATCH 10/13] Temporarily reverting decorator changes --- test/braket_tests/base/test_jobs_qaoa.py | 25 +++++----- test/braket_tests/common/braket_jobs_util.py | 25 ++++------ test/braket_tests/pytorch/test_jobs_qaoa.py | 24 +++++---- .../braket_tests/tensorflow/test_jobs_qaoa.py | 24 +++++---- test/resources/qaoa_entry_point.py | 49 ++++++++++--------- 5 files changed, 76 insertions(+), 71 deletions(-) diff --git a/test/braket_tests/base/test_jobs_qaoa.py b/test/braket_tests/base/test_jobs_qaoa.py index bdfe414d..471ac57a 100644 --- a/test/braket_tests/base/test_jobs_qaoa.py +++ b/test/braket_tests/base/test_jobs_qaoa.py @@ -12,21 +12,24 @@ # language governing permissions and limitations under the License. import time - from ..common.braket_jobs_util import job_test def test_qaoa_circuit(account, role, s3_bucket, image_list): assert len(image_list) > 0, "Unable to find images for testing" - job_args = { - "p": 2, - "seed": 1967, - "max_parallel": 10, - "num_iterations": 5, - "stepsize": 0.1, - "shots": 100, - "pl_interface": "autograd", - "start_time": time.time(), + create_job_args = { + "source_module": "./test/resources/", + "entry_point": "resources.qaoa_entry_point", + "hyperparameters": { + "p": "2", + "seed": "1967", + "max_parallel": "10", + "num_iterations": "5", + "stepsize": "0.1", + "shots": "100", + "interface": "autograd", + "start_time": time.time(), + } } for image_path in image_list: - job_test(account, role, s3_bucket, image_path, "base-qaoa", job_args) + job_test(account, role, s3_bucket, image_path, "base-qaoa", **create_job_args) diff --git a/test/braket_tests/common/braket_jobs_util.py b/test/braket_tests/common/braket_jobs_util.py index 1bfaee14..0567005c 100644 --- a/test/braket_tests/common/braket_jobs_util.py +++ b/test/braket_tests/common/braket_jobs_util.py @@ -12,22 +12,20 @@ # language governing permissions and limitations under the License. import io -import sys +import os import time from contextlib import redirect_stdout -from braket.aws import AwsSession -from braket.jobs import hybrid_job -from braket.devices import Devices +import boto3 -from ...resources.qaoa_entry_point import entry_point +from braket.aws import AwsQuantumJob, AwsSession -def job_test(account, role, s3_bucket, image_path, job_type, job_args): +def job_test(account, role, s3_bucket, image_path, job_type, **kwargs): job_output = io.StringIO() with redirect_stdout(job_output): try: - create_job(account, role, s3_bucket, image_path, job_type, job_args) + create_job(account, role, s3_bucket, image_path, job_type, **kwargs) except Exception as e: print(e) output = job_output.getvalue() @@ -35,20 +33,15 @@ def job_test(account, role, s3_bucket, image_path, job_type, job_args): assert output.find("Braket Container Run Success") > 0, "Container did not run successfully" -def create_job(account, role, s3_bucket, image_path, job_type, job_args): +def create_job(account, role, s3_bucket, image_path, job_type, **kwargs): aws_session = AwsSession(default_bucket=s3_bucket) job_name = f"ContainerTest-{job_type}-{int(time.time())}" - - @hybrid_job( + AwsQuantumJob.create( aws_session=aws_session, job_name=job_name, - device=Devices.Amazon.SV1, + device="arn:aws:braket:::device/quantum-simulator/amazon/sv1", role_arn=f"arn:aws:iam::{account}:role/{role}", image_uri=image_path, wait_until_complete=True, - include_modules="test.resources", + **kwargs ) - def decorator_job(*args, **kwargs): - return entry_point(*args, **kwargs) - - decorator_job(**job_args) diff --git a/test/braket_tests/pytorch/test_jobs_qaoa.py b/test/braket_tests/pytorch/test_jobs_qaoa.py index 04d6f129..cf180e7b 100644 --- a/test/braket_tests/pytorch/test_jobs_qaoa.py +++ b/test/braket_tests/pytorch/test_jobs_qaoa.py @@ -17,15 +17,19 @@ def test_qaoa_circuit(account, role, s3_bucket, image_list): assert len(image_list) > 0, "Unable to find images for testing" - job_args = { - "p": 2, - "seed": 1967, - "max_parallel": 10, - "num_iterations": 5, - "stepsize": 0.1, - "shots": 100, - "pl_interface": "torch", - "start_time": time.time(), + create_job_args = { + "source_module": "./test/resources/", + "entry_point": "resources.qaoa_entry_point", + "hyperparameters": { + "p": "2", + "seed": "1967", + "max_parallel": "10", + "num_iterations": "5", + "stepsize": "0.1", + "shots": "100", + "interface": "torch", + "start_time": time.time(), + } } for image_path in image_list: - job_test(account, role, s3_bucket, image_path, "pytorch-qaoa", job_args) + job_test(account, role, s3_bucket, image_path, "pytorch-qaoa", **create_job_args) diff --git a/test/braket_tests/tensorflow/test_jobs_qaoa.py b/test/braket_tests/tensorflow/test_jobs_qaoa.py index 7bd3c9e7..e5c07fdc 100644 --- a/test/braket_tests/tensorflow/test_jobs_qaoa.py +++ b/test/braket_tests/tensorflow/test_jobs_qaoa.py @@ -17,15 +17,19 @@ def test_qaoa_circuit(account, role, s3_bucket, image_list): assert len(image_list) > 0, "Unable to find images for testing" - job_args = { - "p": 2, - "seed": 1967, - "max_parallel": 10, - "num_iterations": 5, - "stepsize": 0.1, - "shots": 100, - "pl_interface": "torch", - "start_time": time.time(), + create_job_args = { + "source_module": "./test/resources/", + "entry_point": "resources.qaoa_entry_point", + "hyperparameters": { + "p": "2", + "seed": "1967", + "max_parallel": "10", + "num_iterations": "5", + "stepsize": "0.1", + "shots": "100", + "interface": "tf", + "start_time": time.time(), + } } for image_path in image_list: - job_test(account, role, s3_bucket, image_path, "tf-qaoa", job_args) + job_test(account, role, s3_bucket, image_path, "tf-qaoa", **create_job_args) diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index b07076d1..c6814782 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -11,6 +11,8 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. +import json +import os import time import boto3 @@ -18,7 +20,7 @@ from pennylane import numpy as np import pennylane as qml -from braket.jobs import get_job_device_arn, save_job_checkpoint, save_job_result +from braket.jobs import save_job_checkpoint, save_job_result from braket.jobs.metrics import log_metric from . import qaoa_utils @@ -32,7 +34,7 @@ def record_test_metrics(metric, start_time, interface): 'Dimensions': [ { 'Name': 'TYPE', - 'Value': 'braket_container_tests' + 'Value': 'braket_tests' }, { 'Name': 'INTERFACE', @@ -42,7 +44,7 @@ def record_test_metrics(metric, start_time, interface): 'Unit': 'Seconds', 'Value': time.time() - start_time }], - Namespace='/aws/braket' + Namespace='braket-container-metrics' ) @@ -58,16 +60,22 @@ def init_pl_device(device_arn, num_nodes, shots, max_parallel): ) -def entry_point( - p: int, - seed: int, - max_parallel: int, - num_iterations: int, - stepsize: float, - shots: int, - pl_interface: str, - start_time: float, -): +def start_function(): + # Read the hyperparameters + hp_file = os.environ["AMZN_BRAKET_HP_FILE"] + with open(hp_file, "r") as f: + hyperparams = json.load(f) + print(hyperparams) + + p = int(hyperparams["p"]) + seed = int(hyperparams["seed"]) + max_parallel = int(hyperparams["max_parallel"]) + num_iterations = int(hyperparams["num_iterations"]) + stepsize = float(hyperparams["stepsize"]) + shots = int(hyperparams["shots"]) + pl_interface = hyperparams["interface"] + start_time = float(hyperparams["start_time"]) + record_test_metrics('Startup', start_time, pl_interface) interface = qaoa_utils.QAOAInterface.get_interface(pl_interface) @@ -79,29 +87,22 @@ def entry_point( cost_h, mixer_h = qml.qaoa.maxcut(g) def qaoa_layer(gamma, alpha): - print(f"cost layer {gamma}, {alpha}") qml.qaoa.cost_layer(gamma, cost_h) qml.qaoa.mixer_layer(alpha, mixer_h) - def my_circuit(params, **kwargs): - p = params.shape[1] - print(f"circuit {params}") + def circuit(params, **kwargs): for i in range(num_nodes): - print(f"wire {i} of {num_nodes}") qml.Hadamard(wires=i) - print(f"done wire {i} of {num_nodes}") - print(f"calling layer") qml.layer(qaoa_layer, p, params[0], params[1]) - device_arn = get_job_device_arn() + device_arn = os.environ["AMZN_BRAKET_DEVICE_ARN"] dev = init_pl_device(device_arn, num_nodes, shots, max_parallel) np.random.seed(seed) @qml.qnode(dev, interface=pl_interface) def cost_function(params): - print(f"cost func {params}") - my_circuit(params) + circuit(params) return qml.expval(cost_h) params = interface.initialize_params(0.01 * np.random.uniform(size=[2, p])) @@ -160,4 +161,4 @@ def cost_function(params): if __name__ == "__main__": - entry_point(2, 1967, 10, 5, 2, 1000, "autograd", time.time()) \ No newline at end of file + start_function() From c0c8489fea9a54059ae3ecae69e633bdd2ecf429 Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Mon, 11 Dec 2023 11:17:43 -0800 Subject: [PATCH 11/13] reverting last change and pinning pl --- test/braket_tests/base/test_jobs_qaoa.py | 25 ++++++------ test/braket_tests/common/braket_jobs_util.py | 25 +++++++----- test/braket_tests/pytorch/test_jobs_qaoa.py | 24 +++++------- .../braket_tests/tensorflow/test_jobs_qaoa.py | 24 +++++------- test/requirements.txt | 2 +- test/resources/qaoa_entry_point.py | 38 ++++++++----------- 6 files changed, 63 insertions(+), 75 deletions(-) diff --git a/test/braket_tests/base/test_jobs_qaoa.py b/test/braket_tests/base/test_jobs_qaoa.py index 471ac57a..bdfe414d 100644 --- a/test/braket_tests/base/test_jobs_qaoa.py +++ b/test/braket_tests/base/test_jobs_qaoa.py @@ -12,24 +12,21 @@ # language governing permissions and limitations under the License. import time + from ..common.braket_jobs_util import job_test def test_qaoa_circuit(account, role, s3_bucket, image_list): assert len(image_list) > 0, "Unable to find images for testing" - create_job_args = { - "source_module": "./test/resources/", - "entry_point": "resources.qaoa_entry_point", - "hyperparameters": { - "p": "2", - "seed": "1967", - "max_parallel": "10", - "num_iterations": "5", - "stepsize": "0.1", - "shots": "100", - "interface": "autograd", - "start_time": time.time(), - } + job_args = { + "p": 2, + "seed": 1967, + "max_parallel": 10, + "num_iterations": 5, + "stepsize": 0.1, + "shots": 100, + "pl_interface": "autograd", + "start_time": time.time(), } for image_path in image_list: - job_test(account, role, s3_bucket, image_path, "base-qaoa", **create_job_args) + job_test(account, role, s3_bucket, image_path, "base-qaoa", job_args) diff --git a/test/braket_tests/common/braket_jobs_util.py b/test/braket_tests/common/braket_jobs_util.py index 0567005c..1bfaee14 100644 --- a/test/braket_tests/common/braket_jobs_util.py +++ b/test/braket_tests/common/braket_jobs_util.py @@ -12,20 +12,22 @@ # language governing permissions and limitations under the License. import io -import os +import sys import time from contextlib import redirect_stdout -import boto3 +from braket.aws import AwsSession +from braket.jobs import hybrid_job +from braket.devices import Devices -from braket.aws import AwsQuantumJob, AwsSession +from ...resources.qaoa_entry_point import entry_point -def job_test(account, role, s3_bucket, image_path, job_type, **kwargs): +def job_test(account, role, s3_bucket, image_path, job_type, job_args): job_output = io.StringIO() with redirect_stdout(job_output): try: - create_job(account, role, s3_bucket, image_path, job_type, **kwargs) + create_job(account, role, s3_bucket, image_path, job_type, job_args) except Exception as e: print(e) output = job_output.getvalue() @@ -33,15 +35,20 @@ def job_test(account, role, s3_bucket, image_path, job_type, **kwargs): assert output.find("Braket Container Run Success") > 0, "Container did not run successfully" -def create_job(account, role, s3_bucket, image_path, job_type, **kwargs): +def create_job(account, role, s3_bucket, image_path, job_type, job_args): aws_session = AwsSession(default_bucket=s3_bucket) job_name = f"ContainerTest-{job_type}-{int(time.time())}" - AwsQuantumJob.create( + + @hybrid_job( aws_session=aws_session, job_name=job_name, - device="arn:aws:braket:::device/quantum-simulator/amazon/sv1", + device=Devices.Amazon.SV1, role_arn=f"arn:aws:iam::{account}:role/{role}", image_uri=image_path, wait_until_complete=True, - **kwargs + include_modules="test.resources", ) + def decorator_job(*args, **kwargs): + return entry_point(*args, **kwargs) + + decorator_job(**job_args) diff --git a/test/braket_tests/pytorch/test_jobs_qaoa.py b/test/braket_tests/pytorch/test_jobs_qaoa.py index cf180e7b..04d6f129 100644 --- a/test/braket_tests/pytorch/test_jobs_qaoa.py +++ b/test/braket_tests/pytorch/test_jobs_qaoa.py @@ -17,19 +17,15 @@ def test_qaoa_circuit(account, role, s3_bucket, image_list): assert len(image_list) > 0, "Unable to find images for testing" - create_job_args = { - "source_module": "./test/resources/", - "entry_point": "resources.qaoa_entry_point", - "hyperparameters": { - "p": "2", - "seed": "1967", - "max_parallel": "10", - "num_iterations": "5", - "stepsize": "0.1", - "shots": "100", - "interface": "torch", - "start_time": time.time(), - } + job_args = { + "p": 2, + "seed": 1967, + "max_parallel": 10, + "num_iterations": 5, + "stepsize": 0.1, + "shots": 100, + "pl_interface": "torch", + "start_time": time.time(), } for image_path in image_list: - job_test(account, role, s3_bucket, image_path, "pytorch-qaoa", **create_job_args) + job_test(account, role, s3_bucket, image_path, "pytorch-qaoa", job_args) diff --git a/test/braket_tests/tensorflow/test_jobs_qaoa.py b/test/braket_tests/tensorflow/test_jobs_qaoa.py index e5c07fdc..7bd3c9e7 100644 --- a/test/braket_tests/tensorflow/test_jobs_qaoa.py +++ b/test/braket_tests/tensorflow/test_jobs_qaoa.py @@ -17,19 +17,15 @@ def test_qaoa_circuit(account, role, s3_bucket, image_list): assert len(image_list) > 0, "Unable to find images for testing" - create_job_args = { - "source_module": "./test/resources/", - "entry_point": "resources.qaoa_entry_point", - "hyperparameters": { - "p": "2", - "seed": "1967", - "max_parallel": "10", - "num_iterations": "5", - "stepsize": "0.1", - "shots": "100", - "interface": "tf", - "start_time": time.time(), - } + job_args = { + "p": 2, + "seed": 1967, + "max_parallel": 10, + "num_iterations": 5, + "stepsize": 0.1, + "shots": 100, + "pl_interface": "torch", + "start_time": time.time(), } for image_path in image_list: - job_test(account, role, s3_bucket, image_path, "tf-qaoa", **create_job_args) + job_test(account, role, s3_bucket, image_path, "tf-qaoa", job_args) diff --git a/test/requirements.txt b/test/requirements.txt index 983b9031..edb7276a 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -4,7 +4,7 @@ boto3==1.28.53 certifi>=2023.7.22 invoke==2.2.0 mock -pennylane +pennylane==0.32.0 pytest==7.2.2 pytest-xdist sagemaker diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index c6814782..1da33061 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -11,8 +11,6 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. -import json -import os import time import boto3 @@ -20,7 +18,7 @@ from pennylane import numpy as np import pennylane as qml -from braket.jobs import save_job_checkpoint, save_job_result +from braket.jobs import get_job_device_arn, save_job_checkpoint, save_job_result from braket.jobs.metrics import log_metric from . import qaoa_utils @@ -34,7 +32,7 @@ def record_test_metrics(metric, start_time, interface): 'Dimensions': [ { 'Name': 'TYPE', - 'Value': 'braket_tests' + 'Value': 'braket_container_tests' }, { 'Name': 'INTERFACE', @@ -44,7 +42,7 @@ def record_test_metrics(metric, start_time, interface): 'Unit': 'Seconds', 'Value': time.time() - start_time }], - Namespace='braket-container-metrics' + Namespace='/aws/braket' ) @@ -60,22 +58,16 @@ def init_pl_device(device_arn, num_nodes, shots, max_parallel): ) -def start_function(): - # Read the hyperparameters - hp_file = os.environ["AMZN_BRAKET_HP_FILE"] - with open(hp_file, "r") as f: - hyperparams = json.load(f) - print(hyperparams) - - p = int(hyperparams["p"]) - seed = int(hyperparams["seed"]) - max_parallel = int(hyperparams["max_parallel"]) - num_iterations = int(hyperparams["num_iterations"]) - stepsize = float(hyperparams["stepsize"]) - shots = int(hyperparams["shots"]) - pl_interface = hyperparams["interface"] - start_time = float(hyperparams["start_time"]) - +def entry_point( + p: int, + seed: int, + max_parallel: int, + num_iterations: int, + stepsize: float, + shots: int, + pl_interface: str, + start_time: float, +): record_test_metrics('Startup', start_time, pl_interface) interface = qaoa_utils.QAOAInterface.get_interface(pl_interface) @@ -95,7 +87,7 @@ def circuit(params, **kwargs): qml.Hadamard(wires=i) qml.layer(qaoa_layer, p, params[0], params[1]) - device_arn = os.environ["AMZN_BRAKET_DEVICE_ARN"] + device_arn = get_job_device_arn() dev = init_pl_device(device_arn, num_nodes, shots, max_parallel) np.random.seed(seed) @@ -161,4 +153,4 @@ def cost_function(params): if __name__ == "__main__": - start_function() + entry_point(2, 1967, 10, 5, 2, 1000, "autograd", time.time()) \ No newline at end of file From 544963b94ac5fea8824ba2d984ef577459d4ccca Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Mon, 11 Dec 2023 11:18:41 -0800 Subject: [PATCH 12/13] nit whitespace --- test/resources/qaoa_entry_point.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index 1da33061..6ec23dd0 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -153,4 +153,5 @@ def cost_function(params): if __name__ == "__main__": - entry_point(2, 1967, 10, 5, 2, 1000, "autograd", time.time()) \ No newline at end of file + entry_point(2, 1967, 10, 5, 2, 1000, "autograd", time.time()) + \ No newline at end of file From 5497b453aa285612388c7445ac2c9956afe9cdb0 Mon Sep 17 00:00:00 2001 From: Milan Krneta Date: Mon, 11 Dec 2023 13:03:20 -0800 Subject: [PATCH 13/13] reverting decorator --- test/braket_tests/base/test_jobs_qaoa.py | 25 +++++++------ test/braket_tests/common/braket_jobs_util.py | 25 +++++-------- test/braket_tests/pytorch/test_jobs_qaoa.py | 24 +++++++------ .../braket_tests/tensorflow/test_jobs_qaoa.py | 24 +++++++------ test/requirements.txt | 2 +- test/resources/qaoa_entry_point.py | 35 +++++++++++-------- 6 files changed, 73 insertions(+), 62 deletions(-) diff --git a/test/braket_tests/base/test_jobs_qaoa.py b/test/braket_tests/base/test_jobs_qaoa.py index bdfe414d..471ac57a 100644 --- a/test/braket_tests/base/test_jobs_qaoa.py +++ b/test/braket_tests/base/test_jobs_qaoa.py @@ -12,21 +12,24 @@ # language governing permissions and limitations under the License. import time - from ..common.braket_jobs_util import job_test def test_qaoa_circuit(account, role, s3_bucket, image_list): assert len(image_list) > 0, "Unable to find images for testing" - job_args = { - "p": 2, - "seed": 1967, - "max_parallel": 10, - "num_iterations": 5, - "stepsize": 0.1, - "shots": 100, - "pl_interface": "autograd", - "start_time": time.time(), + create_job_args = { + "source_module": "./test/resources/", + "entry_point": "resources.qaoa_entry_point", + "hyperparameters": { + "p": "2", + "seed": "1967", + "max_parallel": "10", + "num_iterations": "5", + "stepsize": "0.1", + "shots": "100", + "interface": "autograd", + "start_time": time.time(), + } } for image_path in image_list: - job_test(account, role, s3_bucket, image_path, "base-qaoa", job_args) + job_test(account, role, s3_bucket, image_path, "base-qaoa", **create_job_args) diff --git a/test/braket_tests/common/braket_jobs_util.py b/test/braket_tests/common/braket_jobs_util.py index 1bfaee14..0567005c 100644 --- a/test/braket_tests/common/braket_jobs_util.py +++ b/test/braket_tests/common/braket_jobs_util.py @@ -12,22 +12,20 @@ # language governing permissions and limitations under the License. import io -import sys +import os import time from contextlib import redirect_stdout -from braket.aws import AwsSession -from braket.jobs import hybrid_job -from braket.devices import Devices +import boto3 -from ...resources.qaoa_entry_point import entry_point +from braket.aws import AwsQuantumJob, AwsSession -def job_test(account, role, s3_bucket, image_path, job_type, job_args): +def job_test(account, role, s3_bucket, image_path, job_type, **kwargs): job_output = io.StringIO() with redirect_stdout(job_output): try: - create_job(account, role, s3_bucket, image_path, job_type, job_args) + create_job(account, role, s3_bucket, image_path, job_type, **kwargs) except Exception as e: print(e) output = job_output.getvalue() @@ -35,20 +33,15 @@ def job_test(account, role, s3_bucket, image_path, job_type, job_args): assert output.find("Braket Container Run Success") > 0, "Container did not run successfully" -def create_job(account, role, s3_bucket, image_path, job_type, job_args): +def create_job(account, role, s3_bucket, image_path, job_type, **kwargs): aws_session = AwsSession(default_bucket=s3_bucket) job_name = f"ContainerTest-{job_type}-{int(time.time())}" - - @hybrid_job( + AwsQuantumJob.create( aws_session=aws_session, job_name=job_name, - device=Devices.Amazon.SV1, + device="arn:aws:braket:::device/quantum-simulator/amazon/sv1", role_arn=f"arn:aws:iam::{account}:role/{role}", image_uri=image_path, wait_until_complete=True, - include_modules="test.resources", + **kwargs ) - def decorator_job(*args, **kwargs): - return entry_point(*args, **kwargs) - - decorator_job(**job_args) diff --git a/test/braket_tests/pytorch/test_jobs_qaoa.py b/test/braket_tests/pytorch/test_jobs_qaoa.py index 04d6f129..cf180e7b 100644 --- a/test/braket_tests/pytorch/test_jobs_qaoa.py +++ b/test/braket_tests/pytorch/test_jobs_qaoa.py @@ -17,15 +17,19 @@ def test_qaoa_circuit(account, role, s3_bucket, image_list): assert len(image_list) > 0, "Unable to find images for testing" - job_args = { - "p": 2, - "seed": 1967, - "max_parallel": 10, - "num_iterations": 5, - "stepsize": 0.1, - "shots": 100, - "pl_interface": "torch", - "start_time": time.time(), + create_job_args = { + "source_module": "./test/resources/", + "entry_point": "resources.qaoa_entry_point", + "hyperparameters": { + "p": "2", + "seed": "1967", + "max_parallel": "10", + "num_iterations": "5", + "stepsize": "0.1", + "shots": "100", + "interface": "torch", + "start_time": time.time(), + } } for image_path in image_list: - job_test(account, role, s3_bucket, image_path, "pytorch-qaoa", job_args) + job_test(account, role, s3_bucket, image_path, "pytorch-qaoa", **create_job_args) diff --git a/test/braket_tests/tensorflow/test_jobs_qaoa.py b/test/braket_tests/tensorflow/test_jobs_qaoa.py index 7bd3c9e7..e5c07fdc 100644 --- a/test/braket_tests/tensorflow/test_jobs_qaoa.py +++ b/test/braket_tests/tensorflow/test_jobs_qaoa.py @@ -17,15 +17,19 @@ def test_qaoa_circuit(account, role, s3_bucket, image_list): assert len(image_list) > 0, "Unable to find images for testing" - job_args = { - "p": 2, - "seed": 1967, - "max_parallel": 10, - "num_iterations": 5, - "stepsize": 0.1, - "shots": 100, - "pl_interface": "torch", - "start_time": time.time(), + create_job_args = { + "source_module": "./test/resources/", + "entry_point": "resources.qaoa_entry_point", + "hyperparameters": { + "p": "2", + "seed": "1967", + "max_parallel": "10", + "num_iterations": "5", + "stepsize": "0.1", + "shots": "100", + "interface": "tf", + "start_time": time.time(), + } } for image_path in image_list: - job_test(account, role, s3_bucket, image_path, "tf-qaoa", job_args) + job_test(account, role, s3_bucket, image_path, "tf-qaoa", **create_job_args) diff --git a/test/requirements.txt b/test/requirements.txt index edb7276a..983b9031 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -4,7 +4,7 @@ boto3==1.28.53 certifi>=2023.7.22 invoke==2.2.0 mock -pennylane==0.32.0 +pennylane pytest==7.2.2 pytest-xdist sagemaker diff --git a/test/resources/qaoa_entry_point.py b/test/resources/qaoa_entry_point.py index 6ec23dd0..32c823b5 100644 --- a/test/resources/qaoa_entry_point.py +++ b/test/resources/qaoa_entry_point.py @@ -11,6 +11,8 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. +import json +import os import time import boto3 @@ -18,7 +20,7 @@ from pennylane import numpy as np import pennylane as qml -from braket.jobs import get_job_device_arn, save_job_checkpoint, save_job_result +from braket.jobs import save_job_checkpoint, save_job_result from braket.jobs.metrics import log_metric from . import qaoa_utils @@ -58,16 +60,22 @@ def init_pl_device(device_arn, num_nodes, shots, max_parallel): ) -def entry_point( - p: int, - seed: int, - max_parallel: int, - num_iterations: int, - stepsize: float, - shots: int, - pl_interface: str, - start_time: float, -): +def start_function(): + # Read the hyperparameters + hp_file = os.environ["AMZN_BRAKET_HP_FILE"] + with open(hp_file, "r") as f: + hyperparams = json.load(f) + print(hyperparams) + + p = int(hyperparams["p"]) + seed = int(hyperparams["seed"]) + max_parallel = int(hyperparams["max_parallel"]) + num_iterations = int(hyperparams["num_iterations"]) + stepsize = float(hyperparams["stepsize"]) + shots = int(hyperparams["shots"]) + pl_interface = hyperparams["interface"] + start_time = float(hyperparams["start_time"]) + record_test_metrics('Startup', start_time, pl_interface) interface = qaoa_utils.QAOAInterface.get_interface(pl_interface) @@ -87,7 +95,7 @@ def circuit(params, **kwargs): qml.Hadamard(wires=i) qml.layer(qaoa_layer, p, params[0], params[1]) - device_arn = get_job_device_arn() + device_arn = os.environ["AMZN_BRAKET_DEVICE_ARN"] dev = init_pl_device(device_arn, num_nodes, shots, max_parallel) np.random.seed(seed) @@ -153,5 +161,4 @@ def cost_function(params): if __name__ == "__main__": - entry_point(2, 1967, 10, 5, 2, 1000, "autograd", time.time()) - \ No newline at end of file + start_function()