Skip to content

Commit 61db445

Browse files
chuyang-dengyuanzhua
authored andcommitted
change: region build from staging pr (#979)
* Add eu-west-3, eu-north-1, sa-east-1 and ap-east-1 to the no-p2 regions and no-p3 regions. * making changes for regions without m4 instances. Adding account for HKG. Squash commits. * unit test for asimov hkg account image uri * keep skipping broken tests * add new region support
1 parent 254267b commit 61db445

37 files changed

+476
-255
lines changed

src/sagemaker/amazon/amazon_estimator.py

+12
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ def registry(region_name, algorithm=None):
386386
"eu-west-2": "644912444149",
387387
"us-west-1": "632365934929",
388388
"us-iso-east-1": "490574956308",
389+
"ap-east-1": "286214385809",
390+
"eu-north-1": "669576153137",
391+
"eu-west-3": "749696950732",
392+
"sa-east-1": "855470959533",
389393
}[region_name]
390394
elif algorithm in ["lda"]:
391395
account_id = {
@@ -422,6 +426,10 @@ def registry(region_name, algorithm=None):
422426
"eu-west-2": "644912444149",
423427
"us-west-1": "632365934929",
424428
"us-iso-east-1": "490574956308",
429+
"ap-east-1": "286214385809",
430+
"eu-north-1": "669576153137",
431+
"eu-west-3": "749696950732",
432+
"sa-east-1": "855470959533",
425433
}[region_name]
426434
elif algorithm in [
427435
"xgboost",
@@ -447,6 +455,10 @@ def registry(region_name, algorithm=None):
447455
"eu-west-2": "644912444149",
448456
"us-west-1": "632365934929",
449457
"us-iso-east-1": "490574956308",
458+
"ap-east-1": "286214385809",
459+
"eu-north-1": "669576153137",
460+
"eu-west-3": "749696950732",
461+
"sa-east-1": "855470959533",
450462
}[region_name]
451463
elif algorithm in ["image-classification-neo", "xgboost-neo"]:
452464
account_id = NEO_IMAGE_ACCOUNT[region_name]

src/sagemaker/fw_registry.py

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
"ca-central-1": {"sparkml-serving": "341280168497", "scikit-learn": "341280168497"},
3333
"us-gov-west-1": {"sparkml-serving": "414596584902", "scikit-learn": "414596584902"},
3434
"us-iso-east-1": {"sparkml-serving": "833128469047", "scikit-learn": "833128469047"},
35+
"ap-east-1": {"sparkml-serving": "651117190479", "scikit-learn": "651117190479"},
36+
"sa-east-1": {"sparkml-serving": "737474898029", "scikit-learn": "737474898029"},
37+
"eu-north-1": {"sparkml-serving": "662702820516", "scikit-learn": "662702820516"},
38+
"eu-west-3": {"sparkml-serving": "659782779980", "scikit-learn": "659782779980"},
3539
}
3640

3741

src/sagemaker/fw_utils.py

+6-21
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
UploadedCode = namedtuple("UserCode", ["s3_prefix", "script_name"])
3030
"""sagemaker.fw_utils.UserCode: An object containing the S3 prefix and script name.
31-
3231
This is for the source code used for the entry point with an ``Estimator``. It can be
3332
instantiated with positional or keyword arguments.
3433
"""
@@ -54,6 +53,8 @@
5453
VALID_PY_VERSIONS = ["py2", "py3"]
5554
VALID_EIA_FRAMEWORKS = ["tensorflow", "tensorflow-serving", "mxnet", "mxnet-serving"]
5655
VALID_ACCOUNTS_BY_REGION = {"us-gov-west-1": "246785580436", "us-iso-east-1": "744548109606"}
56+
OPT_IN_ACCOUNTS_BY_REGION = {"ap-east-1": "057415533634"}
57+
ASIMOV_OPT_IN_ACCOUNTS_BY_REGION = {"ap-east-1": "871362719292"}
5758

