From de45707d8d22b0f23376c0365208397c3928dae6 Mon Sep 17 00:00:00 2001 From: Angel Antonio Avalos Cisneros Date: Mon, 26 Feb 2024 13:49:59 -0800 Subject: [PATCH] Project import generated by Copybara. (#90) GitOrigin-RevId: c12bb2459ddbff1633abda8352a2f126ee767eba Co-authored-by: Snowflake Authors --- .bazelrc | 1 + CHANGELOG.md | 23 ++++ README.md | 2 +- WORKSPACE | 4 +- bazel/get_affected_targets.sh | 26 ++--- bazel/requirements/templates/meta.tpl.yaml | 2 +- bazel/requirements/templates/pyproject.toml | 3 +- ci/build_and_run_tests.sh | 106 +++++++++++------- ci/conda_recipe/README.md | 2 +- ci/conda_recipe/conda_build_config.yaml | 1 + ci/conda_recipe/meta.yaml | 6 +- codegen/sklearn_wrapper_generator.py | 3 + codegen/sklearn_wrapper_template.py_template | 32 ++++++ ...nsformer_autogen_test_template.py_template | 10 +- requirements.txt | 2 +- requirements.yml | 4 +- .../scripts/install-snowpark-ml-conda.sh | 13 +-- snowflake/ml/feature_store/entity.py | 18 ++- snowflake/ml/feature_store/feature_store.py | 73 ++++++++---- snowflake/ml/feature_store/feature_view.py | 17 ++- .../customer_demo/Basic_Feature_Demo.ipynb | 17 +-- .../customer_demo/Basic_Feature_Demo.pdf | Bin 222468 -> 216328 bytes .../DBT_External_Feature_Pipeline_Demo.ipynb | 7 +- .../DBT_External_Feature_Pipeline_Demo.pdf | Bin 469343 -> 470592 bytes .../Time_Series_Feature_Demo.ipynb | 17 +-- .../Time_Series_Feature_Demo.pdf | Bin 257608 -> 251085 bytes .../ml/model/_client/model/model_impl.py | 19 +++- .../ml/model/_client/model/model_impl_test.py | 9 ++ snowflake/ml/model/_client/ops/model_ops.py | 16 ++- .../ml/model/_client/ops/model_ops_test.py | 18 ++- .../ml/model/_client/sql/model_version.py | 13 +++ .../model/_client/sql/model_version_test.py | 17 +++ .../ml/model/_signatures/snowpark_test.py | 17 +++ snowflake/ml/model/model_signature.py | 16 ++- .../distributed_hpo_trainer.py | 2 +- .../snowpark_handlers.py | 5 + snowflake/ml/modeling/metrics/BUILD.bazel | 1 + .../ml/modeling/metrics/classification.py | 77 +++++++++++++ .../model_selection/grid_search_cv.py | 39 +++++++ .../model_selection/randomized_search_cv.py | 39 +++++++ snowflake/ml/modeling/pipeline/pipeline.py | 19 ++++ snowflake/ml/registry/model_registry.py | 37 +++--- snowflake/ml/registry/model_registry_test.py | 26 ++--- snowflake/ml/registry/registry.py | 13 ++- snowflake/ml/registry/registry_test.py | 4 +- snowflake/ml/version.bzl | 2 +- .../feature_store_case_sensitivity_test.py | 7 +- .../ml/feature_store/feature_store_test.py | 23 +++- .../_client/model/model_impl_integ_test.py | 15 ++- .../ml/modeling/model_selection/BUILD.bazel | 2 + .../model_selection/grid_search_integ_test.py | 32 +++++- .../randomized_search_integ_test.py | 34 +++++- .../ml/modeling/pipeline/BUILD.bazel | 1 + .../ml/modeling/pipeline/pipeline_test.py | 32 ++++++ .../model/registry_custom_model_test.py | 17 +++ third_party/rules_conda/env.bzl | 2 +- 56 files changed, 743 insertions(+), 200 deletions(-) diff --git a/.bazelrc b/.bazelrc index f4ea3bf0..22d4e20a 100644 --- a/.bazelrc +++ b/.bazelrc @@ -25,6 +25,7 @@ build:_extended_gpu_oss --platforms //bazel/platforms:extended_conda_gpu_env --h build:py3.8 --repo_env=BAZEL_CONDA_PYTHON_VERSION=3.8 build:py3.9 --repo_env=BAZEL_CONDA_PYTHON_VERSION=3.9 build:py3.10 --repo_env=BAZEL_CONDA_PYTHON_VERSION=3.10 +build:py3.11 --repo_env=BAZEL_CONDA_PYTHON_VERSION=3.11 # Default diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e1429f..4e4da97a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Release History +## 1.2.3 + +### Bug Fixes + +- Registry: Now when providing Decimal Type column to a DOUBLE or FLOAT feature will not error out but auto cast with + warnings. +- Registry: Improve the error message when specifying currently unsupported `pip_requirements` argument. +- Model Development: Fix precision_recall_fscore_support incorrect results when `average="samples"`. +- Model Registry: Fix an issue that leads to description, metrics or tags are not correctly returned in newly created + Model Registry (PrPr) due to Snowflake BCR [2024_01]( + https://docs.snowflake.com/en/release-notes/bcr-bundles/2024_01/bcr-1483) + +### Behavior Changes + +- Feature Store: `FeatureStore.suspend_feature_view` and `FeatureStore.resume_feature_view` doesn't mutate input feature + view argument any more. The updated status only reflected in the returned feature view object. + +### New Features + +- Model Development: support `score_samples` method for all the classes, including Pipeline, + GridSearchCV, RandomizedSearchCV, PCA, IsolationForest, ... +- Registry: Support deleting a version of a model. + ## 1.2.2 ### Bug Fixes diff --git a/README.md b/README.md index af37ef3a..0d75f737 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ If you don't have a Snowflake account yet, you can [sign up for a 30-day free tr Follow the [installation instructions](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#installing-snowpark-ml) in the Snowflake documentation. -Python versions 3.8, 3.9 & 3.10 are supported. You can use [miniconda](https://docs.conda.io/en/latest/miniconda.html) or +Python versions 3.8 to 3.11 are supported. You can use [miniconda](https://docs.conda.io/en/latest/miniconda.html) or [anaconda](https://www.anaconda.com/) to create a Conda environment (recommended), or [virtualenv](https://docs.python.org/3/tutorial/venv.html) to create a virtual environment. diff --git a/WORKSPACE b/WORKSPACE index 83e0e3ba..78d0bdae 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -4,9 +4,9 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_jar") http_jar( name = "bazel_diff", - sha256 = "9c4546623a8b9444c06370165ea79a897fcb9881573b18fa5c9ee5c8ba0867e2", + sha256 = "eca2d221f5c3ec9545c841ed62d319bbb59e447a1ceade563bc8f8e1b9186a34", urls = [ - "https://github.com/Tinder/bazel-diff/releases/download/4.3.0/bazel-diff_deploy.jar", + "https://github.com/Tinder/bazel-diff/releases/download/5.0.1/bazel-diff_deploy.jar", ], ) diff --git a/bazel/get_affected_targets.sh b/bazel/get_affected_targets.sh index 166cfaf6..13d78f2b 100755 --- a/bazel/get_affected_targets.sh +++ b/bazel/get_affected_targets.sh @@ -69,38 +69,34 @@ trap 'rm -rf "${working_dir}"' EXIT starting_hashes_json="${working_dir}/starting_hashes.json" final_hashes_json="${working_dir}/final_hashes.json" impacted_targets_path="${working_dir}/impacted_targets.txt" -bazel_diff="${working_dir}/bazel_diff" -seed_file="${working_dir}/bazel_diff_seed" -ci_hash_file="${working_dir}/ci_scripts_hash" - -cat <"${seed_file}" -${ci_hash_file} -${workspace_path}/requirements.yml -SeedFileContent - -"${bazel}" run --config=pre_build :bazel-diff --script_path="${bazel_diff}" +ci_hash_file_pr="${working_dir}/ci_hash_file_pr" +ci_hash_file_base="${working_dir}/ci_hash_file_base" git -C "${workspace_path}" checkout "${pr_revision}" --quiet trap 'git -C "${workspace_path}" checkout "${current_revision}" --quiet' EXIT echo "Generating Hashes for Revision '${pr_revision}'" -git ls-files -s "${workspace_path}/ci" | git hash-object --stdin >"${ci_hash_file}" +git ls-files -s "${workspace_path}/ci" "${workspace_path}/bazel" | git hash-object --stdin >"${ci_hash_file_pr}" -"${bazel_diff}" generate-hashes -w "${workspace_path}" -b "${bazel}" -s "${seed_file}" "${final_hashes_json}" +"${bazel}" run --config=pre_build :bazel-diff -- generate-hashes -w "${workspace_path}" -b "${bazel}" "${final_hashes_json}" MERGE_BASE_MAIN=$(git merge-base "${pr_revision}" main) git -C "${workspace_path}" checkout "${MERGE_BASE_MAIN}" --quiet echo "Generating Hashes for merge base ${MERGE_BASE_MAIN}" -git ls-files -s "${workspace_path}/ci" | git hash-object --stdin >"${ci_hash_file}" +git ls-files -s "${workspace_path}/ci" "${workspace_path}/bazel" | git hash-object --stdin >"${ci_hash_file_base}" -$"${bazel_diff}" generate-hashes -w "${workspace_path}" -b "${bazel}" -s "${seed_file}" "${starting_hashes_json}" +"${bazel}" run --config=pre_build :bazel-diff -- generate-hashes -w "${workspace_path}" -b "${bazel}" "${starting_hashes_json}" git -C "${workspace_path}" checkout "${pr_revision}" --quiet echo "Determining Impacted Targets and output to ${output_path}" -$"${bazel_diff}" get-impacted-targets -sh "${starting_hashes_json}" -fh "${final_hashes_json}" -o "${impacted_targets_path}" +"${bazel}" run --config=pre_build :bazel-diff -- get-impacted-targets -sh "${starting_hashes_json}" -fh "${final_hashes_json}" -o "${impacted_targets_path}" + +if ! cmp -s "$ci_hash_file_pr" "$ci_hash_file_base"; then + echo '//...' >> "${impacted_targets_path}" +fi filter_query_rules_file="${working_dir}/filter_query_rules" diff --git a/bazel/requirements/templates/meta.tpl.yaml b/bazel/requirements/templates/meta.tpl.yaml index 2ddac5b8..6eab3374 100644 --- a/bazel/requirements/templates/meta.tpl.yaml +++ b/bazel/requirements/templates/meta.tpl.yaml @@ -13,7 +13,7 @@ requirements: - python - bazel >=6.0.0 run: - - python>=3.8,<3.11 + - python>=3.8,<3.12 run_constrained: - pytorch<2.1.0 # [win] diff --git a/bazel/requirements/templates/pyproject.toml b/bazel/requirements/templates/pyproject.toml index 60ada30c..7ca3a073 100644 --- a/bazel/requirements/templates/pyproject.toml +++ b/bazel/requirements/templates/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Database", "Topic :: Software Development", "Topic :: Software Development :: Libraries", @@ -29,7 +30,7 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Scientific/Engineering :: Information Analysis" ] -requires-python = ">=3.8, <4" +requires-python = ">=3.8, <3.12" dynamic = ["version", "readme"] [project.urls] diff --git a/ci/build_and_run_tests.sh b/ci/build_and_run_tests.sh index e6fe56ca..53f4d51e 100755 --- a/ci/build_and_run_tests.sh +++ b/ci/build_and_run_tests.sh @@ -40,6 +40,7 @@ WITH_SNOWPARK=false MODE="continuous_run" PYTHON_VERSION=3.8 PYTHON_JENKINS_ENABLE="/opt/rh/rh-python38/enable" +PYTHON_ENABLE_SCRIPT="bin/activate" SNOWML_DIR="snowml" SNOWPARK_DIR="snowpark-python" IS_NT=false @@ -96,21 +97,6 @@ while (($#)); do shift done -case ${PYTHON_VERSION} in - 3.8) - PYTHON_EXECUTABLE="python3.8" - PYTHON_JENKINS_ENABLE="/opt/rh/rh-python38/enable" - ;; - 3.9) - PYTHON_EXECUTABLE="python3.9" - PYTHON_JENKINS_ENABLE="/opt/rh/rh-python39/enable" - ;; - 3.10) - PYTHON_EXECUTABLE="python3.10" - PYTHON_JENKINS_ENABLE="/opt/rh/rh-python310/enable" - ;; -esac - echo "Running build_and_run_tests with PYTHON_VERSION ${PYTHON_VERSION}" EXT="" @@ -148,9 +134,53 @@ case "${PLATFORM}_${ARCH}" in ;; esac -# Verify that the requested python version exists -# TODO(SNOW-845592): ideally we should download python from conda if it's not present. Currently we just fail. -if [ "${ENV}" = "pip" ]; then +if [ ${IS_NT} = true ]; then + EXT=".exe" + PYTHON_ENABLE_SCRIPT="Scripts/activate" + BAZEL_ADDITIONAL_BUILD_FLAGS+=(--nobuild_python_zip) + BAZEL_ADDITIONAL_BUILD_FLAGS+=(--enable_runfiles) + BAZEL_ADDITIONAL_BUILD_FLAGS+=(--action_env="USERPROFILE=${USERPROFILE}") + BAZEL_ADDITIONAL_BUILD_FLAGS+=(--host_action_env="USERPROFILE=${USERPROFILE}") + BAZEL_ADDITIONAL_STARTUP_FLAGS+=(--output_user_root=C:/broot) +fi + +case ${PYTHON_VERSION} in + 3.8) + if [ ${IS_NT} = true ]; then + PYTHON_EXECUTABLE="py -3.8" + else + PYTHON_EXECUTABLE="python3.8" + fi + PYTHON_JENKINS_ENABLE="/opt/rh/rh-python38/enable" + ;; + 3.9) + if [ ${IS_NT} = true ]; then + PYTHON_EXECUTABLE="py -3.9" + else + PYTHON_EXECUTABLE="python3.9" + fi + PYTHON_JENKINS_ENABLE="/opt/rh/rh-python39/enable" + ;; + 3.10) + if [ ${IS_NT} = true ]; then + PYTHON_EXECUTABLE="py -3.10" + else + PYTHON_EXECUTABLE="python3.10" + fi + PYTHON_JENKINS_ENABLE="/opt/rh/rh-python310/enable" + ;; + 3.11) + if [ ${IS_NT} = true ]; then + PYTHON_EXECUTABLE="py -3.11" + else + PYTHON_EXECUTABLE="python3.11" + fi + PYTHON_JENKINS_ENABLE="/opt/rh/rh-python311/enable" + ;; +esac + +# TODO(SNOW-901629): Use native python provided in the node once SNOW-1046060 resolved +if [[ "${ENV}" = "pip" && ${IS_NT} = false ]]; then set +eu # shellcheck source=/dev/null source ${PYTHON_JENKINS_ENABLE} @@ -163,13 +193,6 @@ if [ "${ENV}" = "pip" ]; then set -eu fi -if [ ${IS_NT} = true ]; then - EXT=".exe" - BAZEL_ADDITIONAL_BUILD_FLAGS+=(--nobuild_python_zip) - BAZEL_ADDITIONAL_BUILD_FLAGS+=(--enable_runfiles) - BAZEL_ADDITIONAL_STARTUP_FLAGS+=(--output_user_root=D:/broot) -fi - cd "${WORKSPACE}" # Check and download yq if not presented. @@ -210,12 +233,7 @@ pushd "${TEMP_TEST_DIR}" rsync -av --exclude-from "${EXCLUDE_TESTS}" "../${SNOWML_DIR}/tests" . popd -# Bazel on windows is consuming a lot of memory, let's clean it before proceed to avoid OOM. -if [ ${IS_NT} = true ]; then - "${BAZEL}" "${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]+"${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]}"}" clean --expunge - "${BAZEL}" "${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]+"${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]}"}" shutdown -fi - +"${BAZEL}" "${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]+"${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]}"}" clean --expunge popd # Build snowml package @@ -228,10 +246,12 @@ if [ "${ENV}" = "pip" ]; then pushd ${SNOWPARK_DIR} rm -rf venv ${PYTHON_EXECUTABLE} -m venv venv - source venv/bin/activate - ${PYTHON_EXECUTABLE} -m pip install -U pip setuptools wheel + # shellcheck disable=SC1090 + source "venv/${PYTHON_ENABLE_SCRIPT}" + python --version + python -m pip install -U pip setuptools wheel echo "Building snowpark wheel from main:$(git rev-parse HEAD)." - pip wheel . --no-deps + python -m pip wheel . --no-deps cp "$(find . -maxdepth 1 -iname 'snowflake_snowpark_python-*.whl')" "${WORKSPACE}" deactivate popd @@ -240,7 +260,7 @@ if [ "${ENV}" = "pip" ]; then # Build SnowML pushd ${SNOWML_DIR} "${BAZEL}" "${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]+"${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]}"}" build "${BAZEL_ADDITIONAL_BUILD_FLAGS[@]+"${BAZEL_ADDITIONAL_BUILD_FLAGS[@]}"}" //:wheel - cp "$(${BAZEL} info bazel-bin)/dist/snowflake_ml_python-${VERSION}-py3-none-any.whl" "${WORKSPACE}" + cp "$("${BAZEL}" "${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]+"${BAZEL_ADDITIONAL_STARTUP_FLAGS[@]}"}" info bazel-bin)/dist/snowflake_ml_python-${VERSION}-py3-none-any.whl" "${WORKSPACE}" popd else # Clean conda cache @@ -284,21 +304,23 @@ if [ "${ENV}" = "pip" ]; then # Create testing env ${PYTHON_EXECUTABLE} -m venv testenv - source testenv/bin/activate + # shellcheck disable=SC1090 + source "testenv/${PYTHON_ENABLE_SCRIPT}" # Install all of the packages in single line, # otherwise it will fail in dependency resolution. - ${PYTHON_EXECUTABLE} -m pip install --upgrade pip - ${PYTHON_EXECUTABLE} -m pip list - ${PYTHON_EXECUTABLE} -m pip install "snowflake_ml_python-${VERSION}-py3-none-any.whl[all]" "pytest-xdist[psutil]==2.5.0" -r "${WORKSPACE}/${SNOWML_DIR}/requirements.txt" --no-cache-dir --force-reinstall + python --version + python -m pip install --upgrade pip + python -m pip list + python -m pip install "snowflake_ml_python-${VERSION}-py3-none-any.whl[all]" "pytest-xdist[psutil]==2.5.0" -r "${WORKSPACE}/${SNOWML_DIR}/requirements.txt" --no-cache-dir --force-reinstall if [ "${WITH_SNOWPARK}" = true ]; then cp "$(find "${WORKSPACE}" -maxdepth 1 -iname 'snowflake_snowpark_python-*.whl')" "${TEMP_TEST_DIR}" - ${PYTHON_EXECUTABLE} -m pip install "$(find . -maxdepth 1 -iname 'snowflake_snowpark_python-*.whl')" --no-deps --force-reinstall + python -m pip install "$(find . -maxdepth 1 -iname 'snowflake_snowpark_python-*.whl')" --no-deps --force-reinstall fi - ${PYTHON_EXECUTABLE} -m pip list + python -m pip list # Run the tests set +e - TEST_SRCDIR="${TEMP_TEST_DIR}" ${PYTHON_EXECUTABLE} -m pytest "${COMMON_PYTEST_FLAG[@]}" -m "not pip_incompatible" tests/integ/ + TEST_SRCDIR="${TEMP_TEST_DIR}" python -m pytest "${COMMON_PYTEST_FLAG[@]}" -m "not pip_incompatible" tests/integ/ TEST_RETCODE=$? set -e else diff --git a/ci/conda_recipe/README.md b/ci/conda_recipe/README.md index af412a73..54824f7d 100644 --- a/ci/conda_recipe/README.md +++ b/ci/conda_recipe/README.md @@ -6,7 +6,7 @@ Conda's guide on building a conda package from a wheel: To invoke conda build: ```sh -conda build --prefix-length=0 --python=[3.8|3.9|3.10] ci/conda_recipe +conda build --prefix-length=0 --python=[3.8|3.9|3.10|3.11] ci/conda_recipe ``` - `--prefix-length=0`: prevent the conda build environment from being created in diff --git a/ci/conda_recipe/conda_build_config.yaml b/ci/conda_recipe/conda_build_config.yaml index afb39f11..00ccdcbf 100644 --- a/ci/conda_recipe/conda_build_config.yaml +++ b/ci/conda_recipe/conda_build_config.yaml @@ -3,3 +3,4 @@ python: - 3.8 - 3.9 - 3.10 + - 3.11 diff --git a/ci/conda_recipe/meta.yaml b/ci/conda_recipe/meta.yaml index 20347c94..486baec4 100644 --- a/ci/conda_recipe/meta.yaml +++ b/ci/conda_recipe/meta.yaml @@ -17,7 +17,7 @@ build: noarch: python package: name: snowflake-ml-python - version: 1.2.2 + version: 1.2.3 requirements: build: - python @@ -26,7 +26,7 @@ requirements: - absl-py>=0.15,<2 - aiohttp!=4.0.0a0, !=4.0.0a1 - anyio>=3.5.0,<4 - - cachetools>=3.1.1,<5 + - cachetools>=3.1.1,<6 - cloudpickle>=2.0.0 - fsspec>=2022.11,<2024 - importlib_resources>=5.1.4, <6 @@ -46,7 +46,7 @@ requirements: - sqlparse>=0.4,<1 - typing-extensions>=4.1.0,<5 - xgboost>=1.7.3,<2 - - python>=3.8,<3.11 + - python>=3.8,<3.12 run_constrained: - lightgbm==3.3.5 - mlflow>=2.1.0,<2.4 diff --git a/codegen/sklearn_wrapper_generator.py b/codegen/sklearn_wrapper_generator.py index 637a7317..793aaf37 100644 --- a/codegen/sklearn_wrapper_generator.py +++ b/codegen/sklearn_wrapper_generator.py @@ -583,6 +583,7 @@ def __init__(self, module_name: str, class_object: Tuple[str, type]) -> None: self.fit_predict_docstring = "" self.fit_transform_docstring = "" self.predict_proba_docstring = "" + self.score_samples_docstring = "" self.score_docstring = "" self.predict_log_proba_docstring = "" self.decision_function_docstring = "" @@ -728,6 +729,7 @@ def _populate_function_doc_fields(self) -> None: "transform", "score", "kneighbors", + "score_samples", ] _CLASS_FUNC = {name: func for name, func in inspect.getmembers(self.class_object[1])} for _each_method in _METHODS: @@ -757,6 +759,7 @@ def _populate_function_doc_fields(self) -> None: self.predict_docstring = self.estimator_function_docstring["predict"] self.fit_predict_docstring = self.estimator_function_docstring["fit_predict"] self.predict_proba_docstring = self.estimator_function_docstring["predict_proba"] + self.score_samples_docstring = self.estimator_function_docstring["score_samples"] self.predict_log_proba_docstring = self.estimator_function_docstring["predict_log_proba"] self.decision_function_docstring = self.estimator_function_docstring["decision_function"] self.score_docstring = self.estimator_function_docstring["score"] diff --git a/codegen/sklearn_wrapper_template.py_template b/codegen/sklearn_wrapper_template.py_template index dfed46b6..068a7646 100644 --- a/codegen/sklearn_wrapper_template.py_template +++ b/codegen/sklearn_wrapper_template.py_template @@ -601,6 +601,38 @@ class {transform.original_class_name}(BaseTransformer): return output_df + @available_if(original_estimator_has_callable("score_samples")) # type: ignore[misc] + @telemetry.send_api_usage_telemetry( + project=_PROJECT, + subproject=_SUBPROJECT, + custom_tags=dict([("autogen", True)]), + ) + def score_samples( + self, dataset: Union[DataFrame, pd.DataFrame], output_cols_prefix: str = "score_samples_" + ) -> Union[DataFrame, pd.DataFrame]: + """{transform.score_samples_docstring} + output_cols_prefix: Prefix for the response columns + + Returns: + Output dataset with probability of the sample for each class in the model. + """ + super()._check_dataset_type(dataset) + if isinstance(dataset, DataFrame): + output_df = self._batch_inference( + dataset=dataset, + inference_method="score_samples", + expected_output_cols_list=self._get_output_column_names(output_cols_prefix), + expected_output_cols_type="float" + ) + elif isinstance(dataset, pd.DataFrame): + output_df = self._sklearn_inference( + dataset=dataset, + inference_method="score_samples", + expected_output_cols_list=self._get_output_column_names(output_cols_prefix), + ) + + return output_df + @available_if(original_estimator_has_callable("score")) # type: ignore[misc] @telemetry.send_api_usage_telemetry( project=_PROJECT, diff --git a/codegen/transformer_autogen_test_template.py_template b/codegen/transformer_autogen_test_template.py_template index 488aa272..94f8d3a0 100644 --- a/codegen/transformer_autogen_test_template.py_template +++ b/codegen/transformer_autogen_test_template.py_template @@ -183,7 +183,7 @@ class {transform.test_class_name}(TestCase): else: np.testing.assert_allclose(actual_arr, sklearn_numpy_arr, rtol=1.e-1, atol=1.e-2) - expected_methods = ["predict_proba", "predict_log_proba", "decision_function", "kneighbors"] + expected_methods = ["predict_proba", "predict_log_proba", "decision_function", "kneighbors", "score_samples"] for m in expected_methods: assert not ( callable(getattr(sklearn_reg, m, None)) @@ -234,6 +234,14 @@ class {transform.test_class_name}(TestCase): np.testing.assert_allclose( actual_inference_result[:, 0, :], sklearn_inference_result[:, 0, :], rtol=1.e-1, atol=1.e-2 ) + elif ( + m == "score_samples" + and reg.__class__.__name__ == 'BernoulliRBM' + ): + # score_samples is not deterministic for BernoulliRBM: + # it computes a quantity called the free energy on X, + # then on a randomly corrupted version of X, and returns the log of the logistic function of the difference. + assert actual_inference_result.shape == sklearn_inference_result.shape else: np.testing.assert_allclose( actual_inference_result, sklearn_inference_result, rtol=1.e-1, atol=1.e-2 diff --git a/requirements.txt b/requirements.txt index a0a23af1..8b2074ee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -45,7 +45,7 @@ snowflake-snowpark-python==1.8.0 sphinx==5.0.2 sqlparse==0.4.4 starlette==0.27.0 -tensorflow==2.13.1 +tensorflow==2.13.0 tokenizers==0.13.2 toml==0.10.2 torch==2.0.1 diff --git a/requirements.yml b/requirements.yml index 24bd26cc..80eafd96 100644 --- a/requirements.yml +++ b/requirements.yml @@ -255,7 +255,7 @@ version_requirements: '>=0.4,<1' - name: tensorflow dev_version_conda: 2.10.0 - dev_version_pypi: 2.13.1 + dev_version_pypi: 2.13.0 version_requirements: '>=2.9,<3,!=2.12.0' requirements_extra_tags: - tensorflow @@ -306,7 +306,7 @@ from_channel: conda-forge - name: cachetools dev_version: 4.2.2 - version_requirements: '>=3.1.1,<5' + version_requirements: '>=3.1.1,<6' - name: pytimeparse dev_version: 1.1.8 version_requirements: '>=1.1.8,<2' diff --git a/snowflake/ml/feature_store/_internal/scripts/install-snowpark-ml-conda.sh b/snowflake/ml/feature_store/_internal/scripts/install-snowpark-ml-conda.sh index 969a28df..4eb55c8f 100755 --- a/snowflake/ml/feature_store/_internal/scripts/install-snowpark-ml-conda.sh +++ b/snowflake/ml/feature_store/_internal/scripts/install-snowpark-ml-conda.sh @@ -3,7 +3,7 @@ # Setup a conda environment & installs snowpark ML. # # Usage -# install-snowpark-ml-conda.sh [-d ] [-n ] [-p 3.8|3.9|3.10] [-h] +# install-snowpark-ml-conda.sh [-d ] [-n ] [-p ] [-h] set -o pipefail set -eu @@ -36,9 +36,9 @@ DEFAULT_FILENAME=$(dirname "$PROG")/snowflake-ml-python-1.0.12-fs-0.2.0-conda.zi function help() { exitcode=$1 && shift - echo "Usage: ${PROG} [-d ] [-n ] [-p 3.8|3.9|3.10] [-h]" + echo "Usage: ${PROG} [-d ] [-n ] [-p ] [-h]" echo " -d OUTPUT_DIR: Optional, default is ${CHANNEL_HOME}" - echo " -p PY_VERSION: Optional, default is 3.8. Options are 3.9, 3.10." + echo " -p PY_VERSION: Optional, default is 3.8." if [ "${CONDA_DEFAULT_ENV-}" ]; then echo " -n CONDA_ENV_NAME: Optional, default is \`${CONDA_DEFAULT_ENV}\` (current environment). If an existing env provided, it will reuse. It will create otherwise." else @@ -59,12 +59,7 @@ while (($#)); do ;; -p) shift - if [[ $1 = "3.8" || $1 = "3.9" || $1 == "3.10" ]]; then - PY_VERSION=$1 - else - echo "Invalid python version: $1" - help 1 - fi + PY_VERSION=$1 ;; -h|--help) help 0 diff --git a/snowflake/ml/feature_store/entity.py b/snowflake/ml/feature_store/entity.py index d88546a6..3140e900 100644 --- a/snowflake/ml/feature_store/entity.py +++ b/snowflake/ml/feature_store/entity.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from snowflake.ml._internal.utils.sql_identifier import ( SqlIdentifier, @@ -35,7 +35,8 @@ def __init__(self, name: str, join_keys: List[str], desc: str = "") -> None: self.name: SqlIdentifier = SqlIdentifier(name) self.join_keys: List[SqlIdentifier] = to_sql_identifiers(join_keys) - self.desc = desc + self.owner: Optional[str] = None + self.desc: str = desc def _validate(self, name: str, join_keys: List[str]) -> None: if len(name) > _ENTITY_NAME_LENGTH_LIMIT: @@ -62,6 +63,12 @@ def _to_dict(self) -> Dict[str, str]: entity_dict[k] = str(v) return entity_dict + @staticmethod + def _construct_entity(name: str, join_keys: List[str], desc: str, owner: str) -> "Entity": + e = Entity(name, join_keys, desc) + e.owner = owner + return e + def __repr__(self) -> str: states = (f"{k}={v}" for k, v in vars(self).items()) return f"{type(self).__name__}({', '.join(states)})" @@ -70,4 +77,9 @@ def __eq__(self, other: object) -> bool: if not isinstance(other, Entity): return False - return self.name == other.name and self.desc == other.desc and self.join_keys == other.join_keys + return ( + self.name == other.name + and self.desc == other.desc + and self.join_keys == other.join_keys + and self.owner == other.owner + ) diff --git a/snowflake/ml/feature_store/feature_store.py b/snowflake/ml/feature_store/feature_store.py index e130b650..2517dce3 100644 --- a/snowflake/ml/feature_store/feature_store.py +++ b/snowflake/ml/feature_store/feature_store.py @@ -87,12 +87,17 @@ def switch_warehouse( @functools.wraps(f) def wrapper(self: FeatureStore, /, *args: _Args.args, **kargs: _Args.kwargs) -> _RT: original_warehouse = self._session.get_current_warehouse() + if original_warehouse is not None: + original_warehouse = SqlIdentifier(original_warehouse) + warehouse_updated = False try: - if self._default_warehouse is not None: + if original_warehouse != self._default_warehouse: self._session.use_warehouse(self._default_warehouse) + warehouse_updated = True return f(self, *args, **kargs) finally: - self._session.use_warehouse(original_warehouse) # type: ignore[arg-type] + if warehouse_updated and original_warehouse is not None: + self._session.use_warehouse(original_warehouse) return wrapper @@ -278,10 +283,15 @@ def register_feature_view( """ Materialize a FeatureView to Snowflake backend. Incremental maintenance for updates on the source data will be automated if refresh_freq is set. - NOTE: Each new materialization will trigger a full FeatureView history refresh for the data included in the FeatureView. + Examples: + ... + draft_fv = FeatureView(name="my_fv", entities=[entities], feature_df) + registered_fv = fs.register_feature_view(feature_view=draft_fv, version="v1") + ... + Args: feature_view: FeatureView instance to materialize. version: version of the registered FeatureView. @@ -306,12 +316,13 @@ def register_feature_view( version = FeatureViewVersion(version) if feature_view.status != FeatureViewStatus.DRAFT: - raise snowml_exceptions.SnowflakeMLException( - error_code=error_codes.OBJECT_ALREADY_EXISTS, - original_exception=ValueError( - f"FeatureView {feature_view.name}/{feature_view.version} has already been registered." - ), + warnings.warn( + f"FeatureView {feature_view.name}/{feature_view.version} has already been registered. " + + "Skipping registration.", + stacklevel=2, + category=UserWarning, ) + return feature_view # TODO: ideally we should move this to FeatureView creation time for e in feature_view.entities: @@ -472,8 +483,9 @@ def list_feature_views( fvs = self._find_feature_views(entity_name, feature_view_name) else: fvs = [] + entities = self.list_entities().collect() for row in self._get_fv_backend_representations(feature_view_name, prefix_match=True): - fvs.append(self._compose_feature_view(row)) + fvs.append(self._compose_feature_view(row, entities)) if as_dataframe: result = None @@ -511,7 +523,7 @@ def get_feature_view(self, name: str, version: str) -> FeatureView: original_exception=ValueError(f"Failed to find FeatureView {name}/{version}: {results}"), ) - return self._compose_feature_view(results[0]) + return self._compose_feature_view(results[0], self.list_entities().collect()) @dispatch_decorator(prpr_version="1.0.8") def merge_features( @@ -620,7 +632,7 @@ def resume_feature_view(self, feature_view: FeatureView) -> FeatureView: feature_view: FeatureView to resume. Returns: - FeatureView with updated status. + A new feature view with updated status. Raises: SnowflakeMLException: [ValueError] FeatureView is not in suspended status. @@ -646,7 +658,7 @@ def suspend_feature_view(self, feature_view: FeatureView) -> FeatureView: feature_view: FeatureView to suspend. Returns: - FeatureView with updated status. + A new feature view with updated status. Raises: SnowflakeMLException: [ValueError] FeatureView is not in running status. @@ -712,6 +724,7 @@ def list_entities(self) -> DataFrame: F.col('"name"').substr(prefix_len, _ENTITY_NAME_LENGTH_LIMIT).alias("NAME"), F.col('"allowed_values"').alias("JOIN_KEYS"), F.col('"comment"').alias("DESC"), + F.col('"owner"').alias("OWNER"), ), ) @@ -747,10 +760,12 @@ def get_entity(self, name: str) -> Entity: raw_join_keys = result[0]["JOIN_KEYS"] join_keys = raw_join_keys.strip("[]").split(",") - return Entity( - name=result[0]["NAME"], + + return Entity._construct_entity( + name=SqlIdentifier(result[0]["NAME"], case_sensitive=True).identifier(), join_keys=join_keys, desc=result[0]["DESC"], + owner=result[0]["OWNER"], ) @dispatch_decorator(prpr_version="1.0.8") @@ -1339,7 +1354,7 @@ def join_cols(cols: List[SqlIdentifier], end_comma: bool, rename: bool, prefix: {f_ts_col} {s_ts_col}, {join_keys_str}, {join_cols(s_only_cols, end_comma=True, rename=False, prefix='null AS ')} - {join_cols(f_only_cols,end_comma=False, rename=False)} + {join_cols(f_only_cols, end_comma=False, rename=False)} FROM {f_table_name}""" union_cte = f""" unioned_{layer} AS ( @@ -1422,9 +1437,8 @@ def _update_feature_view_status(self, feature_view: FeatureView, operation: str) original_exception=RuntimeError(f"Failed to update feature view {fully_qualified_name}'s status: {e}"), ) from e - feature_view._status = self.get_feature_view(feature_view.name, feature_view.version).status logger.info(f"Successfully {operation} FeatureView {feature_view.name}/{feature_view.version}.") - return feature_view + return self.get_feature_view(feature_view.name, feature_view.version) def _find_feature_views( self, entity_name: SqlIdentifier, feature_view_name: Optional[SqlIdentifier] @@ -1464,6 +1478,8 @@ def _find_feature_views( error_code=error_codes.INTERNAL_SNOWPARK_ERROR, original_exception=RuntimeError(f"Failed to retrieve feature views' information: {e}"), ) from e + + entities = self.list_entities().collect() outputs = [] for r in results: if entity_name == SqlIdentifier(r["TAG_VALUE"], case_sensitive=True): @@ -1472,14 +1488,25 @@ def _find_feature_views( obj_name = SqlIdentifier(r["OBJECT_NAME"], case_sensitive=True) if feature_view_name is not None: if fv_name == feature_view_name: - outputs.append(self._compose_feature_view(fv_maps[obj_name])) + outputs.append(self._compose_feature_view(fv_maps[obj_name], entities)) else: continue else: - outputs.append(self._compose_feature_view(fv_maps[obj_name])) + outputs.append(self._compose_feature_view(fv_maps[obj_name], entities)) return outputs - def _compose_feature_view(self, row: Row) -> FeatureView: + def _compose_feature_view(self, row: Row, entity_list: List[Row]) -> FeatureView: + def find_and_compose_entity(name: str) -> Entity: + name = SqlIdentifier(name).resolved() + for e in entity_list: + if e["NAME"] == name: + return Entity( + name=SqlIdentifier(e["NAME"], case_sensitive=True).identifier(), + join_keys=e["JOIN_KEYS"].strip("[]").split(","), + desc=e["DESC"], + ) + raise RuntimeError(f"Cannot find entity {name} from retrieved entity list: {entity_list}") + name, version = row["name"].split(_FEATURE_VIEW_NAME_DELIMITER) name = SqlIdentifier(name, case_sensitive=True) m = re.match(_DT_OR_VIEW_QUERY_PATTERN, row["text"]) @@ -1494,7 +1521,7 @@ def _compose_feature_view(self, row: Row) -> FeatureView: df = self._session.sql(query) desc = m.group("comment") entity_names = m.group("entities") - entities = [self.get_entity(n) for n in entity_names.split(_FEATURE_VIEW_ENTITY_TAG_DELIMITER)] + entities = [find_and_compose_entity(n) for n in entity_names.split(_FEATURE_VIEW_ENTITY_TAG_DELIMITER)] ts_col = m.group("ts_col") timestamp_col = ts_col if ts_col != _TIMESTAMP_COL_PLACEHOLDER else None @@ -1515,6 +1542,7 @@ def _compose_feature_view(self, row: Row) -> FeatureView: warehouse=SqlIdentifier(row["warehouse"], case_sensitive=True).identifier(), refresh_mode=row["refresh_mode"], refresh_mode_reason=row["refresh_mode_reason"], + owner=row["owner"], ) return fv else: @@ -1522,7 +1550,7 @@ def _compose_feature_view(self, row: Row) -> FeatureView: df = self._session.sql(query) desc = m.group("comment") entity_names = m.group("entities") - entities = [self.get_entity(n) for n in entity_names.split(_FEATURE_VIEW_ENTITY_TAG_DELIMITER)] + entities = [find_and_compose_entity(n) for n in entity_names.split(_FEATURE_VIEW_ENTITY_TAG_DELIMITER)] ts_col = m.group("ts_col") timestamp_col = ts_col if ts_col != _TIMESTAMP_COL_PLACEHOLDER else None @@ -1541,6 +1569,7 @@ def _compose_feature_view(self, row: Row) -> FeatureView: warehouse=None, refresh_mode=None, refresh_mode_reason=None, + owner=row["owner"], ) return fv diff --git a/snowflake/ml/feature_store/feature_view.py b/snowflake/ml/feature_store/feature_view.py index ccceff88..1f4b8b67 100644 --- a/snowflake/ml/feature_store/feature_view.py +++ b/snowflake/ml/feature_store/feature_view.py @@ -138,6 +138,7 @@ def __init__( self._warehouse: Optional[SqlIdentifier] = None self._refresh_mode: Optional[str] = None self._refresh_mode_reason: Optional[str] = None + self._owner: Optional[str] = None self._validate() def slice(self, names: List[str]) -> FeatureViewSlice: @@ -291,6 +292,10 @@ def refresh_mode(self) -> Optional[str]: def refresh_mode_reason(self) -> Optional[str]: return self._refresh_mode_reason + @property + def owner(self) -> Optional[str]: + return self._owner + def _get_query(self) -> str: if len(self._feature_df.queries["queries"]) != 1: raise ValueError( @@ -354,6 +359,7 @@ def __eq__(self, other: object) -> bool: and self.warehouse == other.warehouse and self.refresh_mode == other.refresh_mode and self.refresh_mode_reason == other.refresh_mode_reason + and self._owner == other._owner ) def _to_dict(self) -> Dict[str, str]: @@ -394,9 +400,15 @@ def from_json(cls, json_str: str, session: Session) -> FeatureView: if _FEATURE_OBJ_TYPE not in json_dict or json_dict[_FEATURE_OBJ_TYPE] != cls.__name__: raise ValueError(f"Invalid json str for {cls.__name__}: {json_str}") + entities = [] + for e_json in json_dict["_entities"]: + e = Entity(e_json["name"], e_json["join_keys"], e_json["desc"]) + e.owner = e_json["owner"] + entities.append(e) + return FeatureView._construct_feature_view( name=json_dict["_name"], - entities=[Entity(**e) for e in json_dict["_entities"]], + entities=entities, feature_df=session.sql(json_dict["_query"]), timestamp_col=json_dict["_timestamp_col"], desc=json_dict["_desc"], @@ -409,6 +421,7 @@ def from_json(cls, json_str: str, session: Session) -> FeatureView: warehouse=json_dict["_warehouse"], refresh_mode=json_dict["_refresh_mode"], refresh_mode_reason=json_dict["_refresh_mode_reason"], + owner=json_dict["_owner"], ) @staticmethod @@ -439,6 +452,7 @@ def _construct_feature_view( warehouse: Optional[str], refresh_mode: Optional[str], refresh_mode_reason: Optional[str], + owner: Optional[str], ) -> FeatureView: fv = FeatureView( name=name, @@ -455,5 +469,6 @@ def _construct_feature_view( fv._warehouse = SqlIdentifier(warehouse) if warehouse is not None else None fv._refresh_mode = refresh_mode fv._refresh_mode_reason = refresh_mode_reason + fv._owner = owner fv.attach_feature_desc(feature_descs) return fv diff --git a/snowflake/ml/feature_store/notebooks/customer_demo/Basic_Feature_Demo.ipynb b/snowflake/ml/feature_store/notebooks/customer_demo/Basic_Feature_Demo.ipynb index 8c4aec7b..4ae6b64e 100644 --- a/snowflake/ml/feature_store/notebooks/customer_demo/Basic_Feature_Demo.ipynb +++ b/snowflake/ml/feature_store/notebooks/customer_demo/Basic_Feature_Demo.ipynb @@ -5,20 +5,9 @@ "id": "0bb54abc", "metadata": {}, "source": [ - "- snowflake-ml-python version: 1.2.0\n", - "- Feature Store PrPr Version: 0.4.0\n", - "- Updated date: 1/3/2024" - ] - }, - { - "cell_type": "markdown", - "id": "144c09b2", - "metadata": {}, - "source": [ - "## Before getting started\n", - "\n", - "### Watch out object name case sensitivity\n", - "The Model Registry and Feature Store are not consistent with each other in the way they case names for databases, schemas, and other SQL objects. (Keep in mind that the objects in both APIs are Snowflake objects on the back end.) The model registry preserves the case of names for these objects, while the feature store converts names to uppercase unless you enclose them in double quotes. The way the feature store handles names is consistent with Snowflake’s identifier requirements. We are working to make this more consistent. In the meantime, we suggest using uppercase names in both APIs to ensure correct interoperation between the feature store and the model registry." + "- snowflake-ml-python version: 1.2.2\n", + "- Feature Store PrPr Version: 0.5.1\n", + "- Updated date: 2/12/2024" ] }, { diff --git a/snowflake/ml/feature_store/notebooks/customer_demo/Basic_Feature_Demo.pdf b/snowflake/ml/feature_store/notebooks/customer_demo/Basic_Feature_Demo.pdf index af5b0a63c7e639a9b0aab48167e2d5560d1086fb..c96e8ec5e97421357f9f8a5e71d1d4035432e351 100644 GIT binary patch delta 56803 zcmY(}V{G70)GzRQYumPM+qP}DTmNd?Hn+BI+vaY!+S={?Ke;zId6Ic^CMW03OeUF6 zzM)eHk=Y1|`t+$9Q|KE}n$qO*E zu?PwhyScksm^i?C68eKrH1d$x7-ZiZ#o=&^Ol|5wuX=tA8vy>REFDHOv@Tih1_ z3YxtAhG}1L148cOOA1<;1Wfc_l5wf)+gC=$es%&-(Dywblh@g*NehYP_x<^xS2Wa+ zgY#3DE+?EqNh`!T2q!Dti4-1qKk%m1&iWmlMz`nQMS5RsiPV&lUjdhSE?vqk%lG$UN-4q&!2-157%%U2*b6&QZ1HT!{HNx{^7E1eFv;7q{4AMHW-TxpvT z3M&idd5`OOV}l?Y!sAvDPH;gEMw(Ixm%{WSM)p?I|F1>wuhD%8S5`$=~5k$<|IEz?c%cN5%B^qn2RJ_ z$z%v$NTu#Q~m{L5|#Tlb#s0%n0$X$a&xAiE zw<|TBmy-|`r?`q@&d}Vom`RH`FMGF~Cr?3~hm>(648fF{=YylYwUi)l6%^Em?$Z-Y zT%de9lNK+XlAC+yS-7+!Ja&-;}Ncw|E$1OKlHXe9UjapukNUuIo)DIjf11 zJrUXgdxO%I#BwY2-zagn%@i2XYL3t+PGa`=KcYnFgAKe^-FFF+7Uzw^Ga~Ezfa(kk zOFQv{3Ur0>dhm&)PS`A4{mMspT?UK zB?(Cz9bE^>ENeNW#j9W{k+E$45!!GBTV3Jqkr?-Ed%nFw__0PxqD5H4KWmYgo#7mU z(I$3aSa(Np-> z88p7J0kzWhfJ2$jH(x=nHKz6xC(GZt2IZ-rtnc2cP6(omq2>nZS*T*nz*U@dj3!ib znDRCk97z~vuz17@?ggG{_ofXCXJ^v>b=%lAm*V@$z5R)&e??=$0N%Y!AF{shpp=pC zgTZ8TVuPMbO}qY023&8d9a|36Y#i)Q71Ae*HDUB^-3J%nZPcH(HDcK_^fowO#=C(I zz?RDSZ%**G&7FPF%{YN^;Qh1IX+N~RWT;2Euin>YbHn<6vsWPR*z|j_7Fhor4Hs1H zHsPASIyHTF)ZK5O9;4)nb79w_xf|&eFKWrh*AG7s^}h2)MTqc_s%lKpN|Y z^7OlKu#4W+xQzK+!!cm0Y>C@+FmzOBYFn55xy>BlX4+w&EM`g#c+m?vmWNWYk9IYB z%7G60+-y+Tw8QpV4E4Y~b(eiDLS1@#y0WXIN!x}zsmwmSbrAA;5`3>c*ZV5*Y`@@*LmEF&+Z?R{OjHSYIKDpWP+YSqpyHICWyT4d082N4W^Zo1gb*gyYx+@C{D7$uy`KDKH6nwr)^tc#M z-*3QJwz@U;$s(rzetri@mbkd6a-=Dk|B}g^;kT>d+-W^zBYba2&F-*T-jV42Gdg z-n6kZj}w#U2U3eH-6GxD!P5gQc&)gco~cE5@8(TCki0C4r^&sQ>>hRAEB+4GjtI7M zEMHXDJ!8(I#xASuN(6T$N`-u^j|8JfXOJRL1O0150EUOCi@59VZp7xEYHVIFDsi0$Rbm?)sWTmT-^gGya}(WtTl|ppp2_QOIuG|x--cWV z^9)}bVC|abbP?m;k-@c1%d^48?+bhP+<&vgSIg5f`b=|PsNTQJe%paaXbo(0wxd0@ z-Fz5kE9!M9?M4EH@Q-=hymfin(*@n<{uYOm+tY=?z1~ z?#H^bw?BK!U65FB&9q8(^9X!_KNg^n5g%i~fbu~z4QjisBwdVJAxH$#tdJH~bip;G z&W*H+5YZq}g$PLG0gsF%hI zz}eiAnIGXL%O`Qpk`f>Mo3M63VnoE;a~^_6cT>-DI-Wn{>)YJ8WNTw10}J!>#!gFb zuH)5R!{OsI*QsZ%<9%iFU%OdI=zzTVPcy5~G`7+e!N1r@QuWRCu$$8Uea-=XJq))N zZri|Dgq-b(ZOF^!F=Y={Zb4W|F(FqckmGQ|xp~JSlbDs&#`%&FzBc>UZ$;!KPL1bB z$r2-;mD}n?Jm0}>A{E7qZw1vH5mIm0Y|l^E=b)#5R00V8{24m}k58p;Dp(IZ{{};r zaaI_IdLF0sdn~WD9=;D3f%jgnCZKh0u(zh^th)AvP!~!N`GNo6uE)-<27bT_a3bZ^ zcNf4*E#bF7-QVmYJ>=S@*}1>2H}R*d)t^FdlV`Gjqr58?!Ri_Nh6*1KXUWp1>2YJv z^O-Q(GKA>dgrQz+|LuP3S@L3`FXQh?BRg^8+w&i%(jegMba%0er%&7WPI82@ccioL zlPf3SZC_kB%XtO?f9Y5bj3eL(U_?Cf%^!Z(5WI3Gva&}Vs2S5z%X#?a%z3z-Sl)7* zA~-BS65a_zJ0%zngC(asmii+Q@~b7V;4WF^U{mRl=%kWha^*9)E3|7VB1OsrbuE1L zR6+KvIs1{);UI!)&XBC)FL(g@N6+yhZz7SAVTDBxlvdf^jS_usZm$|LK)jaeFJCuw z&y$Zrwd5~WC7BNfP}}$#OsN*r2ojrA&ETU3`^2!Tgo^}F-bVA^y_cdNpCd@GTVUF= z^z&a-wP{m&k6=zK6xhem&E&U@((Y1iADO^t>DhDK6knoGEvWj6cV2Ihw}Y3KL!e9d zSjaC<&cng{nQ83&sjnytbn^5qR_>8~%n5AGxHP|XaWC*tP~y&e&hbuy&*?bvUgpxr zAOCialY48Od~wG`iz=^;FWv#oxqjiL`&qS$zhA0Y`c3{DVUXW^0?+UG9s9P`J?io9 zf*@M3=f0uH3vYm?Z<{rA{KpI=gZ7;($LD5einbLA@ilhb4tpjWAc{UT-|>@#=ACFg zjJh=M*4|p|ITAUon|eg_pbpu;#}JJe=|+G&HUXKaGOT@?hg_h9Nwyvt8HOBA zxENx;PCA+|2u~z*95ndo5TSu#lPuWvsJIXo)I?fXYdRL}{K(4UIfU<4a_E4f=-9M~ zRIz0bN;>yGvm3byz;ZS!Yd`15c)lPuQ!*0k$FS z8oVI%K8{=J^dkoLp(Tk1-Tk04CHI$5JjB!pZYoStl{)o(wm)e+jssZyW1I<<+LjHCAkO{s}X(qWOK%Dy`eoGzNDDQ z;t!%DCe*Ujo5^LIh1*pYx{Tr-65(~WiCN((vQAh+mznQCEly|9x{QMPG9z?TT3#Zl z3Z+J7w?Rp`3gk{Y`=fKRSs;5z#HrEWMUI;tZZf3v?}AHeXl_uw=Ag6MVt_%+dbZ- zIy{ZBEO@Rlm!`B8!CYKie{h{$B(UV94-3oHq`P-4}*>oHW+)Y*@$WJ!A2?8e(@6|z`RSHLM=<@|PoOk+Op zD&YKmK#9=Z-2sJYyrmcXxourA2(^40)`w_kFEF}od@txPsn~44V zz)aVzZ`j=uB*}PA{p6^$b74A=N@}aW>!PYA+ckN zA|HN3P02pRo*GpmJSMo^ao7bC;I?VzQ@Dq`3kRKvZdB#gweok8myW{g=52Dv(LXO6 zqVog3dLcT)^em|HX-i15V+#^~c0p~QgU2ZNZYl<01){aJ~7O~JJ zTQdx+^Rm3dJQ>>T8J*9;*3{5uBJ${-G{y&g7JqV4qC*rnV?D-wrouO#_0)nZQRs*9 zZs%DPHuNmp8Dt>Wq!yYeS{R7Gxit;VEMOe6U#)$^C>QSkQyh zr1-0-{O*PXy2gbdCH{4<3X9Yn))P?|MQHpE)GwZl0vxQ&|I7FAC*#T5ANP!k z+(6cyjX=l(OV6KpCP5|zq7WdQ!T7$BLivmuqe(SNY0b#P>+|a9(nefD+@%$HPs)=kIN!Z|B!`9Wg9>!S;3foeuyD z(dD<$xAU!2z~}kZGSZ*BWnll(M`lKj)t2k!_DbpOo5?BkKtd+|4=hdW zh-n)u9!lFr2(@7FYB6Nr2@zE9k?h#=g1mFUp{@b-F`-&WVb=+f=j&UvUi{}>m>x(B zBnbkvrO1bcoAzHsXvC>cDYA->2XLT~dZ(|)|4kT6jJxK_A%jT>w~f1#nOxL|f(_Y7+MZltyt@v8957~yA!lHwI<4X{eq$q2^>n>^~7zMzTUi5k; zJYN3T=Y{xGrs)m1i5(+mm5%aI+UzL_%(uUNyb&+x?8p^e= zl?mQlmbiI{WoMj}+A=j_s7RYk)cT6=_mRhZCTm-Xdo)j3_uh~r{SGD87>1~82%-`f zH6mzY1>ooyqCp@o)u?fBKs1I&E`|Q4voW}Se~5mqbx0ib8*E>Os?n;W&!-5y@`zi zte)B(u}&a-rktg?tJyTGvBWuHj!oF?>@WqsHDp8pBdj^rUmh#QPIRCqPZwEJ^FE*4 z|3{eDsUOnlFLP;T&oNCj-}h!z)`5xgR7&s+66H8nSdlAP3p?Fp;|1Bd7KB)R9R5zb ze+^Mj`l&&1Cvh36nKW&qZmGc(yV3P^bl@K#ze=dk5OP>%%YqOHNwRP_V)OjX0I zsUT#(pPl<4YMe&1HhJ?~-l@%3+GQI%wB9y!WzbS6RB9hGl+*$!K+%?cEMEmW>vRK2_6e8$}6m!ZY=z z>6V61N-wu+&8Pq|co_A1GQWK&wz2WVTzn>l^hW^?3ayX0rA>1U19+g}4g)xuNzpmo z@5pg;F-Vh)RXvM-o=hYWFZHGgwbu$m4aJ68Uwd*^qbt?LC_Fng=5V<3P@P{)ljt(t z-rT*(TLMgGR)Gs?tv;Vq)otxQDXwN%9y-mk zQ$(Z+{Qh?BUX)?zGxI{B4(Fv`g4515XV`GfhPoc9v2u0ciu4w#CY_V-6UIbtd+8n4eQ*|Sk zB;B7tp8-7kPNdA}DhsogbgeYS}wed+UW|tO@<|iv@x&6Y}|;B&B}ou zdmgG0E`cSEqrn&L=n!-ZQ8*(!u38zBA)=qi*rdyR&_+%ir;}gQnBfQsGmf348y90Jsf}AOdvM;aVqcy`^$Iqp=dI`pmbXuBWbet#|oQ=#7 z3V@$r@f0%UR<^s+QpeqD6;gg!?Vk{?&{{e%s}ZX|7?V92U7D&-93B}#i;?CTw!Cj0 z@%jYsJoLF3bZsTtb&E+gi>)n^;h}3x1)Iy*LjF#|IuqB%^G$ziY(J7nzTsu9|g#lwgA15xUJXDl_u3}TZ7)uX^ig-d2dQl zlPM37c0L|ERlOORKD|^I1#dBi02}@JmvaedP(D^yG7dZWe%j#=WAk$Uh(%giVdnkI z*LHrroz8#ucvgl@mp_rM8YFDXB8Pfa_fwB8ceJbMxn^$y2$M(TE@QON_DjY%bO05V z#^R>fgi+DF`7P^zIHM`qo>#^;wZ=~Z{hM1df-Ivm`8NJXlH}NgfxNbQOKR}w+uKCu z-f3Ci*?W6(jcDO@U@w+BuI0vmk|Lx+iHW0at`_FsqUXX9U>nEJDJ zS1(=#@}U#K7ia(EZjazcuOnmNR)DTHpqCXs%OAMuaGN@f2jD?-Gb1aD9UE(0{~0D2 zcB_#ha=k!|ma6svSIT>k%d3<&=(S3qVAB=m4nlHOvNjjmY-zV@RPddf00zr@gOIbI za!oc`tb*w=bwHCwr;J*aYV}kb?(=oWp$%d`u+>My#(rF4$vlkOqXld{UeHM9$Shld zrR3sizN*f-^)s1TPSb4qme?b;8$f6V?D`3^N{fn>`1(m-EwtMUfW8wd+gAatpfKE{ zJzT1?f^s--19U(CR05BW*!T|?HhcFIM2_%=P?3FCobzlnhd%r7aw240nVr^bDKt=ePzs&6U z-am^^TLSGPQ7(77wqyadwm^X7D<{wT^~k31V0J3ya-U zXY5oSNxY64W30UkivdGtDI8ts6UUl5ax1zl?|3RK8a_>L`Z4{xpt-=^qf!7k*0+8t z4AU+%O)Kc{ivFVM-{1DdCRm^$!kHvkzwBt1c?4g?S4cjbl7a%U$ zIc~&`EL*(N8C=FT?7=~C;<9AGs`9Wj6#h&OWT+Yp50A2=jc>y)8hKNAaI>HS(IxVJ zXJlmw;~WGS6{2)DEPSa%F}EPwLz!y4sgf|%$Hv9TfC!qbaeLxAK6Cb4<@c5NLY)mSbv6KhyU2}$*!DQsD#6=E@P_4md+4g}hYFDr>FpwN ze3Yz;4+2DoCD}(Qa)3LAtsuc+MT}OI?z7**e4zskZ482Vw$D)s<|Rid#M~Dpe$FQ& z(yy6W5qBv4;TI&R#_b0`R?y)r6qqgC1v0$BTf+JPX zQqle@5E%mrE!O-S8bQ+`Ko& zslNb=-q%?DOjfgg$W46Pdaq-3Vswk#KOx1j@Ahh`ICbJ(m^kR;Ft&pz3L-3t_eHL` zzL}_14!g%4-@_XjcO*NLID+Zwb*g?n8Ao_Z@^L4dp#sm{ncuv}XeoXrqKuQj;T2@= zvZBrX2P+5r9-Yw;ZKr3=!spH;ASY-%=Sl$y4*rDa<(hfVCHMnFu}Wv8c;VM6Zlt!A zw8QJ7NaFxA2>aTWGbV1V_a={{i%?!hg~>BQP{K$wsgD{;$PGKk3@{MS#$ACm(FnFF zWxC9mj%jLxdRWzhaACKJ*ABE-&?ac%De4zvS=7Fc1gc0Kr$_PEd-eM6__bjJB)W~H8HRO(?3J2z zQg?Q(^ont1m0m1$H!R$@``2eA{cs>;SjzyLaDt~A5*2|ED2GgjH`G1dhz56DH~tU= z%h?YB9oc@bDUg*&es)%hbl7VZcTH`BY&T11lF`KW~u0gMb*6u8dBJ_zc>Ew zeVj%aLp%ZV#hXARKt`kJCpCT!61pOHOu~-{ET;{?L-Mal_)KTr=Bu2+hXC$$uI`FU z0*zy8`U#%etf9E0GO-S#vndGSSxLM;wsxdy&Q`pIg0U|nSMdj6aZlu|5U5SUgfY{L zy?0fngfNK81+vc4$%w(v``0jvlGQIbU@-AhX;hnJzIVjB&#M-ZYtA?d4eBX5x{~0| z-O{rd?jhKg>BI+UeZ7a|tAOXSHn{tB-5G);oCuG@6mx}ou7X9I9Au*WsDAf5{7hI~O{2CXWqfOi&bF50oAj;R>;5Hpt?l#MX zH*&4>Wr?FQR*`toEL5rCwEL)%6*?y}*XcQK0Nl; zD*U|{V_Ii8J$0gf+kaawkBI8$V2=O#R-@|)pZr{U4GgDN0SSfK4Bm{|=Q2R2h-Vc?CwK={kVRHnCvUso7;2!jDD)%1=MCx#dfK{d`my2TxCzeM+kKgY zm8ba>2=A}4SyF&$Xf$#;m;it4?vKKR{Q)A(BVBX!Qz7j4(N(L>U~VSwK1vABqQFj4 z2#?E>eFWUu$aFccF!QQ~3a>W^2wC;q#XK&Jf{rBxhn9x~$f@Z$4@f zWuQB&KM_BWMua06Q;?{50CpZW_Wz|j1e5V6ZU5UXqZ% z**cZ)SHB-Fgp9u4BBuLi+1v-u+Ojcv?Id2-;oXl)yDkQRGbFW2Mq>Ob{rZ2yaj2K z8}|43`AA_6Vg5hfY2@x@CKb69Mb7vSd;0y9PKlU|zAUcCR(D-RQc-JW*o?khUh@IO z=cGHqPU>G}@$Ckk-3ZH&GI3=qhrI7Q+Trxk$a(83mA&!g+4rtR9BGeJk&fUea7p4W zGzq5C8=S(;tjn2pLql=ETWb)hUSgYT9rDOC3V!NLe(Z`6W3OIrp*Qx3(|mj)HG1ij}=ZHT- zDDl@!Z#kQ!XHr#qvwQh>Ow{9L1|e%9X@?NplVnXxb!MMipmamW;3<%!j^KkyM?FNr zV19;l)+Du_jjqP(e)7~}*0C&i=xQ;Fsx&xmQJ{e7wUp(lzt^70Y$4z-KJ)-mI^!R^y0BGsW>fKaYxnpzshUT2BjK6+>E;3 zpmH3z*aaL9K4b+BU4r`?K|a3~;QD)Px9s@-91>1+)_S!|LsE&k98v!r?*6+_)tSC{80pi<%Ca*USx^d?&v@LP-8NZaS2fwWpxcDl&`0(LKz{QT{MO0hSB*T zYeNAKJ!d}#b34x>3V-_$VG958hi=+^8whW$TTVJpJ)C0mAsRWb7(TIsPg$n`s%8kI z@koF)(sf89#SY=vR6=77o%|h`$TBZePWmBvO_fjB+5=oo89ODjlK)|b?F7NmkP zQ@ULxo@w%ltM3*C#n)Y{SoXI;U{Y5i-O>Pbe3ns}=sB zmR+$KW4>s`>WQN3?^I7|%5IN+L>f}L7E^>$Oii2Pw11odPTMZed-x8egbqY?%mRBd z2Ca`%ihtc_z+K;a!V(qGkhs z8#RpD6ruIf3U&<=6gl%zI5$IKpsMOFrSk$gQML5Bh-zAmD!_TBa6IbTq8~p-1D>_Gg=jtEJ_`9s3W{pJ7siU}lv$90@k;#&~K=BC|4*SsbKeSl(OFA&hC5rc#~yOG8ezJ-Pv@4H2<34R&D(r` zZ+q7^Cr8cb#pKovFUY5~n~E)$PTx22&tb?gj6%kR_{K4mkKsn22G5+=8gYJ&@w>uP zkg;k|S5fmzH#F0-_LT_r(62lJHwL!?f(Co=S!p26QFzi_EUD%KOUnLp>{CT=3#avQ zAFa7i>vXk)e?>EcOk1J)Jsc_N_x;l7%0wdT%?3TM#bC6%&Wa3~(c~Lt=UheL$!10k zZ@D;ixLUVw0=p?|@st*!LNy*@YUh>dD=*W-OWY>BueP+F?0V zIMpC=Ym!!F&q|es3c00(?ZylqxJV2sHz!%^rhJ#53fq~OcX&G4bfUFnA=fV5X6GB9 zshyTn&V;#5<*HEi7b5dOa+gzArAJ}z{scyl3-_AQzW>KnVJ=nl@$=TqtC#OurMJ_} zQ}#A;?xjU|rWN8-HvSO86RV4B!#W6bNN=nY(i5sWA`>3!&V~5~+T;nuYeqY^gOF53 z5VFyKUM(t2jb`3B0UJrL`Sr_RB@S;d0I>?2q(pRSiIy?9NSF?wd`s@v206t5ACU0a z;8)O+K&z=@$|g1!CeyT>!J9Yk4Hbst&jz26fVNrVDDW~JsE0x60h6sUbK^q*nPs_# zj!R`4(JNH&(@S9C)2*P5?PyTT{px;ywd_N?M@mSlkHc`sgs%y^h4>3|6qC4?Ek@f> z5zIn&Pcj38At?h~pvlVt%HfcHBz8P0=(0{Yz_imgS)cH0xM3d9?muj9%)jbM{;64A3> zDA(%PtguNGw)9=o6_AJuh3VpM13jeNhxf_dGF~kC3-p1{BAsY?HL+|(MKKs~f*QkK z>^iaiX%{hdcu7p6^uKwbAACF#dlt)|g9N2ioTWPj%p7OC_9`oFf@t;zyM8BTgDxn3 zORRZY@r(oJaU9W<49$N$pdi6@KcM`J7#lURjk7kWoEL%6Ot_l4dO{NO+L)Lfi-gr{~O&+eLnTgb73= zx$gZz#4zNFT*N63cA`AMEf^4+irt2zC~fgs=T)9l{mRIndg^>kC8lZ5nHHmUpSnUd z$9<*zn2&Oz_Z$1Ly3YUC`M&$*JIhaH4^{y1XjYZB6wK#Fj`mNs9yAY5YnzzT(~lC) zGi)^}CY+_EO?cvn9?kVQs!PvHq;&?sg3L$Jx?x}hwmHsq)~So)4hu+ zHnYARhw2ZC2V)%OI44s8LLD_;(X43ppT)wA-MfQiPK zV|ZD^D@>hEmjlS$sSr)yKIUd%j@+%l35?OWbBNH_;?HwZkvo>IOi-nDiNJf`vJiyb7&Y_~GvYNi zzV;NA%INh9d{^4**)v^65HMhZ-yPQA%bUO~vY15Amem~OHMa-sPs%b(O(yjnOi!AU z@u)#C2pTMHMnyTA{EK^VBhNX68aj2TTDbKfq;%`gxR0#N?VK}sclO2xhC#4{+)`4{ z3oe!`_anM=fnPWibRTCN;1UX>J6kX>ME)Q@tvalKAJ}&KD}Rn)xb6ThkkY5{A>-Ee zkVH$0-B}0*5nT73{#k84hOY4;NO*mv=II4Zk6LHu>4)=f>NNBq161!c!82HYDkjnk zSbtV+DVYdGeYbe~{;ug5Ttg@_JMT@)8*!TstKxsYC*W|CRp79%t`znDAtvJldk_2R zU>V`>*N5;gnk{9?s`eW2-3VO!_{SWZwmbByn}YWpj;&P9(P?Nfd)0_ShP9+QldW3l zLYRz?mUr*plF9|QSozsReot7}wmcH=6&}wP^;Su?w6=u zPp_2~>Avgcufdeug*`Ygf7HOi=+`2D1SVS>XctN_ucTWsz=za0}Sfj z#}KbYG`3O0QIH_O&v;$kFr<8PILh`1#taU`3R~!F&IHIb1Q}RGM7Z z=n3*Tl5@er?C=_n@ySfXE;cic`iehge4LVW*Q1?8R-`hB2)QecB)4%XT{nHd$Bcy( z3y%uTXpavTwux2L!pWTk;|!=Pw*|j)+z2N&deUsKT>ra&yFwT)>^9)>Bq8zqo_A3t zifnXHrX}1v4Bwz1*SvLZn@ZW>P!|jB#TmSrV7JlH2@_TjQSSr?EW?}G@-)}a42Su6 zdMT_=NT4$`Xq}wjzfKnmaHOe7h@ZPi4km2&Hce$KypbG4th^?C2A<@@q#I2CJ%M5r z_Y5V$q72Xh`R!4fl$4byMolI`N0nrBwP()WgiIVhZqd?hjRr{qj^YM?&LW~f`j(?9 z(MN+)$w)nA$5+{+DUGwV*@M(DIaOhNj-pBE(WL_!J1-Ory0q-GTor@JZ$ZPaOdC#+ z;N(#Mj7LxeMt_>f_*hF8XI9hTT<40jXz7DU5fxAaXKIs)z0LO8(k1cGb5+%pIe)iW zkif_7!kh_2BPDqlZ)X=|AI4tlThBhzq$Dk%V4!-aHm4*V`e8=>?$Z7*R8~&DE3hO7jOiKq+2J`m zX;%ILl+GMw@AZ2{7MvZihH~$+acyQ|eHRB%cFk1BDeu*H-EN{(kdy_UJ=%v!tPE3=&f4PuP(PQQ)<)uzX(K~Bcw-$R07wcV!l zH3e;5%;C5%1`b+u=}`FAnC@jX!ud-q&iF=f&U*5*ZqS@ewr@beul)rq&@(oC`XMW` zmui|Ul!$~url_=$G2RnF4rzWPw(za_33mjjK|fR~kXSw?4VNR|<4u~V*&BD8spXyk zd!4Ak1pkn_$j+X!-DnF)#vA{#cU{bR#L@_9u*^Vw7OmtC1#`}9;wg>nESkU0KJ)y{YrE+B}D^k;b`ub;fVu^ zm?FzZ4eo|>1zl-^6(5C)-Yxc?UZbz^3^q2MWZ zH+C1?#GPIBtL~i?#bWHU-Q?w&fOd~otiAvH<6#;N1>58$A+q)*P4$~^7yD!9zlhbc z(Rafqo}*RdK*1#u{lrI|*Au{3yNhRvk~sVIevg#%eY#$dFZdbQ{-42_6KVbT!DoZ} z9^I7%rjVu!(vd(MLUJ{wHLDKCpl}X5=ZACac#q?S>jep2zdMf~d0W@D6x9UxwSGmKxdU zZmSmxR?Za+6lVSbYS-xh`FieK{?+0CiM6AU-HkC6t5QhdWc1zW&mt6UM zPQ%iohLDa;qjbXrxF*F64vT!rg$}B0%1?RU2@ruhoynq2nmJ^)4RE!>Lp>bTky&KJ zHM2Qeg@MG-y`eXkRUw_DRNE;-Zpndijv(y^$)AxAxqvc0m^a#_-d)IH%ZI$D8vb^1 zNq3C`g`c=ql#FQJD)&0r{3*qYNt)rS~H^juZgt1IRwI_q|8`+^>pUUIq_ z`vx;XAwXGcAeLI}y-AWGE;_D@Bkbo5!FBA74AEnhpx|`4=S3}KuA|g@R)P#JL$jn? zaqP}md-R?M-tmwSAAyYlOz4BElazo~)kZeU1W1Iz*j!HQ+RvkyuF|rX>`liK zOU;hfxW$!d3L;zgc(bCjx``caWny!Z?3lqrH_)Yk(NP*HAjildjr)T=X(&=AwU zLmmgQwfqzzA9)bu_{n)i8VEZ@8u)_r_6`{iT$}&R-sT~e$Kim0p#d$tUH7Ssl(zY-j=mtB znXKYcOcO>?JM{H6n`<8n0UStZd_cxN%x(>P)pgzTENF?DR>|+L$;!(}#qvI1fo2{) z<2i=VVl`xdDL-z(OCO^{UiyxsBx_~jb2-`1xZ@W3;0NmptKJvK=T9@!Oz3(vv1=>| zB>2K|!Bo>LYFc$uTzzt^SoSdOV;-fC^$rig9X=tuWFs(<)}lQ9e5CYcLg4F=^VnJG z`g<4nnE}Jg;_Cme*P)NkEUFhR@84=Ul~lN+a@&endyV$vg2Sfx$?eyp-`-1OSOeFK zg&uT5Is=i$KR)$Arv~>`2@%!j=9bpu>fY3LHrTByQKnJCnop>nbU~AZ6$Gdt{r|(& zIYn32Me8=UZ6_7mcEwJ`ws-98*tTukPAX0+wr#VbTmL!jKHU4Z*2`+MwYeU~9HaMd zX7sz*2<5OE8uHn>30QtoNvkk<0t@vY?v68ARbry7c!kD zmpxlNU5R~Kedv5u;6n|?JFp+J*2h1eTUjOB3f;SA>z1~2V^wypt9SJ#fu(m(uV-@4 zMN%GNWP2~^kv{A&LU_SRAvcYX$LUU`gfYBF#l0p%c63`)uSAnE;mRvkid6iblB> zphaMbC4NIS_7c5Nr)PX8a9|d&qIY008Z2qJ0%_XmfC8RHw}&JZ6mTtJkNeJp?h$|nXVx`xi?)YH zO{4LgD_$u;N(T6qr-AK2o)C}KjKd+ZxC9TWFN#I5BRq2h#5#oU2Q!9(cBk_9V6l)$ zCaD621o&u?b7MzJ4JFd^82s3J(@P_2C*Sb%VDj;cSYtg|*tvav6MDaoQu-dK*Y$z5 z-OSjj{%bt!%Z?D9uouOFiU}zD{78K_0$tQdEKLyGDy5KsJ?n{6*LWyw3`L6@yOsajuqu{uWtbK@L$&!_vj(3M2>9`8t?fW*D*4Wi}3+eC;Wt#=3RZNj|QRK)IO@Q{0! zZ5;`Wm4r+(`sg16`x4}Nx#>CcHZvN8Y}8l_ehs@v55`Ia)Obr}VZPe?-KoI^{gUhi zA2@ElSE!Dq)ZG$)(LB$ks|FiL+!WBzq&(vTVza3`t_=n`mdawhs?ZXdXx(kzv_&DV z2+;EE>29ed1VCE9brlcR6PwieGgdPeFRHtWAXUM?%j0!4`de(fR1e{xSi!@~yhb)4 znP_8iG%*uqQS_?r(`()29GV9wI7hyi9UM7dWOMK z!ZZXbzWLMID$Z1>oj+s0Hp&R#!T9C@`#{Ef=_7-;Ew+zi+7;%Qu13xE8kO@0qMDVY z7qj!r(AC&5qWxZR>jE!5RJ_CBs9+ps_1yNKGSg>k!^11y-%qWGoJ|~iRU(ak%i+9F z6+mq|n}`pOe7=h5hYjD6yde?Fpop(sqRsh+z-4o;yk#?rC>UX@YefJhis}CXKOt@W zEe9_~k{_gb-N8-@3(@lx|G+iVEk-onrs$=V^PQWvsffEO1@e(EN6ez%gX@tPZ zOAe4V$lPlD`1N*5=AKkp`i@vfQ8{c)1wV0?vaZNSL=@(fv;HDGS^&9;`iZ8A!T6Os z&nVPU-#jU-k>>XE@L9GiR3J$bXrf~(_-7K3=8{~^(TX59K#mtX)vF#(AZ#Dv+E8uY zLZpO`y$vr-U#_*qn1QV89==*3SdvuBA?6XC(3HS?V37EHB&A0zH$~~@ro*{vc>G%E zs_z-v(*4@d>R>cS#$h?N6$F7jHKfcax7hc zppC<1W#5>0ima~k+ls7}7+*b$mZg5C#nk|H-^veI-|Qq{pDhvrH_Oboj*4LJYPxkR zf_i5m(0HER+N6@$cxM*&cPfaUa?>wO17$=d8TE8@)%-0vYEq{Yk3C&CWcM?u>F)c=hWx<2v+k@Qb+J366&r?~kaB8B_yTR8G%PQIaQd~OQwBE(#>=GwSH zb5!GZVK++U6%ZTZ+fTEx?SG&Y-?yv(pp;kS2ifNzq}L8k1-B3PJHXzLC*(BX(3Q); zZNeL{KVI&p(E`}7x#qqa?ay?)lLzc<7y5dioGidGOHutqZjjOcK)ITESo!{*r zk)q;npevgnfEd$PZ6S4ad9P({B|L@b$0-+v^PCaLvUhfxzj0GkU22uljk>;o?G%;(}XHWa{Bnfy?cgPh7+J1`Z2@oMNNaSsZlt5 zWe|T~d&(jFi5yv@u_a)OnrFD8nOG z6OP%y3n2-fAQ6cSItL6w8XJYS7w|$bU_fbC5N!s9gP8G97sN8icG&UdLl~8=gr2Sj zvd0``H|mD8=9uC2m~^Pw z^`Q_}1Zgsm;KJcF3a5+?%x>%4I}vv)5w={nV)VoN8w?Fv4Y5?EYo;HH-y&28UX7DN zp;ry#Q51tRe19HjN<&|=FU^?1>`<*nKP1_=L zH=>ngdf=o+Kc`e3F(aXTv5Lf-P#b(NL2brS{-6g;LT3d2;HvdVfL`7$pmSI8-q418 z@hVE_Usvk-?9Rc;@2o+9oZJMJKu!rYBru84=&-eMYF}mo=b_ObO-S|cg7Z?<_fadD z;*bcp{h3Gz?6r%KG~S;+~4XE#)oobBfIkD^r|n^sLDvHpdz@=Q~0J zz1|j8-eB-Lg*N!B(De>?VyYOn9b7kqIfe;J@GO8szE7S8UQs+x%T}Aj7ia<@S8kuvQ?H6@qbXPSG ztbWY`n&|Q=MYG2w`1KLIUdW`q4BD%ez_#CV~byckB zj}3C1&nszsj-|6zWc%F)OFbOBUwUK53NpySu689|fB$S?er$8yee_0LhoUH2D`OOW zP#Ly7yu=}SDIB%(;5#;O42=M5 zhn|l{NyC^h@NWU#y$frZwatwzDR$}1`tS~8#=o@hw&WH5)f0PEIw7xnM78d9M}(nQ z-U*WA8@0}twWx^LVcM4V+#Oz`vv1FQwoYogNG$qA-=7?j2rqEC>cydRv2OW3{B18W ziw}IR=OCy1)>!`kyxF%kK*yGdb`o$sXUDZ??yRS-rz9%J-oBf#_@dZ;B@zrrRr$`c zeEVy=C~o$9aeuE`&y|kMf^@g}YUNF^lkcR-m+E~h)>?{T>F^?H2g3BWwrqn(*`#bE zK={OkkELyQA48~wnnb=*Z)fy9T$I&DuN}$Mi^T#3-S4#3)K3?{z8U@)V{&%W!-6cbjqYVaMV34_ zd;?H@a&vsG;k+Dm2Se6YRszm0Mp-FVD9}5833{RM!Y@}sxN0YMVzB@%4jm<`vH$`l zWUuCCMX7VUyjZ`E8eaGgH>h=8EZDD~g_Okl_kP9nbgvM^(Y-wuRcufS7U=z2^rb_UzK0J(bX8a9Rk(EzPbC6(Od2<#$bFOz^vUr6e_n-hJ z^DF!1xW@}Svquj=es!ubV+asgYP~yTI(JxcFxf`_nlY+F?k&wohv(+_?@sbz4 z=pz^wrKeyamxG5jD!_3dxzizjdPnl>E|Mx`Ti%QvHj@31Y$!9}ruEG`X=7P6n|@~e zP=%q`**syqiM12wPkI?f)B_!^8RN(L_NRl2vti83VP+!RNTQaU!MEhuuKStZ=R)WN6T~FXs>pwY4k8ZrY-aWR_(TI_$I;nfJs4DzXvep`E^Z9p!QM{=GFPp+3_hI6S(4L~XRX zj^j4kuapN|pIEJ*qv9m#L@-}p4^XlR32GvgHTJWsPmGyUB=er0`hirvU=bII!6O@$ zg4)?l6{vE}z;!fk`z&;X5j|l9StJn|m6L*3h0u59%2Eo@W?Zj=)ca9%LQixjv2Tr} zIuC2yOR(X65jMZq=9mYW(M&rc(u5KvZ7|96nB*dXeS`fhbjY3{q=5TkX-wf*UG7wC zYq-2hV@lwr;2OLe@@pYOg^%~-Li7I7Dx~z47nsX0u#@AYD&kXeF{Y|8bm&&-Cq6_L zL2aJ%)moBc19dUz%2{ev+8$Pp2>nK$SyxDb`L^Hzb5jS3Zh2w6J*eOKFNQTcM2rnAh&$HA!Ra)W(+d#w!wK z7}=k{*6<*fimtg6xPMH|;pC0vf&WmARs<#!dq+8Ugo}K&K%5+s;xP@Jo?WvNvTUp| zf)II3(4b-u$zVtWa_ARFTunM8J#X7@98&_>m$P5(ed1nHrBOC9H|UuOz=4uWj+Dhb zUSPNu4Q>L6ESR2Uzut+R;KNq z?E>xhjyD(bVpLK@SX6C`$8?AO_J0E7`wNbb*S;#w#h7QI6%g73i=gi$!*=C0C?bOAc&}T0*_C`<$(c#@>9Y4)X2Ooj2I_xO?^ z1Fl+NDECi$!B02yhgOe9Q5`&Qxc>UvUj3i&%#}6SBKZULn$1AZvwj-~!vtB6|F2hoLqbr>cy6L-Z12Zzp*9X5A$!o_TQx~{N+?75kglr7Jr&ixFb z?SNLkMXe|t+%!V;c%S!MV&Gdnen8N*!gX{>}8e+O};Rh1Hh z%%Y_1x)mGcT(;_*LKcnAreI_=QkFUz{!Jr5AQE?rr{*>sI!Z2?5GeDs`oXc$>etT0 z-urMGC`WZeBVp6@?`bL_rCFOPREHQX!gmngZczGQ+GbFi-GXZ`c^;R+CF^gAh8ar> zdEjh%{UL2bQS_N=;^U$Y#;ZJTF9ua6N zKhBU5*gp6+-y>%r@I!PY@s10U6IW@3?xtZugq9y2tK2nel$l-$KZeKIZ~&@}&rpP> z!Ly!ZJ_iYYv9jen=+e2&Nxc=z`MKkO5!j)xxb9*;@BP>@k(D???&dwClc83fx|8%G2gi1Dq}JYJ5kzv>6X)|CDms$Ar=GV&j8e9Wcbvff23W# zC#2|ho@bZ=NpOX_U(_aqS*53?^zAr6HSQZ|0?XmXBpIaLVie;^#ke0W%H|-?rGiL% zs_FTy4vX}7pj(9kt=u)YC5viQnlQ8nIWh%)uX3WAd z+Xi-4yGo-HBF;rCg|CD01JhEWo8Rjk#7?1cFfm9!*|$4kq)WSCcrKd7kI4=N{l5(#!g2e<_NVK* za%cbg4yJw*|Ef-b6ADC%7h7R}iuCbs@V%LzGPEjWS7!>W08$jAC(9_pJ&8OLOmz}sIA|qj^Io*h;?T%Yd3pKe}JBELv{Aw%`eR2mnYW(&~3mE zD3Fg#z!i|(9@okF+wbLoq5JjC;h%vt+}8K`{(Gyg{8J^n1M**QMd$sd3|j_vUdGUk zT!!zJOQv4jjW8+!Lu%cf>h|rC+_7q>uh++Gh->g4pJ46yDBk#LDBkF;Y)i z8!LSqlTw`spvZ-t< zU3+lGjRL9OR7<_Z`b{Y`HqGN6*R}h02V9$QiD&_A3FjS4kD7`E27D3g-~C{z!OHSf z65sui=RcdtTk7p_jBlJL&47busg0u8qjf%@pYy{1ru>pMh5{B=8o#a=4Ggy^SI|(* zw=1J%RLRAPnt2Vix};JGyhwNsmd|HBFS8P_zYY{2jfc0!HrgIyPY|uyWnyTIDP-sx zls85SG($JIQpzcNN#-W}up` z12Fg^LiPd^j6{5z@qznN#%+xikPZI^yw;}pgRU8v|MpRz>b0ibg6OtURT@A{Zf)%6sB(QuAfQ_+%ZSTwX; zoaCD8l;lcgDiw4{m8DuF)d)_(1=0HPYd91Pn{{Mz=G_114G^;|25WFVM&Z~VoU$tO zGlT0@__c0*%+hCLI4I%MuFY+_QqyQuWY-yGBIb8NY6>G#4uabcTeXC4+QBi&A{Yhv z)wjm!?p9xL5q2Rm8(E=?$7veuj)P#Ef9c5J1ufwZp5IF@9y@nWXi@HLygNzj~DTde8YXbLYM0?(M<(>e{`2AggK+>4{QcQg{DZX5X)7V?!mx zh}+;&4-7VIyT5W5+Rk*Jps1%~U7g+942~IbNrxQCb$YJ79W>B|a{nFLn@ED4twn3j zx)H8uJhgMVGUV5>;)*n&Lyci0q_4|eGLLv=+o%L!%s|=u85fg_D=#UTsPlF#{i{b+ z$~@vXViH#yS=0Q5mAUdl+x_&GLEphm*`6N-KM>+w49CpKV+z>E7Q}#HEE71bawMe7 z5o{;ojNjWe$w^C|4g;&lxK?>=9hu(zO>M`azJjeSJ@SiJ4xMl9ougz%tCh1^ONzt- ziFqqsWr1WkK848Wbi~>LL`9-SX?%E?k@CO%93q52(z0jOc#*cL9SBj zr|5Kzk2A=*JH7ubRO`DLUkWFw3ar!`QxxM#0Rjcg>zj3-t&Hh|+;@kRkZ%R`*R>$m z%+_y}c^wZ$W`JVOy{)6MX2C2kM0$WqM)SL5a05Vz=qvL@nv*#~e(b{q4d^fJ80wi5 z7|n`7uO3qK`CZedSej7Re`R}5(}e*!nOxV6+p-pohY5`}b~raN30M$|YQk6)xfH+Q ztOB38SZs@6f^QcME@3!8lw6FYN)n-{z?7&YKcn_gq|YaBp@mycX%~Z?u!|P84526O z$%2S^T4`x6LMv)YcFt3N0lG5fN#qIqlrFuckzp-yqqahAT#nL~9gz~ACAZ@m%qBhA zZF+pbv`r1O+4|#>*EhQLj$wg;VeCHcd0%V6f!#k?YDApud z+YFY7XZaDP@DFW1>0%uT^x-votjj6fDw>+0{^KNU+?^P{+XVMpV->0N3JY_N;}AK9 zmMWdLSwx(Df1ZPf6HCl|a)qWNCEcL~Q3wkl)rr%&)LP&np%O!V(6Wf2^OZu zGD>>~QX7AShAS&OFR9!Dw^q zPot)v+E1Hwzw17c^8&$~HvGz%hBW@l*c#@pWwUQb+CI6#!qfH#gC4A2wpb7{8D(q5 zGF1A51|-S#kBeeOh`S1ZxgqIa-;^Y@X$5HYz=N{T>O2il6rkXUk#G`;$aJ<{Gbg2* z`hb^>%YYSQM{|;_v2cl-fZrhPeqYUML?ZR0FkS0&vo_nx2Gz+m+#va4^Q|e$OuPr{ z&uMgNzNhAZfWf2{x{QFO+E^^J9;@qjP0URsKpvXQqkNK z=PpgP0v7Ch&w}WV{K%E|%^Q{+_heq0VY84H2G{w>RivL-T>;(EYK>tOU(y@ zQ*^+mE_kW`y$iE<$mJYMk>sgcmrXPfVbE2`XyP;r4B+ak9FF3Z75bIS=o7+Aqi%Pi=0?Yy1uP3;Nn$ng*q^rnaLXwHD?r|p- z8L;4VXOh+lfJJMCebAC&_6MEu;YBYmTJzSyhv-sL=jhTpF3V_Ufwej`Qi3>h@htbh z_3UC(fWl!R_$@c>y{OX1WK(-rUJ{86L*{>mSwb&B1E*9!sU2k#6<;G}-2W1#Vlhk- z1iXdl8l9ikp_dw17ii|^jfBZ)6Rk~}&1ba>X0F_=VG&jU>kfi21#ThlIGsQ9<^`|F zX|skMPi5M=v1ZJBI3{;oHd0uS(~yDsk3Nd#RG}z2`&K$;*iCU)SImNKq?0n8V!bJt zDXsj5=~7njhp`B`X8FioAS-KcP}1711KMPEHODSN(5SSTAFsxkX^4%QI-IWRAAN-< z1*?u~IuB!f*YDYJxze{kB#y|7G`SpqsL}4bCN>p6^rDj$QdidlXTMX-{+5Etc_nZ7 zfaKj5udLe24!o!B3T~+t#7S>YT%hR%tV=etQnbv%S|%Ly;Eg7QdQ|gW+uc$K0d>*& zIS)ZJh$wTOys_(Jgj6vN*=Is>jAAL>vmv0}8`uMd!D=L;ZS~qH_7GHEQWI-dj@dG5 zZ>9x|a-mSMW(7_`SBMLteKyTR1;*NHR)TV)4|LPk#lEVelXRoNFn~}H1 znzVz16ro)dI}{>yjbB=VkAC8b0c)y5qs>7-yO%@hp=RSW&IW?zcfBTadgW2jT#wkt zO(wjU=2XV`sha&$MQ%!7QF_u2rb)_QRI-=eQ?ISaG=eX>|3o>X=zpuOvHvMXz8$z& z8mOJYgTNdeApNmDeS#VSp#Gg>2(!2wXhM(o{FHZ6?*ZD8UHkj5eas}@Cr|?-C;3;c zoSYNBmi*BRVh$rEHYb<7gqr_mWM{k~zk0TUtqvfwQrd85t~Nx|(!MW}bUWRjW5X3% zd!}J^de=eCWkH<>Zt3Gdb8MV4$ZC0m>Yfta!RdwzQrJAivy76N^nLR!VVTT2(u$!k`S-5q4YB%tl0A=qB zeWp{$pIU~sxZmby^$WPP9pvzix0e~F-8Ndw*keJeOx*MpPMs{Rr@%${Lr60%s_E2a z8|GiuVZ_iODYh55QpYDVZrqb?sD;*Ws~tKckrz*OdH7w3@G$VWFdcs+enR|U>sdX7 zDO7%iPwbj-NrYmw-bx>l3+hm)cp^QE#zVPNmv>IH8m+$yR(4dr7y*<{Sf^8EsR(Jj zL@mV$kb5QaF|s2nUIGI)l^3!d%UDgmkSyB{i_4!*8n%5#NdLkF%KtINMERr88U0ir z*R67`BIa{4>Oj)Xp}^%{@q*H`EaVIh$1&{slUZ}9f9`Qw16VYC~OCBn>j28azMGX&qJuMb!a|zpd!&O{B1XYP_*Vuf!i7vLI8T4?L zAcFOssDYBljtXOg`Z&5&J)mjEe>!=i-as~Gul3}zaCd;Q$9B0U+a6&c1OT~q(a&sE z>OaleQyd0E5$0~$Hoc+fh*o>rbwdyrT+Yyon=GdDB)%C|UyA9VZtCjq6)N!x8Pl-y zQ21ldc|evGUFbCkO~dgHVrB~%N8?T1Cq0A}bpr**-2+-d8mMKrnvj zi*K5_&F8H&qWAAp>7eVvarBnBR$?;xxbfSHV>H0e-E?EB)-P z%NQV@UYh98t=8L|zs>aqEaa1a5lL&301Y!1)ai^bz?mJ!gQfv~F#H%%_JkBd2oQcZ zjP9G?LKl_Q+Gzn|py)}ncGSTCzbCk6Pa%D`WuW{=Dl6%Qv?hL2;8_rye1NZBN(z4c z=$n%4rmC_rmcS;}OtQ6WQau4R!SSalzOwmdALP*YjndsO+|G}uva~#d@P3#fA+pqc z%91Y*JsckczkjhpdBC<0`2TdMx=W`2t3wqwd!PIwiTeB=CC2*RPy0tz{RL(Ee*F{W ztFQd3lD+m{BoX+>_gjccU^7~}`YQ@OD!l}D2%@pfrU)#qbm|8pz~)~fQGiAudM8W~ z_MXP)9pvnS?3a07U0wT01ds?8df=R0XwWFM|oF(+l(t zezycqAsgb}4N6|IH z3&3d%z>vsfGbdAuX$z-Fm#WqRwj(#yBdDvvmkb`2t!hH$maU?oNw2`VPqpM%>*ZcC z5tm;sTaBAj+$$)NvXt%d9$j4Y$NZ;KA#>gT+3+b^R6^4jbjoq`Pgqn_(qgMk>PSsG zoHkMDXNDc{=w>7yEoQD6dRZ|t%|TBlD>~EiBi`!!W19oF+gB*VET#=)?F_MD1$!50 zE13sB=M8}QYt)7rgsybI`ej0cbS0#ENg*=KB*$V5;90)D(JZ2DmZBbe355&km#dQdj1Me$Y zBu8yIBvF%`F5E_2NyK>8C!eVanQuV@4`Md_!@Hsc2sf6Tr;QLZ4iXdlJ1ILf~?RFeVr{?OBiAOj;+YH+@I z=f`*}W;52aK{`IeIDu_3gCn>R5VxT{VafwblgPqtwj-eHDlfy34`qeoI zym+(8M(>lJ)}MW#PW$DY{Uu)jI38#G!~C6yZL~80%hFy8=kk|L&DaT4!N}(4@e`vI z*QG~_L&WN4q2J0JlrWg3M1}1r5?IFk=sfroiOucNgQ0+DeLz`{SK)KBk6g){X zeza~KCyGc*5$%F>bhnN@xAc#Y_RV>kH3?o&;e6G3MBWr&{b9<+xI>a>d*xvL8&LfS z*it!f@#Lz0WQiKQFNKn##+tkDKQ4jt(K}!m!W_b-SGr=pvpepeqMMME&958gbuPb* zCsw>@Z4gZ4L`Vu3fdei^eo^x&^8}eOX?QY0$-v{FgHMW*8ptC5Yl**(_;szp0eGO& z!UO|Gddm$AH}m4R%v7a^xwlS&n6D6CQ=5p~slH4>Yg&2=qLM4VE(gOXkpF7_>Md zh-==2GvlGYZGuvVJT z`uNTbUhL&7&ZPvY`cgPYq-C~(c$3xEZeiF1dmPFY?AM=hWl{i`+GtUn4$YsSFa@zd zQ5=1yVkKo|=^N~*3EBy-3w3`=Cp=t8>Xk*(KcL|;5N+zc7U$g7y3MR%cI{huW?HV* zRVhQ2ot9BUc5ff}*U)y&d$CygZ7f8h@mJSvpYaDmf`heH6 zhM=0KEbexvwRXZADP#+p;m`!)7l{?bfmtWSF!osQtD4f6Iq87uyP7>Hequxr{I9fD z(>?*B7O58P!=mc=mujiZ=KC3_t<^gmx$LN_ff(FAL1s6gip?oio?ZJQ5~OWxO&W{SON1ab7$>KTqN+DBsk+BwN(wv9*Z$6m;cMA;hvp@< zS;N7q4tDp~A8>$pIQ5LM%Se6?X~ryrGi$9;w3?}0qBV&v%8Fo{k%HujASWHj(At9X zWlI8E@93ndtF0L`hL#pkKoXv?E0eU?Tvg`aqEQ{2y+yPMRfrCqK8jiN$j6rsPQ$7> z_y^dqWkY#z zg=bsy5?N#p*w%DcxG3}|5%s@0%?w(UW5rX~tXiJDYzCF<4m=Qn=PPyl`rPNRrr_Np_e`WHaW)jI4Wl^xL?yIgIsTPV|C}lie+MYg z{pu!Mut$c+0OpPN%Beqa^fdo2$aGio$57l+L7QqzZVzR`T$f{Q&ekFyiZLJ8hEg}K3&4~>uD|tmM)I;!;2e{PRWjR%l3u<%+rK-3p z(<3jn+ygi$sGru8{J=-BNLZ9yIXh{>5=Yx4T>gaBao_rx%l$bHaqYH}+ zNnZ>B%>f(VPuldC0UnhOyC$b%u;W7lE5r@Q*yOy<(&7X9QwV*1E#dALr#M;jf(f~M zFt&NtK`nYyjdtR~rCHUNtlI%}uKPv=GTdmOMfB5kgXUfP5oBf@>_|T(pJ41{yfa7( z_N0fR(k?mJsBk$A4BMLzMU-LX{szMD=?o1}oOcp|W+(@3rL4crbW;3en1%HulaLGB zJ=t?x;$I|e1HB3s<}>whZ`^9G?E{7&%aiZ%1KAh)sdqgHk?@)o zq^c4}W6|#iDFs;j`ZpB(C9tyjCfx_3r|GFPQZ*)i>MD-I+fwTXT&!xf1V_HF8Ak+3 zZymh(39ks|!LQU)sFd$$`z?zpm8*V?{xi}BHSw>tC$znMM4O>LPbL*`!%b1q>SWl+ z6}$>g_dlY%haA&u_lNIMald}4>{QO_LR2=nB%&}&FN?3pps36j>BIntdSkK@i+Ry^$-8)g zGRJIXU{33VJEj6}X-ND44gEGOq<68&sa7eWPe`V`@2wa61B=t6nXBNS`5!vKw)i(b zT)pV@`Hqy}deIC|W&=^o2|gDTQS!b!$mXuE0hy$vd9Y)G7eh9Tvh%9d>kzP79W^I8 zC@~`WT>XRfmcqzsgpXtueFvGo{uXmx)L&Q2c-4@ZJwxW1`a9Y7ccw9eh>KrBT4u>w5e7h2U ztlbv0p>iUJF$V+=v+O%NRtY@|sK2n0Wtp|`^8L`Q@4(t<_UL*}&4FX0*sBO4>T;A& zO%%#hxgqtoGj?q9_gm4=(%hssoH?T`9=62X=ppi%O`j5R?pu{dB>TDqdWZ6jGO}g3 z#A!HcZA7=;$nV+h+vu0|S5)CEZugyB&rfp_{-A4DfK}i*8do6Lv8$tT>e2D;rq}kz zffoCB53uOd;o_Hhh5tPO*rZk)`D~-L#nA>^o8FZ9>D*1__^=PT`bdh|&78q^&L$?` z%X$;@iYsJ<@xoQ`f)&0hK zkzaI#!dWfZ9kU{XJ4_$_qR_t=F?lI6R8RBS)fuXABhdFmpd44qfk*a^pe_oYL%&`` zmzzRw^btqnGE%eA+U!!Rww9F2H0gEXttvK&RJt^##}YgT=5Xg~Ywm+Bxx~ImECz9q zAV1f1Ok#Sz@u7~k%Tc_3^DJ;@;en556<~3W5f4^ATbh^uwyYM-nWMAtTJ4YvjkLdX zvX?E;G_sd9LVTK-0P2hJ#rP$ME1uC8-^HWd^8;nCMq5+AQfuFI+GPvox9*WYtHfuv zSiK1ldI|bI!oYHErga96D9p4=!wJh=U4t-ZCJD~ZB^9%XZMqs5p`()=9Q4g$2hMas zNJHrRpj?xAREdZT9q*nv?|*n+q3PUk!o`N&_bl+?-Kwxn0XyW@-2?AB(Dm+pt8Dzj z+FI%8d(MQ&aTN5|Dp2*uI~d7}s&KH$yCKKASj;lJ=?rIJX`0^jhTLqm;aj)R{3oTI zG2((pyNf%HxOEER2@9{iHV-c5es9ZF3?Jj&WaznDlf8tw$ECkQkhOLYEbN=cWEuBq zX~?uxb}ttn0NE;xT|*;nDkAKT|0;DE{!M;heJ;+a(@Wjpsf=CoR3(4vDC?fJ^wP0J z3-9EQ`Q+wf@+#e83HRoN+Hadhp5mUOQCa5!$xF2ui)A89Zcb)$=&)&ScdK)^=9?kS zqvbRYHC*dnfT*fKM(*tbGrkoW&ASgYyN;d2Ceh^~1!g`_8#bU~3mx<3h7?KMjGccK zv3xhpY+<~b74YGz9yf79vi~BK$!dA4Hb2`EBfK_wlETZ#NyO?DlG+#C&3m&T@QNu@PdXOWwpbibz)rN%36Pcx!^7|3V03+2>)@Xgkr@s33yM zx&sG`1Y(x@3jd$dzC50aFaEokLDtBcC0%>=yDx?8dy2GKvXmlOl9Ez4X%Q()nv}Ig z$&wabTUuyQT9lL}Q4~>#gp}vZ*GQ9~F7=l3^$#cg?@*yP%ca4+X)a0=*W)A4m#<3JYy^2>-mF z;wGzh$3Q~-ONF3dHh)ZUsV4b@iC=|;o;=u5zrVCf(j@qCNt$XNaHRykxG7(= zUa}&=29c)f6-*B35i-4*(=@1cQ$6B0D=Gh_$f z<@51A#qa(tsQx7(qw7B4;I`Yf;&wjOZCGEWHKYXfasy17T%-n*K&NuOPZ^|8GJpTO zYiGXBY5KBnPVAi5>l(kR@+JOOmB-yvfB$@Zu2Xqz&zC_H+uKp=;>mBm>D9Y0if!NR z)jZ0i!5+(WI`eP$488M6-@osCq7KhL$8a-!S)pqUag{Hdf|$(Ff!@IJgH0o*Z7Y6= zp4h|;KbrnGa{lL!BlA0-@B7<-*>!h+(=zboLgs;hO-tIlfizryungM2e-w%MJ6g5C z{rKraYsXfemtGL_VZmh~iTbniv!!!8^T+1=IIDel`K!}T2U}E+Tl=(2E+DghRvLPE z^uK)5H>PaJJFJ$^Cs$KD{KnSBq~Rd%rPq3H&*l@D%l=j=2?@r^a+-$&A8!OdftqM8 zt0&~uU(&XUsqZ9Yxx6&;*ael}s%lR^-jfMD=6yr@7QQ(qf|eUu0xgv(-HXV-7FLpe z7P-Ucvq(m`GnMdS4|&7>)6bvekAzueo8-1O9eVRwxe0x8QcOApH(<7R?8=cg%Xd~3 zHR(#F0lyuuE%SYL$tvEqKUp}|>}#r5w~{w9oUXUNvQdk9%j01TPuOeJ({Qo7)T-pv zkA?nQL@p#OjO^LAJ^FO;eoAeIr7=ofFA%Kv z$4ula&p>csv2V}CgP&@3d3`ok)$bq6llZOMv$_gd&l7Qp_-w%sLxJA7M5sl6*Zdab zFi)?@ha}ue)Z9}kdp^^G@u;Sy5+a4@mW=ZPY0_Fnkcd*{41{! zMCjYnBlfv!S1o_*xj*}fW?Yr(9L>~XKg92~U2aD-Bl0-TdFkV=2XEbom$KZx(RF_n zvj0ZornLbA72Ss&H?L+^y5uLFet9OKt@M&$M9=Z7#1k@SD9agdwyjQbM*pUw{p&W> z;;&sgT{KYYvY>#RaOmxWTY~wjOEX_CkR;42rhW}5eZAW1<#lBQS$QPd+L?GYXSH|U zr>$u`<`3tw5(RH->sF_ywF#}!J+$zWL0P!vJW5(j*Y}G&WBe;O#(FWg3JHiE@0L<_ z9kKUXa^9R*agJZY^@YC{{k*R5sc7CtlFFWQiMcrs6U3Iqhlp>*yIwJ=w6A}6^sTDQ z>(uNA{1s>I%Ku#Sli@EC+h$Rm*1Jor|IzN!vz~?@N-}l2XQ7RhyHYzx9`*ALIdm(CI?}|KIEYyVJ}%4twnQR@YRHPR-}X5o z|4^+_7}-2*AS{E@=;ZrgSNUKMtFB4OMe}3<%d>KIF0@uS^hQbPn_CN?zh)kAKlZs8 zI;<;W#T(ENegEx|y4q8zo?A9J=XqUjRowLh&U634diQo0snYRtTj1JNCw@IWap;L| zp4W-eE0HOPnL#=8#*>X>6|X?bh+f>-}qo9xO+RU~~1RB8#Uo=XL47OZyv7RArvQyB>*o zD888AIPLVYC1Y#e4QPdFUyl-dV13&`;bL;6-{wslM7y`gpN<+)PH{FT+u8Yd7?16E zo_A{L)9MtTOA5Qq&ZskTht@qwI(GW-+caiSMy}KK63zA6o8`x&Sq%>_yHxy)b+9OR zabEKM=?2G!b-`DHUmtyOa79m+k^91>{DZqYO3Huxv-%^XVjYm>17TK*9)e}UJ=b=r zss9-2zFvRqe!7*%EvM>z3$=GXY6{3GSG%j_nY)4STa@lR**sGvzKEZQQgmXCnV65B zGWdCJvH8)j7aZW%kilQU=hhv{onvxl)%oGVB*Rl;Vfe=a-SqR0E`o0_j|KC5(>BJD ziz0<8v^Lldyn4&`h5oPLTg#)H3c&|f&pW6jZYrj1;+@m>Yhgt|vHGd9)7E-|gXJrC zYw;g%*}QpVt8p&6QoDAy&dYYbx_i-Xa{}Ha(gm2Qs_A><&7B7S$X3WkbT7U>o<>(< z9Y$pJr3xcI4u!W?Jv^s<|2-~9;^Jq#8voysr*(V3{3=kYF7)3dzG1t=`l_}X!rGNv z6ZRXO>|C*(_v%CC^GQ-qJvZ>B4h+htrlj<>lt7pJOJhSx?R>)7ITfo8?OawVbY_j6 z-S0D^bM7)P7{%LIqx0BipIB!6nsEBc*`Mjl-VbkhbT{%; z^PlQSJiYLux&3s=8%8q3(3y(A%k&|4>KOlEH)j(0fchx(a z?MwfdxgIFn`ln03eQ4yPwrZxq6O+Zpd-?_<`R^^35<8&8+#zcX!e>VGD#Mv3uWcvth$81!e<_gxhS3QIsQFvQEh*t?4zfPXhJoQ{r#Ri zJN{E+jzf&)*{Fh-9gCM}slM>}=&#o%mwMlSpm4{RmB;lW%v1e?Wxw=3y|%~O&OXxI z$LL5v#1jow`JrR>=X0xmo4h{WUEILae?VbVrkvpQGiMrO4{kDk=FI$bHSD=mGml28 zY1T5IZ|z!sp}dgF>!Lchh)asO2@ZicZg zmlrHJ;F8-DH54~@wN=kKnD~83XNTIrX~Wm!vf)#rlW!Q?;3F220%TXWxc$oSR9 z4dzLAUzi@;?<3;)XhY+kGe`CLu8F!mKA3m=nU0mV;o#Hl^B8jS-?LQ2ji8^*Prk$l zU9}+zW!k=Z;LjheGvl%y=Lc68hI}SBuF!gYYRS;Xfhy;Rh4u^1o_hE1x1qr~r%h)L zie5GjRH`$`wj6WNq#ZQA5^nEaBKwINp=j($DgUuI61OYM>21W%x)^+A5@n^Ij#u=* zau?j{96!?DO^83{v7*BGT zW4BXQIkfFdPTN}PukIvY@lM4-B=hQf_vD(FG3D=KcK#Wc3*31#>qvX*<_jT9kI-a4 zxUOB6`Boq;>_xRW)hDYzJG8}4M!|7N{9-t<>D{9AaC^J0czRviD^&w4N-3?Bc49YJ$%BgH&rVFaSx*((!UA4B+GxF!^gw1?k>_%)e zT&xd_tlYqBUA-X-_s*(*mD^Kymx}y- zL@aC+gI?UYs#8r_~`D$*;_s2VCDA9MYL2masZ^44YJqubx8g|-&z)rlPq?22o$ z6xzfr#FggIr3ahk5y6PXE z+}rzlz}I!%nVmHb)kPJe_sV2@9V%N`*qVp?tUtsoprFjVZ#@#ha0j|vqi%lI}|^%Dw9Y>q`BM+yd+BDrM=))MCSxfqdlM`Kk@x-wlRR*KPmv=7F<- zO>*hl{VBl_tPb0Et6H<4Ey_21GBB?>LQy~FM)GD`gR=8iT>QS|e=T0I`%3+e_w{?` zH5a+ORH_`8f7c+jFwl2htz*Q~`#jGBn7#5P#n%<)r`=?N|5MAZMKWl$^p|}lLFS)SPU>ZPT~>52 z)_Kud%exKy@DNi*OTITiaItH%gMpNR-|!i_a{t?T1~^6aMZ50_HX8KdH3PP#_Ec1S zx49D5ICO}A(Lh1S63UAHjYf}s)g2l~kE$vz7d3N9*}1Mr^;C(~>U~jfI_Ks7O>VV4 zdNgtn2kV$QSR6Rqvu303P=eVx*SXf8^>1dM@VVO|u=j}QMHS|E_0vZQ_s{uXZ*%Nb zZW&Oib}};#Ockw&Fs6KCy-K}hw)pcc-N4^TT{a?Ne}A}0%9hmsO2um_#;Nv9-i49p}Cc1{2>+BySEk`2OS{^Gn4Zp8+DDU2p_cDLMv14*go4qf% z3Z#FD&``#2V(mCuSj5z^IuU;T?(f3{(V@NJcX&GZ`-I1LE@ZuuvdmktqW!`fan(WL zqsDKK%Y8r1)kzN6 zPfvI}MvWKkPBNOK;gKXE zta|*!mZsXym>$2%r@I61+^CHgwS6EX{$joI*^S?wyZ-%o6Z{|~glyX3ekySAi?;m| zWm=HgxjKWlh(dbO)i^SB;asyi{@kqt9{zpz<RmPB*3LY})(I^!@WbE-UsJDw)%e`}6#n)Lm&mcw_6`e;F4v zdjz>LT@5~nptQ~(`$a95T{o<@+aA0$;`*QMp6ah8S8m?TuX09vN0p+juv~rSL51q& zQTJV~)l*LwNFrtNZ!H3>MKVkM7Ju7ev-)!Oyezpw&GvS0E%l1H`=h=g$b!9BE-rUD zs9Vz4E2Fdix=7xFx=wF}3u-R{P0-+Gy>oqD!_f)g2>qnGShYxJu)vo%vS*NB`XuoI@kp!4 zpMRZm7Dg-Ot$V)b?!K1L+uy1fo0|U~PIbUtmN9*iqmbT`_tNU-_!=)^F_|UnO7)du zo_q5qK7hej|7^SejE=s@-D@YQMMcue zb*dG7TM~9Fs?<3?O4G^HKk<$y-KHo^vEN=R1m7}reqc1u&*<|S<3(TTeOsT)3Lnbc zwI;Niw7^;^+u}vUw(_>$pD$d{$+xu=?=!Jqvh>u=x^g4tyypk(^cZ2nTKm)={67D( z`t74Z#z`-`(Nvuv+l-_J^v#yJ9kQdRUaGhsu_Ttuf9!T$d4=G0p-4*bAIzb^B7#zbRc02L!?Af;#qx|#z?9>YXsBiNys@PI)O&O;c-ql0v$i` zmqBI!CF1E5e~A;H6N%)Ba~cWz>yFA>AhJn`=L+Tu>aQc>h*UIkF(S#NVIKtJA z;6XbDyN?n0Cx}{Wf?0{C@goEp{-#`-284bbhrcm5Z!Y_;7d^LVC{Jg2PVK>!S--|x zz2~Rlg>7&tHg4OH=iUdy;&`co1JyZib1YsJMxO}^S>L9aH2jG-kxzPT-P_lfh=k0T zt;HukMO1~oH2l|P@T64Z2-kv?T-&Y_dM@Sr?J}HV z#4j*S=sa(hY4>`Ft3qe=mw)U5d_!< z5!#>kth!y+FMj9gJu9wQRm4=R(ms6h#jS`VV#494 ze7fGpn@CsJTi^ZDoE_S|>u^Mp`)RZL5^7wQa4UR-W$aHVLATI<|s=|h6~ZLcx*PFk_$4aimFfgHON>CQ-kIL^Z>aCegcvL^H>c7!wfRLRw2_ z;K)-`Faal1Q!uf_abUiMWJ<@8r>0-e*V@)pLMSU=jiSu^v)PlKA0~l-s9qGv$Xkob

B)aK!NBj1hRl=sF*J#g|;HdBGgy~(m{=RAa7PV5A>3k z$yrDu*%U|NtRsoJNH_{-9f@Y(gtL`IGb)b4*-D~0 z0Y~9%CDDS2qj0v8XekT&O-;el6gQ!ZFr9-Q5QZdCg+-78Yn2d0g;4Rih#7ka&><0M z@$~wmd&Qu|EX8@y1{l354nDc#3C&~O5Q88XZIA>XHHkz2AXGvI(zq=JNx zqfL!RL&=)Z8h||wAn`N4Yr#F?WndIu_)%|oj6#{2MPkt_TmBqxi%*5iwQOd ze%y1q>dR(DjZXh}B04V_D_S=0N_|j6(;&IEG9%Tl-8U}$@syU~Bk}pmm%p^ZR&~8~ zj=_k#^Pa%Jc1_5N)3*ZxyjvUws6%6`BWe_jUA%1q2R%Ip^N+kL)h=|4KKOO@YJBh) z4~HLDI$n2OqZYcIzU~}tWiM?S>@;oOymfizJsGb^?HxN>k6%67+Ze7AYjjuNpmPgzRW`R}2~LRB!sNSg%>G+gEbF ztE))($LGE6B54v<0l_RqlH+QA9ZQZQD$*|e*A-qtr)**ze3Q@z8B6Mxs6-8jX#+w#R=;mw9O-Qkbg`)yl}uGA6PTB7W8 zzrbqiMcZ%d^)|qlhiD6yY+jaZvcYl3trFv`+f>&MougYQ?xef!^P<9UE4J0?%Z6in8{Q}4dfQ&a>%Nyc;Lx(-u1}xK z6}fA?L#Mw!Bp!K{dZr^x<+{kZB$u}q(iyJ5POLoAtE4IYt3Ka9{`i${kFnNO9~#TA zj~pJ@cP94swd6JYXSaCJ8e`!#es4e7;w$eo&Og<_)5n(=V|i5Qolvm2_xB9VEk##0 zitczfV4~-y|9*e1(YuW9-@il&as#Dk1sz(#%B4W+2pY8%fN7Wx#lontApl(NQpgKJ zV~v11dp-sbWsoAOw+!-QDH=n!d4cwthjv&%$q=5k-xBJ8 zF-@hwI$#6MhtNR-*c`35g(4kHaSV=OFs0%q9ATh(OigeMj#)6H;20dMU;+Ab6qki1 z@Mk%S3pl6*JORCH2QirV83}3k+UHv<@xpUj%Q7B3{=V|l7)AGx@i}UI<^FZI=UN9` zBI%si-fY&gKg4;-d!;ss)5le%3TSIRFNsO%pUd|4 zth;-&I5Y7X?(W{BIhxsm3DGgh1V(JFpQ*z^p%A&|cv9$Xm9L!vmMwfA2ZTbEo|Ls3 zhMzQ2sHPZ?7OQ0(6m2J!zNn^Khi8u&42EYb{(R+X7WSoUNzcBk_+7itJ~rxj&T#7( z-QPX0a_Cm%V~M8fBUix}1-QkYTEKowhUKyxqKlx;uFz&w*A*DKHdiPKEp-J(G}R4? zLPOmEJS^RzUl6M34&VW7A^}1TJ;32FZ^#5flRZHP_f60^j6V0Cuz?%Vr(1x}LBhZ;EV$V0?{0taiBl|-X#Ig0Rw?#0wNkV8rU9! z&L)V!+P4*wg;2LGz`-dbA$k)Yg7a2LbJ|0I33!x1hBZ*#04M;ZYy)$?9{?FaC~p9G zQjH*JJDP$W-3x+_pAG`c5FG=}LnDJh=ais{r`m+>r^4nifo;{LVFKH#%b){Pcr%M0 z0ulI_97{<8Q{+4-@PG*f&T|59mH@0aJC55z0=On{o{|iLFkr$bJ^?0}zzM^)P{B15 zfg+F>6H{=)G1WkjfG;t54UirK!bBhm`T_YN5IIx81c=C)0wzF2_7t%7!@e>b^K}UX z%&fEQ!Xa}A{SnMr$c3_q7pfc%7V_g<b2NFSd8pEn6X)mP7ij07i5mYk*EDzg9 zd&-0y5OjS6fQE4t)B~aCnP5eo4?|~A*(k825=Wp!RQE6#r{)NhjG#T>5L@TH=%pjz zNGle4l=P`pgC%nu`URs%Ea*r&31vfQA2__7fZ0Lelc3Sb9KOMWzKaKw0S?zDRP_vG z4igy|+N1&K93>G4%)Q;f(oKN`_?S~pEO2iLQvnI)-x8)G63oFROob$vhfA1>NiY|e zFcp+wJ}zM@D#4sw!cwE8?a>>7g>B4}ndw75tQW+14*RnT}6 zfkP40As-xS&xOxH=(R#{_=6wz=0WXlfo%&Hfv-a7yxX7^L?`kPdZrX?Q~e$2DY~tE z0_r&vvMUXfCxtiWE|kd2Awd4#D@ zg9O4n!bGSs1N&sO?F(28`9~P|Gb?87MgK!+68!Fu0p8dVJFXh?M|qzB$b!8PW#JaW zLJVYIw5p-6BuF93J_wteT0snG9SRHKr2*@s(%DG9c_i~p>5!Z zwT=wmhS1tpNE2OY0+iOv&(JxvtZiZ^Ws`a`B+yqjFdu4W18XcKOb|xyg8I%us{{Qu z25s^IEDu|8fq3iWXYlYqri7EWW{M&NDiJNUfp4L{?T`$nS*6jtdEiD_ws4*}0R#k0EtM1#a2>EXdYz*x`-dPFhsRgXqtx6w&@4DgSJdW6Es;3@+8(hNB# zLf`~S>j2DA=3+#OIZd!($e&csfSQ{o+h%Zc9J#Ti;3o7iVBM(GJRZ>YQ{)|hD<}Gz zMa)f`Kr2l|ZjzT{pxbxBdg$5_fQ8<6I2{!ahs~038T?F!&SzzG2(R+uqL9Uuc*euP zrKZrKa7Zq3p`-VChv-}5!Gj?!L4_?@*MdXK=kSVXjkD(rh!mh9Q~{99787V}g*X$# zG;S!;*wCNEFpZkDH}fpYvkzVfFhxbT+rs#yOAFOrWC&Fk1P41K(*#lBdaM$~5ClorW^NFMZMvvIO{LOgioWzf)8-aNjuIjU_=G z%xa2#CV*)HRk2JH(ME?q!HVE12uFs3LU)0P5G}hqwq)Y##W<&m#@RYJ?laj?*VbGH4}h#k%bqdAI5>;#dW}&ne8FLXo{Od!s;C+2Sz`c zo7u#-y2q?52;IvyVX@{pFZ3-|LPX8Pe5uabCD-~gQ_33>Qlz#G=cr%TrZO5+lIS~B z^duM={U6>OV3r)On|Hk5rpfkuq>|z<%bzC#d5o4y?G=>UXOiX{uzcw=sV@#G`^MWm zMcr?F%xuZI7D_Ik6G_y>O$Znr6R<$^TqkS^1B{A-5CW!Cu^2*@CDjG5Kr{&SDQ5$Z zVS38hpaEwCxC(5u1gx2Z0!(0)_rUxR+Nl7Gpi8qLUG(2~*bjBY!J26N5BL>2R~go1 z9qWa+LFghi(5ToC$07i=n7InVs62CUMwoCd8EE7gC=bPV!Dm=^2H>AyCJc`IO$641 zz~BS`L^I&bOa#1aUyq>$6HqXd`RIaS_%}>op!h6^J~5Y2JZCOZL@<}SQP>eimyuvC zbj4rzJ*rOzGjA|M666V-NEs7kPNa+pG6PI(F(UE5l4K$$lC~sIi|-6eG-aP=TB0fG z<<1as1f0N&N%Exdo*su4vB#XRggi{%iexOxH0SR^}LMxTo!@*2z53NA|X%i#^W`XnjO?$rrl+uN3-|2{9* z%={zr(|uIu@p+lL08J*kod`>!_mz={fRHu*3Y%bq2{S)9P(SRNw0ARf57qyqs56`dlp9*Lc4Ewy$CJ0%hE1; z-|^MZO7i+n*+?T;QtIl~E~k@Kv(JM7) zuVM<{$16%FZ)h&xOI+NrpsP&uolm6V?I)rFT{lt%TLK)lsO+>9jAtW10Da#MJjwT4 zAPPbRbPJX{fQfhv|B9?}1c`%8f!{RY;$x9K5zj$B7ReJq%j9Puk|$0_`5=-fPDJ@^ zsqi!gURKlIK0IFpUFJ|o(KuREJ zGMZ<*$GZLCx-cOm9JB)7elc3p1yz7~(=h{>s?OmKfY=Zxn1hM5Dkm?xjs)6?{|_QW zn0)mAFA;6>rAHSvIZ?*OK z@xNQvIAD?}2t?89oluC3CO;cPXhaCd3bHLW$il*ei7f24=QZ0tNLNL@yy*lSIvF0` zcjI%*Vmc2g9WqWldZ^Cg>?L7QX|MDsmvc*f)8iD6+*Hsger8s_B;jJD)Uvms!X+DG zeCsHCa8j4g@vIpB=XI3H7$km}|991Ci)>fZg&oSHCjuqY4|c8lc-H6Cxf=gBF~@DC zUK}5Mezd97_?^(H+-)&E+8e^_wd^O*PMGj6(3Wv{(!H3GGH$Rc6Z&M5Z>TM_f5KrN zZ(W0lrWg>-V*!~(g!`4Ho9agEOjq4paOPUbhBl?7;!iw@(mKOAS1;LgfaL3jeH*PG z`bd6Ou3&!a*Z*qrEqy`yjpt5__;)^`)rN&$3a(w}{%v2M?$5>DuWzYDB}&Dqx&QX^ zknY?c6@ltKyWYwRO9BOgWws%VqFFpK)gvlErM~Qd1(@yYeZy>;ig^1?()O+q+<&0c z_)Ou*xaZ~QFZ`&GQkX=8B;vg4i;wrthL}->^~mmu*WnL=3-mT%PUi8L4B~w1JKIQ5 z9poy+?_qgEub;KTaQs<#W;R>TZJp=2-7QeH_nqZ?wcHzr`mb+56YAgk&EFPtjSq$1#%ZDuf=FVt7%-gy=zs)bfo5%oWDp{Of?4n7tPDw{2)3Uh!?2VU zaf%HCIV*6+G36AH*dk8xVH6N75+_{7{|4?v0y|*>5~uT7?`1Fz@-KW!gAgX@KEPYm zK!gdk;7&nKf@3VJ%aWub4`EblKR~LnA`*#a<$$9uMdTo=mJ5rcAI*>rXwxD@PlUs^ zVcLT@;W5)E8Ks$(7*oL<;6|n*IP$dD3#gB&U=BRalpO|Ub}DED4)aun2H-e28p?8p z$IOG-S=2}q(Lwuh$Rdb{;R17zfn&!mBbajR(t4;I3pf?=YN}aq18e@MUsS%?Kd8*QeUs9x-UU|*_xuz9A~og);JnwT#Ci|zXRhkQS*@KetOi} z*SI29uRdAX{A-c9SyD~BRl}(jdtaY&+e-`;&uBQsv**3?vWw3`w00xAG_{sbK$tk8 z);0FPX*_`8rDGxAa&!-jh%@nv&&!%F;QQi}9bd}-_7ub1`h@zUt&C`D$wm{~tZIP- zlpT$x)Ku~t%NAthE;-bbq`da^X2%M9NuB<%707s#&&54+PGa_1)YA%;uP(bSep}Lc z%FEFr5SVN1CO?z#ujD*z$v0 zw%F8BGz;%P{SsbU>+^7hoS)a66OMxyw2Yl{I!j(3;v;%oLylSe1Hb>kOx<&JY4G^@ zfb3EJHJ>9i-1D@3Vn5w7|GehwOXKcOB}h4(kM#7VEVlus=IdO6g~YU&mOxo8+Jvcz zYXt(&Cgs39GlBib>V8l|OJEhhfSMmG_GH%rtGI}575^rY}P{z`+XE~QkHxBAI zZoYa_n9#noTHIYgXG!u%MDEik2%tMoGzjg;t=TmkyvitEB}pTFa=!r_wsn#TG2=($FdbJ%^dt~hR)IPLTE+4t~gZ4y}v56s74rN`{ z+BdbVBfyiq*AKg3DH=0`NW!ySR&W4RKM(i{0+6J!ci`=&2qcHJI6fNhH+Y7}iI9 ze}EQ{=LknVdqJ!R@*Gv@uRd54q%=TbM@~No@Id}#A!`+u*MLd%2?P2|9K@bP5<9H{ zoNo{=NFs_XK*XaE$hium)ccS;IN)O$Nx@?D1`!9B#f^oa?}yK9E&*3^8>z~IL-3|z8+AhlWsr8 z*MlHn(#73^G4#Y~q91Vb#0jE*hA}6xSz3e$h%Se4NS@gcE`2C#r+D9a(QiY@HoqRh zt?QpWeZc&fAnDX;`bl_4FTV8Y)lp~p?@D{alD54vyA~HhU$ItW{t|^-Ug40f9W(cn z?&JC!$7`O0m+SrCtgz=l&=Xa9GfXHiy{@hedDfC@dinXB+-p~}N=sb+M5)M$rY5T` z?g6i3`g=6ZS7OHA-kE>p+TR=MFEc*vxXy2pH*hO1Rr1B{>7j{Pj^leq zp1=O}vuvm8hon;j`&JVZGQ=~YV*@^s`qfw1BM*Np7`caN{LR8;Z*CXqPta)LD-iFE z&WNo#dhcu1$?ermRId+WU50bRcb-s=E_uv4y4FAH_qFRuBK!rx`ytA`BM63ZNub$k zjo^zQmwG@J89>$l0z`o{gdeK$4{W#FdT1e9oefH!KrVuSptr_hO)M7?2ca7wz=MNa zL@$g%h@AoDq$8FhXgx3Z6r>}fK!SfRB7)W^BMVu=@1U(b=ULkNPmWhLbO|01h(o;kVc~Sr=Y~L>*)lY#A1GEaF zk5iy_^hO6Xh}8)Mqv>;@e`uiqB*pSb1BG?yeOpM1Nt{aOU?pk9sdNsOr6W$IbFeHO zak_F0Wa)?;B5@0rr6Y1E3vdR+n#xI=Vp%%kMD_w;9Lv%XISG)73}wp;or~ZegkDrhNu5F z?oV@G{$a77QaDW_sMb_J8Bbpk+s40eo>M~49Mh08i?**SZ&bH`+LfkzBJP`psiyJI zwi`Do+C2r{-})j|gP4|?30n_*So^lL*!|YO`}30zpE{++-{XE+CflPSI-aMYV!odK z_tLPlcVk|zR#7lbeHbvT8eD(;g4b4K(>J$x_LL>_BoCw7=g)VK&`5{A6y@5#*|A1^ zPqp$Q!(|pP7J95mSaBjZ?qz!HlanX9H?}|M-=R1n{v{}BO#PorSZst0;Zcc@hRE%5 zrJTO~I}QD={p^(yjoE(#RT2V_q_820DvJR~fIz(leKQ}?z%rEu2&jBxr=~!HQUN;w z$tf&FNk`E43jkJ{=^&*E@{~Ie1Z)yoYX@>(I&)}1Za+&~9~p&>CK5wno7us} zbS)efY)lu!nEpu8gSa9dRZ#~IKM_?# z{sMV0h=J^Z&|{j2Fq+Z|n@O=VOE@x(q6hLzSpJm6(4$Q7^-*SsEed{qRv6>?64g0T z0_J>9WEdv+3L3`|1<(hPOST{u0~oaoqfIpTQ~K z8y|5Wa|E7+>O?>*7ilR?R5))WA{rA8?>b||lF2C@Kb!V_7wdm09p|^fZ4zHjc%`%R z)trH}CH|$+uhiq90SgDAW*>2ngT}A#9n83@Tm&3xt()1DeI;KV>og+9-+%Ua5mjeM zFxZrKsYT+2ipRq{x!Q9x>f9O*`yPLCLC5av5#bZt;s(paMQJ{fO$G5mH=czo-VOiV zrCBsF&2uDVvUVJE&H=q@#lnG&$J?)*wz*Zku#{f(jqcHU>)uj(&+XecuW4_6xq9KMd8&_X<6JMj8!~{` zKe%?n@LyB-fzmAsiiLVBdu1OMx|y`pCTFTS9rJ#_{>3`Wb(UX_G#vgc1>O8^bn_VB z4R^1S`vv!uhIw!-&94))1uiehpktKhM7(E%@l`VuH>T`rd`B#CBmV?XDv?BTvxQ|c zjh5D`TV32#?ABHOAZ_!{&2u-eDeSUZy$KC)GWL0S{zu0K^~tPFv9R;+<83BQroTYS zp#!8G3V4hdQvQeETbiW!2Ba+gf}70R_~ZVF2tBpN(l!D)$(oMX6c=G)=ZC)4Mx?+C z7a*wT09VQa!GTvg&@)K=0ciQV0#Ok@B{P5j!u(ZlQo+J=7M_nr@*|8EA5D1 zM`ZXZ?5rVp7)yJEhPeW@_J}l0#iM8K5ejyW-G`S#rGfFj*&}X~U1a0|u?rs6Y@3f) z;Lc#(z@Shc@1P)moGXz=nz#m(E$I22I%T3JfwB9$Yt_kl!8Rvsn-@oggU* zJ0Rv079PvK;{tJl*k3%JLC1Vc?B7%ys3XA~#hGn%8pavTXamkX<}u7{qf;;%dPW@p$Hc1|iXCSlB+ZBb^MC*{n8919SDGU`{qy8`wwgHU^&d-!?ElumKEqE!fP9 z8SJ_Wt~Mg}b^~`Ceb!_cG>lv0>PN>4WoERI!Sm0U4fZJ+Pr`KfjE6CoZe#!gNCKexH>Xs?K>6EP7}}QN5vCotpXK4`-!Pw zp=V6S9NdOVpkgJaGj9l39qy;266u&lp4pECa**hUm5AE^fMhC}idEaqynsxbIRo%1 zmCV3A+nN0+1dQk5Y9r6uLn?(jAqD?MGL=T11r#ccfn`Kz-jL2N*Wzl!f<3N&3~)ZH z4d{sfw6T#)!_P)C4Nt|=v@-^w5lFMd3SbtaSZDSFVK4W93g=(@3)v z4j6V8l4*3(tmUUM2v~GJeLrmd!4_kj#dIS$qT>OSXSD%AnAJwZf`6`S>9h0$9aLR& zuNIv^AY(OwGcN{(lid462Nh5n$QyG@4uie`(@zH^f@_b# zs{^xCFn~0hRGM)^pv<_J8su~6+-eyVPZ6<-g2`){Z0{8`k}1^Vgt8JE)00h#xEg*P3 zflc>fp7a#@LE|j*3ECJKyEbDGP;SAkXuvBDK&j8_$H3mBn0YO@_&@h!??2cQHlfGW zkvwbfKmw23H3M%1(725bcrO6#3fI6Su$$bIA(5D~bU(P5hP{?Ed4>n1Ml`f z6U5dZIObGte+|@`1EKg&M|M9@#LvBiR8ZE&rRRZ1NS>twsKBk5buEc5&h7Dn;GN(O zis7hac9LPnN&?S()?xtTJqveKaPh1;QD-YjDiCJwouSeIka29em=+8w@cy~M4Lrly z4@956)l@ot_5uM*%`MGT#(!}IRQE(nXc16e?40CaQh zDp1a|R1l2`3LLnXkVa(Fjx)9d$m5hRG3hn{RYkz6%Vzci+t0n!;CZ=SNRaRbjo{iD zdWl9Mb8`!zcALiSWq~%vWPm!ob)XkU4bPkm0OPFHq5-ov-ETrK(Xgmxx)Hkxh(yWU zrXRG?XW^JeC(e>SAobj?1Skv#1vcDcFaZ9!_lb^03S1q5w>ayDbUb60zM+Fan_HTJ zw&4zz33R~3uvZH_|CCh*(Fs-yJ7WpyB9abL zXK{&G+M0WhK^wc6d*)=oJNI0e0sW{P%Rd#Df-na71KhI)v<%l00^bS9CwD*EBw;x% zO`snz2;BXEEY6&aJs#A*(zv59;Eb_f2buXK4Dx>w92(-~x6LO+(7-@{mERs8HfQ^K S6S7zk5LR?SH8qPBmj4G`5`pdj delta 60063 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%0AdSig7I5xzdD4u#Y;*YTs#vcQ5TCv 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 F{sWu>v)upy diff --git a/snowflake/ml/feature_store/notebooks/customer_demo/DBT_External_Feature_Pipeline_Demo.ipynb b/snowflake/ml/feature_store/notebooks/customer_demo/DBT_External_Feature_Pipeline_Demo.ipynb index 91d4c115..a0fad0cf 100644 --- a/snowflake/ml/feature_store/notebooks/customer_demo/DBT_External_Feature_Pipeline_Demo.ipynb +++ b/snowflake/ml/feature_store/notebooks/customer_demo/DBT_External_Feature_Pipeline_Demo.ipynb @@ -5,8 +5,9 @@ "id": "5f46aef7-1fc7-408e-acf1-0dc030981c58", "metadata": {}, "source": [ - "- snowflake-ml-python version: 1.2.1\n", - "- Last updated on: 1/30/2024" + "- snowflake-ml-python version: 1.2.2\n", + "- Feature Store PrPr version: 0.5.1\n", + "- Last updated on: 2/12/2024" ] }, { @@ -525,7 +526,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13" + "version": "3.8.18" } }, "nbformat": 4, diff --git a/snowflake/ml/feature_store/notebooks/customer_demo/DBT_External_Feature_Pipeline_Demo.pdf b/snowflake/ml/feature_store/notebooks/customer_demo/DBT_External_Feature_Pipeline_Demo.pdf index 97666219f2e21684d94658fe661df9fc8304c4b3..d1fd0e3a528aa887fd3fe5bc2633a25989d067f9 100644 GIT binary patch delta 21259 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 diff --git a/snowflake/ml/feature_store/notebooks/customer_demo/Time_Series_Feature_Demo.ipynb b/snowflake/ml/feature_store/notebooks/customer_demo/Time_Series_Feature_Demo.ipynb index 009d2e10..be8b3766 100644 --- a/snowflake/ml/feature_store/notebooks/customer_demo/Time_Series_Feature_Demo.ipynb +++ b/snowflake/ml/feature_store/notebooks/customer_demo/Time_Series_Feature_Demo.ipynb @@ -5,20 +5,9 @@ "id": "4f029c96", "metadata": {}, "source": [ - "- snowflake-ml-python version: 1.2.0\n", - "- Feature Store PrPr version: 0.4.0\n", - "- Updated date: 1/3/2024" - ] - }, - { - "cell_type": "markdown", - "id": "5ba51119", - "metadata": {}, - "source": [ - "## Before getting started\n", - "\n", - "### Watch out object name case sensitivity\n", - "The Model Registry and Feature Store are not consistent with each other in the way they case names for databases, schemas, and other SQL objects. (Keep in mind that the objects in both APIs are Snowflake objects on the back end.) The model registry preserves the case of names for these objects, while the feature store converts names to uppercase unless you enclose them in double quotes. The way the feature store handles names is consistent with Snowflake’s identifier requirements. We are working to make this more consistent. In the meantime, we suggest using uppercase names in both APIs to ensure correct interoperation between the feature store and the model registry." + "- snowflake-ml-python version: 1.2.2\n", + "- Feature Store PrPr version: 0.5.1\n", + "- Updated date: 2/12/2024" ] }, { diff --git a/snowflake/ml/feature_store/notebooks/customer_demo/Time_Series_Feature_Demo.pdf b/snowflake/ml/feature_store/notebooks/customer_demo/Time_Series_Feature_Demo.pdf index 0a0cb99bc21230897b3db0f6a24ed0fc2b81e58a..5d49da4b6a6fbb8a4822ce6dba10b123f0fe98f3 100644 GIT binary patch delta 65631 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 delta 70613 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 pd.DataFrame: ) return pd.DataFrame([row.as_dict() for row in rows]) + @telemetry.send_api_usage_telemetry( + project=_TELEMETRY_PROJECT, + subproject=_TELEMETRY_SUBPROJECT, + ) def delete_version(self, version_name: str) -> None: - raise NotImplementedError("Deleting version has not been supported yet.") + """Drop a version of the model. + + Args: + version_name: The name of the version. + """ + statement_params = telemetry.get_statement_params( + project=_TELEMETRY_PROJECT, + subproject=_TELEMETRY_SUBPROJECT, + ) + self._model_ops.delete_model_or_version( + model_name=self._model_name, + version_name=sql_identifier.SqlIdentifier(version_name), + statement_params=statement_params, + ) @telemetry.send_api_usage_telemetry( project=_TELEMETRY_PROJECT, diff --git a/snowflake/ml/model/_client/model/model_impl_test.py b/snowflake/ml/model/_client/model/model_impl_test.py index c097e09d..95a519e0 100644 --- a/snowflake/ml/model/_client/model/model_impl_test.py +++ b/snowflake/ml/model/_client/model/model_impl_test.py @@ -183,6 +183,15 @@ def test_default_setter(self) -> None: statement_params=mock.ANY, ) + def test_delete_version(self) -> None: + with mock.patch.object(self.m_model._model_ops, "delete_model_or_version") as mock_delete_model_or_version: + self.m_model.delete_version(version_name="V2") + mock_delete_model_or_version.assert_called_once_with( + model_name=sql_identifier.SqlIdentifier("MODEL"), + version_name=sql_identifier.SqlIdentifier("V2"), + statement_params=mock.ANY, + ) + def test_show_tags(self) -> None: m_res = {'DB."schema".MYTAG': "tag content", 'MYDB.SCHEMA."my_another_tag"': "1"} with mock.patch.object(self.m_model._model_ops, "show_tags", return_value=m_res) as mock_show_tags: diff --git a/snowflake/ml/model/_client/ops/model_ops.py b/snowflake/ml/model/_client/ops/model_ops.py index d7ae1f8c..f06dde43 100644 --- a/snowflake/ml/model/_client/ops/model_ops.py +++ b/snowflake/ml/model/_client/ops/model_ops.py @@ -447,8 +447,14 @@ def delete_model_or_version( version_name: Optional[sql_identifier.SqlIdentifier] = None, statement_params: Optional[Dict[str, Any]] = None, ) -> None: - # TODO: Delete version is not supported yet. - self._model_client.drop_model( - model_name=model_name, - statement_params=statement_params, - ) + if version_name: + self._model_version_client.drop_version( + model_name=model_name, + version_name=version_name, + statement_params=statement_params, + ) + else: + self._model_client.drop_model( + model_name=model_name, + statement_params=statement_params, + ) diff --git a/snowflake/ml/model/_client/ops/model_ops_test.py b/snowflake/ml/model/_client/ops/model_ops_test.py index 48729902..2c7709e2 100644 --- a/snowflake/ml/model/_client/ops/model_ops_test.py +++ b/snowflake/ml/model/_client/ops/model_ops_test.py @@ -892,7 +892,7 @@ def test_set_default_version_2(self) -> None: ) mock_set_default_version.assert_not_called() - def test_delete_model_or_version(self) -> None: + def test_delete_model_or_version_1(self) -> None: with mock.patch.object( self.m_ops._model_client, "drop_model", @@ -906,6 +906,22 @@ def test_delete_model_or_version(self) -> None: statement_params=self.m_statement_params, ) + def test_delete_model_or_version_2(self) -> None: + with mock.patch.object( + self.m_ops._model_version_client, + "drop_version", + ) as mock_drop_version: + self.m_ops.delete_model_or_version( + model_name=sql_identifier.SqlIdentifier("MODEL"), + version_name=sql_identifier.SqlIdentifier("V2"), + statement_params=self.m_statement_params, + ) + mock_drop_version.assert_called_once_with( + model_name=sql_identifier.SqlIdentifier("MODEL"), + version_name=sql_identifier.SqlIdentifier("V2"), + statement_params=self.m_statement_params, + ) + if __name__ == "__main__": absltest.main() diff --git a/snowflake/ml/model/_client/sql/model_version.py b/snowflake/ml/model/_client/sql/model_version.py index 7861d2a4..6e64d07c 100644 --- a/snowflake/ml/model/_client/sql/model_version.py +++ b/snowflake/ml/model/_client/sql/model_version.py @@ -222,3 +222,16 @@ def set_metadata( ), statement_params=statement_params, ).has_dimensions(expected_rows=1, expected_cols=1).validate() + + def drop_version( + self, + *, + model_name: sql_identifier.SqlIdentifier, + version_name: sql_identifier.SqlIdentifier, + statement_params: Optional[Dict[str, Any]] = None, + ) -> None: + query_result_checker.SqlResultValidator( + self._session, + f"ALTER MODEL {self.fully_qualified_model_name(model_name)} DROP VERSION {version_name.identifier()}", + statement_params=statement_params, + ).has_dimensions(expected_rows=1, expected_cols=1).validate() diff --git a/snowflake/ml/model/_client/sql/model_version_test.py b/snowflake/ml/model/_client/sql/model_version_test.py index 0fc1c3e1..abc29f8d 100644 --- a/snowflake/ml/model/_client/sql/model_version_test.py +++ b/snowflake/ml/model/_client/sql/model_version_test.py @@ -240,6 +240,23 @@ def test_set_metadata(self) -> None: statement_params=m_statement_params, ) + def test_drop_version(self) -> None: + m_statement_params = {"test": "1"} + m_df = mock_data_frame.MockDataFrame( + collect_result=[Row("Model MODEL successfully altered.")], collect_statement_params=m_statement_params + ) + self.m_session.add_mock_sql("""ALTER MODEL TEMP."test".MODEL DROP VERSION V2""", m_df) + c_session = cast(Session, self.m_session) + model_version_sql.ModelVersionSQLClient( + c_session, + database_name=sql_identifier.SqlIdentifier("TEMP"), + schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), + ).drop_version( + model_name=sql_identifier.SqlIdentifier("MODEL"), + version_name=sql_identifier.SqlIdentifier("V2"), + statement_params=m_statement_params, + ) + if __name__ == "__main__": absltest.main() diff --git a/snowflake/ml/model/_signatures/snowpark_test.py b/snowflake/ml/model/_signatures/snowpark_test.py index 1a9502e1..242efb95 100644 --- a/snowflake/ml/model/_signatures/snowpark_test.py +++ b/snowflake/ml/model/_signatures/snowpark_test.py @@ -224,6 +224,23 @@ def test_validate_data_with_features(self) -> None: ) model_signature._validate_snowpark_data(df, fts) + fts = [ + core.FeatureSpec("a", core.DataType.INT16), + core.FeatureSpec("b", core.DataType.FLOAT), + ] + schema = spt.StructType( + [spt.StructField('"a"', spt.DecimalType(6, 0)), spt.StructField('"b"', spt.DecimalType(6, 2))] + ) + df = self._session.create_dataframe( + [ + [decimal.Decimal(1), decimal.Decimal(2.5)], + [decimal.Decimal(1), decimal.Decimal(6.8)], + ], + schema, + ) + with self.assertWarnsRegex(UserWarning, "is being automatically converted to DOUBLE in the Snowpark DataFrame"): + model_signature._validate_snowpark_data(df, fts) + fts = [ core.FeatureSpec("a", core.DataType.INT16), core.FeatureSpec("b", core.DataType.FLOAT), diff --git a/snowflake/ml/model/model_signature.py b/snowflake/ml/model/model_signature.py index 1a2fc5fd..81db40d2 100644 --- a/snowflake/ml/model/model_signature.py +++ b/snowflake/ml/model/model_signature.py @@ -528,11 +528,8 @@ def _validate_snowpark_type_feature( if not ( isinstance( field_data_type, - (spt._IntegralType, spt.FloatType, spt.DoubleType), + (spt._IntegralType, spt.FloatType, spt.DoubleType, spt.DecimalType), ) - # We are not allowing > 0 scale as it will become a decimal.Decimal - # Although it is castable, the support will be done as another effort. - or (isinstance(field_data_type, spt.DecimalType) and field_data_type.scale == 0) ): raise snowml_exceptions.SnowflakeMLException( error_code=error_codes.INVALID_DATA, @@ -550,6 +547,17 @@ def _validate_snowpark_type_feature( f"because of its original type {field_data_type} is non-Numeric." ), ) + if isinstance(field_data_type, spt.DecimalType) and field_data_type.scale > 0: + warnings.warn( + ( + f"Type {field_data_type} is being automatically converted to DOUBLE in the Snowpark DataFrame. " + "This automatic conversion may lead to potential precision loss and rounding errors. " + "If you wish to prevent this conversion, you should manually perform " + "the necessary data type conversion." + ), + category=UserWarning, + stacklevel=2, + ) min_v, max_v = value_range if ( max_v > np.finfo(ft_type._numpy_type).max # type: ignore[arg-type] diff --git a/snowflake/ml/modeling/_internal/snowpark_implementations/distributed_hpo_trainer.py b/snowflake/ml/modeling/_internal/snowpark_implementations/distributed_hpo_trainer.py index aff9ec13..55c4cec7 100644 --- a/snowflake/ml/modeling/_internal/snowpark_implementations/distributed_hpo_trainer.py +++ b/snowflake/ml/modeling/_internal/snowpark_implementations/distributed_hpo_trainer.py @@ -283,7 +283,7 @@ def fit_search_snowpark( "snowflake-snowpark-python<2", "fastparquet<2023.11", "pyarrow<14", - "cachetools<5", + "cachetools<6", ] @sproc( # type: ignore[misc] diff --git a/snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_handlers.py b/snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_handlers.py index ece6f771..477f596a 100644 --- a/snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_handlers.py +++ b/snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_handlers.py @@ -83,6 +83,8 @@ def batch_inference( statement_params=statement_params, ) def vec_batch_infer(ds: PandasSeries[dict]) -> PandasSeries[dict]: # type: ignore[type-arg] + import numbers + import numpy as np import pandas as pd @@ -120,6 +122,9 @@ def vec_batch_infer(ds: PandasSeries[dict]) -> PandasSeries[dict]: # type: igno ): # In case of kneighbors, functions return a tuple of ndarrays. transformed_numpy_array = np.stack(inference_res, axis=1) + elif isinstance(inference_res, numbers.Number): + # In case of BernoulliRBM, functions return a float + transformed_numpy_array = np.array([inference_res]) else: transformed_numpy_array = inference_res diff --git a/snowflake/ml/modeling/metrics/BUILD.bazel b/snowflake/ml/modeling/metrics/BUILD.bazel index 5e798929..114033ca 100644 --- a/snowflake/ml/modeling/metrics/BUILD.bazel +++ b/snowflake/ml/modeling/metrics/BUILD.bazel @@ -11,6 +11,7 @@ py_library( ":init", ":metrics_utils", "//snowflake/ml/_internal:telemetry", + "//snowflake/ml/_internal/utils:result", ], ) diff --git a/snowflake/ml/modeling/metrics/classification.py b/snowflake/ml/modeling/metrics/classification.py index 82fd3cd2..048e9894 100644 --- a/snowflake/ml/modeling/metrics/classification.py +++ b/snowflake/ml/modeling/metrics/classification.py @@ -7,11 +7,14 @@ import cloudpickle import numpy as np import numpy.typing as npt +import sklearn +from packaging import version from sklearn import exceptions, metrics import snowflake.snowpark._internal.utils as snowpark_utils from snowflake import snowpark from snowflake.ml._internal import telemetry +from snowflake.ml._internal.utils import result from snowflake.ml.modeling.metrics import metrics_utils from snowflake.snowpark import functions as F, types as T from snowflake.snowpark._internal.utils import ( @@ -791,6 +794,80 @@ def precision_recall_fscore_support( support - None (if average is not None) or array of int, shape = [n_unique_labels] The number of occurrences of each label in the y true column(s). """ + if average == "samples": + metrics_utils.check_label_columns(y_true_col_names, y_pred_col_names) + + session = df._session + assert session is not None + sproc_name = snowpark_utils.random_name_for_temp_object(snowpark_utils.TempObjectType.PROCEDURE) + sklearn_release = version.parse(sklearn.__version__).release + statement_params = telemetry.get_statement_params(_PROJECT, _SUBPROJECT) + + cols = metrics_utils.flatten_cols([y_true_col_names, y_pred_col_names, sample_weight_col_name]) + queries = df[cols].queries["queries"] + + pickled_result_module = cloudpickle.dumps(result) + + @F.sproc( # type: ignore[misc] + is_permanent=False, + session=session, + name=sproc_name, + replace=True, + packages=[ + "cloudpickle", + f"scikit-learn=={sklearn_release[0]}.{sklearn_release[1]}.*", + "snowflake-snowpark-python", + ], + statement_params=statement_params, + anonymous=True, + ) + def precision_recall_fscore_support_anon_sproc(session: snowpark.Session) -> bytes: + for query in queries[:-1]: + _ = session.sql(query).collect(statement_params=statement_params) + sp_df = session.sql(queries[-1]) + df = sp_df.to_pandas(statement_params=statement_params) + df.columns = sp_df.columns + + y_true = df[y_true_col_names] + y_pred = df[y_pred_col_names] + sample_weight = df[sample_weight_col_name] if sample_weight_col_name else None + + with warnings.catch_warnings(record=True) as w: + p, r, f, s = metrics.precision_recall_fscore_support( + y_true, + y_pred, + beta=beta, + labels=labels, + pos_label=pos_label, + average=average, + warn_for=warn_for, + sample_weight=sample_weight, + zero_division=zero_division, + ) + + # handle zero_division warnings + warning = None + if len(w) > 0 and issubclass(w[-1].category, exceptions.UndefinedMetricWarning): + warning = w[-1] + + result_module = cloudpickle.loads(pickled_result_module) + return result_module.serialize(session, (p, r, f, s, warning)) # type: ignore[no-any-return] + + kwargs = telemetry.get_sproc_statement_params_kwargs( + precision_recall_fscore_support_anon_sproc, statement_params + ) + result_object = result.deserialize(session, precision_recall_fscore_support_anon_sproc(session, **kwargs)) + + res: Union[ + Tuple[float, float, float, None], + Tuple[npt.NDArray[np.float_], npt.NDArray[np.float_], npt.NDArray[np.float_], npt.NDArray[np.float_]], + ] = result_object[:4] + warning = result_object[-1] + if warning: + warnings.warn(warning.message, category=warning.category, stacklevel=2) + return res + + # Distributed when average != "samples" session = df._session assert session is not None diff --git a/snowflake/ml/modeling/model_selection/grid_search_cv.py b/snowflake/ml/modeling/model_selection/grid_search_cv.py index 87cc794c..93442a97 100644 --- a/snowflake/ml/modeling/model_selection/grid_search_cv.py +++ b/snowflake/ml/modeling/model_selection/grid_search_cv.py @@ -691,6 +691,45 @@ def decision_function( return output_df + @available_if(original_estimator_has_callable("score_samples")) # type: ignore[misc] + @telemetry.send_api_usage_telemetry( + project=_PROJECT, + subproject=_SUBPROJECT, + custom_tags=dict([("autogen", True)]), + ) + def score_samples( + self, dataset: Union[DataFrame, pd.DataFrame], output_cols_prefix: str = "score_samples_" + ) -> Union[DataFrame, pd.DataFrame]: + """Call score_samples on the estimator with the best found parameters. + Only available if refit=True and the underlying estimator supports score_samples. + + Args: + dataset (Union[DataFrame, pd.DataFrame]): + Snowpark or Pandas DataFrame. + output_cols_prefix (str): + Prefix for the response columns. Defaults to "score_samples_". + + Returns: + Union[DataFrame, pd.DataFrame]: + Output dataset with results of the decision function for the samples in input dataset. + """ + super()._check_dataset_type(dataset) + if isinstance(dataset, DataFrame): + output_df = self._batch_inference( + dataset=dataset, + inference_method="score_samples", + expected_output_cols_list=self._get_output_column_names(output_cols_prefix), + expected_output_cols_type="float", + ) + elif isinstance(dataset, pd.DataFrame): + output_df = self._sklearn_inference( + dataset=dataset, + inference_method="score_samples", + expected_output_cols_list=self._get_output_column_names(output_cols_prefix), + ) + + return output_df + @available_if(original_estimator_has_callable("score")) # type: ignore[misc] def score(self, dataset: Union[DataFrame, pd.DataFrame]) -> float: """ diff --git a/snowflake/ml/modeling/model_selection/randomized_search_cv.py b/snowflake/ml/modeling/model_selection/randomized_search_cv.py index 23c3dd54..36a50637 100644 --- a/snowflake/ml/modeling/model_selection/randomized_search_cv.py +++ b/snowflake/ml/modeling/model_selection/randomized_search_cv.py @@ -702,6 +702,45 @@ def decision_function( return output_df + @available_if(original_estimator_has_callable("score_samples")) # type: ignore[misc] + @telemetry.send_api_usage_telemetry( + project=_PROJECT, + subproject=_SUBPROJECT, + custom_tags=dict([("autogen", True)]), + ) + def score_samples( + self, dataset: Union[DataFrame, pd.DataFrame], output_cols_prefix: str = "score_samples_" + ) -> Union[DataFrame, pd.DataFrame]: + """Call score_samples on the estimator with the best found parameters. + Only available if refit=True and the underlying estimator supports score_samples. + + Args: + dataset (Union[DataFrame, pd.DataFrame]): + Snowpark or Pandas DataFrame. + output_cols_prefix (str): + Prefix for the response columns. Defaults to "score_samples_". + + Returns: + Union[DataFrame, pd.DataFrame]: + Output dataset with results of the decision function for the samples in input dataset. + """ + super()._check_dataset_type(dataset) + if isinstance(dataset, DataFrame): + output_df = self._batch_inference( + dataset=dataset, + inference_method="score_samples", + expected_output_cols_list=self._get_output_column_names(output_cols_prefix), + expected_output_cols_type="float", + ) + elif isinstance(dataset, pd.DataFrame): + output_df = self._sklearn_inference( + dataset=dataset, + inference_method="score_samples", + expected_output_cols_list=self._get_output_column_names(output_cols_prefix), + ) + + return output_df + @available_if(original_estimator_has_callable("score")) # type: ignore[misc] def score(self, dataset: Union[DataFrame, pd.DataFrame]) -> float: """ diff --git a/snowflake/ml/modeling/pipeline/pipeline.py b/snowflake/ml/modeling/pipeline/pipeline.py index c57871f0..d4806792 100644 --- a/snowflake/ml/modeling/pipeline/pipeline.py +++ b/snowflake/ml/modeling/pipeline/pipeline.py @@ -392,6 +392,25 @@ def predict(self, dataset: Union[snowpark.DataFrame, pd.DataFrame]) -> Union[sno """ return self._invoke_estimator_func("predict", dataset) + @metaestimators.available_if(_final_step_has("score_samples")) # type: ignore[misc] + @telemetry.send_api_usage_telemetry( + project=_PROJECT, + subproject=_SUBPROJECT, + ) + def score_samples( + self, dataset: Union[snowpark.DataFrame, pd.DataFrame] + ) -> Union[snowpark.DataFrame, pd.DataFrame]: + """ + Transform the dataset by applying all the transformers in order and predict using the estimator. + + Args: + dataset: Input dataset. + + Returns: + Output dataset. + """ + return self._invoke_estimator_func("score_samples", dataset) + @metaestimators.available_if(_final_step_has("predict_proba")) # type: ignore[misc] @telemetry.send_api_usage_telemetry( project=_PROJECT, diff --git a/snowflake/ml/registry/model_registry.py b/snowflake/ml/registry/model_registry.py index ae8a7a18..f19de18c 100644 --- a/snowflake/ml/registry/model_registry.py +++ b/snowflake/ml/registry/model_registry.py @@ -167,7 +167,7 @@ def _create_registry_views( # Create views on most recent metadata items. metadata_view_name_prefix = identifier.concat_names([metadata_table_name, "_LAST_"]) metadata_view_template = formatting.unwrap( - """CREATE OR REPLACE VIEW {database}.{schema}.{attribute_view} COPY GRANTS AS + """CREATE OR REPLACE TEMPORARY VIEW {database}.{schema}.{attribute_view} COPY GRANTS AS SELECT DISTINCT MODEL_ID, {select_expression} AS {final_attribute_name} FROM {metadata_table} WHERE ATTRIBUTE_NAME = '{attribute_name}'""" ) @@ -177,7 +177,9 @@ def _create_registry_views( metadata_select_fields = [] for attribute_name in _LIST_METADATA_ATTRIBUTE: view_name = identifier.concat_names([metadata_view_name_prefix, attribute_name]) - select_expression = f"(LAST_VALUE(VALUE) OVER (PARTITION BY MODEL_ID ORDER BY SEQUENCE_ID))['{attribute_name}']" + select_expression = ( + f"(LAST_VALUE(VALUE) OVER (PARTITION BY MODEL_ID ORDER BY EVENT_TIMESTAMP))['{attribute_name}']" + ) sql = metadata_view_template.format( database=database_name, schema=schema_name, @@ -221,7 +223,7 @@ def _create_registry_views( registry_view_name = identifier.concat_names([registry_table_name, "_VIEW"]) metadata_select_fields_formatted = ",".join(metadata_select_fields) session.sql( - f"""CREATE OR REPLACE VIEW {fully_qualified_schema_name}.{registry_view_name} COPY GRANTS AS + f"""CREATE OR REPLACE TEMPORARY VIEW {fully_qualified_schema_name}.{registry_view_name} COPY GRANTS AS SELECT {registry_table_name}.*, {metadata_select_fields_formatted} FROM {registry_table_name} {metadata_views_join}""" ).collect(statement_params=statement_params) @@ -229,7 +231,7 @@ def _create_registry_views( # Create artifact view. it joins artifact tables with registry table on model id. artifact_view_name = identifier.concat_names([artifact_table_name, "_VIEW"]) session.sql( - f"""CREATE OR REPLACE VIEW {fully_qualified_schema_name}.{artifact_view_name} COPY GRANTS AS + f"""CREATE OR REPLACE TEMPORARY VIEW {fully_qualified_schema_name}.{artifact_view_name} COPY GRANTS AS SELECT {registry_table_name}.NAME AS MODEL_NAME, {registry_table_name}.VERSION AS MODEL_VERSION, @@ -265,7 +267,7 @@ def _create_active_permanent_deployment_view( # Active deployments are those whose last operation is not DROP. active_deployments_view_name = identifier.concat_names([deployment_table_name, "_VIEW"]) active_deployments_view_expr = f""" - CREATE OR REPLACE VIEW {fully_qualified_schema_name}.{active_deployments_view_name} + CREATE OR REPLACE TEMPORARY VIEW {fully_qualified_schema_name}.{active_deployments_view_name} COPY GRANTS AS SELECT DEPLOYMENT_NAME, @@ -343,6 +345,17 @@ def __init__( statement_params = self._get_statement_params(inspect.currentframe()) self._svm.validate_schema_version(statement_params) + _create_registry_views( + session, + self._name, + self._schema, + self._registry_table, + self._metadata_table, + self._deployment_table, + self._artifact_table, + statement_params, + ) + # Private methods def _get_statement_params(self, frame: Optional[types.FrameType]) -> Dict[str, Any]: @@ -2067,10 +2080,6 @@ def create_model_registry( # These might be exposed as parameters in the future. database_name = identifier.get_inferred_name(database_name) schema_name = identifier.get_inferred_name(schema_name) - registry_table_name = identifier.get_inferred_name(_MODELS_TABLE_NAME) - metadata_table_name = identifier.get_inferred_name(_METADATA_TABLE_NAME) - deployment_table_name = identifier.get_inferred_name(_DEPLOYMENT_TABLE_NAME) - artifact_table_name = identifier.get_inferred_name(_initial_schema._ARTIFACT_TABLE_NAME) statement_params = telemetry.get_function_usage_statement_params( project=_TELEMETRY_PROJECT, @@ -2090,16 +2099,6 @@ def create_model_registry( svm.try_upgrade(statement_params) - _create_registry_views( - session, - database_name, - schema_name, - registry_table_name, - metadata_table_name, - deployment_table_name, - artifact_table_name, - statement_params, - ) finally: if not snowpark_utils.is_in_stored_procedure(): # type: ignore[no-untyped-call] # Restore the db & schema to the original ones diff --git a/snowflake/ml/registry/model_registry_test.py b/snowflake/ml/registry/model_registry_test.py index ba539850..5052b9a6 100644 --- a/snowflake/ml/registry/model_registry_test.py +++ b/snowflake/ml/registry/model_registry_test.py @@ -433,6 +433,7 @@ def setup_open_call(self) -> None: ) self._mock_show_version_table_exists({}) self._mock_select_from_version_table({}, _schema._CURRENT_SCHEMA_VERSION) + self.setup_create_views_call() def setup_list_model_call(self) -> mock_data_frame.MockDataFrame: """Setup the expected calls originating from list_model.""" @@ -449,7 +450,7 @@ def setup_create_views_call(self) -> None: """Setup the expected calls originating from _create_views.""" self.add_session_mock_sql( query=( - f"""CREATE OR REPLACE VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_DEPLOYMENTS_TABLE_NAME}_VIEW + f"""CREATE OR REPLACE TEMPORARY VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_DEPLOYMENTS_TABLE_NAME}_VIEW COPY GRANTS AS SELECT DEPLOYMENT_NAME, @@ -474,12 +475,13 @@ def setup_create_views_call(self) -> None: ) self.add_session_mock_sql( query=( - f"""CREATE OR REPLACE VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_METADATA_TABLE_NAME}_LAST_DESCRIPTION + f"""CREATE OR REPLACE TEMPORARY VIEW + {_DATABASE_NAME}.{_SCHEMA_NAME}.{_METADATA_TABLE_NAME}_LAST_DESCRIPTION COPY GRANTS AS SELECT DISTINCT MODEL_ID, (LAST_VALUE(VALUE) OVER ( - PARTITION BY MODEL_ID ORDER BY SEQUENCE_ID))['DESCRIPTION'] + PARTITION BY MODEL_ID ORDER BY EVENT_TIMESTAMP))['DESCRIPTION'] as DESCRIPTION FROM {_METADATA_TABLE_NAME} WHERE ATTRIBUTE_NAME = 'DESCRIPTION'""" ), @@ -489,12 +491,12 @@ def setup_create_views_call(self) -> None: ) self.add_session_mock_sql( query=( - f"""CREATE OR REPLACE VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_METADATA_TABLE_NAME}_LAST_METRICS + f"""CREATE OR REPLACE TEMPORARY VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_METADATA_TABLE_NAME}_LAST_METRICS COPY GRANTS AS SELECT DISTINCT MODEL_ID, (LAST_VALUE(VALUE) OVER ( - PARTITION BY MODEL_ID ORDER BY SEQUENCE_ID))['METRICS'] + PARTITION BY MODEL_ID ORDER BY EVENT_TIMESTAMP))['METRICS'] as METRICS FROM {_METADATA_TABLE_NAME} WHERE ATTRIBUTE_NAME = 'METRICS'""" ), @@ -504,12 +506,12 @@ def setup_create_views_call(self) -> None: ) self.add_session_mock_sql( query=( - f"""CREATE OR REPLACE VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_METADATA_TABLE_NAME}_LAST_TAGS + f"""CREATE OR REPLACE TEMPORARY VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_METADATA_TABLE_NAME}_LAST_TAGS COPY GRANTS AS SELECT DISTINCT MODEL_ID, (LAST_VALUE(VALUE) OVER ( - PARTITION BY MODEL_ID ORDER BY SEQUENCE_ID))['TAGS'] + PARTITION BY MODEL_ID ORDER BY EVENT_TIMESTAMP))['TAGS'] as TAGS FROM {_METADATA_TABLE_NAME} WHERE ATTRIBUTE_NAME = 'TAGS'""" ), @@ -519,7 +521,7 @@ def setup_create_views_call(self) -> None: ) self.add_session_mock_sql( query=( - f"""CREATE OR REPLACE VIEW + f"""CREATE OR REPLACE TEMPORARY VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_METADATA_TABLE_NAME}_LAST_REGISTRATION COPY GRANTS AS SELECT DISTINCT MODEL_ID, EVENT_TIMESTAMP as REGISTRATION_TIMESTAMP @@ -531,7 +533,7 @@ def setup_create_views_call(self) -> None: ) self.add_session_mock_sql( query=( - f"""CREATE OR REPLACE VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_REGISTRY_TABLE_NAME}_VIEW + f"""CREATE OR REPLACE TEMPORARY VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_REGISTRY_TABLE_NAME}_VIEW COPY GRANTS AS SELECT {_REGISTRY_TABLE_NAME}.*, {_METADATA_TABLE_NAME}_LAST_DESCRIPTION.DESCRIPTION AS DESCRIPTION, @@ -555,7 +557,7 @@ def setup_create_views_call(self) -> None: ) self.add_session_mock_sql( query=( - f"""CREATE OR REPLACE VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_ARTIFACTS_TABLE_NAME}_VIEW + f"""CREATE OR REPLACE TEMPORARY VIEW {_DATABASE_NAME}.{_SCHEMA_NAME}.{_ARTIFACTS_TABLE_NAME}_VIEW COPY GRANTS AS SELECT {_REGISTRY_TABLE_NAME}.NAME AS MODEL_NAME, @@ -596,6 +598,7 @@ def setup_open_existing(self) -> None: ) self._mock_show_version_table_exists({}) self._mock_select_from_version_table({}, _schema._CURRENT_SCHEMA_VERSION) + self.setup_create_views_call() def setup_schema_upgrade_calls(self, statement_params: Dict[str, str]) -> None: self._mock_show_version_table_exists(statement_params) @@ -755,8 +758,6 @@ def test_create_new(self) -> None: self.setup_schema_upgrade_calls(statement_params) - self.setup_create_views_call() - model_registry.create_model_registry( session=cast(snowpark.Session, self._session), database_name=_DATABASE_NAME, @@ -781,7 +782,6 @@ def test_create_if_not_exists(self) -> None: self._mock_create_artifacts_table_not_exists(statement_params) self.setup_schema_upgrade_calls(statement_params) - self.setup_create_views_call() # 2. SQL queries issued by ModelRegistry constructor. self.setup_open_existing() diff --git a/snowflake/ml/registry/registry.py b/snowflake/ml/registry/registry.py index 57fb8701..22387889 100644 --- a/snowflake/ml/registry/registry.py +++ b/snowflake/ml/registry/registry.py @@ -108,6 +108,8 @@ def log_model( to specify a dependency. It is a recommended way to specify your dependencies using conda. When channel is not specified, Snowflake Anaconda Channel will be used. Defaults to None. pip_requirements: List of Pip package specifications. Defaults to None. + Currently it is not supported since Model can only executed in Snowflake Warehouse where all + dependencies are required to be retrieved from Snowflake Anaconda Channel. python_version: Python version in which the model is run. Defaults to None. code_paths: List of directories containing code to import. Defaults to None. ext_modules: List of external modules to pickle with the model object. @@ -130,6 +132,9 @@ def log_model( - max_batch_size: Maximum batch size that the method could accept in the Snowflake Warehouse. Defaults to None, determined automatically by Snowflake. + Raises: + NotImplementedError: `pip_requirements` is not supported. + Returns: ModelVersion: ModelVersion object corresponding to the model just logged. """ @@ -138,6 +143,12 @@ def log_model( project=_TELEMETRY_PROJECT, subproject=_MODEL_TELEMETRY_SUBPROJECT, ) + if pip_requirements: + raise NotImplementedError( + "Currently `pip_requirements` is not supported since Model can only executed " + "in Snowflake Warehouse where all dependencies are required to be retrieved " + "from Snowflake Anaconda Channel." + ) return self._model_manager.log_model( model=model, model_name=model_name, @@ -145,7 +156,7 @@ def log_model( comment=comment, metrics=metrics, conda_dependencies=conda_dependencies, - pip_requirements=pip_requirements, + pip_requirements=None, python_version=python_version, signatures=signatures, sample_input_data=sample_input_data, diff --git a/snowflake/ml/registry/registry_test.py b/snowflake/ml/registry/registry_test.py index ef42d1ed..886bfc05 100644 --- a/snowflake/ml/registry/registry_test.py +++ b/snowflake/ml/registry/registry_test.py @@ -114,7 +114,6 @@ def test_log_model(self) -> None: m_model = mock.MagicMock() m_conda_dependency = mock.MagicMock() m_sample_input_data = mock.MagicMock() - m_pip_requirements = mock.MagicMock() m_signatures = mock.MagicMock() m_options = mock.MagicMock() m_python_version = mock.MagicMock() @@ -130,7 +129,6 @@ def test_log_model(self) -> None: comment=m_comment, metrics=m_metrics, conda_dependencies=m_conda_dependency, - pip_requirements=m_pip_requirements, python_version=m_python_version, signatures=m_signatures, sample_input_data=m_sample_input_data, @@ -145,7 +143,7 @@ def test_log_model(self) -> None: comment=m_comment, metrics=m_metrics, conda_dependencies=m_conda_dependency, - pip_requirements=m_pip_requirements, + pip_requirements=None, python_version=m_python_version, signatures=m_signatures, sample_input_data=m_sample_input_data, diff --git a/snowflake/ml/version.bzl b/snowflake/ml/version.bzl index ac48ae7f..6e677b35 100644 --- a/snowflake/ml/version.bzl +++ b/snowflake/ml/version.bzl @@ -1,2 +1,2 @@ # This is parsed by regex in conda reciper meta file. Make sure not to break it. -VERSION = "1.2.2" +VERSION = "1.2.3" diff --git a/tests/integ/snowflake/ml/feature_store/feature_store_case_sensitivity_test.py b/tests/integ/snowflake/ml/feature_store/feature_store_case_sensitivity_test.py index 02d89bf8..a936b07b 100644 --- a/tests/integ/snowflake/ml/feature_store/feature_store_case_sensitivity_test.py +++ b/tests/integ/snowflake/ml/feature_store/feature_store_case_sensitivity_test.py @@ -216,7 +216,8 @@ def test_entity_names(self, equi_names: List[str], diff_names: List[str]) -> Non # retrieve with equivalent name is fine. for equi_name in equi_names: - fs.get_entity(equi_name) + e_2 = fs.get_entity(equi_name) + self.assertEqual(e_2.name, SqlIdentifier(equi_name)) # delete with different names will fail for diff_name in diff_names: @@ -224,8 +225,8 @@ def test_entity_names(self, equi_names: List[str], diff_names: List[str]) -> Non fs.delete_entity(diff_name) # register with different names is fine - e_2 = Entity(name=diff_names[0], join_keys=["a"]) - fs.register_entity(e_2) + e_3 = Entity(name=diff_names[0], join_keys=["a"]) + fs.register_entity(e_3) # registered two entiteis. self.assertEqual(len(fs.list_entities().collect()), 2) diff --git a/tests/integ/snowflake/ml/feature_store/feature_store_test.py b/tests/integ/snowflake/ml/feature_store/feature_store_test.py index 0e616f01..0b816cff 100644 --- a/tests/integ/snowflake/ml/feature_store/feature_store_test.py +++ b/tests/integ/snowflake/ml/feature_store/feature_store_test.py @@ -199,6 +199,7 @@ def test_create_and_delete_entities(self) -> None: "NAME": ["aD", "PRODUCT", "USER"], "JOIN_KEYS": ['["AID"]', '["CID","PID"]', '["uid"]'], "DESC": ["", "", ""], + "OWNER": ["REGTEST_RL", "REGTEST_RL", "REGTEST_RL"], }, sort_cols=["NAME"], ) @@ -220,6 +221,7 @@ def test_create_and_delete_entities(self) -> None: "NAME": ["PRODUCT", "USER"], "JOIN_KEYS": ['["CID","PID"]', '["uid"]'], "DESC": ["", ""], + "OWNER": ["REGTEST_RL", "REGTEST_RL"], }, sort_cols=["NAME"], ) @@ -249,12 +251,17 @@ def test_retrieve_entity(self) -> None: e1 = Entity(name="foo", join_keys=["a", "b"], desc="my foo") e2 = Entity(name="bar", join_keys=["c"]) - fs.register_entity(e1) fs.register_entity(e2) + re1 = fs.get_entity("foo") + re2 = fs.get_entity("bar") - self.assertEqual(e1, fs.get_entity("foo")) - self.assertEqual(e2, fs.get_entity("bar")) + self.assertEqual(e1.name, re1.name) + self.assertEqual(e1.join_keys, re1.join_keys) + self.assertEqual(e1.desc, re1.desc) + self.assertEqual(e2.name, re2.name) + self.assertEqual(e2.join_keys, re2.join_keys) + self.assertEqual(e2.desc, re2.desc) compare_dataframe( actual_df=fs.list_entities().to_pandas(), @@ -262,6 +269,7 @@ def test_retrieve_entity(self) -> None: "NAME": ["FOO", "BAR"], "JOIN_KEYS": ['["A","B"]', '["C"]'], "DESC": ["my foo", ""], + "OWNER": ["REGTEST_RL", "REGTEST_RL"], }, sort_cols=["NAME"], ) @@ -513,6 +521,10 @@ def test_create_duplicated_feature_view(self) -> None: ) fv = fs.register_feature_view(feature_view=fv, version="v1") + with self.assertWarnsRegex(UserWarning, "FeatureView .* has already been registered."): + fv = fs.register_feature_view(feature_view=fv, version="v1") + self.assertIsNotNone(fv) + fv = FeatureView( name="fv", entities=[e], @@ -635,11 +647,11 @@ def test_register_with_cron_expr(self) -> None: self.assertEqual(res[0]["state"], "started") self.assertEqual(fv.refresh_freq, "DOWNSTREAM") - fs.suspend_feature_view(fv) + fv = fs.suspend_feature_view(fv) res = self._session.sql(f"SHOW TASKS LIKE '{task_name}' IN SCHEMA {fs._config.full_schema_path}").collect() self.assertEqual(res[0]["state"], "suspended") - fs.resume_feature_view(fv) + fv = fs.resume_feature_view(fv) res = self._session.sql(f"SHOW TASKS LIKE '{task_name}' IN SCHEMA {fs._config.full_schema_path}").collect() self.assertEqual(res[0]["state"], "started") @@ -1088,6 +1100,7 @@ def test_list_feature_views(self) -> None: "WAREHOUSE", "REFRESH_MODE", "REFRESH_MODE_REASON", + "OWNER", "PHYSICAL_NAME", ], ) diff --git a/tests/integ/snowflake/ml/model/_client/model/model_impl_integ_test.py b/tests/integ/snowflake/ml/model/_client/model/model_impl_integ_test.py index de9a92cb..af082029 100644 --- a/tests/integ/snowflake/ml/model/_client/model/model_impl_integ_test.py +++ b/tests/integ/snowflake/ml/model/_client/model/model_impl_integ_test.py @@ -86,9 +86,20 @@ def test_default(self) -> None: self.assertEqual(self._model.default.version_name, VERSION_NAME2) @unittest.skipUnless( - test_env_utils.get_current_snowflake_version() >= version.parse("8.2.0"), - "TAG on model only available when the Snowflake Version is newer than 8.2.0", + test_env_utils.get_current_snowflake_version() >= version.parse("8.7.0"), + "Drop version on model only available when the Snowflake Version is newer than 8.7.0", ) + def test_delete_version(self) -> None: + model, test_features, _ = model_factory.ModelFactory.prepare_sklearn_model() + self.registry.log_model( + model=model, + model_name=MODEL_NAME, + version_name="V3", + sample_input_data=test_features, + ) + self._model.delete_version("V3") + self.assertLen(self._model.show_versions(), 2) + def test_tag(self) -> None: fq_tag_name1 = identifier.get_schema_level_object_identifier(self._test_db, self._test_schema, self._tag_name1) fq_tag_name2 = identifier.get_schema_level_object_identifier(self._test_db, self._test_schema, self._tag_name2) diff --git a/tests/integ/snowflake/ml/modeling/model_selection/BUILD.bazel b/tests/integ/snowflake/ml/modeling/model_selection/BUILD.bazel index 83890da1..ab6a8de9 100644 --- a/tests/integ/snowflake/ml/modeling/model_selection/BUILD.bazel +++ b/tests/integ/snowflake/ml/modeling/model_selection/BUILD.bazel @@ -9,6 +9,7 @@ py_test( shard_count = 5, deps = [ "//snowflake/ml/modeling/decomposition:pca", + "//snowflake/ml/modeling/ensemble:isolation_forest", "//snowflake/ml/modeling/ensemble:random_forest_classifier", "//snowflake/ml/modeling/model_selection:grid_search_cv", "//snowflake/ml/modeling/svm:svc", @@ -25,6 +26,7 @@ py_test( shard_count = 3, deps = [ "//snowflake/ml/modeling/decomposition:pca", + "//snowflake/ml/modeling/ensemble:isolation_forest", "//snowflake/ml/modeling/ensemble:random_forest_classifier", "//snowflake/ml/modeling/model_selection:randomized_search_cv", "//snowflake/ml/modeling/svm:svc", diff --git a/tests/integ/snowflake/ml/modeling/model_selection/grid_search_integ_test.py b/tests/integ/snowflake/ml/modeling/model_selection/grid_search_integ_test.py index 10c32a70..9e6ff1d0 100644 --- a/tests/integ/snowflake/ml/modeling/model_selection/grid_search_integ_test.py +++ b/tests/integ/snowflake/ml/modeling/model_selection/grid_search_integ_test.py @@ -8,13 +8,16 @@ from absl.testing import absltest, parameterized from sklearn.datasets import load_iris from sklearn.decomposition import PCA as SkPCA -from sklearn.ensemble import RandomForestClassifier as SkRandomForestClassifier +from sklearn.ensemble import ( + IsolationForest as SkIsolationForest, + RandomForestClassifier as SkRandomForestClassifier, +) from sklearn.model_selection import GridSearchCV as SkGridSearchCV from sklearn.svm import SVC as SkSVC, SVR as SkSVR from xgboost import XGBClassifier as SkXGBClassifier from snowflake.ml.modeling.decomposition import PCA -from snowflake.ml.modeling.ensemble import RandomForestClassifier +from snowflake.ml.modeling.ensemble import IsolationForest, RandomForestClassifier from snowflake.ml.modeling.model_selection import GridSearchCV from snowflake.ml.modeling.svm import SVC, SVR from snowflake.ml.modeling.xgboost import XGBClassifier @@ -345,6 +348,31 @@ def test_not_fitted_exception(self) -> None: ): reg.predict_proba(self._input_df) + def test_score_samples(self) -> None: + param_grid = {"max_features": [1, 2]} + sklearn_reg = SkGridSearchCV( + estimator=SkIsolationForest(random_state=0), param_grid=param_grid, scoring="accuracy" + ) + reg = GridSearchCV(estimator=IsolationForest(random_state=0), param_grid=param_grid, scoring="accuracy") + reg.set_input_cols(self._input_cols) + output_cols = ["OUTPUT_" + c for c in self._label_col] + reg.set_output_cols(output_cols) + reg.set_label_cols(self._label_col) + + reg.fit(self._input_df) + sklearn_reg.fit(X=self._input_df_pandas[self._input_cols], y=self._input_df_pandas[self._label_col].squeeze()) + + # Test score_samples + actual_score_samples_result = reg.score_samples(self._input_df).to_pandas().sort_values(by="INDEX") + actual_output_cols = [c for c in actual_score_samples_result.columns if c.find("score_samples") >= 0] + actual_score_samples_result = actual_score_samples_result[actual_output_cols].to_numpy() + sklearn_score_samples_array = sklearn_reg.score_samples(self._input_df_pandas[self._input_cols]) + np.testing.assert_allclose(actual_score_samples_result.flatten(), sklearn_score_samples_array.flatten()) + + actual_pandas_result = reg.score_samples(self._input_df_pandas[self._input_cols]) + actual_pandas_result = actual_pandas_result[actual_output_cols].to_numpy() + np.testing.assert_allclose(actual_pandas_result.flatten(), sklearn_score_samples_array.flatten()) + if __name__ == "__main__": absltest.main() diff --git a/tests/integ/snowflake/ml/modeling/model_selection/randomized_search_integ_test.py b/tests/integ/snowflake/ml/modeling/model_selection/randomized_search_integ_test.py index ac3b9ebe..1a29eb74 100644 --- a/tests/integ/snowflake/ml/modeling/model_selection/randomized_search_integ_test.py +++ b/tests/integ/snowflake/ml/modeling/model_selection/randomized_search_integ_test.py @@ -8,13 +8,16 @@ from absl.testing import absltest, parameterized from sklearn.datasets import load_iris from sklearn.decomposition import PCA as SkPCA -from sklearn.ensemble import RandomForestClassifier as SkRandomForestClassifier +from sklearn.ensemble import ( + IsolationForest as SkIsolationForest, + RandomForestClassifier as SkRandomForestClassifier, +) from sklearn.model_selection import RandomizedSearchCV as SkRandomizedSearchCV from sklearn.svm import SVC as SkSVC from xgboost import XGBClassifier as SkXGBClassifier from snowflake.ml.modeling.decomposition import PCA -from snowflake.ml.modeling.ensemble import RandomForestClassifier +from snowflake.ml.modeling.ensemble import IsolationForest, RandomForestClassifier from snowflake.ml.modeling.model_selection import RandomizedSearchCV from snowflake.ml.modeling.svm import SVC from snowflake.ml.modeling.xgboost import XGBClassifier @@ -297,6 +300,33 @@ def test_not_fitted_exception(self) -> None: ): reg.predict_proba(self._input_df) + def test_score_samples(self) -> None: + params = {"max_features": range(1, 3)} + sklearn_reg = SkRandomizedSearchCV( + estimator=SkIsolationForest(random_state=0), param_distributions=params, scoring="accuracy" + ) + reg = RandomizedSearchCV( + estimator=IsolationForest(random_state=0), param_distributions=params, scoring="accuracy" + ) + reg.set_input_cols(self._input_cols) + output_cols = ["OUTPUT_" + c for c in self._label_col] + reg.set_output_cols(output_cols) + reg.set_label_cols(self._label_col) + + reg.fit(self._input_df) + sklearn_reg.fit(X=self._input_df_pandas[self._input_cols], y=self._input_df_pandas[self._label_col].squeeze()) + + # Test score_samples + actual_score_samples_result = reg.score_samples(self._input_df).to_pandas().sort_values(by="INDEX") + actual_output_cols = [c for c in actual_score_samples_result.columns if c.find("score_samples") >= 0] + actual_score_samples_result = actual_score_samples_result[actual_output_cols].to_numpy() + sklearn_score_samples_array = sklearn_reg.score_samples(self._input_df_pandas[self._input_cols]) + np.testing.assert_allclose(actual_score_samples_result.flatten(), sklearn_score_samples_array.flatten()) + + actual_pandas_result = reg.score_samples(self._input_df_pandas[self._input_cols]) + actual_pandas_result = actual_pandas_result[actual_output_cols].to_numpy() + np.testing.assert_allclose(actual_pandas_result.flatten(), sklearn_score_samples_array.flatten()) + if __name__ == "__main__": absltest.main() diff --git a/tests/integ/snowflake/ml/modeling/pipeline/BUILD.bazel b/tests/integ/snowflake/ml/modeling/pipeline/BUILD.bazel index c3b2af0f..972d1e14 100644 --- a/tests/integ/snowflake/ml/modeling/pipeline/BUILD.bazel +++ b/tests/integ/snowflake/ml/modeling/pipeline/BUILD.bazel @@ -12,6 +12,7 @@ py_test( srcs = ["pipeline_test.py"], shard_count = SHARD_COUNT, deps = [ + "//snowflake/ml/modeling/ensemble:isolation_forest", "//snowflake/ml/modeling/linear_model:linear_regression", "//snowflake/ml/modeling/linear_model:logistic_regression", "//snowflake/ml/modeling/pipeline", diff --git a/tests/integ/snowflake/ml/modeling/pipeline/pipeline_test.py b/tests/integ/snowflake/ml/modeling/pipeline/pipeline_test.py index 471504c5..4f4a766f 100644 --- a/tests/integ/snowflake/ml/modeling/pipeline/pipeline_test.py +++ b/tests/integ/snowflake/ml/modeling/pipeline/pipeline_test.py @@ -13,6 +13,7 @@ from absl.testing.absltest import TestCase, main from sklearn.compose import ColumnTransformer as SkColumnTransformer from sklearn.datasets import load_diabetes, load_iris +from sklearn.ensemble import IsolationForest as SklearnIsolationForest from sklearn.linear_model import ( LinearRegression as SklearnLinearRegression, LogisticRegression as SklearnLogisticRegression, @@ -25,6 +26,7 @@ from snowflake.ml.model.model_signature import DataType, FeatureSpec, ModelSignature from snowflake.ml.modeling import pipeline as snowml_pipeline +from snowflake.ml.modeling.ensemble import IsolationForest from snowflake.ml.modeling.linear_model import ( LinearRegression as SnowmlLinearRegression, LogisticRegression as SnowmlLogisticRegression, @@ -471,6 +473,36 @@ def test_pipeline_with_label_encoder_output_col(self) -> None: assert "TARGET_OUT" in snow_df_output.columns + def test_pipeline_score_samples(self) -> None: + input_df_pandas = load_iris(as_frame=True).frame + # Normalize column names + input_df_pandas.columns = [inflection.parameterize(c, "_").upper() for c in input_df_pandas.columns] + input_df_pandas["INDEX"] = input_df_pandas.reset_index().index + + input_df = self._session.create_dataframe(input_df_pandas) + + input_cols = [c for c in input_df_pandas.columns if not c.startswith("TARGET") and not c.startswith("INDEX")] + label_cols = ["TARGET"] + + estimator = IsolationForest(input_cols=input_cols, label_cols=label_cols, random_state=0) + + pipeline = snowml_pipeline.Pipeline(steps=[("estimator", estimator)]) + + # fit and predict + pipeline.fit(input_df) + output_df = pipeline.score_samples(input_df) + actual_results = ( + output_df.to_pandas().sort_values(by="INDEX")["SCORE_SAMPLES_"].astype(float).to_numpy().flatten() + ) + + # Do the same with SKLearn + skpipeline = SkPipeline(steps=[("estimator", SklearnIsolationForest(random_state=0))]) + + skpipeline.fit(input_df_pandas[input_cols], input_df_pandas[label_cols]) + sk_predict_results = skpipeline.score_samples(input_df_pandas[input_cols]) + + np.testing.assert_allclose(actual_results, sk_predict_results) + if __name__ == "__main__": main() diff --git a/tests/integ/snowflake/ml/registry/model/registry_custom_model_test.py b/tests/integ/snowflake/ml/registry/model/registry_custom_model_test.py index 96371706..f9aaca9e 100644 --- a/tests/integ/snowflake/ml/registry/model/registry_custom_model_test.py +++ b/tests/integ/snowflake/ml/registry/model/registry_custom_model_test.py @@ -108,6 +108,23 @@ def test_custom_demo_model_sp( }, ) + def test_custom_demo_model_decimal( + self, + ) -> None: + import decimal + + lm = DemoModel(custom_model.ModelContext()) + arr = [[decimal.Decimal(1.2), 2.3, 3.4], [decimal.Decimal(4.6), 2.7, 5.5]] + sp_df = self._session.create_dataframe(arr, schema=['"c1"', '"c2"', '"c3"']) + y_df_expected = pd.DataFrame([[1.2, 2.3, 3.4, 1.2], [4.6, 2.7, 5.5, 4.6]], columns=["c1", "c2", "c3", "output"]) + self._test_registry_model( + model=lm, + sample_input=sp_df, + prediction_assert_fns={ + "predict": (sp_df, lambda res: dataframe_utils.check_sp_df_res(res, y_df_expected, check_dtype=False)) + }, + ) + def test_custom_demo_model_sp_one_query( self, ) -> None: diff --git a/third_party/rules_conda/env.bzl b/third_party/rules_conda/env.bzl index f1f293f1..0d44ae1c 100644 --- a/third_party/rules_conda/env.bzl +++ b/third_party/rules_conda/env.bzl @@ -156,7 +156,7 @@ conda_create_rule = repository_rule( "python_version": attr.string( mandatory = True, doc = "The Python version to use when creating the environment.", - values = ["3.8", "3.9", "3.10"], + values = ["3.8", "3.9", "3.10", "3.11"], ), "quiet": attr.bool( default = True,