5859
MERGED_FRAMEWORKS_REPO_MAP = {
5960
"tensorflow-scriptmode": "tensorflow-training",
@@ -73,12 +74,10 @@
7374
def is_version_equal_or_higher(lowest_version, framework_version):
7475
"""Determine whether the ``framework_version`` is equal to or higher than
7576
``lowest_version``
76-
7777
Args:
7878
lowest_version (List[int]): lowest version represented in an integer
7979
list
8080
framework_version (str): framework version string
81-
8281
Returns:
8382
bool: Whether or not framework_version is equal to or higher than
8483
lowest_version
@@ -125,7 +124,11 @@ def _registry_id(region, framework, py_version, account, accelerator_type, frame
125124
framework_version:
126125
"""
127126
if _using_merged_images(region, framework, py_version, accelerator_type, framework_version):
127+
if region in ASIMOV_OPT_IN_ACCOUNTS_BY_REGION:
128+
return ASIMOV_OPT_IN_ACCOUNTS_BY_REGION.get(region)
128129
return "763104351884"
130+
if region in OPT_IN_ACCOUNTS_BY_REGION:
131+
return OPT_IN_ACCOUNTS_BY_REGION.get(region)
129132
return VALID_ACCOUNTS_BY_REGION.get(region, account)
130133

131134

@@ -140,7 +143,6 @@ def create_image_uri(
140143
optimized_families=None,
141144
):
142145
"""Return the ECR URI of an image.
143-
144146
Args:
145147
region (str): AWS region where the image is uploaded.
146148
framework (str): framework used by the image.
@@ -155,7 +157,6 @@ def create_image_uri(
155157
accelerator_type (str): SageMaker Elastic Inference accelerator type.
156158
optimized_families (str): Instance families for which there exist
157159
specific optimized images.
158-
159160
Returns:
160161
str: The appropriate image URI based on the given parameters.
161162
"""
@@ -249,11 +250,9 @@ def _accelerator_type_valid_for_framework(
249250

250251
def validate_source_dir(script, directory):
251252
"""Validate that the source directory exists and it contains the user script
252-
253253
Args:
254254
script (str): Script filename.
255255
directory (str): Directory containing the source file.
256-
257256
Raises:
258257
ValueError: If ``directory`` does not exist, is not a directory, or does
259258
not contain ``script``.
@@ -272,18 +271,14 @@ def tar_and_upload_dir(
272271
):
273272
"""Package source files and upload a compress tar file to S3. The S3
274273
location will be ``s3://<bucket>/s3_key_prefix/sourcedir.tar.gz``.
275-
276274
If directory is an S3 URI, an UploadedCode object will be returned, but
277275
nothing will be uploaded to S3 (this allow reuse of code already in S3).
278-
279276
If directory is None, the script will be added to the archive at
280277
``./<basename of script>``.
281-
282278
If directory is not None, the (recursive) contents of the directory will
283279
be added to the archive. directory is treated as the base path of the
284280
archive, and the script name is assumed to be a filename or relative path
285281
inside the directory.
286-
287282
Args:
288283
session (boto3.Session): Boto session used to access S3.
289284
bucket (str): S3 bucket to which the compressed file is uploaded.
@@ -296,7 +291,6 @@ def tar_and_upload_dir(
296291
copied into /opt/ml/lib
297292
kms_key (str): Optional. KMS key ID used to upload objects to the bucket
298293
(default: None).
299-
300294
Returns:
301295
sagemaker.fw_utils.UserCode: An object with the S3 bucket and key (S3 prefix) and
302296
script name.
@@ -343,7 +337,6 @@ def _list_files_to_compress(script, directory):
343337
def framework_name_from_image(image_name):
344338
# noinspection LongLine
345339
"""Extract the framework and Python version from the image name.
346-
347340
Args:
348341
image_name (str): Image URI, which should be one of the following forms:
349342
legacy:
@@ -354,7 +347,6 @@ def framework_name_from_image(image_name):
354347
'<account>.dkr.ecr.<region>.amazonaws.com/sagemaker-<fw>:<fw_version>-<device>-<py_ver>'
355348
current:
356349
'<account>.dkr.ecr.<region>.amazonaws.com/sagemaker-rl-<fw>:<rl_toolkit><rl_version>-<device>-<py_ver>'
357-
358350
Returns:
359351
tuple: A tuple containing:
360352
str: The framework name str: The Python version str: The image tag
@@ -390,11 +382,9 @@ def framework_name_from_image(image_name):
390382

391383
def framework_version_from_tag(image_tag):
392384
"""Extract the framework version from the image tag.
393-
394385
Args:
395386
image_tag (str): Image tag, which should take the form
396387
'<framework_version>-<device>-<py_version>'
397-
398388
Returns:
399389
str: The framework version.
400390
"""
@@ -406,10 +396,8 @@ def framework_version_from_tag(image_tag):
406396
def parse_s3_url(url):
407397
"""Returns an (s3 bucket, key name/prefix) tuple from a url with an s3
408398
scheme
409-
410399
Args:
411400
url (str):
412-
413401
Returns:
414402
tuple: A tuple containing:
415403
str: S3 bucket name str: S3 key
@@ -422,16 +410,13 @@ def parse_s3_url(url):
422410

423411
def model_code_key_prefix(code_location_key_prefix, model_name, image):
424412
"""Returns the s3 key prefix for uploading code during model deployment
425-
426413
The location returned is a potential concatenation of 2 parts
427414
1. code_location_key_prefix if it exists
428415
2. model_name or a name derived from the image
429-
430416
Args:
431417
code_location_key_prefix (str): the s3 key prefix from code_location
432418
model_name (str): the name of the model
433419
image (str): the image from which a default name can be extracted
434-
435420
Returns:
436421
str: the key prefix to be used in uploading code
437422
"""

tests/conftest.py

+33
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import boto3
1919
import pytest
20+
import tests.integ
2021
from botocore.config import Config
2122

2223
from sagemaker import Session
@@ -30,6 +31,8 @@
3031

3132
DEFAULT_REGION = "us-west-2"
3233

34+
NO_M4_REGIONS = ["eu-west-3", "eu-north-1", "ap-east-1"]
35+
3336

3437
def pytest_addoption(parser):
3538
parser.addoption("--sagemaker-client-config", action="store", default=None)
@@ -242,3 +245,33 @@ def tf_full_version(request):
242245
@pytest.fixture(scope="module")
243246
def ei_tf_full_version(request):
244247
return request.config.getoption("--ei-tf-full-version")
248+
249+
250+
@pytest.fixture(scope="session")
251+
def cpu_instance_type(sagemaker_session, request):
252+
region = sagemaker_session.boto_session.region_name
253+
if region in NO_M4_REGIONS:
254+
return "ml.m5.xlarge"
255+
else:
256+
return "ml.m4.xlarge"
257+
258+
259+
@pytest.fixture(scope="session")
260+
def cpu_instance_family(cpu_instance_type):
261+
"_".join(cpu_instance_type.split(".")[0:2])
262+
263+
264+
def pytest_generate_tests(metafunc):
265+
if "instance_type" in metafunc.fixturenames:
266+
boto_config = metafunc.config.getoption("--boto-config")
267+
parsed_config = json.loads(boto_config) if boto_config else {}
268+
region = parsed_config.get("region_name", DEFAULT_REGION)
269+
cpu_instance_type = "ml.m5.xlarge" if region in NO_M4_REGIONS else "ml.m4.xlarge"
270+
271+
params = [cpu_instance_type]
272+
if not (
273+
region in tests.integ.HOSTING_NO_P2_REGIONS
274+
or region in tests.integ.TRAINING_NO_P2_REGIONS
275+
):
276+
params.append("ml.p2.xlarge")
277+
metafunc.parametrize("instance_type", params, scope="session")

tests/integ/__init__.py

+25-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,16 @@
2525
PYTHON_VERSION = "py" + str(sys.version_info.major)
2626

2727
# these regions have some p2 and p3 instances, but not enough for continuous testing
28-
HOSTING_NO_P2_REGIONS = ["ca-central-1", "eu-central-1", "eu-west-2", "us-west-1"]
28+
HOSTING_NO_P2_REGIONS = [
29+
"ca-central-1",
30+
"eu-central-1",
31+
"eu-west-2",
32+
"us-west-1",
33+
"eu-west-3",
34+
"eu-north-1",
35+
"sa-east-1",
36+
"ap-east-1",
37+
]
2938
HOSTING_NO_P3_REGIONS = [
3039
"ap-southeast-1",
3140
"ap-southeast-2",
@@ -34,8 +43,19 @@
3443
"eu-central-1",
3544
"eu-west-2",
3645
"us-west-1",
46+
"eu-west-3",
47+
"eu-north-1",
48+
"sa-east-1",
49+
"ap-east-1",
50+
]
51+
TRAINING_NO_P2_REGIONS = [
52+
"ap-southeast-1",
53+
"ap-southeast-2",
54+
"eu-west-3",
55+
"eu-north-1",
56+
"sa-east-1",
57+
"ap-east-1",
3758
]
38-
TRAINING_NO_P2_REGIONS = ["ap-southeast-1", "ap-southeast-2"]
3959

4060
# EI is currently only supported in the following regions
4161
# regions were derived from https://aws.amazon.com/machine-learning/elastic-inference/pricing/
@@ -48,6 +68,9 @@
4868
"ap-northeast-2",
4969
]
5070

71+
NO_LDA_REGIONS = ["eu-west-3", "eu-north-1", "sa-east-1", "ap-east-1"]
72+
NO_MARKET_PLACE_REGIONS = ["eu-west-3", "eu-north-1", "sa-east-1", "ap-east-1"]
73+
5174
logging.getLogger("boto3").setLevel(logging.INFO)
5275
logging.getLogger("botocore").setLevel(logging.INFO)
5376

tests/integ/conftest.py

-7
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414

1515
import os
1616

17-
import pytest
18-
1917

2018
def create_sagemaker_local_network():
2119
"""
@@ -28,8 +26,3 @@ def create_sagemaker_local_network():
2826

2927

3028
create_sagemaker_local_network()
31-
32-
33-
@pytest.fixture(scope="session", params=["local", "ml.c4.xlarge"])
34-
def instance_type(request):
35-
return request.param

tests/integ/marketplace_utils.py

+4
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,8 @@
2626
"ca-central-1": "470592106596",
2727
"eu-west-2": "856760150666",
2828
"us-west-1": "382657785993",
29+
"eu-west-3": "843114510376",
30+
"eu-north-1": "136758871317",
31+
"sa-east-1": "270155090741",
32+
"ap-east-1": "822005858737",
2933
}

tests/integ/test_byo_estimator.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def fm_serializer(data):
4141

4242

4343
@pytest.mark.canary_quick
44-
def test_byo_estimator(sagemaker_session, region):
44+
def test_byo_estimator(sagemaker_session, region, cpu_instance_type):
4545
"""Use Factorization Machines algorithm as an example here.
4646
4747
First we need to prepare data for training. We take standard data set, convert it to the
@@ -74,7 +74,7 @@ def test_byo_estimator(sagemaker_session, region):
7474
image_name=image_name,
7575
role="SageMakerRole",
7676
train_instance_count=1,
77-
train_instance_type="ml.c4.xlarge",
77+
train_instance_type=cpu_instance_type,
7878
sagemaker_session=sagemaker_session,
7979
)
8080

@@ -87,7 +87,7 @@ def test_byo_estimator(sagemaker_session, region):
8787

8888
with timeout_and_delete_endpoint_by_name(job_name, sagemaker_session):
8989
model = estimator.create_model()
90-
predictor = model.deploy(1, "ml.m4.xlarge", endpoint_name=job_name)
90+
predictor = model.deploy(1, cpu_instance_type, endpoint_name=job_name)
9191
predictor.serializer = fm_serializer
9292
predictor.content_type = "application/json"
9393
predictor.deserializer = sagemaker.predictor.json_deserializer
@@ -99,7 +99,7 @@ def test_byo_estimator(sagemaker_session, region):
9999
assert prediction["score"] is not None
100100

101101

102-
def test_async_byo_estimator(sagemaker_session, region):
102+
def test_async_byo_estimator(sagemaker_session, region, cpu_instance_type):
103103
image_name = registry(region) + "/factorization-machines:1"
104104
endpoint_name = unique_name_from_base("byo")
105105
training_data_path = os.path.join(DATA_DIR, "dummy_tensor")
@@ -123,7 +123,7 @@ def test_async_byo_estimator(sagemaker_session, region):
123123
image_name=image_name,
124124
role="SageMakerRole",
125125
train_instance_count=1,
126-
train_instance_type="ml.c4.xlarge",
126+
train_instance_type=cpu_instance_type,
127127
sagemaker_session=sagemaker_session,
128128
)
129129

@@ -139,7 +139,7 @@ def test_async_byo_estimator(sagemaker_session, region):
139139
training_job_name=job_name, sagemaker_session=sagemaker_session
140140
)
141141
model = estimator.create_model()
142-
predictor = model.deploy(1, "ml.m4.xlarge", endpoint_name=endpoint_name)
142+
predictor = model.deploy(1, cpu_instance_type, endpoint_name=endpoint_name)
143143
predictor.serializer = fm_serializer
144144
predictor.content_type = "application/json"
145145
predictor.deserializer = sagemaker.predictor.json_deserializer

0 commit comments

Comments
 (0)