From 2d0044da28645c08524ebac9ee8c5b0130f5ae13 Mon Sep 17 00:00:00 2001 From: Johnu George Date: Fri, 6 Dec 2019 22:32:39 +0530 Subject: [PATCH] Delete v1alpha2 files --- cmd/katib-controller/v1alpha2/Dockerfile | 20 - cmd/katib-controller/v1alpha2/main.go | 97 - cmd/manager-rest/v1alpha2/Dockerfile | 15 - cmd/manager-rest/v1alpha2/proxy.go | 43 - cmd/manager/v1alpha2/Dockerfile | 23 - cmd/manager/v1alpha2/main.go | 216 - cmd/manager/v1alpha2/main_test.go | 612 --- cmd/metricscollector/v1alpha2/Dockerfile | 22 - cmd/metricscollector/v1alpha2/main.go | 87 - .../bayesianoptimization/v1alpha2/Dockerfile | 12 - .../bayesianoptimization/v1alpha2/README.md | 14 - .../bayesianoptimization/v1alpha2/__init__.py | 0 .../bayesianoptimization/v1alpha2/main.py | 25 - .../v1alpha2/requirements.txt | 9 - cmd/suggestion/grid/v1alpha2/Dockerfile | 13 - cmd/suggestion/grid/v1alpha2/__init__.py | 0 cmd/suggestion/grid/v1alpha2/main.py | 23 - cmd/suggestion/grid/v1alpha2/requirements.txt | 9 - cmd/suggestion/hyperband/v1alpha2/Dockerfile | 13 - cmd/suggestion/hyperband/v1alpha2/__init__.py | 0 cmd/suggestion/hyperband/v1alpha2/main.py | 23 - .../hyperband/v1alpha2/requirements.txt | 9 - cmd/suggestion/nasrl/v1alpha2/Dockerfile | 9 - .../nasrl/v1alpha2/Dockerfile.aarch64 | 92 - cmd/suggestion/nasrl/v1alpha2/__init__.py | 0 cmd/suggestion/nasrl/v1alpha2/main.py | 27 - .../nasrl/v1alpha2/requirements.txt | 3 - cmd/suggestion/random/v1alpha2/Dockerfile | 13 - cmd/suggestion/random/v1alpha2/__init__.py | 0 cmd/suggestion/random/v1alpha2/main.py | 23 - .../random/v1alpha2/requirements.txt | 9 - .../v1alpha2/Dockerfile | 5 - .../v1alpha2/Dockerfile.aarch64 | 28 - cmd/tfevent-metricscollector/v1alpha2/main.py | 39 - cmd/ui/v1alpha2/Dockerfile | 25 - cmd/ui/v1alpha2/main.go | 47 - examples/v1alpha2/MinikubeDemo/deploy.sh | 5 - examples/v1alpha2/MinikubeDemo/destroy.sh | 5 - .../RL-cifar10/Dockerfile | 32 - .../RL-cifar10/ModelConstructor.py | 67 - .../RL-cifar10/RunTrial.py | 77 - .../RL-cifar10/op_library.py | 141 - .../RL-cifar10/requirements.txt | 2 - examples/v1alpha2/README.md | 310 -- examples/v1alpha2/bayseopt-example.yaml | 64 - examples/v1alpha2/grid-example.yaml | 64 - examples/v1alpha2/hyperband-example.yaml | 70 - examples/v1alpha2/nasjob-example-RL.yaml | 175 - examples/v1alpha2/pytorchjob-example.yaml | 71 - examples/v1alpha2/random-example.yaml | 59 - .../v1alpha2/tfevent-volume/tfevent-pv.yaml | 14 - .../v1alpha2/tfevent-volume/tfevent-pvc.yaml | 14 - examples/v1alpha2/tfjob-example.yaml | 99 - manifests/v1alpha2/0-namespace.yaml | 4 - manifests/v1alpha2/db/deployment.yaml | 56 - manifests/v1alpha2/db/secret.yaml | 8 - manifests/v1alpha2/db/service.yaml | 17 - .../katib-controller/crd-experiment.yaml | 25 - .../v1alpha2/katib-controller/crd-trial.yaml | 25 - .../katib-controller/katib-controller.yaml | 46 - .../v1alpha2/katib-controller/mcrbac.yaml | 38 - .../metricsControllerConfigMap.yaml | 42 - manifests/v1alpha2/katib-controller/rbac.yaml | 78 - .../v1alpha2/katib-controller/secret.yaml | 5 - .../v1alpha2/katib-controller/service.yaml | 20 - .../trialTemplateConfigmap.yaml | 20 - .../v1alpha2/manager-rest/deployment.yaml | 30 - manifests/v1alpha2/manager-rest/service.yaml | 17 - manifests/v1alpha2/manager/deployment.yaml | 44 - manifests/v1alpha2/manager/service.yaml | 17 - manifests/v1alpha2/pv/pv.yaml | 15 - manifests/v1alpha2/pv/pvc.yaml | 14 - .../bayesianoptimization/deployment.yaml | 28 - .../bayesianoptimization/service.yaml | 17 - .../v1alpha2/suggestion/grid/deployment.yaml | 28 - .../v1alpha2/suggestion/grid/service.yaml | 17 - .../suggestion/hyperband/deployment.yaml | 28 - .../suggestion/hyperband/service.yaml | 17 - .../v1alpha2/suggestion/nasrl/deployment.yaml | 27 - .../v1alpha2/suggestion/nasrl/service.yaml | 17 - .../suggestion/random/deployment.yaml | 28 - .../v1alpha2/suggestion/random/service.yaml | 17 - manifests/v1alpha2/ui/deployment.yaml | 31 - manifests/v1alpha2/ui/rbac.yaml | 37 - manifests/v1alpha2/ui/service.yaml | 17 - .../controller/addtoscheme_katib_v1alpha2.go | 29 - .../common/v1alpha2/common_types.go | 50 - .../common/v1alpha2/zz_generated.deepcopy.go | 67 - .../experiments/v1alpha2/constants.go | 33 - .../controller/experiments/v1alpha2/doc.go | 23 - .../v1alpha2/experiment_defaults.go | 56 - .../experiments/v1alpha2/experiment_types.go | 248 -- .../experiments/v1alpha2/register.go | 42 - .../controller/experiments/v1alpha2/util.go | 175 - .../v1alpha2/zz_generated.deepcopy.go | 474 -- pkg/apis/controller/trials/v1alpha2/doc.go | 23 - .../controller/trials/v1alpha2/register.go | 42 - .../controller/trials/v1alpha2/trial_types.go | 128 - pkg/apis/controller/trials/v1alpha2/util.go | 146 - .../trials/v1alpha2/zz_generated.deepcopy.go | 170 - pkg/apis/{ => manager}/README.md | 6 +- pkg/apis/manager/v1alpha2/Makefile | 2 - pkg/apis/manager/v1alpha2/api.pb.go | 2531 ----------- pkg/apis/manager/v1alpha2/api.pb.gw.go | 972 ---- pkg/apis/manager/v1alpha2/api.proto | 537 --- pkg/apis/manager/v1alpha2/api.swagger.json | 1077 ----- pkg/apis/manager/v1alpha2/build.sh | 11 - pkg/apis/manager/v1alpha2/gen-doc/Dockerfile | 17 - pkg/apis/manager/v1alpha2/gen-doc/api.md | 1095 ----- pkg/apis/manager/v1alpha2/gen-doc/index.html | 2443 ---------- pkg/apis/manager/v1alpha2/python/api_pb2.py | 3916 ----------------- .../manager/v1alpha2/python/api_pb2_grpc.py | 434 -- pkg/common/v1alpha2/common.go | 54 - pkg/common/v1alpha2/katib_manager_util.go | 181 - pkg/controller.v1alpha2/add_experiment.go | 26 - pkg/controller.v1alpha2/add_trial.go | 26 - pkg/controller.v1alpha2/consts/const.go | 7 - pkg/controller.v1alpha2/controller.go | 33 - .../experiment/experiment_controller.go | 337 -- .../experiment_controller_suite_test.go | 102 - .../experiment/experiment_controller_test.go | 307 -- .../experiment/experiment_status.go | 17 - .../experiment/experiment_util.go | 108 - .../experiment/managerclient/managerclient.go | 261 -- .../experiment/manifest/generator.go | 160 - .../experiment/manifest/generator_test.go | 295 -- .../experiment/suggestion/fake/fake.go | 18 - .../experiment/suggestion/suggestion.go | 31 - .../experiment/util/status_util.go | 173 - .../trial/managerclient/managerclient.go | 159 - .../trial/trial_controller.go | 364 -- .../trial/trial_controller_consts.go | 10 - .../trial/trial_controller_status.go | 17 - .../trial/trial_controller_suite_test.go | 83 - .../trial/trial_controller_test.go | 357 -- .../trial/trial_controller_util.go | 145 - pkg/db/v1alpha2/db_init.go | 78 - pkg/db/v1alpha2/interface.go | 790 ---- pkg/db/v1alpha2/interface_test.go | 531 --- pkg/mock/v1alpha2/api/manager.go | 376 -- pkg/mock/v1alpha2/api/suggestion.go | 76 - pkg/mock/v1alpha2/db/db.go | 277 -- .../experiment/managerclient/managerclient.go | 107 - .../v1alpha2/experiment/manifest/generator.go | 93 - .../experiment/suggestion/suggestion.go | 50 - .../trial/managerclient/katibmanager.go | 106 - .../v1alpha2/util/katibclient/katibclient.go | 241 - .../AlgorithmSettings.py | 70 - .../NAS_Reinforcement_Learning/Controller.py | 219 - .../NAS_Reinforcement_Learning/LSTM.py | 28 - .../NAS_Reinforcement_Learning/Operation.py | 76 - .../NAS_Reinforcement_Learning/README.md | 129 - .../NAS_Reinforcement_Learning/Trainer.py | 143 - .../NAS_Reinforcement_Learning/example.png | Bin 137757 -> 0 bytes pkg/suggestion/v1alpha2/__init__.py | 0 pkg/suggestion/v1alpha2/bayesian_service.py | 220 - .../bayesianoptimization/src/__init__.py | 0 .../src/acquisition_func.py | 36 - .../src/algorithm_manager.py | 201 - .../src/bayesian_optimization_algorithm.py | 73 - .../src/global_optimizer.py | 309 -- .../src/model/__init__.py | 0 .../bayesianoptimization/src/model/gp.py | 38 - .../bayesianoptimization/src/model/rf.py | 24 - .../bayesianoptimization/src/utils.py | 17 - pkg/suggestion/v1alpha2/grid_service.py | 110 - pkg/suggestion/v1alpha2/hyperband_service.py | 302 -- pkg/suggestion/v1alpha2/nasrl_service.py | 397 -- pkg/suggestion/v1alpha2/parameter.py | 52 - pkg/suggestion/v1alpha2/parsing_util.py | 144 - pkg/suggestion/v1alpha2/random_service.py | 44 - pkg/ui/v1alpha2/backend.go | 463 -- pkg/ui/v1alpha2/frontend/.gitignore | 27 - pkg/ui/v1alpha2/frontend/README.md | 5 - pkg/ui/v1alpha2/frontend/config/env.js | 93 - .../frontend/config/jest/cssTransform.js | 14 - .../frontend/config/jest/fileTransform.js | 31 - pkg/ui/v1alpha2/frontend/config/paths.js | 89 - .../frontend/config/webpack.config.js | 605 --- .../config/webpackDevServer.config.js | 104 - pkg/ui/v1alpha2/frontend/package.json | 140 - pkg/ui/v1alpha2/frontend/public/favicon.ico | Bin 3870 -> 0 bytes pkg/ui/v1alpha2/frontend/public/index.html | 55 - pkg/ui/v1alpha2/frontend/public/logo.png | Bin 81189 -> 0 bytes pkg/ui/v1alpha2/frontend/public/manifest.json | 15 - pkg/ui/v1alpha2/frontend/scripts/build.js | 192 - pkg/ui/v1alpha2/frontend/scripts/start.js | 132 - pkg/ui/v1alpha2/frontend/scripts/test.js | 60 - .../frontend/src/actions/generalActions.js | 47 - .../frontend/src/actions/hpCreateActions.js | 131 - .../frontend/src/actions/hpMonitorActions.js | 45 - .../frontend/src/actions/nasCreateActions.js | 187 - .../frontend/src/actions/nasMonitorActions.js | 30 - .../frontend/src/actions/templateActions.js | 63 - .../v1alpha2/frontend/src/components/App.jsx | 47 - .../frontend/src/components/HP/Create/HP.jsx | 38 - .../src/components/HP/Create/HPParameters.jsx | 186 - .../components/HP/Create/Params/Algorithm.jsx | 160 - .../HP/Create/Params/CommonMeta.jsx | 75 - .../HP/Create/Params/CommonSpec.jsx | 76 - .../components/HP/Create/Params/Objective.jsx | 178 - .../HP/Create/Params/Parameters.jsx | 214 - .../src/components/HP/Create/Params/Trial.jsx | 102 - .../src/components/HP/Create/YAML.jsx | 82 - .../src/components/HP/Monitor/FilterPanel.jsx | 81 - .../src/components/HP/Monitor/HPJobInfo.jsx | 71 - .../src/components/HP/Monitor/HPJobList.jsx | 92 - .../components/HP/Monitor/HPJobMonitor.jsx | 38 - .../src/components/HP/Monitor/HPJobPlot.jsx | 94 - .../src/components/HP/Monitor/HPJobTable.jsx | 88 - .../components/HP/Monitor/TrialInfoDialog.jsx | 88 - .../src/components/Menu/DeleteDialog.jsx | 58 - .../frontend/src/components/Menu/Header.jsx | 56 - .../frontend/src/components/Menu/Main.jsx | 73 - .../frontend/src/components/Menu/Menu.jsx | 186 - .../frontend/src/components/Menu/Snack.jsx | 66 - .../src/components/NAS/Create/NAS.jsx | 38 - .../components/NAS/Create/NASParameters.jsx | 206 - .../NAS/Create/Params/Algorithm.jsx | 160 - .../NAS/Create/Params/CommonMeta.jsx | 75 - .../NAS/Create/Params/CommonSpec.jsx | 76 - .../NAS/Create/Params/NASConfig.jsx | 424 -- .../NAS/Create/Params/Objective.jsx | 178 - .../components/NAS/Create/Params/Trial.jsx | 102 - .../src/components/NAS/Create/YAML.jsx | 83 - .../components/NAS/Monitor/FilterPanel.jsx | 81 - .../src/components/NAS/Monitor/NASJobInfo.jsx | 90 - .../src/components/NAS/Monitor/NASJobList.jsx | 92 - .../components/NAS/Monitor/NASJobMonitor.jsx | 39 - .../components/NAS/Monitor/NASJobStepInfo.jsx | 61 - .../src/components/Templates/Collector.jsx | 53 - .../components/Templates/Common/AddDialog.jsx | 122 - .../Templates/Common/DeleteDialog.jsx | 71 - .../Templates/Common/EditDialog.jsx | 110 - .../Templates/Common/TemplateList.jsx | 65 - .../Templates/Common/TemplatePanel.jsx | 91 - .../src/components/Templates/Trial.jsx | 52 - pkg/ui/v1alpha2/frontend/src/index.js | 54 - .../v1alpha2/frontend/src/reducers/general.js | 105 - .../frontend/src/reducers/hpCreate.js | 249 -- .../frontend/src/reducers/hpMonitor.js | 107 - .../v1alpha2/frontend/src/reducers/index.js | 18 - .../frontend/src/reducers/nasCreate.js | 563 --- .../frontend/src/reducers/nasMonitor.js | 95 - .../frontend/src/reducers/template.js | 137 - pkg/ui/v1alpha2/frontend/src/sagas/index.js | 690 --- pkg/ui/v1alpha2/frontend/src/serviceWorker.js | 135 - pkg/ui/v1alpha2/frontend/src/store/index.js | 24 - pkg/ui/v1alpha2/types.go | 56 - pkg/ui/v1alpha2/util.go | 140 - pkg/util/v1alpha2/katibclient/katib_client.go | 190 - .../metricscollector/metricscollector.go | 113 - .../tfevent-metricscollector/__init__.py | 0 .../tfevent_loader.py | 65 - .../v1alpha2/experiment/mutate_webhook.go | 70 - .../v1alpha2/experiment/validation_webhook.go | 82 - .../experiment/validator/validator.go | 212 - .../experiment/validator/validator_test.go | 190 - pkg/webhook/v1alpha2/webhook.go | 88 - prow_config.yaml | 83 - scripts/mockgen.sh | 17 - scripts/v1alpha2/build.sh | 54 - scripts/v1alpha2/deploy.sh | 37 - scripts/v1alpha2/undeploy.sh | 45 - test/e2e/v1alpha2/invalid-experiment.yaml | 53 - test/e2e/v1alpha2/run-e2e-experiment.go | 102 - test/e2e/v1alpha2/test-katib-manager.py | 147 - test/e2e/v1alpha2/test_requirements.txt | 3 - test/e2e/v1alpha2/valid-experiment.yaml | 53 - .../v1alpha2/build-earlystopping-median.sh | 44 - .../v1alpha2/build-katib-controller.sh | 51 - test/scripts/v1alpha2/build-manager-rest.sh | 41 - test/scripts/v1alpha2/build-manager.sh | 41 - test/scripts/v1alpha2/build-suggestion-bo.sh | 42 - .../scripts/v1alpha2/build-suggestion-grid.sh | 42 - .../v1alpha2/build-suggestion-hyperband.sh | 42 - .../build-suggestion-nasenvelopenet.sh | 44 - .../v1alpha2/build-suggestion-nasrl.sh | 42 - .../v1alpha2/build-suggestion-random.sh | 42 - .../v1alpha2/build-tc-nasrl-cifar10.sh | 40 - test/scripts/v1alpha2/build-ui.sh | 43 - test/scripts/v1alpha2/create-cluster.sh | 38 - test/scripts/v1alpha2/delete-cluster.sh | 31 - test/scripts/v1alpha2/python-tests.sh | 25 - test/scripts/v1alpha2/run-tests.sh | 136 - test/unit/v1alpha2/crds/pytorchjob_v1.yaml | 12 - test/unit/v1alpha2/crds/tfjob_v1.yaml | 12 - test/workflows/components/params.libsonnet | 8 - .../components/workflows-v1alpha2.jsonnet | 14 - .../components/workflows-v1alpha2.libsonnet | 370 -- 290 files changed, 3 insertions(+), 39159 deletions(-) delete mode 100644 cmd/katib-controller/v1alpha2/Dockerfile delete mode 100644 cmd/katib-controller/v1alpha2/main.go delete mode 100644 cmd/manager-rest/v1alpha2/Dockerfile delete mode 100644 cmd/manager-rest/v1alpha2/proxy.go delete mode 100644 cmd/manager/v1alpha2/Dockerfile delete mode 100644 cmd/manager/v1alpha2/main.go delete mode 100644 cmd/manager/v1alpha2/main_test.go delete mode 100644 cmd/metricscollector/v1alpha2/Dockerfile delete mode 100644 cmd/metricscollector/v1alpha2/main.go delete mode 100644 cmd/suggestion/bayesianoptimization/v1alpha2/Dockerfile delete mode 100644 cmd/suggestion/bayesianoptimization/v1alpha2/README.md delete mode 100644 cmd/suggestion/bayesianoptimization/v1alpha2/__init__.py delete mode 100644 cmd/suggestion/bayesianoptimization/v1alpha2/main.py delete mode 100644 cmd/suggestion/bayesianoptimization/v1alpha2/requirements.txt delete mode 100644 cmd/suggestion/grid/v1alpha2/Dockerfile delete mode 100644 cmd/suggestion/grid/v1alpha2/__init__.py delete mode 100644 cmd/suggestion/grid/v1alpha2/main.py delete mode 100644 cmd/suggestion/grid/v1alpha2/requirements.txt delete mode 100644 cmd/suggestion/hyperband/v1alpha2/Dockerfile delete mode 100644 cmd/suggestion/hyperband/v1alpha2/__init__.py delete mode 100644 cmd/suggestion/hyperband/v1alpha2/main.py delete mode 100644 cmd/suggestion/hyperband/v1alpha2/requirements.txt delete mode 100644 cmd/suggestion/nasrl/v1alpha2/Dockerfile delete mode 100644 cmd/suggestion/nasrl/v1alpha2/Dockerfile.aarch64 delete mode 100644 cmd/suggestion/nasrl/v1alpha2/__init__.py delete mode 100644 cmd/suggestion/nasrl/v1alpha2/main.py delete mode 100644 cmd/suggestion/nasrl/v1alpha2/requirements.txt delete mode 100644 cmd/suggestion/random/v1alpha2/Dockerfile delete mode 100644 cmd/suggestion/random/v1alpha2/__init__.py delete mode 100644 cmd/suggestion/random/v1alpha2/main.py delete mode 100644 cmd/suggestion/random/v1alpha2/requirements.txt delete mode 100644 cmd/tfevent-metricscollector/v1alpha2/Dockerfile delete mode 100644 cmd/tfevent-metricscollector/v1alpha2/Dockerfile.aarch64 delete mode 100644 cmd/tfevent-metricscollector/v1alpha2/main.py delete mode 100644 cmd/ui/v1alpha2/Dockerfile delete mode 100644 cmd/ui/v1alpha2/main.go delete mode 100755 examples/v1alpha2/MinikubeDemo/deploy.sh delete mode 100755 examples/v1alpha2/MinikubeDemo/destroy.sh delete mode 100644 examples/v1alpha2/NAS-training-containers/RL-cifar10/Dockerfile delete mode 100644 examples/v1alpha2/NAS-training-containers/RL-cifar10/ModelConstructor.py delete mode 100644 examples/v1alpha2/NAS-training-containers/RL-cifar10/RunTrial.py delete mode 100644 examples/v1alpha2/NAS-training-containers/RL-cifar10/op_library.py delete mode 100644 examples/v1alpha2/NAS-training-containers/RL-cifar10/requirements.txt delete mode 100644 examples/v1alpha2/README.md delete mode 100644 examples/v1alpha2/bayseopt-example.yaml delete mode 100644 examples/v1alpha2/grid-example.yaml delete mode 100644 examples/v1alpha2/hyperband-example.yaml delete mode 100644 examples/v1alpha2/nasjob-example-RL.yaml delete mode 100644 examples/v1alpha2/pytorchjob-example.yaml delete mode 100644 examples/v1alpha2/random-example.yaml delete mode 100644 examples/v1alpha2/tfevent-volume/tfevent-pv.yaml delete mode 100644 examples/v1alpha2/tfevent-volume/tfevent-pvc.yaml delete mode 100644 examples/v1alpha2/tfjob-example.yaml delete mode 100644 manifests/v1alpha2/0-namespace.yaml delete mode 100644 manifests/v1alpha2/db/deployment.yaml delete mode 100644 manifests/v1alpha2/db/secret.yaml delete mode 100644 manifests/v1alpha2/db/service.yaml delete mode 100644 manifests/v1alpha2/katib-controller/crd-experiment.yaml delete mode 100644 manifests/v1alpha2/katib-controller/crd-trial.yaml delete mode 100644 manifests/v1alpha2/katib-controller/katib-controller.yaml delete mode 100644 manifests/v1alpha2/katib-controller/mcrbac.yaml delete mode 100644 manifests/v1alpha2/katib-controller/metricsControllerConfigMap.yaml delete mode 100644 manifests/v1alpha2/katib-controller/rbac.yaml delete mode 100644 manifests/v1alpha2/katib-controller/secret.yaml delete mode 100644 manifests/v1alpha2/katib-controller/service.yaml delete mode 100644 manifests/v1alpha2/katib-controller/trialTemplateConfigmap.yaml delete mode 100644 manifests/v1alpha2/manager-rest/deployment.yaml delete mode 100644 manifests/v1alpha2/manager-rest/service.yaml delete mode 100644 manifests/v1alpha2/manager/deployment.yaml delete mode 100644 manifests/v1alpha2/manager/service.yaml delete mode 100644 manifests/v1alpha2/pv/pv.yaml delete mode 100644 manifests/v1alpha2/pv/pvc.yaml delete mode 100644 manifests/v1alpha2/suggestion/bayesianoptimization/deployment.yaml delete mode 100644 manifests/v1alpha2/suggestion/bayesianoptimization/service.yaml delete mode 100644 manifests/v1alpha2/suggestion/grid/deployment.yaml delete mode 100644 manifests/v1alpha2/suggestion/grid/service.yaml delete mode 100644 manifests/v1alpha2/suggestion/hyperband/deployment.yaml delete mode 100644 manifests/v1alpha2/suggestion/hyperband/service.yaml delete mode 100644 manifests/v1alpha2/suggestion/nasrl/deployment.yaml delete mode 100644 manifests/v1alpha2/suggestion/nasrl/service.yaml delete mode 100644 manifests/v1alpha2/suggestion/random/deployment.yaml delete mode 100644 manifests/v1alpha2/suggestion/random/service.yaml delete mode 100644 manifests/v1alpha2/ui/deployment.yaml delete mode 100644 manifests/v1alpha2/ui/rbac.yaml delete mode 100644 manifests/v1alpha2/ui/service.yaml delete mode 100644 pkg/apis/controller/addtoscheme_katib_v1alpha2.go delete mode 100644 pkg/apis/controller/common/v1alpha2/common_types.go delete mode 100644 pkg/apis/controller/common/v1alpha2/zz_generated.deepcopy.go delete mode 100644 pkg/apis/controller/experiments/v1alpha2/constants.go delete mode 100644 pkg/apis/controller/experiments/v1alpha2/doc.go delete mode 100644 pkg/apis/controller/experiments/v1alpha2/experiment_defaults.go delete mode 100644 pkg/apis/controller/experiments/v1alpha2/experiment_types.go delete mode 100644 pkg/apis/controller/experiments/v1alpha2/register.go delete mode 100644 pkg/apis/controller/experiments/v1alpha2/util.go delete mode 100644 pkg/apis/controller/experiments/v1alpha2/zz_generated.deepcopy.go delete mode 100644 pkg/apis/controller/trials/v1alpha2/doc.go delete mode 100644 pkg/apis/controller/trials/v1alpha2/register.go delete mode 100644 pkg/apis/controller/trials/v1alpha2/trial_types.go delete mode 100644 pkg/apis/controller/trials/v1alpha2/util.go delete mode 100644 pkg/apis/controller/trials/v1alpha2/zz_generated.deepcopy.go rename pkg/apis/{ => manager}/README.md (80%) delete mode 100644 pkg/apis/manager/v1alpha2/Makefile delete mode 100644 pkg/apis/manager/v1alpha2/api.pb.go delete mode 100644 pkg/apis/manager/v1alpha2/api.pb.gw.go delete mode 100644 pkg/apis/manager/v1alpha2/api.proto delete mode 100644 pkg/apis/manager/v1alpha2/api.swagger.json delete mode 100755 pkg/apis/manager/v1alpha2/build.sh delete mode 100644 pkg/apis/manager/v1alpha2/gen-doc/Dockerfile delete mode 100644 pkg/apis/manager/v1alpha2/gen-doc/api.md delete mode 100644 pkg/apis/manager/v1alpha2/gen-doc/index.html delete mode 100644 pkg/apis/manager/v1alpha2/python/api_pb2.py delete mode 100644 pkg/apis/manager/v1alpha2/python/api_pb2_grpc.py delete mode 100644 pkg/common/v1alpha2/common.go delete mode 100644 pkg/common/v1alpha2/katib_manager_util.go delete mode 100644 pkg/controller.v1alpha2/add_experiment.go delete mode 100644 pkg/controller.v1alpha2/add_trial.go delete mode 100644 pkg/controller.v1alpha2/consts/const.go delete mode 100644 pkg/controller.v1alpha2/controller.go delete mode 100644 pkg/controller.v1alpha2/experiment/experiment_controller.go delete mode 100644 pkg/controller.v1alpha2/experiment/experiment_controller_suite_test.go delete mode 100644 pkg/controller.v1alpha2/experiment/experiment_controller_test.go delete mode 100644 pkg/controller.v1alpha2/experiment/experiment_status.go delete mode 100644 pkg/controller.v1alpha2/experiment/experiment_util.go delete mode 100644 pkg/controller.v1alpha2/experiment/managerclient/managerclient.go delete mode 100644 pkg/controller.v1alpha2/experiment/manifest/generator.go delete mode 100644 pkg/controller.v1alpha2/experiment/manifest/generator_test.go delete mode 100644 pkg/controller.v1alpha2/experiment/suggestion/fake/fake.go delete mode 100644 pkg/controller.v1alpha2/experiment/suggestion/suggestion.go delete mode 100644 pkg/controller.v1alpha2/experiment/util/status_util.go delete mode 100644 pkg/controller.v1alpha2/trial/managerclient/managerclient.go delete mode 100644 pkg/controller.v1alpha2/trial/trial_controller.go delete mode 100644 pkg/controller.v1alpha2/trial/trial_controller_consts.go delete mode 100644 pkg/controller.v1alpha2/trial/trial_controller_status.go delete mode 100644 pkg/controller.v1alpha2/trial/trial_controller_suite_test.go delete mode 100644 pkg/controller.v1alpha2/trial/trial_controller_test.go delete mode 100644 pkg/controller.v1alpha2/trial/trial_controller_util.go delete mode 100644 pkg/db/v1alpha2/db_init.go delete mode 100644 pkg/db/v1alpha2/interface.go delete mode 100644 pkg/db/v1alpha2/interface_test.go delete mode 100644 pkg/mock/v1alpha2/api/manager.go delete mode 100644 pkg/mock/v1alpha2/api/suggestion.go delete mode 100644 pkg/mock/v1alpha2/db/db.go delete mode 100644 pkg/mock/v1alpha2/experiment/managerclient/managerclient.go delete mode 100644 pkg/mock/v1alpha2/experiment/manifest/generator.go delete mode 100644 pkg/mock/v1alpha2/experiment/suggestion/suggestion.go delete mode 100644 pkg/mock/v1alpha2/trial/managerclient/katibmanager.go delete mode 100644 pkg/mock/v1alpha2/util/katibclient/katibclient.go delete mode 100644 pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/AlgorithmSettings.py delete mode 100755 pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Controller.py delete mode 100755 pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/LSTM.py delete mode 100644 pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Operation.py delete mode 100644 pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/README.md delete mode 100644 pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Trainer.py delete mode 100644 pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/example.png delete mode 100644 pkg/suggestion/v1alpha2/__init__.py delete mode 100644 pkg/suggestion/v1alpha2/bayesian_service.py delete mode 100644 pkg/suggestion/v1alpha2/bayesianoptimization/src/__init__.py delete mode 100644 pkg/suggestion/v1alpha2/bayesianoptimization/src/acquisition_func.py delete mode 100644 pkg/suggestion/v1alpha2/bayesianoptimization/src/algorithm_manager.py delete mode 100644 pkg/suggestion/v1alpha2/bayesianoptimization/src/bayesian_optimization_algorithm.py delete mode 100644 pkg/suggestion/v1alpha2/bayesianoptimization/src/global_optimizer.py delete mode 100644 pkg/suggestion/v1alpha2/bayesianoptimization/src/model/__init__.py delete mode 100644 pkg/suggestion/v1alpha2/bayesianoptimization/src/model/gp.py delete mode 100644 pkg/suggestion/v1alpha2/bayesianoptimization/src/model/rf.py delete mode 100644 pkg/suggestion/v1alpha2/bayesianoptimization/src/utils.py delete mode 100644 pkg/suggestion/v1alpha2/grid_service.py delete mode 100644 pkg/suggestion/v1alpha2/hyperband_service.py delete mode 100644 pkg/suggestion/v1alpha2/nasrl_service.py delete mode 100644 pkg/suggestion/v1alpha2/parameter.py delete mode 100644 pkg/suggestion/v1alpha2/parsing_util.py delete mode 100644 pkg/suggestion/v1alpha2/random_service.py delete mode 100644 pkg/ui/v1alpha2/backend.go delete mode 100755 pkg/ui/v1alpha2/frontend/.gitignore delete mode 100755 pkg/ui/v1alpha2/frontend/README.md delete mode 100644 pkg/ui/v1alpha2/frontend/config/env.js delete mode 100644 pkg/ui/v1alpha2/frontend/config/jest/cssTransform.js delete mode 100644 pkg/ui/v1alpha2/frontend/config/jest/fileTransform.js delete mode 100644 pkg/ui/v1alpha2/frontend/config/paths.js delete mode 100644 pkg/ui/v1alpha2/frontend/config/webpack.config.js delete mode 100644 pkg/ui/v1alpha2/frontend/config/webpackDevServer.config.js delete mode 100644 pkg/ui/v1alpha2/frontend/package.json delete mode 100755 pkg/ui/v1alpha2/frontend/public/favicon.ico delete mode 100755 pkg/ui/v1alpha2/frontend/public/index.html delete mode 100644 pkg/ui/v1alpha2/frontend/public/logo.png delete mode 100755 pkg/ui/v1alpha2/frontend/public/manifest.json delete mode 100644 pkg/ui/v1alpha2/frontend/scripts/build.js delete mode 100644 pkg/ui/v1alpha2/frontend/scripts/start.js delete mode 100644 pkg/ui/v1alpha2/frontend/scripts/test.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/actions/generalActions.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/actions/hpCreateActions.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/actions/hpMonitorActions.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/actions/nasCreateActions.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/actions/nasMonitorActions.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/actions/templateActions.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/App.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Create/HP.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Create/HPParameters.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Algorithm.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/CommonMeta.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/CommonSpec.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Objective.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Parameters.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Trial.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Create/YAML.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/FilterPanel.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobInfo.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobList.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobMonitor.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobPlot.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobTable.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/TrialInfoDialog.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Menu/DeleteDialog.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Menu/Header.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Menu/Main.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Menu/Menu.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Menu/Snack.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Create/NAS.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Create/NASParameters.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Algorithm.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/CommonMeta.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/CommonSpec.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/NASConfig.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Objective.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Trial.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Create/YAML.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/FilterPanel.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobInfo.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobList.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobMonitor.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobStepInfo.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Templates/Collector.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Templates/Common/AddDialog.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Templates/Common/DeleteDialog.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Templates/Common/EditDialog.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Templates/Common/TemplateList.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Templates/Common/TemplatePanel.jsx delete mode 100644 pkg/ui/v1alpha2/frontend/src/components/Templates/Trial.jsx delete mode 100755 pkg/ui/v1alpha2/frontend/src/index.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/reducers/general.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/reducers/hpCreate.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/reducers/hpMonitor.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/reducers/index.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/reducers/nasCreate.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/reducers/nasMonitor.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/reducers/template.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/sagas/index.js delete mode 100755 pkg/ui/v1alpha2/frontend/src/serviceWorker.js delete mode 100644 pkg/ui/v1alpha2/frontend/src/store/index.js delete mode 100644 pkg/ui/v1alpha2/types.go delete mode 100644 pkg/ui/v1alpha2/util.go delete mode 100644 pkg/util/v1alpha2/katibclient/katib_client.go delete mode 100644 pkg/util/v1alpha2/metricscollector/metricscollector.go delete mode 100644 pkg/util/v1alpha2/tfevent-metricscollector/__init__.py delete mode 100644 pkg/util/v1alpha2/tfevent-metricscollector/tfevent_loader.py delete mode 100644 pkg/webhook/v1alpha2/experiment/mutate_webhook.go delete mode 100644 pkg/webhook/v1alpha2/experiment/validation_webhook.go delete mode 100644 pkg/webhook/v1alpha2/experiment/validator/validator.go delete mode 100644 pkg/webhook/v1alpha2/experiment/validator/validator_test.go delete mode 100644 pkg/webhook/v1alpha2/webhook.go delete mode 100755 scripts/v1alpha2/build.sh delete mode 100755 scripts/v1alpha2/deploy.sh delete mode 100755 scripts/v1alpha2/undeploy.sh delete mode 100644 test/e2e/v1alpha2/invalid-experiment.yaml delete mode 100644 test/e2e/v1alpha2/run-e2e-experiment.go delete mode 100644 test/e2e/v1alpha2/test-katib-manager.py delete mode 100644 test/e2e/v1alpha2/test_requirements.txt delete mode 100644 test/e2e/v1alpha2/valid-experiment.yaml delete mode 100755 test/scripts/v1alpha2/build-earlystopping-median.sh delete mode 100755 test/scripts/v1alpha2/build-katib-controller.sh delete mode 100755 test/scripts/v1alpha2/build-manager-rest.sh delete mode 100755 test/scripts/v1alpha2/build-manager.sh delete mode 100755 test/scripts/v1alpha2/build-suggestion-bo.sh delete mode 100755 test/scripts/v1alpha2/build-suggestion-grid.sh delete mode 100755 test/scripts/v1alpha2/build-suggestion-hyperband.sh delete mode 100755 test/scripts/v1alpha2/build-suggestion-nasenvelopenet.sh delete mode 100755 test/scripts/v1alpha2/build-suggestion-nasrl.sh delete mode 100755 test/scripts/v1alpha2/build-suggestion-random.sh delete mode 100755 test/scripts/v1alpha2/build-tc-nasrl-cifar10.sh delete mode 100755 test/scripts/v1alpha2/build-ui.sh delete mode 100755 test/scripts/v1alpha2/create-cluster.sh delete mode 100755 test/scripts/v1alpha2/delete-cluster.sh delete mode 100755 test/scripts/v1alpha2/python-tests.sh delete mode 100755 test/scripts/v1alpha2/run-tests.sh delete mode 100644 test/unit/v1alpha2/crds/pytorchjob_v1.yaml delete mode 100644 test/unit/v1alpha2/crds/tfjob_v1.yaml delete mode 100644 test/workflows/components/workflows-v1alpha2.jsonnet delete mode 100644 test/workflows/components/workflows-v1alpha2.libsonnet diff --git a/cmd/katib-controller/v1alpha2/Dockerfile b/cmd/katib-controller/v1alpha2/Dockerfile deleted file mode 100644 index b36e84e8964..00000000000 --- a/cmd/katib-controller/v1alpha2/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -# Build the manager binary -FROM golang:alpine AS build-env - -# Copy in the go src -ADD . /go/src/github.com/kubeflow/katib - -WORKDIR /go/src/github.com/kubeflow/katib/cmd/katib-controller -# Build -RUN if [ "$(uname -m)" = "ppc64le" ]; then \ - CGO_ENABLED=0 GOOS=linux GOARCH=ppc64le go build -a -o katib-controller ./v1alpha2; \ - elif [ "$(uname -m)" = "aarch64" ]; then \ - CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -a -o katib-controller ./v1alpha2; \ - else \ - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o katib-controller ./v1alpha2; \ - fi -# Copy the controller-manager into a thin image -FROM alpine:3.7 -WORKDIR /app -COPY --from=build-env /go/src/github.com/kubeflow/katib/cmd/katib-controller/katib-controller . -ENTRYPOINT ["./katib-controller"] diff --git a/cmd/katib-controller/v1alpha2/main.go b/cmd/katib-controller/v1alpha2/main.go deleted file mode 100644 index 251726a3157..00000000000 --- a/cmd/katib-controller/v1alpha2/main.go +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright 2018 The Kubeflow Authors -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* - Katib-controller is a controller (operator) for Experiments and Trials -*/ -package main - -import ( - "flag" - "os" - - "github.com/spf13/viper" - _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" - "sigs.k8s.io/controller-runtime/pkg/client/config" - "sigs.k8s.io/controller-runtime/pkg/manager" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - "sigs.k8s.io/controller-runtime/pkg/runtime/signals" - - apis "github.com/kubeflow/katib/pkg/apis/controller" - controller "github.com/kubeflow/katib/pkg/controller.v1alpha2" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/consts" - webhook "github.com/kubeflow/katib/pkg/webhook/v1alpha2" -) - -func main() { - logf.SetLogger(logf.ZapLogger(false)) - log := logf.Log.WithName("entrypoint") - - var experimentSuggestionName string - var metricsAddr string - - flag.StringVar(&experimentSuggestionName, "experiment-suggestion-name", - "default", "The implementation of suggestion interface in experiment controller (default|fake)") - flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") - - flag.Parse() - - viper.Set(consts.ConfigExperimentSuggestionName, experimentSuggestionName) - log.Info("Config:", - consts.ConfigExperimentSuggestionName, - viper.GetString(consts.ConfigExperimentSuggestionName)) - - // Get a config to talk to the apiserver - cfg, err := config.GetConfig() - if err != nil { - log.Error(err, "Fail to get the config") - os.Exit(1) - } - - // Create a new katib controller to provide shared dependencies and start components - mgr, err := manager.New(cfg, manager.Options{ - MetricsBindAddress: metricsAddr, - }) - if err != nil { - log.Error(err, "unable add APIs to scheme") - os.Exit(1) - } - - log.Info("Registering Components.") - - // Setup Scheme for all resources - if err := apis.AddToScheme(mgr.GetScheme()); err != nil { - log.Error(err, "Fail to create the manager") - os.Exit(1) - } - - // Setup all Controllers - log.Info("Setting up controller") - if err := controller.AddToManager(mgr); err != nil { - log.Error(err, "unable to register controllers to the manager") - os.Exit(1) - } - - log.Info("Setting up webhooks") - if err := webhook.AddToManager(mgr); err != nil { - log.Error(err, "unable to register webhooks to the manager") - os.Exit(1) - } - - // Start the Cmd - log.Info("Starting the Cmd.") - if err := mgr.Start(signals.SetupSignalHandler()); err != nil { - log.Error(err, "unable to run the manager") - os.Exit(1) - } -} diff --git a/cmd/manager-rest/v1alpha2/Dockerfile b/cmd/manager-rest/v1alpha2/Dockerfile deleted file mode 100644 index 3527bbcfa55..00000000000 --- a/cmd/manager-rest/v1alpha2/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM golang:alpine AS build-env -# The GOPATH in the image is /go. -ADD . /go/src/github.com/kubeflow/katib -WORKDIR /go/src/github.com/kubeflow/katib/cmd/manager-rest -RUN if [ "$(uname -m)" = "ppc64le" ] || [ "$(uname -m)" = "aarch64" ]; then \ - apk --update add gcc musl-dev && \ - go build -o katib-manager-rest ./v1alpha2; \ - else \ - go build -o katib-manager-rest ./v1alpha2; \ - fi - -FROM alpine:3.7 -WORKDIR /app -COPY --from=build-env /go/src/github.com/kubeflow/katib/cmd/manager-rest/katib-manager-rest /app/ -ENTRYPOINT ["./katib-manager-rest"] diff --git a/cmd/manager-rest/v1alpha2/proxy.go b/cmd/manager-rest/v1alpha2/proxy.go deleted file mode 100644 index 2fa1cb1df36..00000000000 --- a/cmd/manager-rest/v1alpha2/proxy.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "flag" - "net/http" - - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "golang.org/x/net/context" - "google.golang.org/grpc" - "k8s.io/klog" - - gw "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" -) - -var ( - katibManagerEndpoint = flag.String("echo_endpoint", "katib-manager:6789", "katib-manager endpoint") -) - -func run() error { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - mux := runtime.NewServeMux() - opts := []grpc.DialOption{grpc.WithInsecure()} - // register handlers for the HTTP endpoints - err := gw.RegisterManagerHandlerFromEndpoint(ctx, mux, *katibManagerEndpoint, opts) - if err != nil { - return err - } - - // proxy server listens on port 80 - return http.ListenAndServe(":80", mux) -} - -func main() { - flag.Parse() - defer klog.Flush() - - if err := run(); err != nil { - klog.Fatal(err) - } -} diff --git a/cmd/manager/v1alpha2/Dockerfile b/cmd/manager/v1alpha2/Dockerfile deleted file mode 100644 index 07d674b7dde..00000000000 --- a/cmd/manager/v1alpha2/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM golang:alpine AS build-env -# The GOPATH in the image is /go. -ADD . /go/src/github.com/kubeflow/katib -WORKDIR /go/src/github.com/kubeflow/katib/cmd/manager -RUN if [ "$(uname -m)" = "ppc64le" ] || [ "$(uname -m)" = "aarch64" ]; then \ - apk --update add git gcc musl-dev && \ - go build -o katib-manager ./v1alpha2 && \ - go get github.com/grpc-ecosystem/grpc-health-probe && \ - mv $GOPATH/bin/grpc-health-probe /bin/grpc_health_probe && \ - chmod +x /bin/grpc_health_probe; \ - else \ - go build -o katib-manager ./v1alpha2 && \ - GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \ - wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ - chmod +x /bin/grpc_health_probe; \ - fi - -FROM alpine:3.7 -WORKDIR /app -COPY --from=build-env /bin/grpc_health_probe /bin/ -COPY --from=build-env /go/src/github.com/kubeflow/katib/cmd/manager/katib-manager /app/ -ENTRYPOINT ["./katib-manager"] -CMD ["-w", "kubernetes"] diff --git a/cmd/manager/v1alpha2/main.go b/cmd/manager/v1alpha2/main.go deleted file mode 100644 index d7f7d2df72b..00000000000 --- a/cmd/manager/v1alpha2/main.go +++ /dev/null @@ -1,216 +0,0 @@ -package main - -import ( - "context" - "errors" - "flag" - "fmt" - "net" - - health_pb "github.com/kubeflow/katib/pkg/apis/manager/health" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - kdb "github.com/kubeflow/katib/pkg/db/v1alpha2" - "k8s.io/klog" - - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" -) - -const ( - port = "0.0.0.0:6789" -) - -var dbIf kdb.KatibDBInterface - -type server struct { -} - -// Register a Experiment to DB. -func (s *server) RegisterExperiment(ctx context.Context, in *api_pb.RegisterExperimentRequest) (*api_pb.RegisterExperimentReply, error) { - err := dbIf.RegisterExperiment(in.Experiment) - return &api_pb.RegisterExperimentReply{}, err -} - -// Register a Experiment to DB. -func (s *server) PreCheckRegisterExperiment(ctx context.Context, in *api_pb.RegisterExperimentRequest) (*api_pb.PreCheckRegisterExperimentReply, error) { - can_register, err := dbIf.PreCheckRegisterExperiment(in.Experiment) - return &api_pb.PreCheckRegisterExperimentReply{ - CanRegister: can_register, - }, err -} - -// Delete a Experiment from DB by name. -func (s *server) DeleteExperiment(ctx context.Context, in *api_pb.DeleteExperimentRequest) (*api_pb.DeleteExperimentReply, error) { - err := dbIf.DeleteExperiment(in.ExperimentName) - return &api_pb.DeleteExperimentReply{}, err -} - -// Get a Experiment from DB by name. -func (s *server) GetExperiment(ctx context.Context, in *api_pb.GetExperimentRequest) (*api_pb.GetExperimentReply, error) { - exp, err := dbIf.GetExperiment(in.ExperimentName) - return &api_pb.GetExperimentReply{ - Experiment: exp, - }, err -} - -// Get a summary list of Experiment from DB. -// The summary includes name and condition. -func (s *server) GetExperimentList(ctx context.Context, in *api_pb.GetExperimentListRequest) (*api_pb.GetExperimentListReply, error) { - expList, err := dbIf.GetExperimentList() - return &api_pb.GetExperimentListReply{ - ExperimentSummaries: expList, - }, err -} - -// Update Status of a experiment. -func (s *server) UpdateExperimentStatus(ctx context.Context, in *api_pb.UpdateExperimentStatusRequest) (*api_pb.UpdateExperimentStatusReply, error) { - err := dbIf.UpdateExperimentStatus(in.ExperimentName, in.NewStatus) - return &api_pb.UpdateExperimentStatusReply{}, err -} - -// Update AlgorithmExtraSettings. -// The ExtraSetting is created if it does not exist, otherwise it is overwrited. -func (s *server) UpdateAlgorithmExtraSettings(ctx context.Context, in *api_pb.UpdateAlgorithmExtraSettingsRequest) (*api_pb.UpdateAlgorithmExtraSettingsReply, error) { - err := dbIf.UpdateAlgorithmExtraSettings(in.ExperimentName, in.ExtraAlgorithmSettings) - return &api_pb.UpdateAlgorithmExtraSettingsReply{}, err -} - -// Get all AlgorithmExtraSettings. -func (s *server) GetAlgorithmExtraSettings(ctx context.Context, in *api_pb.GetAlgorithmExtraSettingsRequest) (*api_pb.GetAlgorithmExtraSettingsReply, error) { - eas, err := dbIf.GetAlgorithmExtraSettings(in.ExperimentName) - return &api_pb.GetAlgorithmExtraSettingsReply{ - ExtraAlgorithmSettings: eas, - }, err -} - -// Register a Trial to DB. -// ID will be filled by manager automatically. -func (s *server) RegisterTrial(ctx context.Context, in *api_pb.RegisterTrialRequest) (*api_pb.RegisterTrialReply, error) { - err := dbIf.RegisterTrial(in.Trial) - return &api_pb.RegisterTrialReply{}, err -} - -// Delete a Trial from DB by ID. -func (s *server) DeleteTrial(ctx context.Context, in *api_pb.DeleteTrialRequest) (*api_pb.DeleteTrialReply, error) { - err := dbIf.DeleteTrial(in.TrialName) - return &api_pb.DeleteTrialReply{}, err -} - -// Get a list of Trial from DB by name of a Experiment. -func (s *server) GetTrialList(ctx context.Context, in *api_pb.GetTrialListRequest) (*api_pb.GetTrialListReply, error) { - trList, err := dbIf.GetTrialList(in.ExperimentName, in.Filter) - return &api_pb.GetTrialListReply{ - Trials: trList, - }, err -} - -// Get a Trial from DB by ID of Trial. -func (s *server) GetTrial(ctx context.Context, in *api_pb.GetTrialRequest) (*api_pb.GetTrialReply, error) { - tr, err := dbIf.GetTrial(in.TrialName) - return &api_pb.GetTrialReply{ - Trial: tr, - }, err -} - -// Update Status of a trial. -func (s *server) UpdateTrialStatus(ctx context.Context, in *api_pb.UpdateTrialStatusRequest) (*api_pb.UpdateTrialStatusReply, error) { - err := dbIf.UpdateTrialStatus(in.TrialName, in.NewStatus) - return &api_pb.UpdateTrialStatusReply{}, err -} - -// Report a log of Observations for a Trial. -// The log consists of timestamp and value of metric. -// Katib store every log of metrics. -// You can see accuracy curve or other metric logs on UI. -func (s *server) ReportObservationLog(ctx context.Context, in *api_pb.ReportObservationLogRequest) (*api_pb.ReportObservationLogReply, error) { - err := dbIf.RegisterObservationLog(in.TrialName, in.ObservationLog) - return &api_pb.ReportObservationLogReply{}, err -} - -// Get all log of Observations for a Trial. -func (s *server) GetObservationLog(ctx context.Context, in *api_pb.GetObservationLogRequest) (*api_pb.GetObservationLogReply, error) { - ol, err := dbIf.GetObservationLog(in.TrialName, in.MetricName, in.StartTime, in.EndTime) - return &api_pb.GetObservationLogReply{ - ObservationLog: ol, - }, err -} - -func (s *server) getSuggestionServiceConnection(algoName string) (*grpc.ClientConn, error) { - if algoName == "" { - return nil, errors.New("No algorithm name is specified") - } - return grpc.Dial("katib-suggestion-"+algoName+":6789", grpc.WithInsecure()) -} - -// Get Suggestions from a Suggestion service. -func (s *server) GetSuggestions(ctx context.Context, in *api_pb.GetSuggestionsRequest) (*api_pb.GetSuggestionsReply, error) { - conn, err := s.getSuggestionServiceConnection(in.AlgorithmName) - if err != nil { - return &api_pb.GetSuggestionsReply{Trials: []*api_pb.Trial{}}, err - } - defer conn.Close() - c := api_pb.NewSuggestionClient(conn) - r, err := c.GetSuggestions(ctx, in) - if err != nil { - return &api_pb.GetSuggestionsReply{Trials: []*api_pb.Trial{}}, err - } - return r, nil -} - -// Validate AlgorithmSettings in an Experiment. -// Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid -func (s *server) ValidateAlgorithmSettings(ctx context.Context, in *api_pb.ValidateAlgorithmSettingsRequest) (*api_pb.ValidateAlgorithmSettingsReply, error) { - conn, err := s.getSuggestionServiceConnection(in.AlgorithmName) - if err != nil { - return &api_pb.ValidateAlgorithmSettingsReply{}, err - } - defer conn.Close() - c := api_pb.NewSuggestionClient(conn) - return c.ValidateAlgorithmSettings(ctx, in) -} - -func (s *server) Check(ctx context.Context, in *health_pb.HealthCheckRequest) (*health_pb.HealthCheckResponse, error) { - resp := health_pb.HealthCheckResponse{ - Status: health_pb.HealthCheckResponse_SERVING, - } - - // We only accept optional service name only if it's set to suggested format. - if in != nil && in.Service != "" && in.Service != "grpc.health.v1.Health" { - resp.Status = health_pb.HealthCheckResponse_UNKNOWN - return &resp, fmt.Errorf("grpc.health.v1.Health can only be accepted if you specify service name.") - } - - // Check if connection to katib-db is okay since otherwise manager could not serve most of its methods. - err := dbIf.SelectOne() - if err != nil { - resp.Status = health_pb.HealthCheckResponse_NOT_SERVING - return &resp, fmt.Errorf("Failed to execute `SELECT 1` probe: %v", err) - } - - return &resp, nil -} - -func main() { - flag.Parse() - var err error - - dbIf, err = kdb.New() - if err != nil { - klog.Fatalf("Failed to open db connection: %v", err) - } - dbIf.DBInit() - listener, err := net.Listen("tcp", port) - if err != nil { - klog.Fatalf("Failed to listen: %v", err) - } - - size := 1<<31 - 1 - klog.Infof("Start Katib manager: %s", port) - s := grpc.NewServer(grpc.MaxRecvMsgSize(size), grpc.MaxSendMsgSize(size)) - api_pb.RegisterManagerServer(s, &server{}) - health_pb.RegisterHealthServer(s, &server{}) - reflection.Register(s) - if err = s.Serve(listener); err != nil { - klog.Fatalf("Failed to serve: %v", err) - } -} diff --git a/cmd/manager/v1alpha2/main_test.go b/cmd/manager/v1alpha2/main_test.go deleted file mode 100644 index fbe8b587300..00000000000 --- a/cmd/manager/v1alpha2/main_test.go +++ /dev/null @@ -1,612 +0,0 @@ -package main - -import ( - "context" - "testing" - - "github.com/golang/mock/gomock" - - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - mockdb "github.com/kubeflow/katib/pkg/mock/v1alpha2/db" -) - -func TestRegisterExperiment(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.RegisterExperimentRequest{ - Experiment: &api_pb.Experiment{ - Name: "testExp", - Spec: &api_pb.ExperimentSpec{ - ParameterSpecs: &api_pb.ExperimentSpec_ParameterSpecs{ - Parameters: []*api_pb.ParameterSpec{}, - }, - Objective: &api_pb.ObjectiveSpec{ - Type: api_pb.ObjectiveType_UNKNOWN, - Goal: 0.99, - ObjectiveMetricName: "f1_score", - AdditionalMetricNames: []string{"loss", "precision", "recall"}, - }, - Algorithm: &api_pb.AlgorithmSpec{}, - TrialTemplate: "", - ParallelTrialCount: 10, - MaxTrialCount: 100, - }, - Status: &api_pb.ExperimentStatus{ - Condition: api_pb.ExperimentStatus_CREATED, - StartTime: "2019-02-03T04:05:06+09:00", - CompletionTime: "", - }, - }, - } - mockDB.EXPECT().RegisterExperiment(req.Experiment).Return(nil) - _, err := s.RegisterExperiment(context.Background(), req) - if err != nil { - t.Fatalf("RegisterExperiment Error %v", err) - } -} - -func TestDeleteExperiment(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.DeleteExperimentRequest{ - ExperimentName: "testExp", - } - mockDB.EXPECT().DeleteExperiment(req.ExperimentName).Return(nil) - _, err := s.DeleteExperiment(context.Background(), req) - if err != nil { - t.Fatalf("DeleteExperiment Error %v", err) - } -} - -func TestGetExperiment(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - req := &api_pb.GetExperimentRequest{ - ExperimentName: "testExp", - } - - testExp := api_pb.Experiment{ - Name: "testExp", - Spec: &api_pb.ExperimentSpec{ - ParameterSpecs: &api_pb.ExperimentSpec_ParameterSpecs{ - Parameters: []*api_pb.ParameterSpec{}, - }, - Objective: &api_pb.ObjectiveSpec{ - Type: api_pb.ObjectiveType_UNKNOWN, - Goal: 0.99, - ObjectiveMetricName: "f1_score", - AdditionalMetricNames: []string{"loss", "precision", "recall"}, - }, - Algorithm: &api_pb.AlgorithmSpec{}, - TrialTemplate: "", - ParallelTrialCount: 10, - MaxTrialCount: 100, - }, - Status: &api_pb.ExperimentStatus{ - Condition: api_pb.ExperimentStatus_CREATED, - StartTime: "2019-02-03T04:05:06+09:00", - CompletionTime: "", - }, - } - mockDB.EXPECT().GetExperiment(req.ExperimentName).Return(&testExp, nil) - ret, err := s.GetExperiment(context.Background(), req) - if ret.Experiment.Name != testExp.Name { - t.Fatalf("GetExperiment Test fail expect experiment name %s got %s", ret.Experiment.Name, testExp.Name) - } - if err != nil { - t.Fatalf("GetExperiment Error %v", err) - } -} - -func TestGetExperimentList(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - req := &api_pb.GetExperimentListRequest{} - - testExpList := []*api_pb.ExperimentSummary{ - { - ExperimentName: "test1", - Status: &api_pb.ExperimentStatus{ - Condition: api_pb.ExperimentStatus_CREATED, - StartTime: "2019-02-03T04:05:06+09:00", - CompletionTime: "", - }, - }, - { - ExperimentName: "test2", - Status: &api_pb.ExperimentStatus{ - Condition: api_pb.ExperimentStatus_SUCCEEDED, - StartTime: "2019-02-03T04:02:06+09:00", - CompletionTime: "2019-02-03T04:03:06+09:00", - }, - }, - } - mockDB.EXPECT().GetExperimentList().Return(testExpList, nil) - ret, err := s.GetExperimentList(context.Background(), req) - if len(ret.ExperimentSummaries) != len(testExpList) { - t.Fatalf("GetExperimentList Test fail expect experiment number %d got %d", len(testExpList), len(ret.ExperimentSummaries)) - } - if err != nil { - t.Fatalf("GetExperimentList Error %v", err) - } -} - -func TestUpdateExperimentStatus(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.UpdateExperimentStatusRequest{ - ExperimentName: "test1", - NewStatus: &api_pb.ExperimentStatus{ - Condition: api_pb.ExperimentStatus_RUNNING, - StartTime: "2019-02-03T04:05:06+09:00", - CompletionTime: "", - }, - } - mockDB.EXPECT().UpdateExperimentStatus(req.ExperimentName, req.NewStatus).Return(nil) - _, err := s.UpdateExperimentStatus(context.Background(), req) - if err != nil { - t.Fatalf("UpdateExperimentStatus Error %v", err) - } -} - -func TestUpdateAlgorithmExtraSettings(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.UpdateAlgorithmExtraSettingsRequest{ - ExperimentName: "test1", - ExtraAlgorithmSettings: []*api_pb.AlgorithmSetting{ - { - Name: "set1", - Value: "10", - }, - { - Name: "set2", - Value: "0.5", - }, - }, - } - mockDB.EXPECT().UpdateAlgorithmExtraSettings(req.ExperimentName, req.ExtraAlgorithmSettings).Return(nil) - _, err := s.UpdateAlgorithmExtraSettings(context.Background(), req) - if err != nil { - t.Fatalf("UpdateAlgorithmExtraSettings Error %v", err) - } -} - -func TestGetAlgorithmExtraSettings(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.GetAlgorithmExtraSettingsRequest{ - ExperimentName: "test1", - } - extraAlgoSets := []*api_pb.AlgorithmSetting{ - { - Name: "set1", - Value: "10", - }, - { - Name: "set2", - Value: "0.5", - }, - } - mockDB.EXPECT().GetAlgorithmExtraSettings(req.ExperimentName).Return(extraAlgoSets, nil) - ret, err := s.GetAlgorithmExtraSettings(context.Background(), req) - if len(ret.ExtraAlgorithmSettings) != len(extraAlgoSets) { - t.Fatalf("GetAlgorithmExtraSettings Test fail expect experiment number %d got %d", len(extraAlgoSets), len(ret.ExtraAlgorithmSettings)) - } - if err != nil { - t.Fatalf("UpdateAlgorithmExtraSettings Error %v", err) - } -} - -func TestRegisterTrial(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.RegisterTrialRequest{ - Trial: &api_pb.Trial{ - Name: "test1-trial1", - Spec: &api_pb.TrialSpec{ - ExperimentName: "test1", - RunSpec: "", - ParameterAssignments: &api_pb.TrialSpec_ParameterAssignments{ - Assignments: []*api_pb.ParameterAssignment{ - { - Name: "param1", - Value: "10", - }, - { - Name: "param2", - Value: "0.1", - }, - }, - }, - }, - Status: &api_pb.TrialStatus{ - Condition: api_pb.TrialStatus_RUNNING, - StartTime: "2019-02-03T04:05:06+09:00", - CompletionTime: "", - Observation: &api_pb.Observation{ - Metrics: []*api_pb.Metric{ - { - Name: "f1_score", - Value: "88.95", - }, - { - Name: "loss", - Value: "0.5", - }, - { - Name: "precision", - Value: "88.7", - }, - { - Name: "recall", - Value: "89.2", - }, - }, - }, - }, - }, - } - mockDB.EXPECT().RegisterTrial(req.Trial).Return(nil) - _, err := s.RegisterTrial(context.Background(), req) - if err != nil { - t.Fatalf("RegisterTrial Error %v", err) - } -} - -func TestDeleteTrial(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.DeleteTrialRequest{ - TrialName: "test1-trial1", - } - mockDB.EXPECT().DeleteTrial(req.TrialName).Return(nil) - _, err := s.DeleteTrial(context.Background(), req) - if err != nil { - t.Fatalf("DeleteTrial Error %v", err) - } -} - -func TestGetTrialList(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.GetTrialListRequest{ - ExperimentName: "test1", - Filter: "trial", - } - trialList := []*api_pb.Trial{ - { - Name: "test1-trial1", - Spec: &api_pb.TrialSpec{ - ExperimentName: "test1", - RunSpec: "", - ParameterAssignments: &api_pb.TrialSpec_ParameterAssignments{ - Assignments: []*api_pb.ParameterAssignment{ - { - Name: "param1", - Value: "10", - }, - { - Name: "param2", - Value: "0.1", - }, - }, - }, - }, - Status: &api_pb.TrialStatus{ - Condition: api_pb.TrialStatus_RUNNING, - StartTime: "2019-02-03T04:05:06+09:00", - CompletionTime: "", - Observation: &api_pb.Observation{ - Metrics: []*api_pb.Metric{ - { - Name: "f1_score", - Value: "88.95", - }, - { - Name: "loss", - Value: "0.5", - }, - { - Name: "precision", - Value: "88.7", - }, - { - Name: "recall", - Value: "89.2", - }, - }, - }, - }, - }, - { - Name: "test1-trial2", - Spec: &api_pb.TrialSpec{ - ExperimentName: "test1", - RunSpec: "", - ParameterAssignments: &api_pb.TrialSpec_ParameterAssignments{ - Assignments: []*api_pb.ParameterAssignment{ - { - Name: "param1", - Value: "20", - }, - { - Name: "param2", - Value: "0.5", - }, - }, - }, - }, - Status: &api_pb.TrialStatus{ - Condition: api_pb.TrialStatus_CREATED, - StartTime: "", - CompletionTime: "", - Observation: &api_pb.Observation{ - Metrics: []*api_pb.Metric{}, - }, - }, - }, - } - mockDB.EXPECT().GetTrialList(req.ExperimentName, "trial").Return(trialList, nil) - ret, err := s.GetTrialList(context.Background(), req) - if len(ret.Trials) != len(trialList) { - t.Fatalf("GetTrialList Test fail expect tiral number %d got %d", len(trialList), len(ret.Trials)) - } - if err != nil { - t.Fatalf("GetTrialList Error %v", err) - } - -} - -func TestGetTrial(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - req := &api_pb.GetTrialRequest{ - TrialName: "test1-trial1", - } - - trial := &api_pb.Trial{ - Name: "test1-trial1", - Spec: &api_pb.TrialSpec{ - ExperimentName: "test1", - RunSpec: "", - ParameterAssignments: &api_pb.TrialSpec_ParameterAssignments{ - Assignments: []*api_pb.ParameterAssignment{ - { - Name: "param1", - Value: "10", - }, - { - Name: "param2", - Value: "0.1", - }, - }, - }, - }, - Status: &api_pb.TrialStatus{ - Condition: api_pb.TrialStatus_RUNNING, - StartTime: "2019-02-03T04:05:06+09:00", - CompletionTime: "", - Observation: &api_pb.Observation{ - Metrics: []*api_pb.Metric{ - { - Name: "f1_score", - Value: "88.95", - }, - { - Name: "loss", - Value: "0.5", - }, - { - Name: "precision", - Value: "88.7", - }, - { - Name: "recall", - Value: "89.2", - }, - }, - }, - }, - } - mockDB.EXPECT().GetTrial(req.TrialName).Return(trial, nil) - ret, err := s.GetTrial(context.Background(), req) - if ret.Trial.Name != trial.Name { - t.Fatalf("GetTrial Test fail expect tiral %s got %s", trial.Name, ret.Trial.Name) - } - if err != nil { - t.Fatalf("GetTrial Error %v", err) - } -} - -func TestUpdateTrialStatus(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.UpdateTrialStatusRequest{ - TrialName: "test1-trial1", - NewStatus: &api_pb.TrialStatus{ - Condition: api_pb.TrialStatus_SUCCEEDED, - StartTime: "2019-02-03T04:05:06+09:00", - CompletionTime: "2019-02-03T05:05:06+09:00", - Observation: &api_pb.Observation{ - Metrics: []*api_pb.Metric{ - { - Name: "f1_score", - Value: "88.95", - }, - { - Name: "loss", - Value: "0.5", - }, - { - Name: "precision", - Value: "88.7", - }, - { - Name: "recall", - Value: "89.2", - }, - }, - }, - }, - } - mockDB.EXPECT().UpdateTrialStatus(req.TrialName, req.NewStatus).Return(nil) - _, err := s.UpdateTrialStatus(context.Background(), req) - if err != nil { - t.Fatalf("UpdateTrialStatus Error %v", err) - } -} - -func TestReportObservationLog(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.ReportObservationLogRequest{ - TrialName: "test1-trial1", - ObservationLog: &api_pb.ObservationLog{ - MetricLogs: []*api_pb.MetricLog{ - { - TimeStamp: "2019-02-03T04:05:06+09:00", - Metric: &api_pb.Metric{ - Name: "f1_score", - Value: "88.95", - }, - }, - { - TimeStamp: "2019-02-03T04:05:06+09:00", - Metric: &api_pb.Metric{ - Name: "loss", - Value: "0.5", - }, - }, - { - TimeStamp: "2019-02-03T04:05:06+09:00", - Metric: &api_pb.Metric{ - Name: "precision", - Value: "88.7", - }, - }, - { - TimeStamp: "2019-02-03T04:05:06+09:00", - Metric: &api_pb.Metric{ - Name: "recall", - Value: "89.2", - }, - }, - }, - }, - } - mockDB.EXPECT().RegisterObservationLog(req.TrialName, req.ObservationLog).Return(nil) - _, err := s.ReportObservationLog(context.Background(), req) - if err != nil { - t.Fatalf("ReportObservationLog Error %v", err) - } -} - -func TestGetObservationLog(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - s := &server{} - mockDB := mockdb.NewMockKatibDBInterface(ctrl) - dbIf = mockDB - - req := &api_pb.GetObservationLogRequest{ - TrialName: "test1-trial1", - StartTime: "2019-02-03T03:05:06+09:00", - EndTime: "2019-02-03T05:05:06+09:00", - } - - obs := &api_pb.ObservationLog{ - MetricLogs: []*api_pb.MetricLog{ - { - TimeStamp: "2019-02-03T04:05:06+09:00", - Metric: &api_pb.Metric{ - Name: "f1_score", - Value: "88.95", - }, - }, - { - TimeStamp: "2019-02-03T04:05:06+09:00", - Metric: &api_pb.Metric{ - Name: "loss", - Value: "0.5", - }, - }, - { - TimeStamp: "2019-02-03T04:05:06+09:00", - Metric: &api_pb.Metric{ - Name: "precision", - Value: "88.7", - }, - }, - { - TimeStamp: "2019-02-03T04:05:06+09:00", - Metric: &api_pb.Metric{ - Name: "recall", - Value: "89.2", - }, - }, - }, - } - - mockDB.EXPECT().GetObservationLog(req.TrialName, req.MetricName, req.StartTime, req.EndTime).Return(obs, nil) - ret, err := s.GetObservationLog(context.Background(), req) - if err != nil { - t.Fatalf("GetObservationLog Error %v", err) - } - if len(obs.MetricLogs) != len(ret.ObservationLog.MetricLogs) { - t.Fatalf("GetObservationLog Test fail expect metrics number %d got %d", len(obs.MetricLogs), len(ret.ObservationLog.MetricLogs)) - } -} -func TestGetSuggestions(t *testing.T) { -} -func TestValidateAlgorithmSettings(t *testing.T) { -} diff --git a/cmd/metricscollector/v1alpha2/Dockerfile b/cmd/metricscollector/v1alpha2/Dockerfile deleted file mode 100644 index cd81358eeeb..00000000000 --- a/cmd/metricscollector/v1alpha2/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -# Build the manager binary -FROM golang:alpine AS build-env - -# Copy in the go src -ADD . /go/src/github.com/kubeflow/katib - -WORKDIR /go/src/github.com/kubeflow/katib/cmd/metricscollector - -# Build -RUN if [ "$(uname -m)" = "ppc64le" ]; then \ - CGO_ENABLED=0 GOOS=linux GOARCH=ppc64le go build -a -o metricscollector ./v1alpha2; \ - elif [ "$(uname -m)" = "aarch64" ]; then \ - CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -a -o metricscollector ./v1alpha2; \ - else \ - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o metricscollector ./v1alpha2; \ - fi - -# Copy the controller-manager into a thin image -FROM alpine:3.7 -WORKDIR /app -COPY --from=build-env /go/src/github.com/kubeflow/katib/cmd/metricscollector/metricscollector . -ENTRYPOINT ["./metricscollector"] diff --git a/cmd/metricscollector/v1alpha2/main.go b/cmd/metricscollector/v1alpha2/main.go deleted file mode 100644 index 4b7ad53a8f6..00000000000 --- a/cmd/metricscollector/v1alpha2/main.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2018 The Kubeflow Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -MetricsCollector is a default metricscollector for worker. -It will collect metrics from pod log. -You should print metrics in {{MetricsName}}={{MetricsValue}} format. -For example, the objective value name is F1 and the metrics are loss, your training code should print like below. - --- - epoch 1: - batch1 loss=0.8 - batch2 loss=0.6 - - F1=0.4 - - epoch 2: - batch1 loss=0.4 - batch2 loss=0.2 - - F1=0.7 - --- -The metrics collector will collect all logs of metrics. -*/ - -package main - -import ( - "context" - "flag" - "strings" - - "google.golang.org/grpc" - "k8s.io/klog" - - api "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - "github.com/kubeflow/katib/pkg/util/v1alpha2/metricscollector" -) - -var experimentName = flag.String("e", "", "Experiment Name") -var trialName = flag.String("t", "", "Trial Name") -var jobKind = flag.String("k", "", "Job Kind") -var namespace = flag.String("n", "", "NameSpace") -var managerService = flag.String("m", "", "Katib Manager service") -var metricNames = flag.String("mn", "", "Metric names") - -func main() { - flag.Parse() - klog.Infof("Experiment Name: %s, Trial Name: %s, Job Kind: %s", *experimentName, *trialName, *jobKind) - conn, err := grpc.Dial(*managerService, grpc.WithInsecure()) - if err != nil { - klog.Fatalf("could not connect: %v", err) - } - defer conn.Close() - c := api.NewManagerClient(conn) - mc, err := metricscollector.NewMetricsCollector() - if err != nil { - klog.Fatalf("Failed to create MetricsCollector: %v", err) - } - ctx := context.Background() - olog, err := mc.CollectObservationLog(*trialName, *jobKind, strings.Split(*metricNames, ";"), *namespace) - if err != nil { - klog.Fatalf("Failed to collect logs: %v", err) - } - reportreq := &api.ReportObservationLogRequest{ - TrialName: *trialName, - ObservationLog: olog, - } - _, err = c.ReportObservationLog(ctx, reportreq) - if err != nil { - klog.Fatalf("Failed to Report logs: %v", err) - } - klog.Infof("Metrics reported. :\n%v", olog) - return -} diff --git a/cmd/suggestion/bayesianoptimization/v1alpha2/Dockerfile b/cmd/suggestion/bayesianoptimization/v1alpha2/Dockerfile deleted file mode 100644 index a89e043acce..00000000000 --- a/cmd/suggestion/bayesianoptimization/v1alpha2/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM python:3.6 - -ADD . /usr/src/app/github.com/kubeflow/katib -WORKDIR /usr/src/app/github.com/kubeflow/katib/cmd/suggestion/bayesianoptimization/v1alpha2 -RUN if [ "$(uname -m)" = "ppc64le" ] || [ "$(uname -m)" = "aarch64" ]; then \ - apt-get update && apt-get -y install libblas-dev liblapack-dev libatlas-base-dev gfortran && \ - pip install cython; \ - fi -RUN pip install --no-cache-dir -r requirements.txt -ENV PYTHONPATH /usr/src/app/github.com/kubeflow/katib:/usr/src/app/github.com/kubeflow/katib/pkg/apis/manager/v1alpha2/python - -ENTRYPOINT ["python", "main.py"] diff --git a/cmd/suggestion/bayesianoptimization/v1alpha2/README.md b/cmd/suggestion/bayesianoptimization/v1alpha2/README.md deleted file mode 100644 index 89788a8ae67..00000000000 --- a/cmd/suggestion/bayesianoptimization/v1alpha2/README.md +++ /dev/null @@ -1,14 +0,0 @@ -- start the service - -``` -python suggestion/bayesian/main.py -``` - -- start the testing client - -``` -python suggestion/test_client.py -``` - -note: -the testing client uses the [Franke's function](http://www.sfu.ca/~ssurjano/franke2d.html) as the black box, and the maximum of Franke's function is around 1.22 diff --git a/cmd/suggestion/bayesianoptimization/v1alpha2/__init__.py b/cmd/suggestion/bayesianoptimization/v1alpha2/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/cmd/suggestion/bayesianoptimization/v1alpha2/main.py b/cmd/suggestion/bayesianoptimization/v1alpha2/main.py deleted file mode 100644 index 1860ddf4738..00000000000 --- a/cmd/suggestion/bayesianoptimization/v1alpha2/main.py +++ /dev/null @@ -1,25 +0,0 @@ -import grpc -from concurrent import futures - -import time - -from pkg.apis.manager.v1alpha2.python import api_pb2_grpc -from pkg.suggestion.v1alpha2.bayesian_service import BayesianService - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 -DEFAULT_PORT = "0.0.0.0:6789" - -def serve(): - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) - api_pb2_grpc.add_SuggestionServicer_to_server(BayesianService(), server) - server.add_insecure_port(DEFAULT_PORT) - print("Listening...") - server.start() - try: - while True: - time.sleep(_ONE_DAY_IN_SECONDS) - except KeyboardInterrupt: - server.stop(0) - -if __name__ == "__main__": - serve() diff --git a/cmd/suggestion/bayesianoptimization/v1alpha2/requirements.txt b/cmd/suggestion/bayesianoptimization/v1alpha2/requirements.txt deleted file mode 100644 index 8d2c9d4bda7..00000000000 --- a/cmd/suggestion/bayesianoptimization/v1alpha2/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -grpcio -duecredit -cloudpickle==0.5.6 -numpy>=1.13.3 -scikit-learn>=0.19.0 -scipy>=0.19.1 -forestci -protobuf -googleapis-common-protos diff --git a/cmd/suggestion/grid/v1alpha2/Dockerfile b/cmd/suggestion/grid/v1alpha2/Dockerfile deleted file mode 100644 index 03cf4b21223..00000000000 --- a/cmd/suggestion/grid/v1alpha2/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.6 - -ADD . /usr/src/app/github.com/kubeflow/katib -WORKDIR /usr/src/app/github.com/kubeflow/katib/cmd/suggestion/grid/v1alpha2 -RUN if [ "$(uname -m)" = "ppc64le" ] || [ "$(uname -m)" = "aarch64" ]; then \ - apt-get -y update && \ - apt-get -y install gfortran libopenblas-dev liblapack-dev && \ - pip install cython; \ - fi -RUN pip install --no-cache-dir -r requirements.txt -ENV PYTHONPATH /usr/src/app/github.com/kubeflow/katib:/usr/src/app/github.com/kubeflow/katib/pkg/apis/manager/v1alpha2/python - -ENTRYPOINT ["python", "main.py"] diff --git a/cmd/suggestion/grid/v1alpha2/__init__.py b/cmd/suggestion/grid/v1alpha2/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/cmd/suggestion/grid/v1alpha2/main.py b/cmd/suggestion/grid/v1alpha2/main.py deleted file mode 100644 index 7a58f44ca47..00000000000 --- a/cmd/suggestion/grid/v1alpha2/main.py +++ /dev/null @@ -1,23 +0,0 @@ -import grpc -import time -from pkg.apis.manager.v1alpha2.python import api_pb2_grpc -from pkg.suggestion.v1alpha2.grid_service import GridService -from concurrent import futures - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 -DEFAULT_PORT = "0.0.0.0:6789" - -def serve(): - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) - api_pb2_grpc.add_SuggestionServicer_to_server(GridService(), server) - server.add_insecure_port(DEFAULT_PORT) - print("Listening...") - server.start() - try: - while True: - time.sleep(_ONE_DAY_IN_SECONDS) - except KeyboardInterrupt: - server.stop(0) - -if __name__ == "__main__": - serve() diff --git a/cmd/suggestion/grid/v1alpha2/requirements.txt b/cmd/suggestion/grid/v1alpha2/requirements.txt deleted file mode 100644 index 8d2c9d4bda7..00000000000 --- a/cmd/suggestion/grid/v1alpha2/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -grpcio -duecredit -cloudpickle==0.5.6 -numpy>=1.13.3 -scikit-learn>=0.19.0 -scipy>=0.19.1 -forestci -protobuf -googleapis-common-protos diff --git a/cmd/suggestion/hyperband/v1alpha2/Dockerfile b/cmd/suggestion/hyperband/v1alpha2/Dockerfile deleted file mode 100644 index 6ba92835ad8..00000000000 --- a/cmd/suggestion/hyperband/v1alpha2/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.6 - -ADD . /usr/src/app/github.com/kubeflow/katib -WORKDIR /usr/src/app/github.com/kubeflow/katib/cmd/suggestion/hyperband/v1alpha2 -RUN if [ "$(uname -m)" = "ppc64le" ] || [ "$(uname -m)" = "aarch64" ]; then \ - apt-get -y update && \ - apt-get -y install gfortran libopenblas-dev liblapack-dev && \ - pip install cython; \ - fi -RUN pip install --no-cache-dir -r requirements.txt -ENV PYTHONPATH /usr/src/app/github.com/kubeflow/katib:/usr/src/app/github.com/kubeflow/katib/pkg/apis/manager/v1alpha2/python - -ENTRYPOINT ["python", "main.py"] diff --git a/cmd/suggestion/hyperband/v1alpha2/__init__.py b/cmd/suggestion/hyperband/v1alpha2/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/cmd/suggestion/hyperband/v1alpha2/main.py b/cmd/suggestion/hyperband/v1alpha2/main.py deleted file mode 100644 index d005e3569cb..00000000000 --- a/cmd/suggestion/hyperband/v1alpha2/main.py +++ /dev/null @@ -1,23 +0,0 @@ -import grpc -import time -from pkg.apis.manager.v1alpha2.python import api_pb2_grpc -from pkg.suggestion.v1alpha2.hyperband_service import HyperbandService -from concurrent import futures - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 -DEFAULT_PORT = "0.0.0.0:6789" - -def serve(): - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) - api_pb2_grpc.add_SuggestionServicer_to_server(HyperbandService(), server) - server.add_insecure_port(DEFAULT_PORT) - print("Listening...") - server.start() - try: - while True: - time.sleep(_ONE_DAY_IN_SECONDS) - except KeyboardInterrupt: - server.stop(0) - -if __name__ == "__main__": - serve() diff --git a/cmd/suggestion/hyperband/v1alpha2/requirements.txt b/cmd/suggestion/hyperband/v1alpha2/requirements.txt deleted file mode 100644 index 8d2c9d4bda7..00000000000 --- a/cmd/suggestion/hyperband/v1alpha2/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -grpcio -duecredit -cloudpickle==0.5.6 -numpy>=1.13.3 -scikit-learn>=0.19.0 -scipy>=0.19.1 -forestci -protobuf -googleapis-common-protos diff --git a/cmd/suggestion/nasrl/v1alpha2/Dockerfile b/cmd/suggestion/nasrl/v1alpha2/Dockerfile deleted file mode 100644 index 6111fdcbd1f..00000000000 --- a/cmd/suggestion/nasrl/v1alpha2/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM python:3.6 - -ADD . /usr/src/app/github.com/kubeflow/katib -WORKDIR /usr/src/app/github.com/kubeflow/katib/cmd/suggestion/nasrl/v1alpha2 -RUN pip install https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.12.0-cp36-cp36m-linux_x86_64.whl -RUN pip install --no-cache-dir -r requirements.txt -ENV PYTHONPATH /usr/src/app/github.com/kubeflow/katib:/usr/src/app/github.com/kubeflow/katib/pkg/apis/manager/v1alpha2/python - -ENTRYPOINT ["python", "-u", "main.py"] diff --git a/cmd/suggestion/nasrl/v1alpha2/Dockerfile.aarch64 b/cmd/suggestion/nasrl/v1alpha2/Dockerfile.aarch64 deleted file mode 100644 index 26b8a3748b3..00000000000 --- a/cmd/suggestion/nasrl/v1alpha2/Dockerfile.aarch64 +++ /dev/null @@ -1,92 +0,0 @@ -FROM ubuntu:18.04 - -#install bazel -RUN apt-get update \ - && apt-get install -y software-properties-common \ - build-essential \ - curl \ - openjdk-8-jdk \ - openjdk-8-jre-headless \ - pkg-config \ - zip \ - g++ \ - wget \ - git \ - zlib1g-dev \ - unzip \ - python3.6 \ - python3-pip \ - python3.6-dev \ - python3-setuptools \ - libhdf5-serial-dev \ - libcurl3-dev \ - libfreetype6-dev \ - libzmq3-dev \ - rsync \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -#set default python as python3 -RUN ln -s /usr/bin/python3.6 /usr/bin/python && ln -s /usr/bin/pip3 /usr/bin/pip - -ENV BAZEL_VERSION=0.18.1 - -RUN mkdir -p /bazel \ - && cd /bazel \ - && curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-dist.zip \ - && unzip bazel-$BAZEL_VERSION-dist.zip \ - && ./compile.sh \ - && cp output/bazel /usr/local/bin \ - && rm -rf /bazel - -#build and install tensorflow -RUN pip install -U cython six 'numpy==1.16.4' wheel mock 'future>=0.17.1' \ - && pip install keras_applications==1.0.6 --no-deps \ - && pip install keras_preprocessing==1.0.5 --no-deps \ - && pip install tensorflow_estimator --no-deps - -ENV TF_ROOT=/tensorflow -ENV PYTHON_BIN_PATH=/usr/bin/python3 -ENV PYTHON_LIB_PATH="$($PYTHON_BIN_PATH -c 'import site; print(site.getsitepackages()[0])')" -ENV PYTHONPATH=${TF_ROOT}/lib -ENV PYTHON_ARG=${TF_ROOT}/lib -ENV TF_NEED_GCP=0 -ENV TF_NEED_CUDA=0 -ENV TF_NEED_HDFS=0 -ENV TF_NEED_OPENCL=0 -ENV TF_NEED_JEMALLOC=0 -ENV TF_ENABLE_XLA=0 -ENV TF_NEED_VERBS=0 -ENV TF_NEED_MKL=0 -ENV TF_DOWNLOAD_MKL=0 -ENV TF_NEED_AWS=0 -ENV TF_NEED_MPI=0 -ENV TF_NEED_GDR=0 -ENV TF_NEED_S3=0 -ENV TF_NEED_OPENCL_SYCL=0 -ENV TF_SET_ANDROID_WORKSPACE=0 -ENV TF_NEED_COMPUTECPP=0 -ENV CC_OPT_FLAGS="-march=native" -ENV TF_SET_ANDROID_WORKSPACE=0 -ENV TF_NEED_KAFKA=0 -ENV TF_NEED_TENSORRT=0 -ENV TF_NEED_AWS=0 - -RUN git clone https://github.com/tensorflow/tensorflow.git \ - && cd tensorflow \ - && git checkout v1.12.0 \ - && sed -i 's/ "-mfpu=neon",//' /tensorflow/tensorflow/contrib/lite/kernels/internal/BUILD \ - && sed -i '0,/conditions:default": \[\],/s//conditions:default": glob(\["aws-cpp-sdk-core\/source\/platform\/linux-shared\/*\.cpp",\]),/' /tensorflow/third_party/aws.BUILD \ - && ./configure \ - && bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package \ - && bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg \ - && pip install --upgrade --force-reinstall /tmp/tensorflow_pkg/tensorflow*.whl\ - && rm -rf /tensorflow \ - && rm -r /tmp/tensorflow_pkg/tensorflow*.whl - -ADD . /usr/src/app/github.com/kubeflow/katib -WORKDIR /usr/src/app/github.com/kubeflow/katib/cmd/suggestion/nasrl/v1alpha2 -RUN pip install --no-cache-dir -r requirements.txt -ENV PYTHONPATH /usr/src/app/github.com/kubeflow/katib:/usr/src/app/github.com/kubeflow/katib/pkg/apis/manager/v1alpha2/python - -ENTRYPOINT ["python", "-u", "main.py"] diff --git a/cmd/suggestion/nasrl/v1alpha2/__init__.py b/cmd/suggestion/nasrl/v1alpha2/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/cmd/suggestion/nasrl/v1alpha2/main.py b/cmd/suggestion/nasrl/v1alpha2/main.py deleted file mode 100644 index 6a646f71303..00000000000 --- a/cmd/suggestion/nasrl/v1alpha2/main.py +++ /dev/null @@ -1,27 +0,0 @@ -import grpc -from concurrent import futures - -import time - -from pkg.apis.manager.v1alpha2.python import api_pb2_grpc -from pkg.suggestion.v1alpha2.nasrl_service import NasrlService - - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 -DEFAULT_PORT = "0.0.0.0:6789" - -def serve(): - print("NAS RL Suggestion Service") - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) - api_pb2_grpc.add_SuggestionServicer_to_server(NasrlService(), server) - server.add_insecure_port(DEFAULT_PORT) - print("Listening...") - server.start() - try: - while True: - time.sleep(_ONE_DAY_IN_SECONDS) - except KeyboardInterrupt: - server.stop(0) - -if __name__ == "__main__": - serve() diff --git a/cmd/suggestion/nasrl/v1alpha2/requirements.txt b/cmd/suggestion/nasrl/v1alpha2/requirements.txt deleted file mode 100644 index 155e383b5f7..00000000000 --- a/cmd/suggestion/nasrl/v1alpha2/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -grpcio -protobuf -googleapis-common-protos diff --git a/cmd/suggestion/random/v1alpha2/Dockerfile b/cmd/suggestion/random/v1alpha2/Dockerfile deleted file mode 100644 index cc0f0ebee2b..00000000000 --- a/cmd/suggestion/random/v1alpha2/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.6 - -ADD . /usr/src/app/github.com/kubeflow/katib -WORKDIR /usr/src/app/github.com/kubeflow/katib/cmd/suggestion/random/v1alpha2 -RUN if [ "$(uname -m)" = "ppc64le" ] || [ "$(uname -m)" = "aarch64" ]; then \ - apt-get -y update && \ - apt-get -y install gfortran libopenblas-dev liblapack-dev && \ - pip install cython; \ - fi -RUN pip install --no-cache-dir -r requirements.txt -ENV PYTHONPATH /usr/src/app/github.com/kubeflow/katib:/usr/src/app/github.com/kubeflow/katib/pkg/apis/manager/v1alpha2/python - -ENTRYPOINT ["python", "main.py"] diff --git a/cmd/suggestion/random/v1alpha2/__init__.py b/cmd/suggestion/random/v1alpha2/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/cmd/suggestion/random/v1alpha2/main.py b/cmd/suggestion/random/v1alpha2/main.py deleted file mode 100644 index e5cdd72385d..00000000000 --- a/cmd/suggestion/random/v1alpha2/main.py +++ /dev/null @@ -1,23 +0,0 @@ -import grpc -import time -from pkg.apis.manager.v1alpha2.python import api_pb2_grpc -from pkg.suggestion.v1alpha2.random_service import RandomService -from concurrent import futures - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 -DEFAULT_PORT = "0.0.0.0:6789" - -def serve(): - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) - api_pb2_grpc.add_SuggestionServicer_to_server(RandomService(), server) - server.add_insecure_port(DEFAULT_PORT) - print("Listening...") - server.start() - try: - while True: - time.sleep(_ONE_DAY_IN_SECONDS) - except KeyboardInterrupt: - server.stop(0) - -if __name__ == "__main__": - serve() diff --git a/cmd/suggestion/random/v1alpha2/requirements.txt b/cmd/suggestion/random/v1alpha2/requirements.txt deleted file mode 100644 index 8d2c9d4bda7..00000000000 --- a/cmd/suggestion/random/v1alpha2/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -grpcio -duecredit -cloudpickle==0.5.6 -numpy>=1.13.3 -scikit-learn>=0.19.0 -scipy>=0.19.1 -forestci -protobuf -googleapis-common-protos diff --git a/cmd/tfevent-metricscollector/v1alpha2/Dockerfile b/cmd/tfevent-metricscollector/v1alpha2/Dockerfile deleted file mode 100644 index 4f9d85c25a2..00000000000 --- a/cmd/tfevent-metricscollector/v1alpha2/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM tensorflow/tensorflow:1.11.0 -RUN pip install rfc3339 grpcio googleapis-common-protos -ADD . /usr/src/app/github.com/kubeflow/katib -WORKDIR /usr/src/app/github.com/kubeflow/katib/cmd/tfevent-metricscollector/v1alpha2 -ENV PYTHONPATH /usr/src/app/github.com/kubeflow/katib:/usr/src/app/github.com/kubeflow/katib/pkg/apis/manager/v1alpha2/python:/usr/src/app/github.com/kubeflow/katib/pkg/util/v1alpha2/tfevent-metricscollector diff --git a/cmd/tfevent-metricscollector/v1alpha2/Dockerfile.aarch64 b/cmd/tfevent-metricscollector/v1alpha2/Dockerfile.aarch64 deleted file mode 100644 index a7626a5b093..00000000000 --- a/cmd/tfevent-metricscollector/v1alpha2/Dockerfile.aarch64 +++ /dev/null @@ -1,28 +0,0 @@ -FROM ubuntu:18.04 - -RUN apt-get update \ - && apt-get -y install software-properties-common \ - autoconf \ - automake \ - build-essential \ - cmake \ - pkg-config \ - wget \ - python-pip \ - libhdf5-dev \ - libhdf5-serial-dev \ - hdf5-tools\ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -RUN wget https://github.com/lhelontra/tensorflow-on-arm/releases/download/v1.11.0/tensorflow-1.11.0-cp27-none-linux_aarch64.whl \ - && pip install tensorflow-1.11.0-cp27-none-linux_aarch64.whl \ - && rm tensorflow-1.11.0-cp27-none-linux_aarch64.whl \ - && rm -rf .cache - -RUN pip install rfc3339 grpcio googleapis-common-protos jupyter -ADD . /usr/src/app/github.com/kubeflow/katib -WORKDIR /usr/src/app/github.com/kubeflow/katib/cmd/tfevent-metricscollector/v1alpha2 -ENV PYTHONPATH /usr/src/app/github.com/kubeflow/katib:/usr/src/app/github.com/kubeflow/katib/pkg/apis/manager/v1alpha2/python:/usr/src/app/github.com/kubeflow/katib/pkg/util/v1alpha2/tfevent-metricscollector - -CMD ["bash","-c","jupyter notebook --ip 0.0.0.0 --no-browser --allow-root"] diff --git a/cmd/tfevent-metricscollector/v1alpha2/main.py b/cmd/tfevent-metricscollector/v1alpha2/main.py deleted file mode 100644 index ef09582266f..00000000000 --- a/cmd/tfevent-metricscollector/v1alpha2/main.py +++ /dev/null @@ -1,39 +0,0 @@ -import grpc -import argparse -import api_pb2 -import api_pb2_grpc -from tfevent_loader import MetricsCollector -from logging import getLogger, StreamHandler, INFO - -def parse_options(): - parser = argparse.ArgumentParser( - description='TF-Event MetricsCollector', - add_help = True - ) - parser.add_argument("-a", "--manager_addr", type = str, default = "katib-manager") - parser.add_argument("-p", "--manager_port", type = int, default = 6789 ) - parser.add_argument("-t", "--trial_name", type = str, default = "") - parser.add_argument("-d", "--log_dir", type = str, default = "/log") - parser.add_argument("-m", "--metric_names", type = str, default = "") - opt = parser.parse_args() - return opt - -if __name__ == '__main__': - logger = getLogger(__name__) - handler = StreamHandler() - handler.setLevel(INFO) - logger.setLevel(INFO) - logger.addHandler(handler) - logger.propagate = False - opt = parse_options() - - mc = MetricsCollector(opt.metric_names.split(',')) - observation_log = mc.parse_file(opt.log_dir) - - channel = grpc.beta.implementations.insecure_channel(opt.manager_addr, opt.manager_port) - with api_pb2.beta_create_Manager_stub(channel) as client: - logger.info("In " + opt.trial_name + " " + str(len(observation_log.metric_logs)) + " metrics will be reported.") - client.ReportObservationLog(api_pb2.ReportObservationLogRequest( - trial_name=opt.trial_name, - observation_log=observation_log - ), 10) \ No newline at end of file diff --git a/cmd/ui/v1alpha2/Dockerfile b/cmd/ui/v1alpha2/Dockerfile deleted file mode 100644 index c6f29a5d674..00000000000 --- a/cmd/ui/v1alpha2/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -FROM node:10.16.2-alpine AS npm-build - -ADD /pkg/ui/v1alpha2/frontend /frontend -RUN cd /frontend && npm install -RUN cd /frontend && npm run build -RUN rm -rf /frontend/node_modules - -FROM golang:alpine AS go-build -# The GOPATH in the image is /go. -ADD . /go/src/github.com/kubeflow/katib -WORKDIR /go/src/github.com/kubeflow/katib/cmd/ui -RUN if [ "$(uname -m)" = "ppc64le" ] || [ "$(uname -m)" = "aarch64" ]; then \ - apk --update add gcc musl-dev && \ - go build -o katib-ui ./v1alpha2; \ - else \ - go build -o katib-ui ./v1alpha2; \ - fi - -FROM alpine:3.7 -WORKDIR /app -# v1alpha2 source code -COPY --from=go-build /go/src/github.com/kubeflow/katib/cmd/ui/katib-ui /app/ -COPY --from=npm-build /frontend/build /app/build - -ENTRYPOINT ["./katib-ui"] diff --git a/cmd/ui/v1alpha2/main.go b/cmd/ui/v1alpha2/main.go deleted file mode 100644 index e7019e25418..00000000000 --- a/cmd/ui/v1alpha2/main.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "net/http" - - ui "github.com/kubeflow/katib/pkg/ui/v1alpha2" -) - -var ( - port, host, buildDir *string -) - -func init() { - port = flag.String("port", "80", "the port to listen to for incoming HTTP connections") - host = flag.String("host", "0.0.0.0", "the host to listen to for incoming HTTP connections") - buildDir = flag.String("build-dir", "/app/build", "the dir of frontend") -} -func main() { - flag.Parse() - kuh := ui.NewKatibUIHandler() - - frontend := http.FileServer(http.Dir(*buildDir)) - http.Handle("/katib/", http.StripPrefix("/katib/", frontend)) - - http.HandleFunc("/katib/fetch_hp_jobs/", kuh.FetchHPJobs) - http.HandleFunc("/katib/fetch_nas_jobs/", kuh.FetchNASJobs) - http.HandleFunc("/katib/submit_yaml/", kuh.SubmitYamlJob) - http.HandleFunc("/katib/submit_hp_job/", kuh.SubmitParamsJob) - http.HandleFunc("/katib/submit_nas_job/", kuh.SubmitParamsJob) - - //TODO: Add it in Katib client - http.HandleFunc("/katib/delete_experiment/", kuh.DeleteExperiment) - - http.HandleFunc("/katib/fetch_hp_job_info/", kuh.FetchHPJobInfo) - http.HandleFunc("/katib/fetch_hp_job_trial_info/", kuh.FetchHPJobTrialInfo) - http.HandleFunc("/katib/fetch_nas_job_info/", kuh.FetchNASJobInfo) - - http.HandleFunc("/katib/fetch_trial_templates/", kuh.FetchTrialTemplates) - http.HandleFunc("/katib/fetch_collector_templates/", kuh.FetchMetricsCollectorTemplates) - http.HandleFunc("/katib/update_template/", kuh.AddEditDeleteTemplate) - - if err := http.ListenAndServe(fmt.Sprintf("%s:%s", *host, *port), nil); err != nil { - panic(err) - } -} diff --git a/examples/v1alpha2/MinikubeDemo/deploy.sh b/examples/v1alpha2/MinikubeDemo/deploy.sh deleted file mode 100755 index f911fdea596..00000000000 --- a/examples/v1alpha2/MinikubeDemo/deploy.sh +++ /dev/null @@ -1,5 +0,0 @@ -#/bin/bash -set -x -set -e -minikube start --disk-size 50g --memory 4096 --cpus 4 -bash ../../../scripts/v1alpha2/deploy.sh diff --git a/examples/v1alpha2/MinikubeDemo/destroy.sh b/examples/v1alpha2/MinikubeDemo/destroy.sh deleted file mode 100755 index 3b352104a9b..00000000000 --- a/examples/v1alpha2/MinikubeDemo/destroy.sh +++ /dev/null @@ -1,5 +0,0 @@ -#/bin/bash -set -x -set -e -minikube delete -pkill kubectl diff --git a/examples/v1alpha2/NAS-training-containers/RL-cifar10/Dockerfile b/examples/v1alpha2/NAS-training-containers/RL-cifar10/Dockerfile deleted file mode 100644 index 6b0fa7344a6..00000000000 --- a/examples/v1alpha2/NAS-training-containers/RL-cifar10/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -ARG cuda_version=9.0 -ARG cudnn_version=7 -FROM nvidia/cuda:${cuda_version}-cudnn${cudnn_version}-devel - -# Install system packages -RUN apt-get update && apt-get install -y software-properties-common && \ - add-apt-repository ppa:deadsnakes/ppa && \ - apt-get update && \ - apt-get install -y --no-install-recommends \ - bzip2 \ - g++ \ - git \ - graphviz \ - libgl1-mesa-glx \ - libhdf5-dev \ - openmpi-bin \ - python3.5 \ - python3-pip \ - python3-setuptools \ - python3-dev \ - wget && \ - rm -rf /var/lib/apt/lists/* - - -ADD . /usr/src/app/github.com/kubeflow/katib -WORKDIR /usr/src/app/github.com/kubeflow/katib/examples/v1alpha2/NAS-training-containers/RL-cifar10 - -RUN pip3 install --upgrade pip -RUN pip3 install --no-cache-dir -r requirements.txt -ENV PYTHONPATH /usr/src/app/github.com/kubeflow/katib/examples/v1alpha2/NAS-training-containers/RL-cifar10 - -ENTRYPOINT ["python3.5", "-u", "RunTrial.py"] diff --git a/examples/v1alpha2/NAS-training-containers/RL-cifar10/ModelConstructor.py b/examples/v1alpha2/NAS-training-containers/RL-cifar10/ModelConstructor.py deleted file mode 100644 index 6ef93cc3301..00000000000 --- a/examples/v1alpha2/NAS-training-containers/RL-cifar10/ModelConstructor.py +++ /dev/null @@ -1,67 +0,0 @@ -import numpy as np -from keras.models import Model -from keras import backend as K -import json -from keras.layers import Input, Conv2D, ZeroPadding2D, concatenate, MaxPooling2D, \ - AveragePooling2D, Dense, Activation, BatchNormalization, GlobalAveragePooling2D, Dropout -from op_library import concat, conv, sp_conv, dw_conv, reduction - - -class ModelConstructor(object): - def __init__(self, arc_json, nn_json): - self.arch = json.loads(arc_json) - nn_config = json.loads(nn_json) - self.num_layers = nn_config['num_layers'] - self.input_sizes = nn_config['input_sizes'] - self.output_size = nn_config['output_sizes'][-1] - self.embedding = nn_config['embedding'] - - def build_model(self): - # a list of the data all layers - all_layers = [0 for _ in range(self.num_layers + 1)] - # a list of all the dimensions of all layers - all_dims = [0 for _ in range(self.num_layers + 1)] - - # ================= Stacking layers ================= - # Input Layer. Layer 0 - input_layer = Input(shape=self.input_sizes) - all_layers[0] = input_layer - - # Intermediate Layers. Starting from layer 1. - for l in range(1, self.num_layers + 1): - input_layers = list() - opt = self.arch[l - 1][0] - opt_config = self.embedding[str(opt)] - skip = self.arch[l - 1][1:l+1] - - # set up the connection to the previous layer first - input_layers.append(all_layers[l - 1]) - - # then add skip connections - for i in range(l - 1): - if l > 1 and skip[i] == 1: - input_layers.append(all_layers[i]) - - layer_input = concat(input_layers) - if opt_config['opt_type'] == 'convolution': - layer_output = conv(layer_input, opt_config) - if opt_config['opt_type'] == 'separable_convolution': - layer_output = sp_conv(layer_input, opt_config) - if opt_config['opt_type'] == 'depthwise_convolution': - layer_output = dw_conv(layer_input, opt_config) - elif opt_config['opt_type'] == 'reduction': - layer_output = reduction(layer_input, opt_config) - - all_layers[l] = layer_output - - # Final Layer - # Global Average Pooling, then Fully connected with softmax. - avgpooled = GlobalAveragePooling2D()(all_layers[self.num_layers]) - dropped = Dropout(0.4)(avgpooled) - logits = Dense(units=self.output_size, - activation='softmax')(dropped) - - # Encapsulate the model - self.model = Model(inputs=input_layer, outputs=logits) - - return self.model diff --git a/examples/v1alpha2/NAS-training-containers/RL-cifar10/RunTrial.py b/examples/v1alpha2/NAS-training-containers/RL-cifar10/RunTrial.py deleted file mode 100644 index 82e5b0e1cef..00000000000 --- a/examples/v1alpha2/NAS-training-containers/RL-cifar10/RunTrial.py +++ /dev/null @@ -1,77 +0,0 @@ -import keras -import numpy as np -from keras.datasets import cifar10 -from ModelConstructor import ModelConstructor -from keras.utils import to_categorical -from keras.utils import multi_gpu_model -from keras.preprocessing.image import ImageDataGenerator -import argparse -import time - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description='TrainingContainer') - parser.add_argument('--architecture', type=str, default="", metavar='N', - help='architecture of the neural network') - parser.add_argument('--nn_config', type=str, default="", metavar='N', - help='configurations and search space embeddings') - parser.add_argument('--num_epochs', type=int, default=10, metavar='N', - help='number of epoches that each child will be trained') - parser.add_argument('--num_gpus', type=int, default=1, metavar='N', - help='number of GPU that used for training') - args = parser.parse_args() - - arch = args.architecture.replace("\'", "\"") - print(">>> arch received by trial") - print(arch) - - nn_config = args.nn_config.replace("\'", "\"") - print(">>> nn_config received by trial") - print(nn_config) - - num_epochs = args.num_epochs - print(">>> num_epochs received by trial") - print(num_epochs) - - num_gpus = args.num_gpus - print(">>> num_gpus received by trial:") - print(num_gpus) - - print("\n>>> Constructing Model...") - constructor = ModelConstructor(arch, nn_config) - test_model = constructor.build_model() - print(">>> Model Constructed Successfully\n") - - if num_gpus > 1: - test_model = multi_gpu_model(test_model, gpus=num_gpus) - - test_model.summary() - test_model.compile(loss=keras.losses.categorical_crossentropy, - optimizer=keras.optimizers.Adam(lr=1e-3, decay=1e-4), - metrics=['accuracy']) - - (x_train, y_train), (x_test, y_test) = cifar10.load_data() - x_train = x_train.astype('float32') - x_test = x_test.astype('float32') - x_train /= 255 - x_test /= 255 - y_train = to_categorical(y_train) - y_test = to_categorical(y_test) - - augmentation = ImageDataGenerator( - width_shift_range=0.1, - height_shift_range=0.1, - horizontal_flip=True) - - aug_data_flow = augmentation.flow(x_train, y_train, batch_size=128) - - print(">>> Data Loaded. Training starts.") - for e in range(num_epochs): - print("\nTotal Epoch {}/{}".format(e+1, num_epochs)) - history = test_model.fit_generator(generator=aug_data_flow, - steps_per_epoch=int(len(x_train)/128)+1, - epochs=1, verbose=1, - validation_data=(x_test, y_test)) - print("Training-Accuracy={}".format(history.history['acc'][-1])) - print("Training-Loss={}".format(history.history['loss'][-1])) - print("Validation-Accuracy={}".format(history.history['val_acc'][-1])) - print("Validation-Loss={}".format(history.history['val_loss'][-1])) diff --git a/examples/v1alpha2/NAS-training-containers/RL-cifar10/op_library.py b/examples/v1alpha2/NAS-training-containers/RL-cifar10/op_library.py deleted file mode 100644 index cd95429d97b..00000000000 --- a/examples/v1alpha2/NAS-training-containers/RL-cifar10/op_library.py +++ /dev/null @@ -1,141 +0,0 @@ -import numpy as np -from keras import backend as K -from keras.layers import Input, Conv2D, ZeroPadding2D, concatenate, MaxPooling2D, \ - AveragePooling2D, Dense, Activation, BatchNormalization, GlobalAveragePooling2D, \ - SeparableConv2D, DepthwiseConv2D - - -def concat(inputs): - n = len(inputs) - if n == 1: - return inputs[0] - - total_dim = list() - for x in inputs: - total_dim.append(K.int_shape(x)) - total_dim = np.asarray(total_dim) - max_dim = max(total_dim[:, 1]) - - padded_input = [0 for _ in range(n)] - - for i in range(n): - if total_dim[i][1] < max_dim: - diff = max_dim - total_dim[i][1] - half_diff = int(diff / 2) - if diff % 2 == 0: - padded_input[i] = ZeroPadding2D(padding=(half_diff, half_diff))(inputs[i]) - else: - padded_input[i] = ZeroPadding2D(padding=((half_diff, half_diff + 1), - (half_diff, half_diff + 1)))(inputs[i]) - else: - padded_input[i] = inputs[i] - - result = concatenate(inputs=padded_input, axis=-1) - return result - - -def conv(x, config): - parameters = { - "num_filter": 64, - "filter_size": 3, - "stride": 1, - } - for k in parameters.keys(): - if k in config: - parameters[k] = int(config[k]) - - activated = Activation('relu')(x) - - conved = Conv2D( - filters=parameters['num_filter'], - kernel_size=parameters['filter_size'], - strides=parameters['stride'], - padding='same')(activated) - - result = BatchNormalization()(conved) - - return result - - -def sp_conv(x, config): - parameters = { - "num_filter": 64, - "filter_size": 3, - "stride": 1, - "depth_multiplier": 1, - } - - for k in parameters.keys(): - if k in config: - parameters[k] = int(config[k]) - - activated = Activation('relu')(x) - - conved = SeparableConv2D( - filters=parameters['num_filter'], - kernel_size=parameters['filter_size'], - strides=parameters['stride'], - depth_multiplier=parameters['depth_multiplier'], - padding='same')(activated) - - result = BatchNormalization()(conved) - - return result - -def dw_conv(x, config): - parameters = { - "filter_size": 3, - "stride": 1, - "depth_multiplier": 1, - } - for k in parameters.keys(): - if k in config: - parameters[k] = int(config[k]) - - activated = Activation('relu')(x) - - conved = DepthwiseConv2D( - kernel_size=parameters['filter_size'], - strides=parameters['stride'], - depth_multiplier=parameters['depth_multiplier'], - padding='same')(activated) - - result = BatchNormalization()(conved) - - return result - - -def reduction(x, config): - # handle the exteme case where the input has the dimension 1 by 1 and is not reductible - # we will just change the reduction layer to identity layer - # such situation is very likely to appear though - dim = K.int_shape(x) - if dim[1] == 1 or dim[2] == 1: - print("WARNING: One or more dimensions of the input of the reduction layer is 1. It cannot be further reduced. A identity layer will be used instead.") - return x - - parameters = { - 'reduction_type': "max_pooling", - 'pool_size': 2, - 'stride': None, - } - - if 'reduction_type' in config: - parameters['reduction_type'] = config['reduction_type'] - if 'pool_size' in config: - parameters['pool_size'] = int(config['pool_size']) - if 'stride' in config: - parameters['stride'] = int(config['stride']) - - if parameters['reduction_type'] == 'max_pooling': - result = MaxPooling2D( - pool_size=parameters['pool_size'], - strides=parameters['stride'] - )(x) - elif parameters['reduction_type'] == 'avg_pooling': - result = AveragePooling2D( - pool_size=parameters['pool_size'], - strides=parameters['stride'] - )(x) - - return result diff --git a/examples/v1alpha2/NAS-training-containers/RL-cifar10/requirements.txt b/examples/v1alpha2/NAS-training-containers/RL-cifar10/requirements.txt deleted file mode 100644 index ce7881a31e3..00000000000 --- a/examples/v1alpha2/NAS-training-containers/RL-cifar10/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -tensorflow-gpu==1.12.0 -keras==2.2.4 diff --git a/examples/v1alpha2/README.md b/examples/v1alpha2/README.md deleted file mode 100644 index e7227a597f6..00000000000 --- a/examples/v1alpha2/README.md +++ /dev/null @@ -1,310 +0,0 @@ -# Simple Minikube Demo -You can deploy katib components and try a simple mnist demo on your laptop! - -## Requirement -* [Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) -* kubectl - -## Deploy katib -Start Katib on Minikube with [deploy.sh](./MinikubeDemo/deploy.sh). -A Minikube cluster and Katib components will be deployed! You can check them with `kubectl -n kubeflow get pods`. - -Then, start port-forward for katib UI `8000 -> UI`. - -kubectl v1.10~ -``` -$ kubectl -n kubeflow port-forward svc/katib-ui 8000:80 & -``` - -kubectl ~v1.9 - -``` -& kubectl -n kubeflow port-forward $(kubectl -n kubeflow get pod -o=name | grep katib-ui | sed -e "s@pods\/@@") 8000:80 & -``` - -## Create Experiment -#### Random Suggestion Demo -``` -$ kubectl apply -f random-example.yaml -``` -#### Grid Suggestion Demo -``` -$ kubectl apply -f grid-example.yaml -``` -#### Bayesian Optimization Suggestion Demo -``` -$ kubectl apply -f bayseopt-example.yaml -``` -#### Hyperband Suggestion Demo -``` -$ kubectl apply -f hyperband-example.yaml -``` -#### Run trial evaluation job by [PyTorchJob](https://github.com/kubeflow/pytorch-operator) -``` -$ kubectl apply -f pytorchjob-example.yaml -``` -#### Run trial evaluation job by [TFJob](https://github.com/kubeflow/tf-operator) -``` -$ kubectl apply -f tfevent-volume/ -$ kubectl apply -f tfjob-example.yaml -``` -## Monitor Experiment -#### CLI -You can submit a new Experiment or check your Experiment results with `kubectl` CLI. -List experiments -``` -# kubectl get experiment -n kubeflow -NAME STATUS AGE -random-experiment Succeeded 25m -``` -Check experiment result -``` -# kubectl get experiment random-experiment -n kubeflow -oyaml -apiVersion: kubeflow.org/v1alpha2 -kind: Experiment -metadata: - annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"kubeflow.org/v1alpha2","kind":"Experiment","metadata":{"annotations":{},"name":"random-experiment","namespace":"kubeflow"},"spec":{"algorithm":{"algorithmName":"random"},"maxFailedTrialCount":3,"maxTrialCount":12,"objective":{"additionalMetricNames":["accuracy"],"goal":0.99,"objectiveMetricName":"Validation-accuracy","type":"maximize"},"parallelTrialCount":3,"parameters":[{"feasibleSpace":{"max":"0.03","min":"0.01"},"name":"--lr","parameterType":"double"},{"feasibleSpace":{"max":"5","min":"2"},"name":"--num-layers","parameterType":"int"},{"feasibleSpace":{"list":["sgd","adam","ftrl"]},"name":"--optimizer","parameterType":"categorical"}],"trialTemplate":{"goTemplate":{"rawTemplate":"apiVersion: batch/v1\nkind: Job\nmetadata:\n name: {{.Trial}}\n namespace: {{.NameSpace}}\nspec:\n template:\n spec:\n containers:\n - name: {{.Trial}}\n image: katib/mxnet-mnist-example\n command:\n - \"python\"\n - \"/mxnet/example/image-classification/train_mnist.py\"\n - \"--batch-size=64\"\n {{- with .HyperParameters}}\n {{- range .}}\n - \"{{.Name}}={{.Value}}\"\n {{- end}}\n {{- end}}\n restartPolicy: Never"}}}} - creationTimestamp: 2019-07-15T07:37:40Z - finalizers: - - clean-data-in-db - name: random-experiment - namespace: kubeflow - resourceVersion: "22147879" - selfLink: /apis/kubeflow.org/v1alpha2/namespaces/kubeflow/experiments/random-experiment - uid: 6c8896db-a6d3-11e9-b55b-00163e01b303 -spec: - algorithm: - algorithmName: random - algorithmSettings: null - maxFailedTrialCount: 3 - maxTrialCount: 12 - objective: - additionalMetricNames: - - accuracy - goal: 0.99 - objectiveMetricName: Validation-accuracy - type: maximize - parallelTrialCount: 3 - parameters: - - feasibleSpace: - max: "0.03" - min: "0.01" - name: --lr - parameterType: double - - feasibleSpace: - max: "5" - min: "2" - name: --num-layers - parameterType: int - - feasibleSpace: - list: - - sgd - - adam - - ftrl - name: --optimizer - parameterType: categorical - trialTemplate: - goTemplate: - rawTemplate: |- - apiVersion: batch/v1 - kind: Job - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - restartPolicy: Never -status: - completionTime: 2019-07-15T07:45:56Z - conditions: - - lastTransitionTime: 2019-07-15T07:37:29Z - lastUpdateTime: 2019-07-15T07:37:29Z - message: Experiment is created - reason: ExperimentCreated - status: "True" - type: Created - - lastTransitionTime: 2019-07-15T07:45:56Z - lastUpdateTime: 2019-07-15T07:45:56Z - message: Experiment is running - reason: ExperimentRunning - status: "False" - type: Running - - lastTransitionTime: 2019-07-15T07:45:56Z - lastUpdateTime: 2019-07-15T07:45:56Z - message: Experiment has succeeded because max trial count has reached - reason: ExperimentSucceeded - status: "True" - type: Succeeded - currentOptimalTrial: - observation: - metrics: - - name: Validation-accuracy - value: 0.98119 - parameterAssignments: - - name: --lr - value: "0.01178778887185771" - - name: --num-layers - value: "4" - - name: --optimizer - value: sgd - startTime: 2019-07-15T07:37:29Z - trials: 12 - trialsSucceeded: 12 -``` -List trials -``` -# kubectl get trials -n kubeflow -NAME STATUS AGE -random-experiment-24lgqghm Succeeded 26m -random-experiment-2vdqlqfm Succeeded 28m -random-experiment-4xg8n48f Succeeded 30m -random-experiment-64stflgp Succeeded 29m -random-experiment-d9jgsm96 Succeeded 29m -random-experiment-pnrqmqdm Succeeded 27m -random-experiment-qvcdfppz Succeeded 27m -random-experiment-r49pflgp Succeeded 30m -random-experiment-r7d7mcbx Succeeded 29m -random-experiment-rwbf62k5 Succeeded 26m -random-experiment-vs8pmh2m Succeeded 27m -random-experiment-wmnlq972 Succeeded 30m -``` -Check trial detail -``` -# kubectl get trials random-experiment-24lgqghm -oyaml -n kubeflow -apiVersion: kubeflow.org/v1alpha2 -kind: Trial -metadata: - creationTimestamp: 2019-07-15T07:41:38Z - generation: 1 - labels: - experiment: random-experiment - name: random-experiment-24lgqghm - namespace: kubeflow - ownerReferences: - - apiVersion: kubeflow.org/v1alpha2 - blockOwnerDeletion: true - controller: true - kind: Experiment - name: random-experiment - uid: 6c8896db-a6d3-11e9-b55b-00163e01b303 - resourceVersion: "22147830" - selfLink: /apis/kubeflow.org/v1alpha2/namespaces/kubeflow/trials/random-experiment-24lgqghm - uid: fad59cb8-a6d3-11e9-b55b-00163e01b303 -spec: - metricsCollectorSpec: |- - apiVersion: batch/v1beta1 - kind: CronJob - metadata: - name: random-experiment-24lgqghm - namespace: kubeflow - spec: - schedule: "*/1 * * * *" - successfulJobsHistoryLimit: 0 - failedJobsHistoryLimit: 1 - concurrencyPolicy: Forbid - jobTemplate: - spec: - backoffLimit: 0 - template: - spec: - serviceAccountName: metrics-collector - containers: - - name: random-experiment-24lgqghm - image: gcr.io/kubeflow-images-public/katib/v1alpha2/metrics-collector - imagePullPolicy: IfNotPresent - command: ["./metricscollector"] - args: - - "-e" - - "random-experiment" - - "-t" - - "random-experiment-24lgqghm" - - "-k" - - "Job" - - "-n" - - "kubeflow" - - "-m" - - "katib-manager.kubeflow:6789" - - "-mn" - - "Validation-accuracy;accuracy" - restartPolicy: Never - objective: - additionalMetricNames: - - accuracy - goal: 0.99 - objectiveMetricName: Validation-accuracy - type: maximize - parameterAssignments: - - name: --lr - value: "0.017151855585117313" - - name: --num-layers - value: "5" - - name: --optimizer - value: adam - runSpec: |- - apiVersion: batch/v1 - kind: Job - metadata: - name: random-experiment-24lgqghm - namespace: kubeflow - spec: - template: - spec: - containers: - - name: random-experiment-24lgqghm - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - - "--lr=0.017151855585117313" - - "--num-layers=5" - - "--optimizer=adam" - restartPolicy: Never -status: - completionTime: 2019-07-15T07:45:42Z - conditions: - - lastTransitionTime: 2019-07-15T07:41:29Z - lastUpdateTime: 2019-07-15T07:41:29Z - message: Trial is created - reason: TrialCreated - status: "True" - type: Created - - lastTransitionTime: 2019-07-15T07:45:42Z - lastUpdateTime: 2019-07-15T07:45:42Z - message: Trial is running - reason: TrialRunning - status: "False" - type: Running - - lastTransitionTime: 2019-07-15T07:45:42Z - lastUpdateTime: 2019-07-15T07:45:42Z - message: Trial has succeeded - reason: TrialSucceeded - status: "True" - type: Succeeded - observation: - metrics: - - name: Validation-accuracy - value: 0.969347 - startTime: 2019-07-15T07:41:29Z -``` -#### UI -You can submit a new Experiment or check your Experiment results with Web UI. -Acsess to `http://127.0.0.1:8000/katib` -## Clean -Clean up with [destroy.sh](./MinikubeDemo/destroy.sh) script. -It will stop port-forward process and delete minikube cluster. diff --git a/examples/v1alpha2/bayseopt-example.yaml b/examples/v1alpha2/bayseopt-example.yaml deleted file mode 100644 index 70e69f37e48..00000000000 --- a/examples/v1alpha2/bayseopt-example.yaml +++ /dev/null @@ -1,64 +0,0 @@ -apiVersion: "kubeflow.org/v1alpha2" -kind: Experiment -metadata: - namespace: kubeflow - labels: - controller-tools.k8s.io: "1.0" - name: bayseopt-example -spec: - objective: - type: maximize - goal: 0.99 - objectiveMetricName: Validation-accuracy - additionalMetricNames: - - accuracy - algorithm: - algorithmName: bayesianoptimization - algorithmSettings: - - name: "burn_in" - value: "5" - parallelTrialCount: 3 - maxTrialCount: 12 - maxFailedTrialCount: 3 - parameters: - - name: --lr - parameterType: double - feasibleSpace: - min: "0.01" - max: "0.03" - - name: --num-layers - parameterType: int - feasibleSpace: - min: "2" - max: "5" - - name: --optimizer - parameterType: categorical - feasibleSpace: - list: - - sgd - - adam - - ftrl - trialTemplate: - goTemplate: - rawTemplate: |- - apiVersion: batch/v1 - kind: Job - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - restartPolicy: Never diff --git a/examples/v1alpha2/grid-example.yaml b/examples/v1alpha2/grid-example.yaml deleted file mode 100644 index b7f6f71f26b..00000000000 --- a/examples/v1alpha2/grid-example.yaml +++ /dev/null @@ -1,64 +0,0 @@ -apiVersion: "kubeflow.org/v1alpha2" -kind: Experiment -metadata: - namespace: kubeflow - name: grid-experiment -spec: - parallelTrialCount: 3 - maxTrialCount: 12 - maxFailedTrialCount: 3 - objective: - type: maximize - goal: 0.99 - objectiveMetricName: Validation-accuracy - additionalMetricNames: - - accuracy - algorithm: - algorithmName: grid - algorithmSettings: - - name: --num-layers - value: "5" - - name: --optimizer - value: "3" - trialTemplate: - goTemplate: - rawTemplate: |- - apiVersion: batch/v1 - kind: Job - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - restartPolicy: Never - parameters: - - name: --lr - parameterType: double - feasibleSpace: - min: "0.01" - max: "0.03" - - name: --num-layers - parameterType: int - feasibleSpace: - min: "1" - max: "15" - - name: --optimizer - parameterType: categorical - feasibleSpace: - list: - - sgd - - adam - - ftrl diff --git a/examples/v1alpha2/hyperband-example.yaml b/examples/v1alpha2/hyperband-example.yaml deleted file mode 100644 index fd72ab0e578..00000000000 --- a/examples/v1alpha2/hyperband-example.yaml +++ /dev/null @@ -1,70 +0,0 @@ -apiVersion: "kubeflow.org/v1alpha2" -kind: Experiment -metadata: - namespace: kubeflow - name: hyperband-example -spec: - parallelTrialCount: 9 - objective: - type: maximize - goal: 0.99 - objectiveMetricName: Validation-accuracy - additionalMetricNames: - - accuracy - algorithm: - algorithmName: hyperband - algorithmSettings: - - name: "resourceName" - value: "--num-epochs" - - name: "eta" - value: "3" - - name: "r_l" - value: "9" - maxFailedTrialCount: 9 - parameters: - - name: --lr - parameterType: double - feasibleSpace: - min: "0.01" - max: "0.03" - - name: --num-layers - parameterType: int - feasibleSpace: - min: "2" - max: "5" - - name: --optimizer - parameterType: categorical - feasibleSpace: - list: - - sgd - - adam - - ftrl - - name: --num-epochs - parametertype: int - feasible: - min: "20" - max: "20" - trialTemplate: - goTemplate: - rawTemplate: |- - apiVersion: batch/v1 - kind: Job - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - restartPolicy: Never diff --git a/examples/v1alpha2/nasjob-example-RL.yaml b/examples/v1alpha2/nasjob-example-RL.yaml deleted file mode 100644 index 56eb994238c..00000000000 --- a/examples/v1alpha2/nasjob-example-RL.yaml +++ /dev/null @@ -1,175 +0,0 @@ -# This example aims to show all the possible operations -# is not very likely to get good result due to the extensive search space - -# In practice, setting up a limited search space with more common operations is more likely to get better performance. -# For example, Efficient Neural Architecture Search via Parameter Sharing (https://arxiv.org/abs/1802.03268) -# uses only 6 operations, 3x3/5x5 convolution, 3x3/5x5 separable_convolution and 3x3 max_pooling/avg_pooling - -apiVersion: "kubeflow.org/v1alpha2" -kind: Experiment -metadata: - namespace: kubeflow - name: nas-rl-example -spec: - parallelTrialCount: 3 - maxTrialCount: 12 - maxFailedTrialCount: 3 - objective: - type: maximize - goal: 0.99 - objectiveMetricName: Validation-Accuracy - algorithm: - algorithmName: nasrl - algorithmSettings: - - name: "lstm_num_cells" - value: "64" - - name: "lstm_num_layers" - value: "1" - - name: "lstm_keep_prob" - value: "1.0" - - name: "optimizer" - value: "adam" - - name: "init_learning_rate" - value: "1e-3" - - name: "lr_decay_start" - value: "0" - - name: "lr_decay_every" - value: "1000" - - name: "lr_decay_rate" - value: "0.9" - - name: "skip-target" - value: "0.4" - - name: "skip-weight" - value: "0.8" - - name: "l2_reg" - value: "0" - - name: "entropy_weight" - value: "1e-4" - - name: "baseline_decay" - value: "0.9999" - trialTemplate: - goTemplate: - rawTemplate: |- - apiVersion: batch/v1 - kind: Job - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: katib/v1alpha2/training-container-nasrl-cifar10 - command: - - "python3.5" - - "-u" - - "RunTrial.py" - {{- with .HyperParameters}} - {{- range .}} - - "--{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - resources: - limits: - nvidia.com/gpu: 1 - restartPolicy: Never - nasConfig: - graphConfig: - numLayers: 8 - inputSizes: - - 32 - - 32 - - 3 - outputSizes: - - 10 - operations: - - operationType: convolution - parameters: - - name: filter_size - parameterType: categorical - feasibleSpace: - list: - - "3" - - "5" - - "7" - - name: num_filter - parameterType: categorical - feasibleSpace: - list: - - "32" - - "48" - - "64" - - "96" - - "128" - - name: stride - parameterType: categorical - feasibleSpace: - list: - - "1" - - "2" - - operationType: separable_convolution - parameters: - - name: filter_size - parameterType: categorical - feasibleSpace: - list: - - "3" - - "5" - - "7" - - name: num_filter - parameterType: categorical - feasibleSpace: - list: - - "32" - - "48" - - "64" - - "96" - - "128" - - name: stride - parameterType: categorical - feasibleSpace: - list: - - "1" - - "2" - - name: depth_multiplier - parameterType: categorical - feasibleSpace: - list: - - "1" - - "2" - - operationType: depthwise_convolution - parameters: - - name: filter_size - parameterType: categorical - feasibleSpace: - list: - - "3" - - "5" - - "7" - - name: stride - parameterType: categorical - feasibleSpace: - list: - - "1" - - "2" - - name: depth_multiplier - parameterType: categorical - feasibleSpace: - list: - - "1" - - "2" - - operationType: reduction - parameters: - - name: reduction_type - parameterType: categorical - feasibleSpace: - list: - - max_pooling - - avg_pooling - - name: pool_size - parameterType: int - feasibleSpace: - min: "2" - max: "3" - step: "1" diff --git a/examples/v1alpha2/pytorchjob-example.yaml b/examples/v1alpha2/pytorchjob-example.yaml deleted file mode 100644 index 1cfa06aa792..00000000000 --- a/examples/v1alpha2/pytorchjob-example.yaml +++ /dev/null @@ -1,71 +0,0 @@ -apiVersion: "kubeflow.org/v1alpha2" -kind: Experiment -metadata: - namespace: kubeflow - name: random-experiment -spec: - parallelTrialCount: 3 - maxTrialCount: 12 - maxFailedTrialCount: 3 - objective: - type: maximize - goal: 0.99 - objectiveMetricName: accuracy - algorithm: - algorithmName: random - trialTemplate: - retain: true - goTemplate: - rawTemplate: |- - apiVersion: "kubeflow.org/v1" - kind: PyTorchJob - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - pytorchReplicaSpecs: - Master: - replicas: 1 - restartPolicy: OnFailure - template: - spec: - containers: - - name: pytorch - image: gcr.io/kubeflow-ci/pytorch-dist-mnist-test:v1.0 - imagePullPolicy: Always - command: - - "python" - - "/var/mnist.py" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - Worker: - replicas: 2 - restartPolicy: OnFailure - template: - spec: - containers: - - name: pytorch - image: gcr.io/kubeflow-ci/pytorch-dist-mnist-test:v1.0 - imagePullPolicy: Always - command: - - "python" - - "/var/mnist.py" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - parameters: - - name: --lr - parameterType: double - feasibleSpace: - min: "0.01" - max: "0.05" - - name: --momentum - parameterType: double - feasibleSpace: - min: "0.5" - max: "0.9" diff --git a/examples/v1alpha2/random-example.yaml b/examples/v1alpha2/random-example.yaml deleted file mode 100644 index 2ca8baee3e6..00000000000 --- a/examples/v1alpha2/random-example.yaml +++ /dev/null @@ -1,59 +0,0 @@ -apiVersion: "kubeflow.org/v1alpha2" -kind: Experiment -metadata: - namespace: kubeflow - name: random-experiment -spec: - parallelTrialCount: 3 - maxTrialCount: 12 - maxFailedTrialCount: 3 - objective: - type: maximize - goal: 0.99 - objectiveMetricName: Validation-accuracy - additionalMetricNames: - - accuracy - algorithm: - algorithmName: random - trialTemplate: - goTemplate: - rawTemplate: |- - apiVersion: batch/v1 - kind: Job - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - restartPolicy: Never - parameters: - - name: --lr - parameterType: double - feasibleSpace: - min: "0.01" - max: "0.03" - - name: --num-layers - parameterType: int - feasibleSpace: - min: "2" - max: "5" - - name: --optimizer - parameterType: categorical - feasibleSpace: - list: - - sgd - - adam - - ftrl diff --git a/examples/v1alpha2/tfevent-volume/tfevent-pv.yaml b/examples/v1alpha2/tfevent-volume/tfevent-pv.yaml deleted file mode 100644 index 93ec2af2c72..00000000000 --- a/examples/v1alpha2/tfevent-volume/tfevent-pv.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: PersistentVolume -metadata: - name: tfevent-volume - labels: - type: local - app: tfjob -spec: - capacity: - storage: 10Gi - accessModes: - - ReadWriteMany - hostPath: - path: /tmp/data diff --git a/examples/v1alpha2/tfevent-volume/tfevent-pvc.yaml b/examples/v1alpha2/tfevent-volume/tfevent-pvc.yaml deleted file mode 100644 index 6bab17d8032..00000000000 --- a/examples/v1alpha2/tfevent-volume/tfevent-pvc.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: tfevent-volume - namespace: kubeflow - labels: - type: local - app: tfjob -spec: - accessModes: - - ReadWriteMany - resources: - requests: - storage: 10Gi diff --git a/examples/v1alpha2/tfjob-example.yaml b/examples/v1alpha2/tfjob-example.yaml deleted file mode 100644 index 528ba8ee8c0..00000000000 --- a/examples/v1alpha2/tfjob-example.yaml +++ /dev/null @@ -1,99 +0,0 @@ -apiVersion: "kubeflow.org/v1alpha2" -kind: Experiment -metadata: - namespace: kubeflow - name: tfjob-example -spec: - parallelTrialCount: 3 - maxTrialCount: 12 - maxFailedTrialCount: 3 - objective: - type: maximize - goal: 0.99 - objectiveMetricName: accuracy_1 - algorithm: - algorithmName: random - parameters: - - name: --learning_rate - parameterType: double - feasibleSpace: - min: "0.01" - max: "0.05" - - name: --batch_size - parameterType: int - feasibleSpace: - min: "100" - max: "200" - trialTemplate: - retain: true - goTemplate: - rawTemplate: |- - apiVersion: "kubeflow.org/v1" - kind: TFJob - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - tfReplicaSpecs: - Worker: - replicas: 1 - restartPolicy: OnFailure - template: - spec: - containers: - - name: tensorflow - image: gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0 - imagePullPolicy: Always - command: - - "python" - - "/var/tf_mnist/mnist_with_summaries.py" - - "--log_dir=/train/{{.Trial}}" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - volumeMounts: - - mountPath: "/train" - name: "train" - volumes: - - name: "train" - persistentVolumeClaim: - claimName: "tfevent-volume" - metricsCollectorSpec: - goTemplate: - rawTemplate: |- - apiVersion: batch/v1beta1 - kind: CronJob - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - schedule: "*/1 * * * *" - successfulJobsHistoryLimit: 0 - failedJobsHistoryLimit: 1 - jobTemplate: - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: gcr.io/kubeflow-images-public/katib/v1alpha2/tfevent-metrics-collector - args: - - "python" - - "main.py" - - "-t" - - "{{.Trial}}" - - "-d" - - "/train/{{.Trial}}" - - "-m" - - "accuracy_1" - volumeMounts: - - mountPath: "/train" - name: "train" - volumes: - - name: "train" - persistentVolumeClaim: - claimName: "tfevent-volume" - restartPolicy: Never - serviceAccountName: metrics-collector diff --git a/manifests/v1alpha2/0-namespace.yaml b/manifests/v1alpha2/0-namespace.yaml deleted file mode 100644 index 7a940e4673d..00000000000 --- a/manifests/v1alpha2/0-namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: kubeflow diff --git a/manifests/v1alpha2/db/deployment.yaml b/manifests/v1alpha2/db/deployment.yaml deleted file mode 100644 index ca2833c0e64..00000000000 --- a/manifests/v1alpha2/db/deployment.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-db - namespace: kubeflow - labels: - app: katib - component: db -spec: - replicas: 1 - selector: - matchLabels: - app: katib - component: db - template: - metadata: - name: katib-db - labels: - app: katib - component: db - spec: - containers: - - name: katib-db - image: mysql:8.0.3 - args: - - --datadir - - /var/lib/mysql/datadir - env: - - name: MYSQL_ROOT_PASSWORD - valueFrom: - secretKeyRef: - name: katib-db-secrets - key: MYSQL_ROOT_PASSWORD - - name: MYSQL_ALLOW_EMPTY_PASSWORD - value: "true" - - name: MYSQL_DATABASE - value: "katib" - ports: - - name: dbapi - containerPort: 3306 - readinessProbe: - exec: - command: - - "/bin/bash" - - "-c" - - "mysql -D $$MYSQL_DATABASE -p$$MYSQL_ROOT_PASSWORD -e 'SELECT 1'" - initialDelaySeconds: 5 - periodSeconds: 2 - timeoutSeconds: 1 - volumeMounts: - - name: katib-mysql - mountPath: /var/lib/mysql - volumes: - - name: katib-mysql - persistentVolumeClaim: - claimName: katib-mysql diff --git a/manifests/v1alpha2/db/secret.yaml b/manifests/v1alpha2/db/secret.yaml deleted file mode 100644 index 8cd0686d00e..00000000000 --- a/manifests/v1alpha2/db/secret.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Secret -type: Opaque -metadata: - name: katib-db-secrets - namespace: kubeflow -data: - MYSQL_ROOT_PASSWORD: dGVzdA== # "test" diff --git a/manifests/v1alpha2/db/service.yaml b/manifests/v1alpha2/db/service.yaml deleted file mode 100644 index 6cd48c6ebe0..00000000000 --- a/manifests/v1alpha2/db/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-db - namespace: kubeflow - labels: - app: katib - component: db -spec: - type: ClusterIP - ports: - - port: 3306 - protocol: TCP - name: dbapi - selector: - app: katib - component: db diff --git a/manifests/v1alpha2/katib-controller/crd-experiment.yaml b/manifests/v1alpha2/katib-controller/crd-experiment.yaml deleted file mode 100644 index 78f090b8e10..00000000000 --- a/manifests/v1alpha2/katib-controller/crd-experiment.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: experiments.kubeflow.org -spec: - additionalPrinterColumns: - - JSONPath: .status.conditions[-1:].type - name: Status - type: string - - JSONPath: .metadata.creationTimestamp - name: Age - type: date - group: kubeflow.org - version: v1alpha2 - scope: Namespaced - subresources: - status: {} - names: - kind: Experiment - singular: experiment - plural: experiments - categories: - - all - - kubeflow - - katib diff --git a/manifests/v1alpha2/katib-controller/crd-trial.yaml b/manifests/v1alpha2/katib-controller/crd-trial.yaml deleted file mode 100644 index a766a9a1ddb..00000000000 --- a/manifests/v1alpha2/katib-controller/crd-trial.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: trials.kubeflow.org -spec: - additionalPrinterColumns: - - JSONPath: .status.conditions[-1:].type - name: Status - type: string - - JSONPath: .metadata.creationTimestamp - name: Age - type: date - group: kubeflow.org - version: v1alpha2 - scope: Namespaced - subresources: - status: {} - names: - kind: Trial - singular: trial - plural: trials - categories: - - all - - kubeflow - - katib diff --git a/manifests/v1alpha2/katib-controller/katib-controller.yaml b/manifests/v1alpha2/katib-controller/katib-controller.yaml deleted file mode 100644 index 55d03863cef..00000000000 --- a/manifests/v1alpha2/katib-controller/katib-controller.yaml +++ /dev/null @@ -1,46 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-controller - namespace: kubeflow - labels: - app: katib-controller -spec: - replicas: 1 - selector: - matchLabels: - app: katib-controller - template: - metadata: - labels: - app: katib-controller - annotations: - prometheus.io/scrape: 'true' - spec: - serviceAccountName: katib-controller - containers: - - name: katib-controller - image: gcr.io/kubeflow-images-public/katib/v1alpha2/katib-controller - imagePullPolicy: IfNotPresent - command: ["./katib-controller"] - ports: - - containerPort: 443 - name: webhook - protocol: TCP - - containerPort: 8080 - name: metrics - protocol: TCP - env: - - name: KATIB_CORE_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - volumeMounts: - - mountPath: /tmp/cert - name: cert - readOnly: true - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: katib-controller diff --git a/manifests/v1alpha2/katib-controller/mcrbac.yaml b/manifests/v1alpha2/katib-controller/mcrbac.yaml deleted file mode 100644 index 2b13d6ce46b..00000000000 --- a/manifests/v1alpha2/katib-controller/mcrbac.yaml +++ /dev/null @@ -1,38 +0,0 @@ -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: metrics-collector -rules: -- apiGroups: - - "" - resources: - - pods - - pods/log - - pods/status - verbs: - - "*" -- apiGroups: - - batch - resources: - - jobs - verbs: - - "*" ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: metrics-collector - namespace: kubeflow ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: metrics-collector -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: metrics-collector -subjects: -- kind: ServiceAccount - name: metrics-collector - namespace: kubeflow diff --git a/manifests/v1alpha2/katib-controller/metricsControllerConfigMap.yaml b/manifests/v1alpha2/katib-controller/metricsControllerConfigMap.yaml deleted file mode 100644 index 09e99ca267b..00000000000 --- a/manifests/v1alpha2/katib-controller/metricsControllerConfigMap.yaml +++ /dev/null @@ -1,42 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: metrics-collector-template - namespace: kubeflow -data: - defaultMetricsCollectorTemplate.yaml : |- - apiVersion: batch/v1beta1 - kind: CronJob - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - schedule: "*/1 * * * *" - successfulJobsHistoryLimit: 0 - failedJobsHistoryLimit: 1 - concurrencyPolicy: Forbid - jobTemplate: - spec: - backoffLimit: 0 - template: - spec: - serviceAccountName: metrics-collector - containers: - - name: {{.Trial}} - image: gcr.io/kubeflow-images-public/katib/v1alpha2/metrics-collector - imagePullPolicy: IfNotPresent - command: ["./metricscollector"] - args: - - "-e" - - "{{.Experiment}}" - - "-t" - - "{{.Trial}}" - - "-k" - - "{{.JobKind}}" - - "-n" - - "{{.NameSpace}}" - - "-m" - - "{{.ManagerService}}" - - "-mn" - - "{{.MetricNames}}" - restartPolicy: Never diff --git a/manifests/v1alpha2/katib-controller/rbac.yaml b/manifests/v1alpha2/katib-controller/rbac.yaml deleted file mode 100644 index c7329932a74..00000000000 --- a/manifests/v1alpha2/katib-controller/rbac.yaml +++ /dev/null @@ -1,78 +0,0 @@ -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: katib-controller -rules: -- apiGroups: - - "" - resources: - - configmaps - - serviceaccounts - - services - - secrets - verbs: - - "*" -- apiGroups: - - "" - resources: - - pods - - pods/log - - pods/status - verbs: - - "*" -- apiGroups: - - batch - resources: - - jobs - - cronjobs - verbs: - - "*" -- apiGroups: - - apiextensions.k8s.io - resources: - - customresourcedefinitions - verbs: - - create - - get -- apiGroups: - - admissionregistration.k8s.io - resources: - - validatingwebhookconfigurations - - mutatingwebhookconfigurations - verbs: - - '*' -- apiGroups: - - kubeflow.org - resources: - - experiments - - experiments/status - - trials - - trials/status - verbs: - - "*" -- apiGroups: - - kubeflow.org - resources: - - tfjobs - - pytorchjobs - verbs: - - "*" ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: katib-controller - namespace: kubeflow ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: katib-controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: katib-controller -subjects: -- kind: ServiceAccount - name: katib-controller - namespace: kubeflow diff --git a/manifests/v1alpha2/katib-controller/secret.yaml b/manifests/v1alpha2/katib-controller/secret.yaml deleted file mode 100644 index 8c9b009caf9..00000000000 --- a/manifests/v1alpha2/katib-controller/secret.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: katib-controller - namespace: kubeflow diff --git a/manifests/v1alpha2/katib-controller/service.yaml b/manifests/v1alpha2/katib-controller/service.yaml deleted file mode 100644 index efcc6ec2327..00000000000 --- a/manifests/v1alpha2/katib-controller/service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-controller - namespace: kubeflow - annotations: - prometheus.io/port: "8080" - prometheus.io/scheme: http - prometheus.io/scrape: "true" -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 443 - name: webhook - - name: metrics - port: 8080 - targetPort: 8080 - selector: - app: katib-controller diff --git a/manifests/v1alpha2/katib-controller/trialTemplateConfigmap.yaml b/manifests/v1alpha2/katib-controller/trialTemplateConfigmap.yaml deleted file mode 100644 index 67ec76c00cd..00000000000 --- a/manifests/v1alpha2/katib-controller/trialTemplateConfigmap.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: trial-template - namespace: kubeflow -data: - defaultTrialTemplate.yaml : |- - apiVersion: batch/v1 - kind: Job - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: alpine - restartPolicy: Never - diff --git a/manifests/v1alpha2/manager-rest/deployment.yaml b/manifests/v1alpha2/manager-rest/deployment.yaml deleted file mode 100644 index 8caff0e65f9..00000000000 --- a/manifests/v1alpha2/manager-rest/deployment.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-manager-rest - namespace: kubeflow - labels: - app: katib - component: manager-rest -spec: - replicas: 1 - selector: - matchLabels: - app: katib - component: manager-rest - template: - metadata: - name: katib-manager-rest - labels: - app: katib - component: manager-rest - spec: - containers: - - name: katib-manager-rest - image: gcr.io/kubeflow-images-public/katib/v1alpha2/katib-manager-rest - imagePullPolicy: IfNotPresent - command: - - './katib-manager-rest' - ports: - - name: api - containerPort: 80 diff --git a/manifests/v1alpha2/manager-rest/service.yaml b/manifests/v1alpha2/manager-rest/service.yaml deleted file mode 100644 index f267f264ba3..00000000000 --- a/manifests/v1alpha2/manager-rest/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-manager-rest - namespace: kubeflow - labels: - app: katib - component: manager-rest -spec: - type: ClusterIP - ports: - - port: 80 - protocol: TCP - name: api - selector: - app: katib - component: manager-rest diff --git a/manifests/v1alpha2/manager/deployment.yaml b/manifests/v1alpha2/manager/deployment.yaml deleted file mode 100644 index 7d405535f3f..00000000000 --- a/manifests/v1alpha2/manager/deployment.yaml +++ /dev/null @@ -1,44 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-manager - namespace: kubeflow - labels: - app: katib - component: manager -spec: - replicas: 1 - selector: - matchLabels: - app: katib - component: manager - template: - metadata: - name: katib-manager - labels: - app: katib - component: manager - spec: - containers: - - name: katib-manager - image: gcr.io/kubeflow-images-public/katib/v1alpha2/katib-manager - imagePullPolicy: IfNotPresent - env: - - name: MYSQL_ROOT_PASSWORD - valueFrom: - secretKeyRef: - name: katib-db-secrets - key: MYSQL_ROOT_PASSWORD - command: - - './katib-manager' - ports: - - name: api - containerPort: 6789 - readinessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:6789"] - initialDelaySeconds: 5 - livenessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:6789"] - initialDelaySeconds: 10 diff --git a/manifests/v1alpha2/manager/service.yaml b/manifests/v1alpha2/manager/service.yaml deleted file mode 100644 index c0c8bcf27d8..00000000000 --- a/manifests/v1alpha2/manager/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-manager - namespace: kubeflow - labels: - app: katib - component: manager -spec: - type: ClusterIP - ports: - - port: 6789 - protocol: TCP - name: api - selector: - app: katib - component: manager diff --git a/manifests/v1alpha2/pv/pv.yaml b/manifests/v1alpha2/pv/pv.yaml deleted file mode 100644 index a3afad40f31..00000000000 --- a/manifests/v1alpha2/pv/pv.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: PersistentVolume -metadata: - name: katib-mysql - labels: - type: local - app: katib -spec: - storageClassName: katib - capacity: - storage: 10Gi - accessModes: - - ReadWriteOnce - hostPath: - path: /tmp/katib diff --git a/manifests/v1alpha2/pv/pvc.yaml b/manifests/v1alpha2/pv/pvc.yaml deleted file mode 100644 index c454826f51e..00000000000 --- a/manifests/v1alpha2/pv/pvc.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: katib-mysql - namespace: kubeflow - labels: - app: katib -spec: - storageClassName: katib - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 10Gi diff --git a/manifests/v1alpha2/suggestion/bayesianoptimization/deployment.yaml b/manifests/v1alpha2/suggestion/bayesianoptimization/deployment.yaml deleted file mode 100644 index f59c24007b1..00000000000 --- a/manifests/v1alpha2/suggestion/bayesianoptimization/deployment.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-suggestion-bayesianoptimization - namespace: kubeflow - labels: - app: katib - component: suggestion-bayesianoptimization -spec: - replicas: 1 - selector: - matchLabels: - app: katib - component: suggestion-bayesianoptimization - template: - metadata: - name: katib-suggestion-bayesianoptimization - labels: - app: katib - component: suggestion-bayesianoptimization - spec: - containers: - - name: katib-suggestion-bayesianoptimization - image: gcr.io/kubeflow-images-public/katib/v1alpha2/suggestion-bayesianoptimization - imagePullPolicy: IfNotPresent - ports: - - name: api - containerPort: 6789 diff --git a/manifests/v1alpha2/suggestion/bayesianoptimization/service.yaml b/manifests/v1alpha2/suggestion/bayesianoptimization/service.yaml deleted file mode 100644 index 3172288ead5..00000000000 --- a/manifests/v1alpha2/suggestion/bayesianoptimization/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-suggestion-bayesianoptimization - namespace: kubeflow - labels: - app: katib - component: suggestion-bayesianoptimization -spec: - type: ClusterIP - ports: - - port: 6789 - protocol: TCP - name: api - selector: - app: katib - component: suggestion-bayesianoptimization diff --git a/manifests/v1alpha2/suggestion/grid/deployment.yaml b/manifests/v1alpha2/suggestion/grid/deployment.yaml deleted file mode 100644 index 7f50802dcb1..00000000000 --- a/manifests/v1alpha2/suggestion/grid/deployment.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-suggestion-grid - namespace: kubeflow - labels: - app: katib - component: suggestion-grid -spec: - replicas: 1 - selector: - matchLabels: - app: katib - component: suggestion-grid - template: - metadata: - name: katib-suggestion-grid - labels: - app: katib - component: suggestion-grid - spec: - containers: - - name: katib-suggestion-grid - image: gcr.io/kubeflow-images-public/katib/v1alpha2/suggestion-grid - imagePullPolicy: IfNotPresent - ports: - - name: api - containerPort: 6789 diff --git a/manifests/v1alpha2/suggestion/grid/service.yaml b/manifests/v1alpha2/suggestion/grid/service.yaml deleted file mode 100644 index 0c2dd61e332..00000000000 --- a/manifests/v1alpha2/suggestion/grid/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-suggestion-grid - namespace: kubeflow - labels: - app: katib - component: suggestion-grid -spec: - type: ClusterIP - ports: - - port: 6789 - protocol: TCP - name: api - selector: - app: katib - component: suggestion-grid diff --git a/manifests/v1alpha2/suggestion/hyperband/deployment.yaml b/manifests/v1alpha2/suggestion/hyperband/deployment.yaml deleted file mode 100644 index 27142a14897..00000000000 --- a/manifests/v1alpha2/suggestion/hyperband/deployment.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-suggestion-hyperband - namespace: kubeflow - labels: - app: katib - component: suggestion-hyperband -spec: - replicas: 1 - selector: - matchLabels: - app: katib - component: suggestion-hyperband - template: - metadata: - name: katib-suggestion-hyperband - labels: - app: katib - component: suggestion-hyperband - spec: - containers: - - name: katib-suggestion-hyperband - image: gcr.io/kubeflow-images-public/katib/v1alpha2/suggestion-hyperband - imagePullPolicy: IfNotPresent - ports: - - name: api - containerPort: 6789 diff --git a/manifests/v1alpha2/suggestion/hyperband/service.yaml b/manifests/v1alpha2/suggestion/hyperband/service.yaml deleted file mode 100644 index 9648d9dc113..00000000000 --- a/manifests/v1alpha2/suggestion/hyperband/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-suggestion-hyperband - namespace: kubeflow - labels: - app: katib - component: suggestion-hyperband -spec: - type: ClusterIP - ports: - - port: 6789 - protocol: TCP - name: api - selector: - app: katib - component: suggestion-hyperband diff --git a/manifests/v1alpha2/suggestion/nasrl/deployment.yaml b/manifests/v1alpha2/suggestion/nasrl/deployment.yaml deleted file mode 100644 index 7d84e837e31..00000000000 --- a/manifests/v1alpha2/suggestion/nasrl/deployment.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-suggestion-nasrl - namespace: kubeflow - labels: - app: katib - component: suggestion-nasrl -spec: - replicas: 1 - selector: - matchLabels: - app: katib - component: suggestion-nasrl - template: - metadata: - name: katib-suggestion-nasrl - labels: - app: katib - component: suggestion-nasrl - spec: - containers: - - name: katib-suggestion-nasrl - image: gcr.io/kubeflow-images-public/katib/v1alpha2/suggestion-nasrl - ports: - - name: api - containerPort: 6789 diff --git a/manifests/v1alpha2/suggestion/nasrl/service.yaml b/manifests/v1alpha2/suggestion/nasrl/service.yaml deleted file mode 100644 index 12df626c7dc..00000000000 --- a/manifests/v1alpha2/suggestion/nasrl/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-suggestion-nasrl - namespace: kubeflow - labels: - app: katib - component: suggestion-nasrl -spec: - type: ClusterIP - ports: - - port: 6789 - protocol: TCP - name: api - selector: - app: katib - component: suggestion-nasrl diff --git a/manifests/v1alpha2/suggestion/random/deployment.yaml b/manifests/v1alpha2/suggestion/random/deployment.yaml deleted file mode 100644 index 4c4ef25571e..00000000000 --- a/manifests/v1alpha2/suggestion/random/deployment.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-suggestion-random - namespace: kubeflow - labels: - app: katib - component: suggestion-random -spec: - replicas: 1 - selector: - matchLabels: - app: katib - component: suggestion-random - template: - metadata: - name: katib-suggestion-random - labels: - app: katib - component: suggestion-random - spec: - containers: - - name: katib-suggestion-random - image: gcr.io/kubeflow-images-public/katib/v1alpha2/suggestion-random - imagePullPolicy: IfNotPresent - ports: - - name: api - containerPort: 6789 diff --git a/manifests/v1alpha2/suggestion/random/service.yaml b/manifests/v1alpha2/suggestion/random/service.yaml deleted file mode 100644 index 653db93aa1c..00000000000 --- a/manifests/v1alpha2/suggestion/random/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-suggestion-random - namespace: kubeflow - labels: - app: katib - component: suggestion-random -spec: - type: ClusterIP - ports: - - port: 6789 - protocol: TCP - name: api - selector: - app: katib - component: suggestion-random diff --git a/manifests/v1alpha2/ui/deployment.yaml b/manifests/v1alpha2/ui/deployment.yaml deleted file mode 100644 index 9cc74669a8e..00000000000 --- a/manifests/v1alpha2/ui/deployment.yaml +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: katib-ui - namespace: kubeflow - labels: - app: katib - component: ui -spec: - replicas: 1 - selector: - matchLabels: - app: katib - component: ui - template: - metadata: - name: katib-ui - labels: - app: katib - component: ui - spec: - containers: - - name: katib-ui - image: gcr.io/kubeflow-images-public/katib/v1alpha2/katib-ui - imagePullPolicy: IfNotPresent - command: - - './katib-ui' - ports: - - name: ui - containerPort: 80 - serviceAccountName: katib-ui diff --git a/manifests/v1alpha2/ui/rbac.yaml b/manifests/v1alpha2/ui/rbac.yaml deleted file mode 100644 index d99849bf506..00000000000 --- a/manifests/v1alpha2/ui/rbac.yaml +++ /dev/null @@ -1,37 +0,0 @@ -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: katib-ui -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - "*" -- apiGroups: - - kubeflow.org - resources: - - experiments - - trials - verbs: - - "*" ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: katib-ui - namespace: kubeflow ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: katib-ui -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: katib-ui -subjects: -- kind: ServiceAccount - name: katib-ui - namespace: kubeflow diff --git a/manifests/v1alpha2/ui/service.yaml b/manifests/v1alpha2/ui/service.yaml deleted file mode 100644 index e6922313115..00000000000 --- a/manifests/v1alpha2/ui/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: katib-ui - namespace: kubeflow - labels: - app: katib - component: ui -spec: - type: ClusterIP - ports: - - port: 80 - protocol: TCP - name: ui - selector: - app: katib - component: ui diff --git a/pkg/apis/controller/addtoscheme_katib_v1alpha2.go b/pkg/apis/controller/addtoscheme_katib_v1alpha2.go deleted file mode 100644 index 29ee53dfd05..00000000000 --- a/pkg/apis/controller/addtoscheme_katib_v1alpha2.go +++ /dev/null @@ -1,29 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package apis - -import ( - experiments "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - trials "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" -) - -func init() { - // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back - AddToSchemes = append(AddToSchemes, - experiments.SchemeBuilder.AddToScheme, - trials.SchemeBuilder.AddToScheme, - ) -} diff --git a/pkg/apis/controller/common/v1alpha2/common_types.go b/pkg/apis/controller/common/v1alpha2/common_types.go deleted file mode 100644 index 3fe9b6e3f95..00000000000 --- a/pkg/apis/controller/common/v1alpha2/common_types.go +++ /dev/null @@ -1,50 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha2 - -// +k8s:deepcopy-gen=true -type ObjectiveSpec struct { - Type ObjectiveType `json:"type,omitempty"` - Goal *float64 `json:"goal,omitempty"` - ObjectiveMetricName string `json:"objectiveMetricName,omitempty"` - // This can be empty if we only care about the objective metric. - // Note: If we adopt a push instead of pull mechanism, this can be omitted completely. - AdditionalMetricNames []string `json:"additionalMetricNames,omitempty"` -} - -type ObjectiveType string - -const ( - ObjectiveTypeUnknown ObjectiveType = "" - ObjectiveTypeMinimize ObjectiveType = "minimize" - ObjectiveTypeMaximize ObjectiveType = "maximize" -) - -type ParameterAssignment struct { - Name string `json:"name,omitempty"` - Value string `json:"value,omitempty"` -} - -type Metric struct { - Name string `json:"name,omitempty"` - Value float64 `json:"value,omitempty"` -} - -// +k8s:deepcopy-gen=true -type Observation struct { - // Key-value pairs for metric names and values - Metrics []Metric `json:"metrics"` -} diff --git a/pkg/apis/controller/common/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/controller/common/v1alpha2/zz_generated.deepcopy.go deleted file mode 100644 index aed6316aaf0..00000000000 --- a/pkg/apis/controller/common/v1alpha2/zz_generated.deepcopy.go +++ /dev/null @@ -1,67 +0,0 @@ -// +build !ignore_autogenerated - -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -// Code generated by main. DO NOT EDIT. - -package v1alpha2 - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ObjectiveSpec) DeepCopyInto(out *ObjectiveSpec) { - *out = *in - if in.Goal != nil { - in, out := &in.Goal, &out.Goal - *out = new(float64) - **out = **in - } - if in.AdditionalMetricNames != nil { - in, out := &in.AdditionalMetricNames, &out.AdditionalMetricNames - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectiveSpec. -func (in *ObjectiveSpec) DeepCopy() *ObjectiveSpec { - if in == nil { - return nil - } - out := new(ObjectiveSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Observation) DeepCopyInto(out *Observation) { - *out = *in - if in.Metrics != nil { - in, out := &in.Metrics, &out.Metrics - *out = make([]Metric, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Observation. -func (in *Observation) DeepCopy() *Observation { - if in == nil { - return nil - } - out := new(Observation) - in.DeepCopyInto(out) - return out -} diff --git a/pkg/apis/controller/experiments/v1alpha2/constants.go b/pkg/apis/controller/experiments/v1alpha2/constants.go deleted file mode 100644 index 550618e1432..00000000000 --- a/pkg/apis/controller/experiments/v1alpha2/constants.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -package v1alpha2 - -const ( - // Default value of Spec.ParallelTrialCount - DefaultTrialParallelCount = 3 - - // Default value of Spec.ConfigMapName for Trial template - DefaultTrialConfigMapName = "trial-template" - - // Default env name of katib namespace - DefaultKatibNamespaceEnvName = "KATIB_CORE_NAMESPACE" - - // Default value of Spec.TemplatePath - DefaultTrialTemplatePath = "defaultTrialTemplate.yaml" - - // Default value of Spec.ConfigMapName for Metrics Collector template - DefaultMetricsCollectorConfigMapName = "metrics-collector-template" -) diff --git a/pkg/apis/controller/experiments/v1alpha2/doc.go b/pkg/apis/controller/experiments/v1alpha2/doc.go deleted file mode 100644 index e4168715dd9..00000000000 --- a/pkg/apis/controller/experiments/v1alpha2/doc.go +++ /dev/null @@ -1,23 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package v1alpha2 contains API Schema definitions for the experiment v1alpha2 API group -// +k8s:openapi-gen=true -// +k8s:deepcopy-gen=package,register -// +k8s:conversion-gen=github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2 -// +k8s:defaulter-gen=TypeMeta -// +kubebuilder:subresource:status -// +groupName=experiment.kubeflow.org -package v1alpha2 diff --git a/pkg/apis/controller/experiments/v1alpha2/experiment_defaults.go b/pkg/apis/controller/experiments/v1alpha2/experiment_defaults.go deleted file mode 100644 index b178eb3f979..00000000000 --- a/pkg/apis/controller/experiments/v1alpha2/experiment_defaults.go +++ /dev/null @@ -1,56 +0,0 @@ -// +build !ignore_autogenerated - -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -// Code generated by main. DO NOT EDIT. - -package v1alpha2 - -import ( - "os" -) - -func (e *Experiment) SetDefault() { - e.setDefaultParallelTrialCount() - e.setDefaultTrialTemplate() -} - -func (e *Experiment) setDefaultParallelTrialCount() { - if e.Spec.ParallelTrialCount == nil { - e.Spec.ParallelTrialCount = new(int32) - *e.Spec.ParallelTrialCount = DefaultTrialParallelCount - } -} - -func (e *Experiment) setDefaultTrialTemplate() { - t := e.Spec.TrialTemplate - if t == nil { - t = &TrialTemplate{ - Retain: true, - } - } - if t.GoTemplate == nil { - t.GoTemplate = &GoTemplate{} - } - if t.GoTemplate.RawTemplate == "" && t.GoTemplate.TemplateSpec == nil { - t.GoTemplate.TemplateSpec = &TemplateSpec{ - ConfigMapNamespace: os.Getenv(DefaultKatibNamespaceEnvName), - ConfigMapName: DefaultTrialConfigMapName, - TemplatePath: DefaultTrialTemplatePath, - } - } - e.Spec.TrialTemplate = t -} diff --git a/pkg/apis/controller/experiments/v1alpha2/experiment_types.go b/pkg/apis/controller/experiments/v1alpha2/experiment_types.go deleted file mode 100644 index 6190ba70213..00000000000 --- a/pkg/apis/controller/experiments/v1alpha2/experiment_types.go +++ /dev/null @@ -1,248 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha2 - -import ( - common "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type ExperimentSpec struct { - // List of hyperparameter configurations. - Parameters []ParameterSpec `json:"parameters,omitempty"` - - // Describes the objective of the experiment. - Objective *common.ObjectiveSpec `json:"objective,omitempty"` - - // Describes the suggestion algorithm. - Algorithm *AlgorithmSpec `json:"algorithm,omitempty"` - - // Template for each run of the trial. - TrialTemplate *TrialTemplate `json:"trialTemplate,omitempty"` - - // How many trials can be processed in parallel. - // Defaults to 3 - ParallelTrialCount *int32 `json:"parallelTrialCount,omitempty"` - - // Max completed trials to mark experiment as succeeded - MaxTrialCount *int32 `json:"maxTrialCount,omitempty"` - - // Max failed trials to mark experiment as failed. - MaxFailedTrialCount *int32 `json:"maxFailedTrialCount,omitempty"` - - // Whether to retain historical data in DB after deletion. - RetainHistoricalData bool `json:"retainHistoricalData,omitempty"` - - // For v1alpha2 we will keep the metrics collector implementation same as v1alpha1. - MetricsCollectorSpec *MetricsCollectorSpec `json:"metricsCollectorSpec,omitempty"` - - NasConfig *NasConfig `json:"nasConfig,omitempty"` - - // TODO - Other fields, exact format is TBD. Will add these back during implementation. - // - Early stopping - // - Resume experiment -} - -type ExperimentStatus struct { - // Represents time when the Experiment was acknowledged by the Experiment controller. - // It is not guaranteed to be set in happens-before order across separate operations. - // It is represented in RFC3339 form and is in UTC. - StartTime *metav1.Time `json:"startTime,omitempty"` - - // Represents time when the Experiment was completed. It is not guaranteed to - // be set in happens-before order across separate operations. - // It is represented in RFC3339 form and is in UTC. - CompletionTime *metav1.Time `json:"completionTime,omitempty"` - - // Represents last time when the Experiment was reconciled. It is not guaranteed to - // be set in happens-before order across separate operations. - // It is represented in RFC3339 form and is in UTC. - LastReconcileTime *metav1.Time `json:"lastReconcileTime,omitempty"` - - // List of observed runtime conditions for this Experiment. - Conditions []ExperimentCondition `json:"conditions,omitempty"` - - // Current optimal trial parameters and observations. - CurrentOptimalTrial OptimalTrial `json:"currentOptimalTrial,omitempty"` - - // Trials is the total number of trials owned by the experiment. - Trials int32 `json:"trials,omitempty"` - - // How many trials have succeeded. - TrialsSucceeded int32 `json:"trialsSucceeded,omitempty"` - - // How many trials have failed. - TrialsFailed int32 `json:"trialsFailed,omitempty"` - - // How many trials have been killed. - TrialsKilled int32 `json:"trialsKilled,omitempty"` - - // How many trials are currently pending. - TrialsPending int32 `json:"trialsPending,omitempty"` - - // How many trials are currently running. - TrialsRunning int32 `json:"trialsRunning,omitempty"` -} - -type OptimalTrial struct { - // Key-value pairs for hyperparameters and assignment values. - ParameterAssignments []common.ParameterAssignment `json:"parameterAssignments"` - - // Observation for this trial - Observation common.Observation `json:"observation,omitempty"` -} - -// +k8s:deepcopy-gen=true -// ExperimentCondition describes the state of the experiment at a certain point. -type ExperimentCondition struct { - // Type of experiment condition. - Type ExperimentConditionType `json:"type"` - - // Status of the condition, one of True, False, Unknown. - Status v1.ConditionStatus `json:"status"` - - // The reason for the condition's last transition. - Reason string `json:"reason,omitempty"` - - // A human readable message indicating details about the transition. - Message string `json:"message,omitempty"` - - // The last time this condition was updated. - LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"` - - // Last time the condition transitioned from one status to another. - LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` -} - -// ExperimentConditionType defines the state of an Experiment. -type ExperimentConditionType string - -const ( - ExperimentCreated ExperimentConditionType = "Created" - ExperimentRunning ExperimentConditionType = "Running" - ExperimentRestarting ExperimentConditionType = "Restarting" - ExperimentSucceeded ExperimentConditionType = "Succeeded" - ExperimentFailed ExperimentConditionType = "Failed" -) - -type ParameterSpec struct { - Name string `json:"name,omitempty"` - ParameterType ParameterType `json:"parameterType,omitempty"` - FeasibleSpace FeasibleSpace `json:"feasibleSpace,omitempty"` -} - -type ParameterType string - -const ( - ParameterTypeUnknown ParameterType = "unknown" - ParameterTypeDouble ParameterType = "double" - ParameterTypeInt ParameterType = "int" - ParameterTypeDiscrete ParameterType = "discrete" - ParameterTypeCategorical ParameterType = "categorical" -) - -type FeasibleSpace struct { - Max string `json:"max,omitempty"` - Min string `json:"min,omitempty"` - List []string `json:"list,omitempty"` - Step string `json:"step,omitempty"` -} - -type AlgorithmSpec struct { - AlgorithmName string `json:"algorithmName,omitempty"` - // Key-value pairs representing settings for suggestion algorithms. - AlgorithmSettings []AlgorithmSetting `json:"algorithmSettings"` - EarlyStopping *EarlyStoppingSpec `json:"earlyStopping,omitempty"` -} - -type AlgorithmSetting struct { - Name string `json:"name,omitempty"` - Value string `json:"value,omitempty"` -} - -type EarlyStoppingSpec struct { - // TODO -} - -type TrialTemplate struct { - Retain bool `json:"retain,omitempty"` - GoTemplate *GoTemplate `json:"goTemplate,omitempty"` -} - -type TemplateSpec struct { - ConfigMapName string `json:"configMapName,omitempty"` - ConfigMapNamespace string `json:"configMapNamespace,omitempty"` - TemplatePath string `json:"templatePath,omitempty"` -} - -type GoTemplate struct { - TemplateSpec *TemplateSpec `json:"templateSpec,omitempty"` - RawTemplate string `json:"rawTemplate,omitempty"` -} - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// Structure of the Experiment custom resource. -// +k8s:openapi-gen=true -// +kubebuilder:subresource:status -type Experiment struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec ExperimentSpec `json:"spec,omitempty"` - Status ExperimentStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ExperimentList contains a list of Experiments -type ExperimentList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Experiment `json:"items"` -} - -// NasConfig contains config for NAS job -type NasConfig struct { - GraphConfig GraphConfig `json:"graphConfig,omitempty"` - Operations []Operation `json:"operations,omitempty"` -} - -// GraphConfig contains a config of DAG -type GraphConfig struct { - NumLayers *int32 `json:"numLayers,omitempty"` - InputSizes []int32 `json:"inputSizes,omitempty"` - OutputSizes []int32 `json:"outputSizes,omitempty"` -} - -// Operation contains type of operation in DAG -type Operation struct { - OperationType string `json:"operationType,omitempty"` - Parameters []ParameterSpec `json:"parameters,omitempty"` -} - -type MetricsCollectorSpec struct { - // Retain - Retain bool `json:"retain,omitempty"` - // GoTemplate - GoTemplate GoTemplate `json:"goTemplate,omitempty"` -} - -func init() { - SchemeBuilder.Register(&Experiment{}, &ExperimentList{}) -} diff --git a/pkg/apis/controller/experiments/v1alpha2/register.go b/pkg/apis/controller/experiments/v1alpha2/register.go deleted file mode 100644 index 21eab40faf5..00000000000 --- a/pkg/apis/controller/experiments/v1alpha2/register.go +++ /dev/null @@ -1,42 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package v1alpha2 contains API Schema definitions for the experiment v1alpha2 API group -// +k8s:openapi-gen=true -// +k8s:deepcopy-gen=package,register -// +k8s:conversion-gen=github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2 -// +k8s:defaulter-gen=TypeMeta -// +kubebuilder:subresource:status -// +groupName=experiments.kubeflow.org -package v1alpha2 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/runtime/scheme" -) - -const ( - Group = "kubeflow.org" - Version = "v1alpha2" -) - -var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} - AddToScheme = SchemeBuilder.AddToScheme -) diff --git a/pkg/apis/controller/experiments/v1alpha2/util.go b/pkg/apis/controller/experiments/v1alpha2/util.go deleted file mode 100644 index 6a7f34b525c..00000000000 --- a/pkg/apis/controller/experiments/v1alpha2/util.go +++ /dev/null @@ -1,175 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha2 - -import ( - "errors" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - cleanDataFinalizer = "clean-data-in-db" -) - -func getCondition(exp *Experiment, condType ExperimentConditionType) *ExperimentCondition { - if exp.Status.Conditions != nil { - for _, condition := range exp.Status.Conditions { - if condition.Type == condType { - return &condition - } - } - } - return nil -} - -func hasCondition(exp *Experiment, condType ExperimentConditionType) bool { - cond := getCondition(exp, condType) - if cond != nil && cond.Status == v1.ConditionTrue { - return true - } - return false -} - -func (exp *Experiment) removeCondition(condType ExperimentConditionType) { - var newConditions []ExperimentCondition - for _, c := range exp.Status.Conditions { - - if c.Type == condType { - continue - } - - newConditions = append(newConditions, c) - } - exp.Status.Conditions = newConditions -} - -func newCondition(conditionType ExperimentConditionType, status v1.ConditionStatus, reason, message string) ExperimentCondition { - return ExperimentCondition{ - Type: conditionType, - Status: status, - LastUpdateTime: metav1.Now(), - LastTransitionTime: metav1.Now(), - Reason: reason, - Message: message, - } -} - -func (exp *Experiment) IsCreated() bool { - return hasCondition(exp, ExperimentCreated) -} - -func (exp *Experiment) IsSucceeded() bool { - return hasCondition(exp, ExperimentSucceeded) -} - -func (exp *Experiment) IsFailed() bool { - return hasCondition(exp, ExperimentFailed) -} - -func (exp *Experiment) IsRunning() bool { - return hasCondition(exp, ExperimentRunning) -} - -func (exp *Experiment) IsRestarting() bool { - return hasCondition(exp, ExperimentRestarting) -} - -func (exp *Experiment) IsCompleted() bool { - return exp.IsSucceeded() || exp.IsFailed() -} - -func (exp *Experiment) GetLastConditionType() (ExperimentConditionType, error) { - if len(exp.Status.Conditions) > 0 { - return exp.Status.Conditions[len(exp.Status.Conditions)-1].Type, nil - } - return "", errors.New("Experiment doesn't have any condition") -} - -func (exp *Experiment) setCondition(conditionType ExperimentConditionType, status v1.ConditionStatus, reason, message string) { - - newCond := newCondition(conditionType, status, reason, message) - currentCond := getCondition(exp, conditionType) - // Do nothing if condition doesn't change - if currentCond != nil && currentCond.Status == newCond.Status && currentCond.Reason == newCond.Reason { - return - } - - // Do not update lastTransitionTime if the status of the condition doesn't change. - if currentCond != nil && currentCond.Status == newCond.Status { - newCond.LastTransitionTime = currentCond.LastTransitionTime - } - - exp.removeCondition(conditionType) - exp.Status.Conditions = append(exp.Status.Conditions, newCond) -} - -func (exp *Experiment) MarkExperimentStatusCreated(reason, message string) { - exp.setCondition(ExperimentCreated, v1.ConditionTrue, reason, message) -} - -func (exp *Experiment) MarkExperimentStatusRunning(reason, message string) { - //exp.removeCondition(ExperimentRestarting) - exp.setCondition(ExperimentRunning, v1.ConditionTrue, reason, message) -} - -func (exp *Experiment) MarkExperimentStatusSucceeded(reason, message string) { - currentCond := getCondition(exp, ExperimentRunning) - if currentCond != nil { - exp.setCondition(ExperimentRunning, v1.ConditionFalse, currentCond.Reason, currentCond.Message) - } - exp.setCondition(ExperimentSucceeded, v1.ConditionTrue, reason, message) - -} - -func (exp *Experiment) MarkExperimentStatusFailed(reason, message string) { - currentCond := getCondition(exp, ExperimentRunning) - if currentCond != nil { - exp.setCondition(ExperimentRunning, v1.ConditionFalse, currentCond.Reason, currentCond.Message) - } - exp.setCondition(ExperimentFailed, v1.ConditionTrue, reason, message) -} - -func (exp *Experiment) NeedUpdateFinalizers() (bool, []string) { - deleted := !exp.ObjectMeta.DeletionTimestamp.IsZero() - pendingFinalizers := exp.GetFinalizers() - contained := false - for _, elem := range pendingFinalizers { - if elem == cleanDataFinalizer { - contained = true - break - } - } - - if !deleted && !contained { - if exp.Spec.RetainHistoricalData { - return false, []string{} - } - finalizers := append(pendingFinalizers, cleanDataFinalizer) - return true, finalizers - } - if deleted && contained { - finalizers := []string{} - for _, pendingFinalizer := range pendingFinalizers { - if pendingFinalizer != cleanDataFinalizer { - finalizers = append(finalizers, pendingFinalizer) - } - } - return true, finalizers - } - return false, []string{} -} diff --git a/pkg/apis/controller/experiments/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/controller/experiments/v1alpha2/zz_generated.deepcopy.go deleted file mode 100644 index 2533d70081a..00000000000 --- a/pkg/apis/controller/experiments/v1alpha2/zz_generated.deepcopy.go +++ /dev/null @@ -1,474 +0,0 @@ -// +build !ignore_autogenerated - -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -// Code generated by main. DO NOT EDIT. - -package v1alpha2 - -import ( - commonv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AlgorithmSetting) DeepCopyInto(out *AlgorithmSetting) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlgorithmSetting. -func (in *AlgorithmSetting) DeepCopy() *AlgorithmSetting { - if in == nil { - return nil - } - out := new(AlgorithmSetting) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AlgorithmSpec) DeepCopyInto(out *AlgorithmSpec) { - *out = *in - if in.AlgorithmSettings != nil { - in, out := &in.AlgorithmSettings, &out.AlgorithmSettings - *out = make([]AlgorithmSetting, len(*in)) - copy(*out, *in) - } - if in.EarlyStopping != nil { - in, out := &in.EarlyStopping, &out.EarlyStopping - *out = new(EarlyStoppingSpec) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlgorithmSpec. -func (in *AlgorithmSpec) DeepCopy() *AlgorithmSpec { - if in == nil { - return nil - } - out := new(AlgorithmSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EarlyStoppingSpec) DeepCopyInto(out *EarlyStoppingSpec) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EarlyStoppingSpec. -func (in *EarlyStoppingSpec) DeepCopy() *EarlyStoppingSpec { - if in == nil { - return nil - } - out := new(EarlyStoppingSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Experiment) DeepCopyInto(out *Experiment) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Experiment. -func (in *Experiment) DeepCopy() *Experiment { - if in == nil { - return nil - } - out := new(Experiment) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Experiment) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExperimentCondition) DeepCopyInto(out *ExperimentCondition) { - *out = *in - in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExperimentCondition. -func (in *ExperimentCondition) DeepCopy() *ExperimentCondition { - if in == nil { - return nil - } - out := new(ExperimentCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExperimentList) DeepCopyInto(out *ExperimentList) { - *out = *in - out.TypeMeta = in.TypeMeta - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Experiment, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExperimentList. -func (in *ExperimentList) DeepCopy() *ExperimentList { - if in == nil { - return nil - } - out := new(ExperimentList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ExperimentList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExperimentSpec) DeepCopyInto(out *ExperimentSpec) { - *out = *in - if in.Parameters != nil { - in, out := &in.Parameters, &out.Parameters - *out = make([]ParameterSpec, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Objective != nil { - in, out := &in.Objective, &out.Objective - *out = new(commonv1alpha2.ObjectiveSpec) - (*in).DeepCopyInto(*out) - } - if in.Algorithm != nil { - in, out := &in.Algorithm, &out.Algorithm - *out = new(AlgorithmSpec) - (*in).DeepCopyInto(*out) - } - if in.TrialTemplate != nil { - in, out := &in.TrialTemplate, &out.TrialTemplate - *out = new(TrialTemplate) - (*in).DeepCopyInto(*out) - } - if in.ParallelTrialCount != nil { - in, out := &in.ParallelTrialCount, &out.ParallelTrialCount - *out = new(int32) - **out = **in - } - if in.MaxTrialCount != nil { - in, out := &in.MaxTrialCount, &out.MaxTrialCount - *out = new(int32) - **out = **in - } - if in.MaxFailedTrialCount != nil { - in, out := &in.MaxFailedTrialCount, &out.MaxFailedTrialCount - *out = new(int32) - **out = **in - } - if in.MetricsCollectorSpec != nil { - in, out := &in.MetricsCollectorSpec, &out.MetricsCollectorSpec - *out = new(MetricsCollectorSpec) - (*in).DeepCopyInto(*out) - } - if in.NasConfig != nil { - in, out := &in.NasConfig, &out.NasConfig - *out = new(NasConfig) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExperimentSpec. -func (in *ExperimentSpec) DeepCopy() *ExperimentSpec { - if in == nil { - return nil - } - out := new(ExperimentSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExperimentStatus) DeepCopyInto(out *ExperimentStatus) { - *out = *in - if in.StartTime != nil { - in, out := &in.StartTime, &out.StartTime - *out = (*in).DeepCopy() - } - if in.CompletionTime != nil { - in, out := &in.CompletionTime, &out.CompletionTime - *out = (*in).DeepCopy() - } - if in.LastReconcileTime != nil { - in, out := &in.LastReconcileTime, &out.LastReconcileTime - *out = (*in).DeepCopy() - } - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]ExperimentCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - in.CurrentOptimalTrial.DeepCopyInto(&out.CurrentOptimalTrial) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExperimentStatus. -func (in *ExperimentStatus) DeepCopy() *ExperimentStatus { - if in == nil { - return nil - } - out := new(ExperimentStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FeasibleSpace) DeepCopyInto(out *FeasibleSpace) { - *out = *in - if in.List != nil { - in, out := &in.List, &out.List - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeasibleSpace. -func (in *FeasibleSpace) DeepCopy() *FeasibleSpace { - if in == nil { - return nil - } - out := new(FeasibleSpace) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GoTemplate) DeepCopyInto(out *GoTemplate) { - *out = *in - if in.TemplateSpec != nil { - in, out := &in.TemplateSpec, &out.TemplateSpec - *out = new(TemplateSpec) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoTemplate. -func (in *GoTemplate) DeepCopy() *GoTemplate { - if in == nil { - return nil - } - out := new(GoTemplate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GraphConfig) DeepCopyInto(out *GraphConfig) { - *out = *in - if in.NumLayers != nil { - in, out := &in.NumLayers, &out.NumLayers - *out = new(int32) - **out = **in - } - if in.InputSizes != nil { - in, out := &in.InputSizes, &out.InputSizes - *out = make([]int32, len(*in)) - copy(*out, *in) - } - if in.OutputSizes != nil { - in, out := &in.OutputSizes, &out.OutputSizes - *out = make([]int32, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GraphConfig. -func (in *GraphConfig) DeepCopy() *GraphConfig { - if in == nil { - return nil - } - out := new(GraphConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetricsCollectorSpec) DeepCopyInto(out *MetricsCollectorSpec) { - *out = *in - in.GoTemplate.DeepCopyInto(&out.GoTemplate) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsCollectorSpec. -func (in *MetricsCollectorSpec) DeepCopy() *MetricsCollectorSpec { - if in == nil { - return nil - } - out := new(MetricsCollectorSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NasConfig) DeepCopyInto(out *NasConfig) { - *out = *in - in.GraphConfig.DeepCopyInto(&out.GraphConfig) - if in.Operations != nil { - in, out := &in.Operations, &out.Operations - *out = make([]Operation, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NasConfig. -func (in *NasConfig) DeepCopy() *NasConfig { - if in == nil { - return nil - } - out := new(NasConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Operation) DeepCopyInto(out *Operation) { - *out = *in - if in.Parameters != nil { - in, out := &in.Parameters, &out.Parameters - *out = make([]ParameterSpec, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Operation. -func (in *Operation) DeepCopy() *Operation { - if in == nil { - return nil - } - out := new(Operation) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OptimalTrial) DeepCopyInto(out *OptimalTrial) { - *out = *in - if in.ParameterAssignments != nil { - in, out := &in.ParameterAssignments, &out.ParameterAssignments - *out = make([]commonv1alpha2.ParameterAssignment, len(*in)) - copy(*out, *in) - } - in.Observation.DeepCopyInto(&out.Observation) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OptimalTrial. -func (in *OptimalTrial) DeepCopy() *OptimalTrial { - if in == nil { - return nil - } - out := new(OptimalTrial) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ParameterSpec) DeepCopyInto(out *ParameterSpec) { - *out = *in - in.FeasibleSpace.DeepCopyInto(&out.FeasibleSpace) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParameterSpec. -func (in *ParameterSpec) DeepCopy() *ParameterSpec { - if in == nil { - return nil - } - out := new(ParameterSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TemplateSpec) DeepCopyInto(out *TemplateSpec) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateSpec. -func (in *TemplateSpec) DeepCopy() *TemplateSpec { - if in == nil { - return nil - } - out := new(TemplateSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TrialTemplate) DeepCopyInto(out *TrialTemplate) { - *out = *in - if in.GoTemplate != nil { - in, out := &in.GoTemplate, &out.GoTemplate - *out = new(GoTemplate) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrialTemplate. -func (in *TrialTemplate) DeepCopy() *TrialTemplate { - if in == nil { - return nil - } - out := new(TrialTemplate) - in.DeepCopyInto(out) - return out -} diff --git a/pkg/apis/controller/trials/v1alpha2/doc.go b/pkg/apis/controller/trials/v1alpha2/doc.go deleted file mode 100644 index f6203daaf50..00000000000 --- a/pkg/apis/controller/trials/v1alpha2/doc.go +++ /dev/null @@ -1,23 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package v1alpha2 contains API Schema definitions for the trial v1alpha2 API group -// +k8s:openapi-gen=true -// +k8s:deepcopy-gen=package,register -// +k8s:conversion-gen=github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2 -// +k8s:defaulter-gen=TypeMeta -// +kubebuilder:subresource:status -// +groupName=trial.kubeflow.org -package v1alpha2 diff --git a/pkg/apis/controller/trials/v1alpha2/register.go b/pkg/apis/controller/trials/v1alpha2/register.go deleted file mode 100644 index a74414b1df9..00000000000 --- a/pkg/apis/controller/trials/v1alpha2/register.go +++ /dev/null @@ -1,42 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package v1alpha2 contains API Schema definitions for the trial v1alpha2 API group -// +k8s:openapi-gen=true -// +k8s:deepcopy-gen=package,register -// +k8s:conversion-gen=github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2 -// +k8s:defaulter-gen=TypeMeta -// +kubebuilder:subresource:status -// +groupName=trials.kubeflow.org -package v1alpha2 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/runtime/scheme" -) - -const ( - Group = "kubeflow.org" - Version = "v1alpha2" -) - -var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} - AddToScheme = SchemeBuilder.AddToScheme -) diff --git a/pkg/apis/controller/trials/v1alpha2/trial_types.go b/pkg/apis/controller/trials/v1alpha2/trial_types.go deleted file mode 100644 index 94c738cba5f..00000000000 --- a/pkg/apis/controller/trials/v1alpha2/trial_types.go +++ /dev/null @@ -1,128 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha2 - -import ( - common "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type TrialSpec struct { - // Describes the objective of the experiment. - Objective *common.ObjectiveSpec `json:"objective,omitempty"` - - // Key-value pairs for hyperparameters and assignment values. - ParameterAssignments []common.ParameterAssignment `json:"parameterAssignments"` - - // Raw text for the trial run spec. This can be any generic Kubernetes - // runtime object. The trial operator should create the resource as written, - // and let the corresponding resource controller (e.g. tf-operator) handle - // the rest. - RunSpec string `json:"runSpec,omitempty"` - // Whether to retain the trial run object after completed. - RetainRun bool `json:"retainRun,omitempty"` - - // Raw text for the metrics collector spec. This must be a CronJob object. - // Deprecated - MetricsCollectorSpec string `json:"metricsCollectorSpec,omitempty"` - // Whether to retain the trial metrics collector CronJob object after completed. - // Deprecated - RetainMetricsCollector bool `json:"retainMetricsCollector,omitempty"` -} - -type TrialStatus struct { - // Represents time when the Trial was acknowledged by the Trial controller. - // It is not guaranteed to be set in happens-before order across separate operations. - // It is represented in RFC3339 form and is in UTC - StartTime *metav1.Time `json:"startTime,omitempty"` - - // Represents time when the Trial was completed. It is not guaranteed to - // be set in happens-before order across separate operations. - // It is represented in RFC3339 form and is in UTC - CompletionTime *metav1.Time `json:"completionTime,omitempty"` - - // Represents last time when the Trial was reconciled. It is not guaranteed to - // be set in happens-before order across separate operations. - // It is represented in RFC3339 form and is in UTC. - LastReconcileTime *metav1.Time `json:"lastReconcileTime,omitempty"` - - // List of observed runtime conditions for this Trial. - Conditions []TrialCondition `json:"conditions,omitempty"` - - // Results of the Trial - objectives and other metrics values. - Observation *common.Observation `json:"observation,omitempty"` -} - -// +k8s:deepcopy-gen=true -// TrialCondition describes the state of the trial at a certain point. -type TrialCondition struct { - // Type of trial condition. - Type TrialConditionType `json:"type"` - - // Status of the condition, one of True, False, Unknown. - Status v1.ConditionStatus `json:"status"` - - // The reason for the condition's last transition. - Reason string `json:"reason,omitempty"` - - // A human readable message indicating details about the transition. - Message string `json:"message,omitempty"` - - // The last time this condition was updated. - LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"` - - // Last time the condition transitioned from one status to another. - LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` -} - -// TrialConditionType describes the various conditions a Trial can be in. -type TrialConditionType string - -const ( - TrialCreated TrialConditionType = "Created" - TrialRunning TrialConditionType = "Running" - TrialSucceeded TrialConditionType = "Succeeded" - TrialKilled TrialConditionType = "Killed" - TrialFailed TrialConditionType = "Failed" -) - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// Represents the structure of a Trial resource. -// +k8s:openapi-gen=true -// +kubebuilder:subresource:status -type Trial struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec TrialSpec `json:"spec,omitempty"` - Status TrialStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// TrialList contains a list of Trials -type TrialList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Trial `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Trial{}, &TrialList{}) -} diff --git a/pkg/apis/controller/trials/v1alpha2/util.go b/pkg/apis/controller/trials/v1alpha2/util.go deleted file mode 100644 index 9a6312334ce..00000000000 --- a/pkg/apis/controller/trials/v1alpha2/util.go +++ /dev/null @@ -1,146 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha2 - -import ( - "errors" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func getCondition(trial *Trial, condType TrialConditionType) *TrialCondition { - for _, condition := range trial.Status.Conditions { - if condition.Type == condType { - return &condition - } - } - return nil -} - -func hasCondition(trial *Trial, condType TrialConditionType) bool { - cond := getCondition(trial, condType) - if cond != nil && cond.Status == v1.ConditionTrue { - return true - } - return false -} - -func (trial *Trial) removeCondition(condType TrialConditionType) { - var newConditions []TrialCondition - for _, c := range trial.Status.Conditions { - - if c.Type == condType { - continue - } - - newConditions = append(newConditions, c) - } - trial.Status.Conditions = newConditions -} - -func newCondition(conditionType TrialConditionType, status v1.ConditionStatus, reason, message string) TrialCondition { - return TrialCondition{ - Type: conditionType, - Status: status, - LastUpdateTime: metav1.Now(), - LastTransitionTime: metav1.Now(), - Reason: reason, - Message: message, - } -} - -func (trial *Trial) IsCreated() bool { - return hasCondition(trial, TrialCreated) -} - -func (trial *Trial) IsRunning() bool { - return hasCondition(trial, TrialRunning) -} - -func (trial *Trial) IsSucceeded() bool { - return hasCondition(trial, TrialSucceeded) -} - -func (trial *Trial) IsFailed() bool { - return hasCondition(trial, TrialFailed) -} - -func (trial *Trial) IsKilled() bool { - return hasCondition(trial, TrialKilled) -} - -func (trial *Trial) IsCompleted() bool { - return trial.IsSucceeded() || trial.IsFailed() || trial.IsKilled() -} - -func (trial *Trial) GetLastConditionType() (TrialConditionType, error) { - if len(trial.Status.Conditions) > 0 { - return trial.Status.Conditions[len(trial.Status.Conditions)-1].Type, nil - } - return "", errors.New("Trial doesn't have any condition") -} - -func (trial *Trial) setCondition(conditionType TrialConditionType, status v1.ConditionStatus, reason, message string) { - - newCond := newCondition(conditionType, status, reason, message) - currentCond := getCondition(trial, conditionType) - // Do nothing if condition doesn't change - if currentCond != nil && currentCond.Status == newCond.Status && currentCond.Reason == newCond.Reason { - return - } - - // Do not update lastTransitionTime if the status of the condition doesn't change. - if currentCond != nil && currentCond.Status == newCond.Status { - newCond.LastTransitionTime = currentCond.LastTransitionTime - } - - trial.removeCondition(conditionType) - trial.Status.Conditions = append(trial.Status.Conditions, newCond) -} - -func (trial *Trial) MarkTrialStatusCreated(reason, message string) { - trial.setCondition(TrialCreated, v1.ConditionTrue, reason, message) -} - -func (trial *Trial) MarkTrialStatusRunning(reason, message string) { - trial.setCondition(TrialRunning, v1.ConditionTrue, reason, message) -} - -func (trial *Trial) MarkTrialStatusSucceeded(reason, message string) { - currentCond := getCondition(trial, TrialRunning) - if currentCond != nil { - trial.setCondition(TrialRunning, v1.ConditionFalse, currentCond.Reason, currentCond.Message) - } - trial.setCondition(TrialSucceeded, v1.ConditionTrue, reason, message) - -} - -func (trial *Trial) MarkTrialStatusFailed(reason, message string) { - currentCond := getCondition(trial, TrialRunning) - if currentCond != nil { - trial.setCondition(TrialRunning, v1.ConditionFalse, currentCond.Reason, currentCond.Message) - } - trial.setCondition(TrialFailed, v1.ConditionTrue, reason, message) -} - -func (trial *Trial) MarkTrialStatusKilled(reason, message string) { - currentCond := getCondition(trial, TrialRunning) - if currentCond != nil { - trial.setCondition(TrialRunning, v1.ConditionFalse, currentCond.Reason, currentCond.Message) - } - trial.setCondition(TrialKilled, v1.ConditionTrue, reason, message) -} diff --git a/pkg/apis/controller/trials/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/controller/trials/v1alpha2/zz_generated.deepcopy.go deleted file mode 100644 index 2c40c00c6e6..00000000000 --- a/pkg/apis/controller/trials/v1alpha2/zz_generated.deepcopy.go +++ /dev/null @@ -1,170 +0,0 @@ -// +build !ignore_autogenerated - -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -// Code generated by main. DO NOT EDIT. - -package v1alpha2 - -import ( - commonv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Trial) DeepCopyInto(out *Trial) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Trial. -func (in *Trial) DeepCopy() *Trial { - if in == nil { - return nil - } - out := new(Trial) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Trial) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TrialCondition) DeepCopyInto(out *TrialCondition) { - *out = *in - in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrialCondition. -func (in *TrialCondition) DeepCopy() *TrialCondition { - if in == nil { - return nil - } - out := new(TrialCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TrialList) DeepCopyInto(out *TrialList) { - *out = *in - out.TypeMeta = in.TypeMeta - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Trial, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrialList. -func (in *TrialList) DeepCopy() *TrialList { - if in == nil { - return nil - } - out := new(TrialList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *TrialList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TrialSpec) DeepCopyInto(out *TrialSpec) { - *out = *in - if in.Objective != nil { - in, out := &in.Objective, &out.Objective - *out = new(commonv1alpha2.ObjectiveSpec) - (*in).DeepCopyInto(*out) - } - if in.ParameterAssignments != nil { - in, out := &in.ParameterAssignments, &out.ParameterAssignments - *out = make([]commonv1alpha2.ParameterAssignment, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrialSpec. -func (in *TrialSpec) DeepCopy() *TrialSpec { - if in == nil { - return nil - } - out := new(TrialSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TrialStatus) DeepCopyInto(out *TrialStatus) { - *out = *in - if in.StartTime != nil { - in, out := &in.StartTime, &out.StartTime - *out = (*in).DeepCopy() - } - if in.CompletionTime != nil { - in, out := &in.CompletionTime, &out.CompletionTime - *out = (*in).DeepCopy() - } - if in.LastReconcileTime != nil { - in, out := &in.LastReconcileTime, &out.LastReconcileTime - *out = (*in).DeepCopy() - } - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]TrialCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Observation != nil { - in, out := &in.Observation, &out.Observation - *out = new(commonv1alpha2.Observation) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrialStatus. -func (in *TrialStatus) DeepCopy() *TrialStatus { - if in == nil { - return nil - } - out := new(TrialStatus) - in.DeepCopyInto(out) - return out -} diff --git a/pkg/apis/README.md b/pkg/apis/manager/README.md similarity index 80% rename from pkg/apis/README.md rename to pkg/apis/manager/README.md index 5e4ac5e08a1..cebb05ccc6c 100644 --- a/pkg/apis/README.md +++ b/pkg/apis/manager/README.md @@ -6,12 +6,12 @@ EarlyStopping service is an API for EarlyStopping services. ## Documentation Please refer to the `api.md`: - * [v1alpha2 documentation](./v1alpha2/gen-doc/api.md) + * [v1alpha3 documentation](./v1alpha3/gen-doc/api.md) ## Update API and generate documents When you want to edit the API, please only edit the corresponding `api.proto` and generate other files from it: - * [v1alpha2/api.proto](./v1alpha2/api.proto) + * [v1alpha3/api.proto](./v1alpha3/api.proto) Documents are also generated from `api.proto` by [protoc-gen-doc](https://github.com/pseudomuto/protoc-gen-doc). Running `build.sh` can update every file from `api.proto` and generate docs: - * [v1alpha2/build.sh](./v1alpha2/build.sh) + * [v1alpha3/build.sh](./v1alpha3/build.sh) diff --git a/pkg/apis/manager/v1alpha2/Makefile b/pkg/apis/manager/v1alpha2/Makefile deleted file mode 100644 index f63e1d5a8f4..00000000000 --- a/pkg/apis/manager/v1alpha2/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -api.pb.go: api.proto - protoc -I. api.proto --go_out=plugins=grpc:. diff --git a/pkg/apis/manager/v1alpha2/api.pb.go b/pkg/apis/manager/v1alpha2/api.pb.go deleted file mode 100644 index a43ced37a6d..00000000000 --- a/pkg/apis/manager/v1alpha2/api.pb.go +++ /dev/null @@ -1,2531 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: api.proto - -/* -Package api_v1_alpha2 is a generated protocol buffer package. - -It is generated from these files: - api.proto - -It has these top-level messages: - FeasibleSpace - ParameterSpec - ObjectiveSpec - AlgorithmSetting - EarlyStoppingSpec - AlgorithmSpec - NasConfig - GraphConfig - Operation - ExperimentSpec - ExperimentStatus - Experiment - ParameterAssignment - Metric - MetricLog - Observation - ObservationLog - TrialSpec - TrialStatus - Trial - RegisterExperimentRequest - RegisterExperimentReply - PreCheckRegisterExperimentReply - DeleteExperimentRequest - DeleteExperimentReply - GetExperimentRequest - GetExperimentReply - ExperimentSummary - GetExperimentListRequest - GetExperimentListReply - UpdateExperimentStatusRequest - UpdateExperimentStatusReply - UpdateAlgorithmExtraSettingsRequest - UpdateAlgorithmExtraSettingsReply - GetAlgorithmExtraSettingsRequest - GetAlgorithmExtraSettingsReply - RegisterTrialRequest - RegisterTrialReply - DeleteTrialRequest - DeleteTrialReply - GetTrialListRequest - GetTrialListReply - GetTrialRequest - GetTrialReply - UpdateTrialStatusRequest - UpdateTrialStatusReply - ReportObservationLogRequest - ReportObservationLogReply - GetObservationLogRequest - GetObservationLogReply - GetSuggestionsRequest - GetSuggestionsReply - ValidateAlgorithmSettingsRequest - ValidateAlgorithmSettingsReply -*/ -package api_v1_alpha2 - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import _ "google.golang.org/genproto/googleapis/api/annotations" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// * -// Types of value for HyperParameter. -type ParameterType int32 - -const ( - ParameterType_UNKNOWN_TYPE ParameterType = 0 - ParameterType_DOUBLE ParameterType = 1 - ParameterType_INT ParameterType = 2 - ParameterType_DISCRETE ParameterType = 3 - ParameterType_CATEGORICAL ParameterType = 4 -) - -var ParameterType_name = map[int32]string{ - 0: "UNKNOWN_TYPE", - 1: "DOUBLE", - 2: "INT", - 3: "DISCRETE", - 4: "CATEGORICAL", -} -var ParameterType_value = map[string]int32{ - "UNKNOWN_TYPE": 0, - "DOUBLE": 1, - "INT": 2, - "DISCRETE": 3, - "CATEGORICAL": 4, -} - -func (x ParameterType) String() string { - return proto.EnumName(ParameterType_name, int32(x)) -} -func (ParameterType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -// * -// Direction of optimization. Minimize or Maximize. -type ObjectiveType int32 - -const ( - ObjectiveType_UNKNOWN ObjectiveType = 0 - ObjectiveType_MINIMIZE ObjectiveType = 1 - ObjectiveType_MAXIMIZE ObjectiveType = 2 -) - -var ObjectiveType_name = map[int32]string{ - 0: "UNKNOWN", - 1: "MINIMIZE", - 2: "MAXIMIZE", -} -var ObjectiveType_value = map[string]int32{ - "UNKNOWN": 0, - "MINIMIZE": 1, - "MAXIMIZE": 2, -} - -func (x ObjectiveType) String() string { - return proto.EnumName(ObjectiveType_name, int32(x)) -} -func (ObjectiveType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -type ExperimentStatus_ExperimentConditionType int32 - -const ( - ExperimentStatus_CREATED ExperimentStatus_ExperimentConditionType = 0 - ExperimentStatus_RUNNING ExperimentStatus_ExperimentConditionType = 1 - ExperimentStatus_RESTARTING ExperimentStatus_ExperimentConditionType = 2 - ExperimentStatus_SUCCEEDED ExperimentStatus_ExperimentConditionType = 3 - ExperimentStatus_FAILED ExperimentStatus_ExperimentConditionType = 4 - ExperimentStatus_UNKNOWN ExperimentStatus_ExperimentConditionType = 5 -) - -var ExperimentStatus_ExperimentConditionType_name = map[int32]string{ - 0: "CREATED", - 1: "RUNNING", - 2: "RESTARTING", - 3: "SUCCEEDED", - 4: "FAILED", - 5: "UNKNOWN", -} -var ExperimentStatus_ExperimentConditionType_value = map[string]int32{ - "CREATED": 0, - "RUNNING": 1, - "RESTARTING": 2, - "SUCCEEDED": 3, - "FAILED": 4, - "UNKNOWN": 5, -} - -func (x ExperimentStatus_ExperimentConditionType) String() string { - return proto.EnumName(ExperimentStatus_ExperimentConditionType_name, int32(x)) -} -func (ExperimentStatus_ExperimentConditionType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor0, []int{10, 0} -} - -type TrialStatus_TrialConditionType int32 - -const ( - TrialStatus_CREATED TrialStatus_TrialConditionType = 0 - TrialStatus_RUNNING TrialStatus_TrialConditionType = 1 - TrialStatus_SUCCEEDED TrialStatus_TrialConditionType = 2 - TrialStatus_KILLED TrialStatus_TrialConditionType = 3 - TrialStatus_FAILED TrialStatus_TrialConditionType = 4 - TrialStatus_UNKNOWN TrialStatus_TrialConditionType = 5 -) - -var TrialStatus_TrialConditionType_name = map[int32]string{ - 0: "CREATED", - 1: "RUNNING", - 2: "SUCCEEDED", - 3: "KILLED", - 4: "FAILED", - 5: "UNKNOWN", -} -var TrialStatus_TrialConditionType_value = map[string]int32{ - "CREATED": 0, - "RUNNING": 1, - "SUCCEEDED": 2, - "KILLED": 3, - "FAILED": 4, - "UNKNOWN": 5, -} - -func (x TrialStatus_TrialConditionType) String() string { - return proto.EnumName(TrialStatus_TrialConditionType_name, int32(x)) -} -func (TrialStatus_TrialConditionType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor0, []int{18, 0} -} - -// * -// Feasible space for optimization. -// Int and Double type use Max/Min. -// Discrete and Categorical type use List. -type FeasibleSpace struct { - Max string `protobuf:"bytes,1,opt,name=max" json:"max,omitempty"` - Min string `protobuf:"bytes,2,opt,name=min" json:"min,omitempty"` - List []string `protobuf:"bytes,3,rep,name=list" json:"list,omitempty"` - Step string `protobuf:"bytes,4,opt,name=step" json:"step,omitempty"` -} - -func (m *FeasibleSpace) Reset() { *m = FeasibleSpace{} } -func (m *FeasibleSpace) String() string { return proto.CompactTextString(m) } -func (*FeasibleSpace) ProtoMessage() {} -func (*FeasibleSpace) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -func (m *FeasibleSpace) GetMax() string { - if m != nil { - return m.Max - } - return "" -} - -func (m *FeasibleSpace) GetMin() string { - if m != nil { - return m.Min - } - return "" -} - -func (m *FeasibleSpace) GetList() []string { - if m != nil { - return m.List - } - return nil -} - -func (m *FeasibleSpace) GetStep() string { - if m != nil { - return m.Step - } - return "" -} - -// * -// Config for a Hyper parameter. -// Katib will create each Hyper parameter from this config. -type ParameterSpec struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - ParameterType ParameterType `protobuf:"varint,2,opt,name=parameter_type,json=parameterType,enum=api.v1.alpha2.ParameterType" json:"parameter_type,omitempty"` - FeasibleSpace *FeasibleSpace `protobuf:"bytes,3,opt,name=feasible_space,json=feasibleSpace" json:"feasible_space,omitempty"` -} - -func (m *ParameterSpec) Reset() { *m = ParameterSpec{} } -func (m *ParameterSpec) String() string { return proto.CompactTextString(m) } -func (*ParameterSpec) ProtoMessage() {} -func (*ParameterSpec) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *ParameterSpec) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *ParameterSpec) GetParameterType() ParameterType { - if m != nil { - return m.ParameterType - } - return ParameterType_UNKNOWN_TYPE -} - -func (m *ParameterSpec) GetFeasibleSpace() *FeasibleSpace { - if m != nil { - return m.FeasibleSpace - } - return nil -} - -type ObjectiveSpec struct { - Type ObjectiveType `protobuf:"varint,1,opt,name=type,enum=api.v1.alpha2.ObjectiveType" json:"type,omitempty"` - Goal float32 `protobuf:"fixed32,2,opt,name=goal" json:"goal,omitempty"` - ObjectiveMetricName string `protobuf:"bytes,3,opt,name=objective_metric_name,json=objectiveMetricName" json:"objective_metric_name,omitempty"` - AdditionalMetricNames []string `protobuf:"bytes,4,rep,name=additional_metric_names,json=additionalMetricNames" json:"additional_metric_names,omitempty"` -} - -func (m *ObjectiveSpec) Reset() { *m = ObjectiveSpec{} } -func (m *ObjectiveSpec) String() string { return proto.CompactTextString(m) } -func (*ObjectiveSpec) ProtoMessage() {} -func (*ObjectiveSpec) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -func (m *ObjectiveSpec) GetType() ObjectiveType { - if m != nil { - return m.Type - } - return ObjectiveType_UNKNOWN -} - -func (m *ObjectiveSpec) GetGoal() float32 { - if m != nil { - return m.Goal - } - return 0 -} - -func (m *ObjectiveSpec) GetObjectiveMetricName() string { - if m != nil { - return m.ObjectiveMetricName - } - return "" -} - -func (m *ObjectiveSpec) GetAdditionalMetricNames() []string { - if m != nil { - return m.AdditionalMetricNames - } - return nil -} - -type AlgorithmSetting struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *AlgorithmSetting) Reset() { *m = AlgorithmSetting{} } -func (m *AlgorithmSetting) String() string { return proto.CompactTextString(m) } -func (*AlgorithmSetting) ProtoMessage() {} -func (*AlgorithmSetting) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -func (m *AlgorithmSetting) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *AlgorithmSetting) GetValue() string { - if m != nil { - return m.Value - } - return "" -} - -type EarlyStoppingSpec struct { -} - -func (m *EarlyStoppingSpec) Reset() { *m = EarlyStoppingSpec{} } -func (m *EarlyStoppingSpec) String() string { return proto.CompactTextString(m) } -func (*EarlyStoppingSpec) ProtoMessage() {} -func (*EarlyStoppingSpec) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } - -type AlgorithmSpec struct { - AlgorithmName string `protobuf:"bytes,1,opt,name=algorithm_name,json=algorithmName" json:"algorithm_name,omitempty"` - AlgorithmSetting []*AlgorithmSetting `protobuf:"bytes,2,rep,name=algorithm_setting,json=algorithmSetting" json:"algorithm_setting,omitempty"` - EarlyStoppingSpec *EarlyStoppingSpec `protobuf:"bytes,3,opt,name=early_stopping_spec,json=earlyStoppingSpec" json:"early_stopping_spec,omitempty"` -} - -func (m *AlgorithmSpec) Reset() { *m = AlgorithmSpec{} } -func (m *AlgorithmSpec) String() string { return proto.CompactTextString(m) } -func (*AlgorithmSpec) ProtoMessage() {} -func (*AlgorithmSpec) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } - -func (m *AlgorithmSpec) GetAlgorithmName() string { - if m != nil { - return m.AlgorithmName - } - return "" -} - -func (m *AlgorithmSpec) GetAlgorithmSetting() []*AlgorithmSetting { - if m != nil { - return m.AlgorithmSetting - } - return nil -} - -func (m *AlgorithmSpec) GetEarlyStoppingSpec() *EarlyStoppingSpec { - if m != nil { - return m.EarlyStoppingSpec - } - return nil -} - -// * -// NasConfig contains a config of NAS job -type NasConfig struct { - GraphConfig *GraphConfig `protobuf:"bytes,1,opt,name=graph_config,json=graphConfig" json:"graph_config,omitempty"` - Operations *NasConfig_Operations `protobuf:"bytes,2,opt,name=operations" json:"operations,omitempty"` -} - -func (m *NasConfig) Reset() { *m = NasConfig{} } -func (m *NasConfig) String() string { return proto.CompactTextString(m) } -func (*NasConfig) ProtoMessage() {} -func (*NasConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } - -func (m *NasConfig) GetGraphConfig() *GraphConfig { - if m != nil { - return m.GraphConfig - } - return nil -} - -func (m *NasConfig) GetOperations() *NasConfig_Operations { - if m != nil { - return m.Operations - } - return nil -} - -type NasConfig_Operations struct { - Operation []*Operation `protobuf:"bytes,1,rep,name=operation" json:"operation,omitempty"` -} - -func (m *NasConfig_Operations) Reset() { *m = NasConfig_Operations{} } -func (m *NasConfig_Operations) String() string { return proto.CompactTextString(m) } -func (*NasConfig_Operations) ProtoMessage() {} -func (*NasConfig_Operations) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6, 0} } - -func (m *NasConfig_Operations) GetOperation() []*Operation { - if m != nil { - return m.Operation - } - return nil -} - -// * -// GraphConfig contains a config of DAG -type GraphConfig struct { - NumLayers int32 `protobuf:"varint,1,opt,name=num_layers,json=numLayers" json:"num_layers,omitempty"` - InputSizes []int32 `protobuf:"varint,2,rep,packed,name=input_sizes,json=inputSizes" json:"input_sizes,omitempty"` - OutputSizes []int32 `protobuf:"varint,3,rep,packed,name=output_sizes,json=outputSizes" json:"output_sizes,omitempty"` -} - -func (m *GraphConfig) Reset() { *m = GraphConfig{} } -func (m *GraphConfig) String() string { return proto.CompactTextString(m) } -func (*GraphConfig) ProtoMessage() {} -func (*GraphConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } - -func (m *GraphConfig) GetNumLayers() int32 { - if m != nil { - return m.NumLayers - } - return 0 -} - -func (m *GraphConfig) GetInputSizes() []int32 { - if m != nil { - return m.InputSizes - } - return nil -} - -func (m *GraphConfig) GetOutputSizes() []int32 { - if m != nil { - return m.OutputSizes - } - return nil -} - -// * -// Config for operations in DAG -type Operation struct { - OperationType string `protobuf:"bytes,1,opt,name=operation_type,json=operationType" json:"operation_type,omitempty"` - ParameterSpecs *Operation_ParameterSpecs `protobuf:"bytes,2,opt,name=parameter_specs,json=parameterSpecs" json:"parameter_specs,omitempty"` -} - -func (m *Operation) Reset() { *m = Operation{} } -func (m *Operation) String() string { return proto.CompactTextString(m) } -func (*Operation) ProtoMessage() {} -func (*Operation) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } - -func (m *Operation) GetOperationType() string { - if m != nil { - return m.OperationType - } - return "" -} - -func (m *Operation) GetParameterSpecs() *Operation_ParameterSpecs { - if m != nil { - return m.ParameterSpecs - } - return nil -} - -// * -// List of ParameterSpec -type Operation_ParameterSpecs struct { - Parameters []*ParameterSpec `protobuf:"bytes,1,rep,name=parameters" json:"parameters,omitempty"` -} - -func (m *Operation_ParameterSpecs) Reset() { *m = Operation_ParameterSpecs{} } -func (m *Operation_ParameterSpecs) String() string { return proto.CompactTextString(m) } -func (*Operation_ParameterSpecs) ProtoMessage() {} -func (*Operation_ParameterSpecs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8, 0} } - -func (m *Operation_ParameterSpecs) GetParameters() []*ParameterSpec { - if m != nil { - return m.Parameters - } - return nil -} - -// * -// Spec of a Experiment. Experiment represents a single optimization run over a feasible space. -// Each Experiment contains a configuration describing the feasible space, as well as a set of Trials. -// It is assumed that objective function f(x) does not change in the course of a Experiment. -type ExperimentSpec struct { - ParameterSpecs *ExperimentSpec_ParameterSpecs `protobuf:"bytes,1,opt,name=parameter_specs,json=parameterSpecs" json:"parameter_specs,omitempty"` - Objective *ObjectiveSpec `protobuf:"bytes,2,opt,name=objective" json:"objective,omitempty"` - Algorithm *AlgorithmSpec `protobuf:"bytes,3,opt,name=algorithm" json:"algorithm,omitempty"` - TrialTemplate string `protobuf:"bytes,4,opt,name=trial_template,json=trialTemplate" json:"trial_template,omitempty"` - MetricsCollectorSpec string `protobuf:"bytes,5,opt,name=metrics_collector_spec,json=metricsCollectorSpec" json:"metrics_collector_spec,omitempty"` - ParallelTrialCount int32 `protobuf:"varint,6,opt,name=parallel_trial_count,json=parallelTrialCount" json:"parallel_trial_count,omitempty"` - MaxTrialCount int32 `protobuf:"varint,7,opt,name=max_trial_count,json=maxTrialCount" json:"max_trial_count,omitempty"` - NasConfig *NasConfig `protobuf:"bytes,8,opt,name=nas_config,json=nasConfig" json:"nas_config,omitempty"` -} - -func (m *ExperimentSpec) Reset() { *m = ExperimentSpec{} } -func (m *ExperimentSpec) String() string { return proto.CompactTextString(m) } -func (*ExperimentSpec) ProtoMessage() {} -func (*ExperimentSpec) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } - -func (m *ExperimentSpec) GetParameterSpecs() *ExperimentSpec_ParameterSpecs { - if m != nil { - return m.ParameterSpecs - } - return nil -} - -func (m *ExperimentSpec) GetObjective() *ObjectiveSpec { - if m != nil { - return m.Objective - } - return nil -} - -func (m *ExperimentSpec) GetAlgorithm() *AlgorithmSpec { - if m != nil { - return m.Algorithm - } - return nil -} - -func (m *ExperimentSpec) GetTrialTemplate() string { - if m != nil { - return m.TrialTemplate - } - return "" -} - -func (m *ExperimentSpec) GetMetricsCollectorSpec() string { - if m != nil { - return m.MetricsCollectorSpec - } - return "" -} - -func (m *ExperimentSpec) GetParallelTrialCount() int32 { - if m != nil { - return m.ParallelTrialCount - } - return 0 -} - -func (m *ExperimentSpec) GetMaxTrialCount() int32 { - if m != nil { - return m.MaxTrialCount - } - return 0 -} - -func (m *ExperimentSpec) GetNasConfig() *NasConfig { - if m != nil { - return m.NasConfig - } - return nil -} - -// * -// List of ParameterSpec -type ExperimentSpec_ParameterSpecs struct { - Parameters []*ParameterSpec `protobuf:"bytes,1,rep,name=parameters" json:"parameters,omitempty"` -} - -func (m *ExperimentSpec_ParameterSpecs) Reset() { *m = ExperimentSpec_ParameterSpecs{} } -func (m *ExperimentSpec_ParameterSpecs) String() string { return proto.CompactTextString(m) } -func (*ExperimentSpec_ParameterSpecs) ProtoMessage() {} -func (*ExperimentSpec_ParameterSpecs) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{9, 0} -} - -func (m *ExperimentSpec_ParameterSpecs) GetParameters() []*ParameterSpec { - if m != nil { - return m.Parameters - } - return nil -} - -type ExperimentStatus struct { - StartTime string `protobuf:"bytes,1,opt,name=start_time,json=startTime" json:"start_time,omitempty"` - CompletionTime string `protobuf:"bytes,2,opt,name=completion_time,json=completionTime" json:"completion_time,omitempty"` - Condition ExperimentStatus_ExperimentConditionType `protobuf:"varint,3,opt,name=condition,enum=api.v1.alpha2.ExperimentStatus_ExperimentConditionType" json:"condition,omitempty"` -} - -func (m *ExperimentStatus) Reset() { *m = ExperimentStatus{} } -func (m *ExperimentStatus) String() string { return proto.CompactTextString(m) } -func (*ExperimentStatus) ProtoMessage() {} -func (*ExperimentStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } - -func (m *ExperimentStatus) GetStartTime() string { - if m != nil { - return m.StartTime - } - return "" -} - -func (m *ExperimentStatus) GetCompletionTime() string { - if m != nil { - return m.CompletionTime - } - return "" -} - -func (m *ExperimentStatus) GetCondition() ExperimentStatus_ExperimentConditionType { - if m != nil { - return m.Condition - } - return ExperimentStatus_CREATED -} - -type Experiment struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Spec *ExperimentSpec `protobuf:"bytes,2,opt,name=spec" json:"spec,omitempty"` - Status *ExperimentStatus `protobuf:"bytes,3,opt,name=status" json:"status,omitempty"` -} - -func (m *Experiment) Reset() { *m = Experiment{} } -func (m *Experiment) String() string { return proto.CompactTextString(m) } -func (*Experiment) ProtoMessage() {} -func (*Experiment) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } - -func (m *Experiment) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Experiment) GetSpec() *ExperimentSpec { - if m != nil { - return m.Spec - } - return nil -} - -func (m *Experiment) GetStatus() *ExperimentStatus { - if m != nil { - return m.Status - } - return nil -} - -type ParameterAssignment struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *ParameterAssignment) Reset() { *m = ParameterAssignment{} } -func (m *ParameterAssignment) String() string { return proto.CompactTextString(m) } -func (*ParameterAssignment) ProtoMessage() {} -func (*ParameterAssignment) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } - -func (m *ParameterAssignment) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *ParameterAssignment) GetValue() string { - if m != nil { - return m.Value - } - return "" -} - -type Metric struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *Metric) Reset() { *m = Metric{} } -func (m *Metric) String() string { return proto.CompactTextString(m) } -func (*Metric) ProtoMessage() {} -func (*Metric) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } - -func (m *Metric) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Metric) GetValue() string { - if m != nil { - return m.Value - } - return "" -} - -type MetricLog struct { - TimeStamp string `protobuf:"bytes,1,opt,name=time_stamp,json=timeStamp" json:"time_stamp,omitempty"` - Metric *Metric `protobuf:"bytes,2,opt,name=metric" json:"metric,omitempty"` -} - -func (m *MetricLog) Reset() { *m = MetricLog{} } -func (m *MetricLog) String() string { return proto.CompactTextString(m) } -func (*MetricLog) ProtoMessage() {} -func (*MetricLog) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } - -func (m *MetricLog) GetTimeStamp() string { - if m != nil { - return m.TimeStamp - } - return "" -} - -func (m *MetricLog) GetMetric() *Metric { - if m != nil { - return m.Metric - } - return nil -} - -type Observation struct { - Metrics []*Metric `protobuf:"bytes,1,rep,name=metrics" json:"metrics,omitempty"` -} - -func (m *Observation) Reset() { *m = Observation{} } -func (m *Observation) String() string { return proto.CompactTextString(m) } -func (*Observation) ProtoMessage() {} -func (*Observation) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } - -func (m *Observation) GetMetrics() []*Metric { - if m != nil { - return m.Metrics - } - return nil -} - -type ObservationLog struct { - MetricLogs []*MetricLog `protobuf:"bytes,1,rep,name=metric_logs,json=metricLogs" json:"metric_logs,omitempty"` -} - -func (m *ObservationLog) Reset() { *m = ObservationLog{} } -func (m *ObservationLog) String() string { return proto.CompactTextString(m) } -func (*ObservationLog) ProtoMessage() {} -func (*ObservationLog) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } - -func (m *ObservationLog) GetMetricLogs() []*MetricLog { - if m != nil { - return m.MetricLogs - } - return nil -} - -type TrialSpec struct { - ExperimentName string `protobuf:"bytes,1,opt,name=experiment_name,json=experimentName" json:"experiment_name,omitempty"` - Objective *ObjectiveSpec `protobuf:"bytes,2,opt,name=objective" json:"objective,omitempty"` - ParameterAssignments *TrialSpec_ParameterAssignments `protobuf:"bytes,3,opt,name=parameter_assignments,json=parameterAssignments" json:"parameter_assignments,omitempty"` - RunSpec string `protobuf:"bytes,4,opt,name=run_spec,json=runSpec" json:"run_spec,omitempty"` - MetricsCollectorSpec string `protobuf:"bytes,5,opt,name=metrics_collector_spec,json=metricsCollectorSpec" json:"metrics_collector_spec,omitempty"` -} - -func (m *TrialSpec) Reset() { *m = TrialSpec{} } -func (m *TrialSpec) String() string { return proto.CompactTextString(m) } -func (*TrialSpec) ProtoMessage() {} -func (*TrialSpec) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } - -func (m *TrialSpec) GetExperimentName() string { - if m != nil { - return m.ExperimentName - } - return "" -} - -func (m *TrialSpec) GetObjective() *ObjectiveSpec { - if m != nil { - return m.Objective - } - return nil -} - -func (m *TrialSpec) GetParameterAssignments() *TrialSpec_ParameterAssignments { - if m != nil { - return m.ParameterAssignments - } - return nil -} - -func (m *TrialSpec) GetRunSpec() string { - if m != nil { - return m.RunSpec - } - return "" -} - -func (m *TrialSpec) GetMetricsCollectorSpec() string { - if m != nil { - return m.MetricsCollectorSpec - } - return "" -} - -// * -// List of ParameterAssignment -type TrialSpec_ParameterAssignments struct { - Assignments []*ParameterAssignment `protobuf:"bytes,1,rep,name=assignments" json:"assignments,omitempty"` -} - -func (m *TrialSpec_ParameterAssignments) Reset() { *m = TrialSpec_ParameterAssignments{} } -func (m *TrialSpec_ParameterAssignments) String() string { return proto.CompactTextString(m) } -func (*TrialSpec_ParameterAssignments) ProtoMessage() {} -func (*TrialSpec_ParameterAssignments) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{17, 0} -} - -func (m *TrialSpec_ParameterAssignments) GetAssignments() []*ParameterAssignment { - if m != nil { - return m.Assignments - } - return nil -} - -type TrialStatus struct { - StartTime string `protobuf:"bytes,1,opt,name=start_time,json=startTime" json:"start_time,omitempty"` - CompletionTime string `protobuf:"bytes,2,opt,name=completion_time,json=completionTime" json:"completion_time,omitempty"` - Condition TrialStatus_TrialConditionType `protobuf:"varint,3,opt,name=condition,enum=api.v1.alpha2.TrialStatus_TrialConditionType" json:"condition,omitempty"` - Observation *Observation `protobuf:"bytes,4,opt,name=observation" json:"observation,omitempty"` -} - -func (m *TrialStatus) Reset() { *m = TrialStatus{} } -func (m *TrialStatus) String() string { return proto.CompactTextString(m) } -func (*TrialStatus) ProtoMessage() {} -func (*TrialStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } - -func (m *TrialStatus) GetStartTime() string { - if m != nil { - return m.StartTime - } - return "" -} - -func (m *TrialStatus) GetCompletionTime() string { - if m != nil { - return m.CompletionTime - } - return "" -} - -func (m *TrialStatus) GetCondition() TrialStatus_TrialConditionType { - if m != nil { - return m.Condition - } - return TrialStatus_CREATED -} - -func (m *TrialStatus) GetObservation() *Observation { - if m != nil { - return m.Observation - } - return nil -} - -type Trial struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Spec *TrialSpec `protobuf:"bytes,2,opt,name=spec" json:"spec,omitempty"` - Status *TrialStatus `protobuf:"bytes,3,opt,name=status" json:"status,omitempty"` -} - -func (m *Trial) Reset() { *m = Trial{} } -func (m *Trial) String() string { return proto.CompactTextString(m) } -func (*Trial) ProtoMessage() {} -func (*Trial) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } - -func (m *Trial) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Trial) GetSpec() *TrialSpec { - if m != nil { - return m.Spec - } - return nil -} - -func (m *Trial) GetStatus() *TrialStatus { - if m != nil { - return m.Status - } - return nil -} - -type RegisterExperimentRequest struct { - Experiment *Experiment `protobuf:"bytes,1,opt,name=experiment" json:"experiment,omitempty"` -} - -func (m *RegisterExperimentRequest) Reset() { *m = RegisterExperimentRequest{} } -func (m *RegisterExperimentRequest) String() string { return proto.CompactTextString(m) } -func (*RegisterExperimentRequest) ProtoMessage() {} -func (*RegisterExperimentRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } - -func (m *RegisterExperimentRequest) GetExperiment() *Experiment { - if m != nil { - return m.Experiment - } - return nil -} - -type RegisterExperimentReply struct { -} - -func (m *RegisterExperimentReply) Reset() { *m = RegisterExperimentReply{} } -func (m *RegisterExperimentReply) String() string { return proto.CompactTextString(m) } -func (*RegisterExperimentReply) ProtoMessage() {} -func (*RegisterExperimentReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } - -type PreCheckRegisterExperimentReply struct { - CanRegister bool `protobuf:"varint,1,opt,name=can_register,json=canRegister" json:"can_register,omitempty"` -} - -func (m *PreCheckRegisterExperimentReply) Reset() { *m = PreCheckRegisterExperimentReply{} } -func (m *PreCheckRegisterExperimentReply) String() string { return proto.CompactTextString(m) } -func (*PreCheckRegisterExperimentReply) ProtoMessage() {} -func (*PreCheckRegisterExperimentReply) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{22} -} - -func (m *PreCheckRegisterExperimentReply) GetCanRegister() bool { - if m != nil { - return m.CanRegister - } - return false -} - -type DeleteExperimentRequest struct { - ExperimentName string `protobuf:"bytes,1,opt,name=experiment_name,json=experimentName" json:"experiment_name,omitempty"` -} - -func (m *DeleteExperimentRequest) Reset() { *m = DeleteExperimentRequest{} } -func (m *DeleteExperimentRequest) String() string { return proto.CompactTextString(m) } -func (*DeleteExperimentRequest) ProtoMessage() {} -func (*DeleteExperimentRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } - -func (m *DeleteExperimentRequest) GetExperimentName() string { - if m != nil { - return m.ExperimentName - } - return "" -} - -type DeleteExperimentReply struct { -} - -func (m *DeleteExperimentReply) Reset() { *m = DeleteExperimentReply{} } -func (m *DeleteExperimentReply) String() string { return proto.CompactTextString(m) } -func (*DeleteExperimentReply) ProtoMessage() {} -func (*DeleteExperimentReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } - -type GetExperimentRequest struct { - ExperimentName string `protobuf:"bytes,1,opt,name=experiment_name,json=experimentName" json:"experiment_name,omitempty"` -} - -func (m *GetExperimentRequest) Reset() { *m = GetExperimentRequest{} } -func (m *GetExperimentRequest) String() string { return proto.CompactTextString(m) } -func (*GetExperimentRequest) ProtoMessage() {} -func (*GetExperimentRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } - -func (m *GetExperimentRequest) GetExperimentName() string { - if m != nil { - return m.ExperimentName - } - return "" -} - -type GetExperimentReply struct { - Experiment *Experiment `protobuf:"bytes,1,opt,name=experiment" json:"experiment,omitempty"` -} - -func (m *GetExperimentReply) Reset() { *m = GetExperimentReply{} } -func (m *GetExperimentReply) String() string { return proto.CompactTextString(m) } -func (*GetExperimentReply) ProtoMessage() {} -func (*GetExperimentReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } - -func (m *GetExperimentReply) GetExperiment() *Experiment { - if m != nil { - return m.Experiment - } - return nil -} - -type ExperimentSummary struct { - ExperimentName string `protobuf:"bytes,1,opt,name=experiment_name,json=experimentName" json:"experiment_name,omitempty"` - Status *ExperimentStatus `protobuf:"bytes,2,opt,name=status" json:"status,omitempty"` -} - -func (m *ExperimentSummary) Reset() { *m = ExperimentSummary{} } -func (m *ExperimentSummary) String() string { return proto.CompactTextString(m) } -func (*ExperimentSummary) ProtoMessage() {} -func (*ExperimentSummary) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } - -func (m *ExperimentSummary) GetExperimentName() string { - if m != nil { - return m.ExperimentName - } - return "" -} - -func (m *ExperimentSummary) GetStatus() *ExperimentStatus { - if m != nil { - return m.Status - } - return nil -} - -type GetExperimentListRequest struct { -} - -func (m *GetExperimentListRequest) Reset() { *m = GetExperimentListRequest{} } -func (m *GetExperimentListRequest) String() string { return proto.CompactTextString(m) } -func (*GetExperimentListRequest) ProtoMessage() {} -func (*GetExperimentListRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } - -type GetExperimentListReply struct { - ExperimentSummaries []*ExperimentSummary `protobuf:"bytes,1,rep,name=experiment_summaries,json=experimentSummaries" json:"experiment_summaries,omitempty"` -} - -func (m *GetExperimentListReply) Reset() { *m = GetExperimentListReply{} } -func (m *GetExperimentListReply) String() string { return proto.CompactTextString(m) } -func (*GetExperimentListReply) ProtoMessage() {} -func (*GetExperimentListReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } - -func (m *GetExperimentListReply) GetExperimentSummaries() []*ExperimentSummary { - if m != nil { - return m.ExperimentSummaries - } - return nil -} - -type UpdateExperimentStatusRequest struct { - ExperimentName string `protobuf:"bytes,1,opt,name=experiment_name,json=experimentName" json:"experiment_name,omitempty"` - NewStatus *ExperimentStatus `protobuf:"bytes,2,opt,name=new_status,json=newStatus" json:"new_status,omitempty"` -} - -func (m *UpdateExperimentStatusRequest) Reset() { *m = UpdateExperimentStatusRequest{} } -func (m *UpdateExperimentStatusRequest) String() string { return proto.CompactTextString(m) } -func (*UpdateExperimentStatusRequest) ProtoMessage() {} -func (*UpdateExperimentStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } - -func (m *UpdateExperimentStatusRequest) GetExperimentName() string { - if m != nil { - return m.ExperimentName - } - return "" -} - -func (m *UpdateExperimentStatusRequest) GetNewStatus() *ExperimentStatus { - if m != nil { - return m.NewStatus - } - return nil -} - -type UpdateExperimentStatusReply struct { -} - -func (m *UpdateExperimentStatusReply) Reset() { *m = UpdateExperimentStatusReply{} } -func (m *UpdateExperimentStatusReply) String() string { return proto.CompactTextString(m) } -func (*UpdateExperimentStatusReply) ProtoMessage() {} -func (*UpdateExperimentStatusReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } - -type UpdateAlgorithmExtraSettingsRequest struct { - ExperimentName string `protobuf:"bytes,1,opt,name=experiment_name,json=experimentName" json:"experiment_name,omitempty"` - ExtraAlgorithmSettings []*AlgorithmSetting `protobuf:"bytes,2,rep,name=extra_algorithm_settings,json=extraAlgorithmSettings" json:"extra_algorithm_settings,omitempty"` -} - -func (m *UpdateAlgorithmExtraSettingsRequest) Reset() { *m = UpdateAlgorithmExtraSettingsRequest{} } -func (m *UpdateAlgorithmExtraSettingsRequest) String() string { return proto.CompactTextString(m) } -func (*UpdateAlgorithmExtraSettingsRequest) ProtoMessage() {} -func (*UpdateAlgorithmExtraSettingsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{32} -} - -func (m *UpdateAlgorithmExtraSettingsRequest) GetExperimentName() string { - if m != nil { - return m.ExperimentName - } - return "" -} - -func (m *UpdateAlgorithmExtraSettingsRequest) GetExtraAlgorithmSettings() []*AlgorithmSetting { - if m != nil { - return m.ExtraAlgorithmSettings - } - return nil -} - -type UpdateAlgorithmExtraSettingsReply struct { -} - -func (m *UpdateAlgorithmExtraSettingsReply) Reset() { *m = UpdateAlgorithmExtraSettingsReply{} } -func (m *UpdateAlgorithmExtraSettingsReply) String() string { return proto.CompactTextString(m) } -func (*UpdateAlgorithmExtraSettingsReply) ProtoMessage() {} -func (*UpdateAlgorithmExtraSettingsReply) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{33} -} - -type GetAlgorithmExtraSettingsRequest struct { - ExperimentName string `protobuf:"bytes,1,opt,name=experiment_name,json=experimentName" json:"experiment_name,omitempty"` -} - -func (m *GetAlgorithmExtraSettingsRequest) Reset() { *m = GetAlgorithmExtraSettingsRequest{} } -func (m *GetAlgorithmExtraSettingsRequest) String() string { return proto.CompactTextString(m) } -func (*GetAlgorithmExtraSettingsRequest) ProtoMessage() {} -func (*GetAlgorithmExtraSettingsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{34} -} - -func (m *GetAlgorithmExtraSettingsRequest) GetExperimentName() string { - if m != nil { - return m.ExperimentName - } - return "" -} - -type GetAlgorithmExtraSettingsReply struct { - ExtraAlgorithmSettings []*AlgorithmSetting `protobuf:"bytes,1,rep,name=extra_algorithm_settings,json=extraAlgorithmSettings" json:"extra_algorithm_settings,omitempty"` -} - -func (m *GetAlgorithmExtraSettingsReply) Reset() { *m = GetAlgorithmExtraSettingsReply{} } -func (m *GetAlgorithmExtraSettingsReply) String() string { return proto.CompactTextString(m) } -func (*GetAlgorithmExtraSettingsReply) ProtoMessage() {} -func (*GetAlgorithmExtraSettingsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } - -func (m *GetAlgorithmExtraSettingsReply) GetExtraAlgorithmSettings() []*AlgorithmSetting { - if m != nil { - return m.ExtraAlgorithmSettings - } - return nil -} - -type RegisterTrialRequest struct { - Trial *Trial `protobuf:"bytes,1,opt,name=trial" json:"trial,omitempty"` -} - -func (m *RegisterTrialRequest) Reset() { *m = RegisterTrialRequest{} } -func (m *RegisterTrialRequest) String() string { return proto.CompactTextString(m) } -func (*RegisterTrialRequest) ProtoMessage() {} -func (*RegisterTrialRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } - -func (m *RegisterTrialRequest) GetTrial() *Trial { - if m != nil { - return m.Trial - } - return nil -} - -type RegisterTrialReply struct { -} - -func (m *RegisterTrialReply) Reset() { *m = RegisterTrialReply{} } -func (m *RegisterTrialReply) String() string { return proto.CompactTextString(m) } -func (*RegisterTrialReply) ProtoMessage() {} -func (*RegisterTrialReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } - -type DeleteTrialRequest struct { - TrialName string `protobuf:"bytes,1,opt,name=trial_name,json=trialName" json:"trial_name,omitempty"` -} - -func (m *DeleteTrialRequest) Reset() { *m = DeleteTrialRequest{} } -func (m *DeleteTrialRequest) String() string { return proto.CompactTextString(m) } -func (*DeleteTrialRequest) ProtoMessage() {} -func (*DeleteTrialRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } - -func (m *DeleteTrialRequest) GetTrialName() string { - if m != nil { - return m.TrialName - } - return "" -} - -type DeleteTrialReply struct { -} - -func (m *DeleteTrialReply) Reset() { *m = DeleteTrialReply{} } -func (m *DeleteTrialReply) String() string { return proto.CompactTextString(m) } -func (*DeleteTrialReply) ProtoMessage() {} -func (*DeleteTrialReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } - -type GetTrialListRequest struct { - ExperimentName string `protobuf:"bytes,1,opt,name=experiment_name,json=experimentName" json:"experiment_name,omitempty"` - Filter string `protobuf:"bytes,2,opt,name=filter" json:"filter,omitempty"` -} - -func (m *GetTrialListRequest) Reset() { *m = GetTrialListRequest{} } -func (m *GetTrialListRequest) String() string { return proto.CompactTextString(m) } -func (*GetTrialListRequest) ProtoMessage() {} -func (*GetTrialListRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } - -func (m *GetTrialListRequest) GetExperimentName() string { - if m != nil { - return m.ExperimentName - } - return "" -} - -func (m *GetTrialListRequest) GetFilter() string { - if m != nil { - return m.Filter - } - return "" -} - -type GetTrialListReply struct { - Trials []*Trial `protobuf:"bytes,1,rep,name=trials" json:"trials,omitempty"` -} - -func (m *GetTrialListReply) Reset() { *m = GetTrialListReply{} } -func (m *GetTrialListReply) String() string { return proto.CompactTextString(m) } -func (*GetTrialListReply) ProtoMessage() {} -func (*GetTrialListReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } - -func (m *GetTrialListReply) GetTrials() []*Trial { - if m != nil { - return m.Trials - } - return nil -} - -type GetTrialRequest struct { - TrialName string `protobuf:"bytes,1,opt,name=trial_name,json=trialName" json:"trial_name,omitempty"` -} - -func (m *GetTrialRequest) Reset() { *m = GetTrialRequest{} } -func (m *GetTrialRequest) String() string { return proto.CompactTextString(m) } -func (*GetTrialRequest) ProtoMessage() {} -func (*GetTrialRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } - -func (m *GetTrialRequest) GetTrialName() string { - if m != nil { - return m.TrialName - } - return "" -} - -type GetTrialReply struct { - Trial *Trial `protobuf:"bytes,1,opt,name=trial" json:"trial,omitempty"` -} - -func (m *GetTrialReply) Reset() { *m = GetTrialReply{} } -func (m *GetTrialReply) String() string { return proto.CompactTextString(m) } -func (*GetTrialReply) ProtoMessage() {} -func (*GetTrialReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } - -func (m *GetTrialReply) GetTrial() *Trial { - if m != nil { - return m.Trial - } - return nil -} - -type UpdateTrialStatusRequest struct { - TrialName string `protobuf:"bytes,1,opt,name=trial_name,json=trialName" json:"trial_name,omitempty"` - NewStatus *TrialStatus `protobuf:"bytes,2,opt,name=new_status,json=newStatus" json:"new_status,omitempty"` -} - -func (m *UpdateTrialStatusRequest) Reset() { *m = UpdateTrialStatusRequest{} } -func (m *UpdateTrialStatusRequest) String() string { return proto.CompactTextString(m) } -func (*UpdateTrialStatusRequest) ProtoMessage() {} -func (*UpdateTrialStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } - -func (m *UpdateTrialStatusRequest) GetTrialName() string { - if m != nil { - return m.TrialName - } - return "" -} - -func (m *UpdateTrialStatusRequest) GetNewStatus() *TrialStatus { - if m != nil { - return m.NewStatus - } - return nil -} - -type UpdateTrialStatusReply struct { -} - -func (m *UpdateTrialStatusReply) Reset() { *m = UpdateTrialStatusReply{} } -func (m *UpdateTrialStatusReply) String() string { return proto.CompactTextString(m) } -func (*UpdateTrialStatusReply) ProtoMessage() {} -func (*UpdateTrialStatusReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } - -type ReportObservationLogRequest struct { - TrialName string `protobuf:"bytes,1,opt,name=trial_name,json=trialName" json:"trial_name,omitempty"` - ObservationLog *ObservationLog `protobuf:"bytes,2,opt,name=observation_log,json=observationLog" json:"observation_log,omitempty"` -} - -func (m *ReportObservationLogRequest) Reset() { *m = ReportObservationLogRequest{} } -func (m *ReportObservationLogRequest) String() string { return proto.CompactTextString(m) } -func (*ReportObservationLogRequest) ProtoMessage() {} -func (*ReportObservationLogRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} } - -func (m *ReportObservationLogRequest) GetTrialName() string { - if m != nil { - return m.TrialName - } - return "" -} - -func (m *ReportObservationLogRequest) GetObservationLog() *ObservationLog { - if m != nil { - return m.ObservationLog - } - return nil -} - -type ReportObservationLogReply struct { -} - -func (m *ReportObservationLogReply) Reset() { *m = ReportObservationLogReply{} } -func (m *ReportObservationLogReply) String() string { return proto.CompactTextString(m) } -func (*ReportObservationLogReply) ProtoMessage() {} -func (*ReportObservationLogReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} } - -type GetObservationLogRequest struct { - TrialName string `protobuf:"bytes,1,opt,name=trial_name,json=trialName" json:"trial_name,omitempty"` - MetricName string `protobuf:"bytes,2,opt,name=metric_name,json=metricName" json:"metric_name,omitempty"` - StartTime string `protobuf:"bytes,3,opt,name=start_time,json=startTime" json:"start_time,omitempty"` - EndTime string `protobuf:"bytes,4,opt,name=end_time,json=endTime" json:"end_time,omitempty"` -} - -func (m *GetObservationLogRequest) Reset() { *m = GetObservationLogRequest{} } -func (m *GetObservationLogRequest) String() string { return proto.CompactTextString(m) } -func (*GetObservationLogRequest) ProtoMessage() {} -func (*GetObservationLogRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} } - -func (m *GetObservationLogRequest) GetTrialName() string { - if m != nil { - return m.TrialName - } - return "" -} - -func (m *GetObservationLogRequest) GetMetricName() string { - if m != nil { - return m.MetricName - } - return "" -} - -func (m *GetObservationLogRequest) GetStartTime() string { - if m != nil { - return m.StartTime - } - return "" -} - -func (m *GetObservationLogRequest) GetEndTime() string { - if m != nil { - return m.EndTime - } - return "" -} - -type GetObservationLogReply struct { - ObservationLog *ObservationLog `protobuf:"bytes,1,opt,name=observation_log,json=observationLog" json:"observation_log,omitempty"` -} - -func (m *GetObservationLogReply) Reset() { *m = GetObservationLogReply{} } -func (m *GetObservationLogReply) String() string { return proto.CompactTextString(m) } -func (*GetObservationLogReply) ProtoMessage() {} -func (*GetObservationLogReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} } - -func (m *GetObservationLogReply) GetObservationLog() *ObservationLog { - if m != nil { - return m.ObservationLog - } - return nil -} - -type GetSuggestionsRequest struct { - ExperimentName string `protobuf:"bytes,1,opt,name=experiment_name,json=experimentName" json:"experiment_name,omitempty"` - AlgorithmName string `protobuf:"bytes,2,opt,name=algorithm_name,json=algorithmName" json:"algorithm_name,omitempty"` - RequestNumber int32 `protobuf:"varint,3,opt,name=request_number,json=requestNumber" json:"request_number,omitempty"` -} - -func (m *GetSuggestionsRequest) Reset() { *m = GetSuggestionsRequest{} } -func (m *GetSuggestionsRequest) String() string { return proto.CompactTextString(m) } -func (*GetSuggestionsRequest) ProtoMessage() {} -func (*GetSuggestionsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} } - -func (m *GetSuggestionsRequest) GetExperimentName() string { - if m != nil { - return m.ExperimentName - } - return "" -} - -func (m *GetSuggestionsRequest) GetAlgorithmName() string { - if m != nil { - return m.AlgorithmName - } - return "" -} - -func (m *GetSuggestionsRequest) GetRequestNumber() int32 { - if m != nil { - return m.RequestNumber - } - return 0 -} - -type GetSuggestionsReply struct { - Trials []*Trial `protobuf:"bytes,1,rep,name=trials" json:"trials,omitempty"` -} - -func (m *GetSuggestionsReply) Reset() { *m = GetSuggestionsReply{} } -func (m *GetSuggestionsReply) String() string { return proto.CompactTextString(m) } -func (*GetSuggestionsReply) ProtoMessage() {} -func (*GetSuggestionsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} } - -func (m *GetSuggestionsReply) GetTrials() []*Trial { - if m != nil { - return m.Trials - } - return nil -} - -type ValidateAlgorithmSettingsRequest struct { - ExperimentSpec *ExperimentSpec `protobuf:"bytes,1,opt,name=experiment_spec,json=experimentSpec" json:"experiment_spec,omitempty"` - AlgorithmName string `protobuf:"bytes,2,opt,name=algorithm_name,json=algorithmName" json:"algorithm_name,omitempty"` -} - -func (m *ValidateAlgorithmSettingsRequest) Reset() { *m = ValidateAlgorithmSettingsRequest{} } -func (m *ValidateAlgorithmSettingsRequest) String() string { return proto.CompactTextString(m) } -func (*ValidateAlgorithmSettingsRequest) ProtoMessage() {} -func (*ValidateAlgorithmSettingsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{52} -} - -func (m *ValidateAlgorithmSettingsRequest) GetExperimentSpec() *ExperimentSpec { - if m != nil { - return m.ExperimentSpec - } - return nil -} - -func (m *ValidateAlgorithmSettingsRequest) GetAlgorithmName() string { - if m != nil { - return m.AlgorithmName - } - return "" -} - -// * -// Return INVALID_ARGUMENT Error if Algorithm Settings are not Valid -type ValidateAlgorithmSettingsReply struct { -} - -func (m *ValidateAlgorithmSettingsReply) Reset() { *m = ValidateAlgorithmSettingsReply{} } -func (m *ValidateAlgorithmSettingsReply) String() string { return proto.CompactTextString(m) } -func (*ValidateAlgorithmSettingsReply) ProtoMessage() {} -func (*ValidateAlgorithmSettingsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} } - -func init() { - proto.RegisterType((*FeasibleSpace)(nil), "api.v1.alpha2.FeasibleSpace") - proto.RegisterType((*ParameterSpec)(nil), "api.v1.alpha2.ParameterSpec") - proto.RegisterType((*ObjectiveSpec)(nil), "api.v1.alpha2.ObjectiveSpec") - proto.RegisterType((*AlgorithmSetting)(nil), "api.v1.alpha2.AlgorithmSetting") - proto.RegisterType((*EarlyStoppingSpec)(nil), "api.v1.alpha2.EarlyStoppingSpec") - proto.RegisterType((*AlgorithmSpec)(nil), "api.v1.alpha2.AlgorithmSpec") - proto.RegisterType((*NasConfig)(nil), "api.v1.alpha2.NasConfig") - proto.RegisterType((*NasConfig_Operations)(nil), "api.v1.alpha2.NasConfig.Operations") - proto.RegisterType((*GraphConfig)(nil), "api.v1.alpha2.GraphConfig") - proto.RegisterType((*Operation)(nil), "api.v1.alpha2.Operation") - proto.RegisterType((*Operation_ParameterSpecs)(nil), "api.v1.alpha2.Operation.ParameterSpecs") - proto.RegisterType((*ExperimentSpec)(nil), "api.v1.alpha2.ExperimentSpec") - proto.RegisterType((*ExperimentSpec_ParameterSpecs)(nil), "api.v1.alpha2.ExperimentSpec.ParameterSpecs") - proto.RegisterType((*ExperimentStatus)(nil), "api.v1.alpha2.ExperimentStatus") - proto.RegisterType((*Experiment)(nil), "api.v1.alpha2.Experiment") - proto.RegisterType((*ParameterAssignment)(nil), "api.v1.alpha2.ParameterAssignment") - proto.RegisterType((*Metric)(nil), "api.v1.alpha2.Metric") - proto.RegisterType((*MetricLog)(nil), "api.v1.alpha2.MetricLog") - proto.RegisterType((*Observation)(nil), "api.v1.alpha2.Observation") - proto.RegisterType((*ObservationLog)(nil), "api.v1.alpha2.ObservationLog") - proto.RegisterType((*TrialSpec)(nil), "api.v1.alpha2.TrialSpec") - proto.RegisterType((*TrialSpec_ParameterAssignments)(nil), "api.v1.alpha2.TrialSpec.ParameterAssignments") - proto.RegisterType((*TrialStatus)(nil), "api.v1.alpha2.TrialStatus") - proto.RegisterType((*Trial)(nil), "api.v1.alpha2.Trial") - proto.RegisterType((*RegisterExperimentRequest)(nil), "api.v1.alpha2.RegisterExperimentRequest") - proto.RegisterType((*RegisterExperimentReply)(nil), "api.v1.alpha2.RegisterExperimentReply") - proto.RegisterType((*PreCheckRegisterExperimentReply)(nil), "api.v1.alpha2.PreCheckRegisterExperimentReply") - proto.RegisterType((*DeleteExperimentRequest)(nil), "api.v1.alpha2.DeleteExperimentRequest") - proto.RegisterType((*DeleteExperimentReply)(nil), "api.v1.alpha2.DeleteExperimentReply") - proto.RegisterType((*GetExperimentRequest)(nil), "api.v1.alpha2.GetExperimentRequest") - proto.RegisterType((*GetExperimentReply)(nil), "api.v1.alpha2.GetExperimentReply") - proto.RegisterType((*ExperimentSummary)(nil), "api.v1.alpha2.ExperimentSummary") - proto.RegisterType((*GetExperimentListRequest)(nil), "api.v1.alpha2.GetExperimentListRequest") - proto.RegisterType((*GetExperimentListReply)(nil), "api.v1.alpha2.GetExperimentListReply") - proto.RegisterType((*UpdateExperimentStatusRequest)(nil), "api.v1.alpha2.UpdateExperimentStatusRequest") - proto.RegisterType((*UpdateExperimentStatusReply)(nil), "api.v1.alpha2.UpdateExperimentStatusReply") - proto.RegisterType((*UpdateAlgorithmExtraSettingsRequest)(nil), "api.v1.alpha2.UpdateAlgorithmExtraSettingsRequest") - proto.RegisterType((*UpdateAlgorithmExtraSettingsReply)(nil), "api.v1.alpha2.UpdateAlgorithmExtraSettingsReply") - proto.RegisterType((*GetAlgorithmExtraSettingsRequest)(nil), "api.v1.alpha2.GetAlgorithmExtraSettingsRequest") - proto.RegisterType((*GetAlgorithmExtraSettingsReply)(nil), "api.v1.alpha2.GetAlgorithmExtraSettingsReply") - proto.RegisterType((*RegisterTrialRequest)(nil), "api.v1.alpha2.RegisterTrialRequest") - proto.RegisterType((*RegisterTrialReply)(nil), "api.v1.alpha2.RegisterTrialReply") - proto.RegisterType((*DeleteTrialRequest)(nil), "api.v1.alpha2.DeleteTrialRequest") - proto.RegisterType((*DeleteTrialReply)(nil), "api.v1.alpha2.DeleteTrialReply") - proto.RegisterType((*GetTrialListRequest)(nil), "api.v1.alpha2.GetTrialListRequest") - proto.RegisterType((*GetTrialListReply)(nil), "api.v1.alpha2.GetTrialListReply") - proto.RegisterType((*GetTrialRequest)(nil), "api.v1.alpha2.GetTrialRequest") - proto.RegisterType((*GetTrialReply)(nil), "api.v1.alpha2.GetTrialReply") - proto.RegisterType((*UpdateTrialStatusRequest)(nil), "api.v1.alpha2.UpdateTrialStatusRequest") - proto.RegisterType((*UpdateTrialStatusReply)(nil), "api.v1.alpha2.UpdateTrialStatusReply") - proto.RegisterType((*ReportObservationLogRequest)(nil), "api.v1.alpha2.ReportObservationLogRequest") - proto.RegisterType((*ReportObservationLogReply)(nil), "api.v1.alpha2.ReportObservationLogReply") - proto.RegisterType((*GetObservationLogRequest)(nil), "api.v1.alpha2.GetObservationLogRequest") - proto.RegisterType((*GetObservationLogReply)(nil), "api.v1.alpha2.GetObservationLogReply") - proto.RegisterType((*GetSuggestionsRequest)(nil), "api.v1.alpha2.GetSuggestionsRequest") - proto.RegisterType((*GetSuggestionsReply)(nil), "api.v1.alpha2.GetSuggestionsReply") - proto.RegisterType((*ValidateAlgorithmSettingsRequest)(nil), "api.v1.alpha2.ValidateAlgorithmSettingsRequest") - proto.RegisterType((*ValidateAlgorithmSettingsReply)(nil), "api.v1.alpha2.ValidateAlgorithmSettingsReply") - proto.RegisterEnum("api.v1.alpha2.ParameterType", ParameterType_name, ParameterType_value) - proto.RegisterEnum("api.v1.alpha2.ObjectiveType", ObjectiveType_name, ObjectiveType_value) - proto.RegisterEnum("api.v1.alpha2.ExperimentStatus_ExperimentConditionType", ExperimentStatus_ExperimentConditionType_name, ExperimentStatus_ExperimentConditionType_value) - proto.RegisterEnum("api.v1.alpha2.TrialStatus_TrialConditionType", TrialStatus_TrialConditionType_name, TrialStatus_TrialConditionType_value) -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// Client API for Manager service - -type ManagerClient interface { - // * - // Register a Experiment to DB. - RegisterExperiment(ctx context.Context, in *RegisterExperimentRequest, opts ...grpc.CallOption) (*RegisterExperimentReply, error) - // * - // PreCheck to register a Experiment to DB. - PreCheckRegisterExperiment(ctx context.Context, in *RegisterExperimentRequest, opts ...grpc.CallOption) (*PreCheckRegisterExperimentReply, error) - // * - // Delete a Experiment from DB by name. - DeleteExperiment(ctx context.Context, in *DeleteExperimentRequest, opts ...grpc.CallOption) (*DeleteExperimentReply, error) - // * - // Get a Experiment from DB by name. - GetExperiment(ctx context.Context, in *GetExperimentRequest, opts ...grpc.CallOption) (*GetExperimentReply, error) - // * - // Get a summary list of Experiment from DB. - // The summary includes name and condition. - GetExperimentList(ctx context.Context, in *GetExperimentListRequest, opts ...grpc.CallOption) (*GetExperimentListReply, error) - // * - // Update Status of a experiment. - UpdateExperimentStatus(ctx context.Context, in *UpdateExperimentStatusRequest, opts ...grpc.CallOption) (*UpdateExperimentStatusReply, error) - // * - // Update AlgorithmExtraSettings. - // The ExtraSetting is created if it does not exist, otherwise it is overwrited. - UpdateAlgorithmExtraSettings(ctx context.Context, in *UpdateAlgorithmExtraSettingsRequest, opts ...grpc.CallOption) (*UpdateAlgorithmExtraSettingsReply, error) - // * - // Get all AlgorithmExtraSettings. - GetAlgorithmExtraSettings(ctx context.Context, in *GetAlgorithmExtraSettingsRequest, opts ...grpc.CallOption) (*GetAlgorithmExtraSettingsReply, error) - // * - // Register a Trial to DB. - // ID will be filled by manager automatically. - RegisterTrial(ctx context.Context, in *RegisterTrialRequest, opts ...grpc.CallOption) (*RegisterTrialReply, error) - // * - // Delete a Trial from DB by ID. - DeleteTrial(ctx context.Context, in *DeleteTrialRequest, opts ...grpc.CallOption) (*DeleteTrialReply, error) - // * - // Get a list of Trial from DB by name of a Experiment. - GetTrialList(ctx context.Context, in *GetTrialListRequest, opts ...grpc.CallOption) (*GetTrialListReply, error) - // * - // Get a Trial from DB by ID of Trial. - GetTrial(ctx context.Context, in *GetTrialRequest, opts ...grpc.CallOption) (*GetTrialReply, error) - // * - // Update Status of a trial. - UpdateTrialStatus(ctx context.Context, in *UpdateTrialStatusRequest, opts ...grpc.CallOption) (*UpdateTrialStatusReply, error) - // * - // Report a log of Observations for a Trial. - // The log consists of timestamp and value of metric. - // Katib store every log of metrics. - // You can see accuracy curve or other metric logs on UI. - ReportObservationLog(ctx context.Context, in *ReportObservationLogRequest, opts ...grpc.CallOption) (*ReportObservationLogReply, error) - // * - // Get all log of Observations for a Trial. - GetObservationLog(ctx context.Context, in *GetObservationLogRequest, opts ...grpc.CallOption) (*GetObservationLogReply, error) - // * - // Get Suggestions from a Suggestion service. - GetSuggestions(ctx context.Context, in *GetSuggestionsRequest, opts ...grpc.CallOption) (*GetSuggestionsReply, error) - // * - // Validate AlgorithmSettings in an Experiment. - // Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid - ValidateAlgorithmSettings(ctx context.Context, in *ValidateAlgorithmSettingsRequest, opts ...grpc.CallOption) (*ValidateAlgorithmSettingsReply, error) -} - -type managerClient struct { - cc *grpc.ClientConn -} - -func NewManagerClient(cc *grpc.ClientConn) ManagerClient { - return &managerClient{cc} -} - -func (c *managerClient) RegisterExperiment(ctx context.Context, in *RegisterExperimentRequest, opts ...grpc.CallOption) (*RegisterExperimentReply, error) { - out := new(RegisterExperimentReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/RegisterExperiment", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) PreCheckRegisterExperiment(ctx context.Context, in *RegisterExperimentRequest, opts ...grpc.CallOption) (*PreCheckRegisterExperimentReply, error) { - out := new(PreCheckRegisterExperimentReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/PreCheckRegisterExperiment", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) DeleteExperiment(ctx context.Context, in *DeleteExperimentRequest, opts ...grpc.CallOption) (*DeleteExperimentReply, error) { - out := new(DeleteExperimentReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/DeleteExperiment", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) GetExperiment(ctx context.Context, in *GetExperimentRequest, opts ...grpc.CallOption) (*GetExperimentReply, error) { - out := new(GetExperimentReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/GetExperiment", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) GetExperimentList(ctx context.Context, in *GetExperimentListRequest, opts ...grpc.CallOption) (*GetExperimentListReply, error) { - out := new(GetExperimentListReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/GetExperimentList", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) UpdateExperimentStatus(ctx context.Context, in *UpdateExperimentStatusRequest, opts ...grpc.CallOption) (*UpdateExperimentStatusReply, error) { - out := new(UpdateExperimentStatusReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/UpdateExperimentStatus", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) UpdateAlgorithmExtraSettings(ctx context.Context, in *UpdateAlgorithmExtraSettingsRequest, opts ...grpc.CallOption) (*UpdateAlgorithmExtraSettingsReply, error) { - out := new(UpdateAlgorithmExtraSettingsReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/UpdateAlgorithmExtraSettings", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) GetAlgorithmExtraSettings(ctx context.Context, in *GetAlgorithmExtraSettingsRequest, opts ...grpc.CallOption) (*GetAlgorithmExtraSettingsReply, error) { - out := new(GetAlgorithmExtraSettingsReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/GetAlgorithmExtraSettings", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) RegisterTrial(ctx context.Context, in *RegisterTrialRequest, opts ...grpc.CallOption) (*RegisterTrialReply, error) { - out := new(RegisterTrialReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/RegisterTrial", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) DeleteTrial(ctx context.Context, in *DeleteTrialRequest, opts ...grpc.CallOption) (*DeleteTrialReply, error) { - out := new(DeleteTrialReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/DeleteTrial", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) GetTrialList(ctx context.Context, in *GetTrialListRequest, opts ...grpc.CallOption) (*GetTrialListReply, error) { - out := new(GetTrialListReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/GetTrialList", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) GetTrial(ctx context.Context, in *GetTrialRequest, opts ...grpc.CallOption) (*GetTrialReply, error) { - out := new(GetTrialReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/GetTrial", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) UpdateTrialStatus(ctx context.Context, in *UpdateTrialStatusRequest, opts ...grpc.CallOption) (*UpdateTrialStatusReply, error) { - out := new(UpdateTrialStatusReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/UpdateTrialStatus", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) ReportObservationLog(ctx context.Context, in *ReportObservationLogRequest, opts ...grpc.CallOption) (*ReportObservationLogReply, error) { - out := new(ReportObservationLogReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/ReportObservationLog", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) GetObservationLog(ctx context.Context, in *GetObservationLogRequest, opts ...grpc.CallOption) (*GetObservationLogReply, error) { - out := new(GetObservationLogReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/GetObservationLog", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) GetSuggestions(ctx context.Context, in *GetSuggestionsRequest, opts ...grpc.CallOption) (*GetSuggestionsReply, error) { - out := new(GetSuggestionsReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/GetSuggestions", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *managerClient) ValidateAlgorithmSettings(ctx context.Context, in *ValidateAlgorithmSettingsRequest, opts ...grpc.CallOption) (*ValidateAlgorithmSettingsReply, error) { - out := new(ValidateAlgorithmSettingsReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Manager/ValidateAlgorithmSettings", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Manager service - -type ManagerServer interface { - // * - // Register a Experiment to DB. - RegisterExperiment(context.Context, *RegisterExperimentRequest) (*RegisterExperimentReply, error) - // * - // PreCheck to register a Experiment to DB. - PreCheckRegisterExperiment(context.Context, *RegisterExperimentRequest) (*PreCheckRegisterExperimentReply, error) - // * - // Delete a Experiment from DB by name. - DeleteExperiment(context.Context, *DeleteExperimentRequest) (*DeleteExperimentReply, error) - // * - // Get a Experiment from DB by name. - GetExperiment(context.Context, *GetExperimentRequest) (*GetExperimentReply, error) - // * - // Get a summary list of Experiment from DB. - // The summary includes name and condition. - GetExperimentList(context.Context, *GetExperimentListRequest) (*GetExperimentListReply, error) - // * - // Update Status of a experiment. - UpdateExperimentStatus(context.Context, *UpdateExperimentStatusRequest) (*UpdateExperimentStatusReply, error) - // * - // Update AlgorithmExtraSettings. - // The ExtraSetting is created if it does not exist, otherwise it is overwrited. - UpdateAlgorithmExtraSettings(context.Context, *UpdateAlgorithmExtraSettingsRequest) (*UpdateAlgorithmExtraSettingsReply, error) - // * - // Get all AlgorithmExtraSettings. - GetAlgorithmExtraSettings(context.Context, *GetAlgorithmExtraSettingsRequest) (*GetAlgorithmExtraSettingsReply, error) - // * - // Register a Trial to DB. - // ID will be filled by manager automatically. - RegisterTrial(context.Context, *RegisterTrialRequest) (*RegisterTrialReply, error) - // * - // Delete a Trial from DB by ID. - DeleteTrial(context.Context, *DeleteTrialRequest) (*DeleteTrialReply, error) - // * - // Get a list of Trial from DB by name of a Experiment. - GetTrialList(context.Context, *GetTrialListRequest) (*GetTrialListReply, error) - // * - // Get a Trial from DB by ID of Trial. - GetTrial(context.Context, *GetTrialRequest) (*GetTrialReply, error) - // * - // Update Status of a trial. - UpdateTrialStatus(context.Context, *UpdateTrialStatusRequest) (*UpdateTrialStatusReply, error) - // * - // Report a log of Observations for a Trial. - // The log consists of timestamp and value of metric. - // Katib store every log of metrics. - // You can see accuracy curve or other metric logs on UI. - ReportObservationLog(context.Context, *ReportObservationLogRequest) (*ReportObservationLogReply, error) - // * - // Get all log of Observations for a Trial. - GetObservationLog(context.Context, *GetObservationLogRequest) (*GetObservationLogReply, error) - // * - // Get Suggestions from a Suggestion service. - GetSuggestions(context.Context, *GetSuggestionsRequest) (*GetSuggestionsReply, error) - // * - // Validate AlgorithmSettings in an Experiment. - // Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid - ValidateAlgorithmSettings(context.Context, *ValidateAlgorithmSettingsRequest) (*ValidateAlgorithmSettingsReply, error) -} - -func RegisterManagerServer(s *grpc.Server, srv ManagerServer) { - s.RegisterService(&_Manager_serviceDesc, srv) -} - -func _Manager_RegisterExperiment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(RegisterExperimentRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).RegisterExperiment(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/RegisterExperiment", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).RegisterExperiment(ctx, req.(*RegisterExperimentRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_PreCheckRegisterExperiment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(RegisterExperimentRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).PreCheckRegisterExperiment(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/PreCheckRegisterExperiment", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).PreCheckRegisterExperiment(ctx, req.(*RegisterExperimentRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_DeleteExperiment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteExperimentRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).DeleteExperiment(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/DeleteExperiment", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).DeleteExperiment(ctx, req.(*DeleteExperimentRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_GetExperiment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetExperimentRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).GetExperiment(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/GetExperiment", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetExperiment(ctx, req.(*GetExperimentRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_GetExperimentList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetExperimentListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).GetExperimentList(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/GetExperimentList", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetExperimentList(ctx, req.(*GetExperimentListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_UpdateExperimentStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateExperimentStatusRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).UpdateExperimentStatus(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/UpdateExperimentStatus", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).UpdateExperimentStatus(ctx, req.(*UpdateExperimentStatusRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_UpdateAlgorithmExtraSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateAlgorithmExtraSettingsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).UpdateAlgorithmExtraSettings(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/UpdateAlgorithmExtraSettings", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).UpdateAlgorithmExtraSettings(ctx, req.(*UpdateAlgorithmExtraSettingsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_GetAlgorithmExtraSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetAlgorithmExtraSettingsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).GetAlgorithmExtraSettings(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/GetAlgorithmExtraSettings", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetAlgorithmExtraSettings(ctx, req.(*GetAlgorithmExtraSettingsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_RegisterTrial_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(RegisterTrialRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).RegisterTrial(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/RegisterTrial", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).RegisterTrial(ctx, req.(*RegisterTrialRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_DeleteTrial_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteTrialRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).DeleteTrial(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/DeleteTrial", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).DeleteTrial(ctx, req.(*DeleteTrialRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_GetTrialList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetTrialListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).GetTrialList(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/GetTrialList", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetTrialList(ctx, req.(*GetTrialListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_GetTrial_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetTrialRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).GetTrial(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/GetTrial", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetTrial(ctx, req.(*GetTrialRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_UpdateTrialStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateTrialStatusRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).UpdateTrialStatus(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/UpdateTrialStatus", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).UpdateTrialStatus(ctx, req.(*UpdateTrialStatusRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_ReportObservationLog_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ReportObservationLogRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).ReportObservationLog(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/ReportObservationLog", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).ReportObservationLog(ctx, req.(*ReportObservationLogRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_GetObservationLog_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetObservationLogRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).GetObservationLog(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/GetObservationLog", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetObservationLog(ctx, req.(*GetObservationLogRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_GetSuggestions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetSuggestionsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).GetSuggestions(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/GetSuggestions", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetSuggestions(ctx, req.(*GetSuggestionsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Manager_ValidateAlgorithmSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ValidateAlgorithmSettingsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).ValidateAlgorithmSettings(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Manager/ValidateAlgorithmSettings", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).ValidateAlgorithmSettings(ctx, req.(*ValidateAlgorithmSettingsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Manager_serviceDesc = grpc.ServiceDesc{ - ServiceName: "api.v1.alpha2.Manager", - HandlerType: (*ManagerServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "RegisterExperiment", - Handler: _Manager_RegisterExperiment_Handler, - }, - { - MethodName: "PreCheckRegisterExperiment", - Handler: _Manager_PreCheckRegisterExperiment_Handler, - }, - { - MethodName: "DeleteExperiment", - Handler: _Manager_DeleteExperiment_Handler, - }, - { - MethodName: "GetExperiment", - Handler: _Manager_GetExperiment_Handler, - }, - { - MethodName: "GetExperimentList", - Handler: _Manager_GetExperimentList_Handler, - }, - { - MethodName: "UpdateExperimentStatus", - Handler: _Manager_UpdateExperimentStatus_Handler, - }, - { - MethodName: "UpdateAlgorithmExtraSettings", - Handler: _Manager_UpdateAlgorithmExtraSettings_Handler, - }, - { - MethodName: "GetAlgorithmExtraSettings", - Handler: _Manager_GetAlgorithmExtraSettings_Handler, - }, - { - MethodName: "RegisterTrial", - Handler: _Manager_RegisterTrial_Handler, - }, - { - MethodName: "DeleteTrial", - Handler: _Manager_DeleteTrial_Handler, - }, - { - MethodName: "GetTrialList", - Handler: _Manager_GetTrialList_Handler, - }, - { - MethodName: "GetTrial", - Handler: _Manager_GetTrial_Handler, - }, - { - MethodName: "UpdateTrialStatus", - Handler: _Manager_UpdateTrialStatus_Handler, - }, - { - MethodName: "ReportObservationLog", - Handler: _Manager_ReportObservationLog_Handler, - }, - { - MethodName: "GetObservationLog", - Handler: _Manager_GetObservationLog_Handler, - }, - { - MethodName: "GetSuggestions", - Handler: _Manager_GetSuggestions_Handler, - }, - { - MethodName: "ValidateAlgorithmSettings", - Handler: _Manager_ValidateAlgorithmSettings_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "api.proto", -} - -// Client API for Suggestion service - -type SuggestionClient interface { - GetSuggestions(ctx context.Context, in *GetSuggestionsRequest, opts ...grpc.CallOption) (*GetSuggestionsReply, error) - ValidateAlgorithmSettings(ctx context.Context, in *ValidateAlgorithmSettingsRequest, opts ...grpc.CallOption) (*ValidateAlgorithmSettingsReply, error) -} - -type suggestionClient struct { - cc *grpc.ClientConn -} - -func NewSuggestionClient(cc *grpc.ClientConn) SuggestionClient { - return &suggestionClient{cc} -} - -func (c *suggestionClient) GetSuggestions(ctx context.Context, in *GetSuggestionsRequest, opts ...grpc.CallOption) (*GetSuggestionsReply, error) { - out := new(GetSuggestionsReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Suggestion/GetSuggestions", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *suggestionClient) ValidateAlgorithmSettings(ctx context.Context, in *ValidateAlgorithmSettingsRequest, opts ...grpc.CallOption) (*ValidateAlgorithmSettingsReply, error) { - out := new(ValidateAlgorithmSettingsReply) - err := grpc.Invoke(ctx, "/api.v1.alpha2.Suggestion/ValidateAlgorithmSettings", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Suggestion service - -type SuggestionServer interface { - GetSuggestions(context.Context, *GetSuggestionsRequest) (*GetSuggestionsReply, error) - ValidateAlgorithmSettings(context.Context, *ValidateAlgorithmSettingsRequest) (*ValidateAlgorithmSettingsReply, error) -} - -func RegisterSuggestionServer(s *grpc.Server, srv SuggestionServer) { - s.RegisterService(&_Suggestion_serviceDesc, srv) -} - -func _Suggestion_GetSuggestions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetSuggestionsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(SuggestionServer).GetSuggestions(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Suggestion/GetSuggestions", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SuggestionServer).GetSuggestions(ctx, req.(*GetSuggestionsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Suggestion_ValidateAlgorithmSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ValidateAlgorithmSettingsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(SuggestionServer).ValidateAlgorithmSettings(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.alpha2.Suggestion/ValidateAlgorithmSettings", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SuggestionServer).ValidateAlgorithmSettings(ctx, req.(*ValidateAlgorithmSettingsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Suggestion_serviceDesc = grpc.ServiceDesc{ - ServiceName: "api.v1.alpha2.Suggestion", - HandlerType: (*SuggestionServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetSuggestions", - Handler: _Suggestion_GetSuggestions_Handler, - }, - { - MethodName: "ValidateAlgorithmSettings", - Handler: _Suggestion_ValidateAlgorithmSettings_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "api.proto", -} - -// Client API for EarlyStopping service - -type EarlyStoppingClient interface { -} - -type earlyStoppingClient struct { - cc *grpc.ClientConn -} - -func NewEarlyStoppingClient(cc *grpc.ClientConn) EarlyStoppingClient { - return &earlyStoppingClient{cc} -} - -// Server API for EarlyStopping service - -type EarlyStoppingServer interface { -} - -func RegisterEarlyStoppingServer(s *grpc.Server, srv EarlyStoppingServer) { - s.RegisterService(&_EarlyStopping_serviceDesc, srv) -} - -var _EarlyStopping_serviceDesc = grpc.ServiceDesc{ - ServiceName: "api.v1.alpha2.EarlyStopping", - HandlerType: (*EarlyStoppingServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{}, - Metadata: "api.proto", -} - -func init() { proto.RegisterFile("api.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 2505 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5a, 0xcb, 0x73, 0x1b, 0x59, - 0xf5, 0x9e, 0x96, 0xfc, 0xd2, 0x51, 0x24, 0xcb, 0xd7, 0x72, 0x22, 0x2b, 0x0f, 0x2b, 0x37, 0x0f, - 0xfb, 0xe7, 0x49, 0xec, 0x44, 0xf3, 0xc8, 0x8c, 0x93, 0xdf, 0xcc, 0x38, 0xb2, 0xe2, 0x72, 0xc5, - 0x91, 0x53, 0x2d, 0x39, 0x90, 0x81, 0x2a, 0xd1, 0x56, 0x6e, 0x94, 0x66, 0x5a, 0xdd, 0x4d, 0x77, - 0x2b, 0x13, 0x93, 0x4a, 0x15, 0x15, 0x58, 0x40, 0x01, 0xa9, 0xa2, 0x60, 0x03, 0x54, 0xc1, 0x9a, - 0x05, 0x6c, 0x60, 0xcb, 0x82, 0x2a, 0x96, 0xec, 0x78, 0xac, 0x58, 0xc2, 0xff, 0x41, 0xdd, 0xd3, - 0xef, 0x97, 0x2c, 0x27, 0xa1, 0xd8, 0xa9, 0xef, 0xfd, 0xee, 0xb9, 0xdf, 0x39, 0xf7, 0x9c, 0xef, - 0x9e, 0x6e, 0x1b, 0x72, 0x92, 0x2e, 0xaf, 0xe9, 0x86, 0x66, 0x69, 0xa4, 0xc0, 0x7f, 0x3e, 0xbd, - 0xbe, 0x26, 0x29, 0xfa, 0x13, 0xa9, 0x5e, 0x3d, 0xd3, 0xd7, 0xb4, 0xbe, 0xc2, 0xd6, 0x25, 0x5d, - 0x5e, 0x97, 0x54, 0x55, 0xb3, 0x24, 0x4b, 0xd6, 0x54, 0xd3, 0x06, 0xd3, 0xaf, 0x41, 0xe1, 0x0e, - 0x93, 0x4c, 0xf9, 0x40, 0x61, 0x6d, 0x5d, 0xea, 0x31, 0x52, 0x82, 0xec, 0x40, 0x7a, 0x56, 0x11, - 0x6a, 0xc2, 0x4a, 0x4e, 0xe4, 0x3f, 0x71, 0x44, 0x56, 0x2b, 0x19, 0x67, 0x44, 0x56, 0x09, 0x81, - 0x09, 0x45, 0x36, 0xad, 0x4a, 0xb6, 0x96, 0x5d, 0xc9, 0x89, 0xf8, 0x9b, 0x8f, 0x99, 0x16, 0xd3, - 0x2b, 0x13, 0x08, 0xc3, 0xdf, 0xf4, 0xb7, 0x02, 0x14, 0xee, 0x4b, 0x86, 0x34, 0x60, 0x16, 0x33, - 0xda, 0x3a, 0xeb, 0x71, 0x94, 0x2a, 0x0d, 0x98, 0x63, 0x1e, 0x7f, 0x93, 0x06, 0x14, 0x75, 0x17, - 0xd4, 0xb5, 0x0e, 0x75, 0x86, 0x5b, 0x15, 0xeb, 0x67, 0xd6, 0x42, 0x8e, 0xac, 0x79, 0x96, 0x3a, - 0x87, 0x3a, 0x13, 0x0b, 0x7a, 0xf0, 0x91, 0x1b, 0x79, 0xec, 0xf8, 0xd1, 0x35, 0xb9, 0x23, 0x95, - 0x6c, 0x4d, 0x58, 0xc9, 0xc7, 0x8c, 0x84, 0x9c, 0x15, 0x0b, 0x8f, 0x83, 0x8f, 0xf4, 0x4f, 0x02, - 0x14, 0xf6, 0x0e, 0xbe, 0xc9, 0x7a, 0x96, 0xfc, 0x94, 0x21, 0xdf, 0x6b, 0x30, 0x81, 0x8c, 0x84, - 0x44, 0x46, 0x1e, 0x16, 0x19, 0x21, 0x92, 0x7b, 0xd8, 0xd7, 0x24, 0x05, 0x7d, 0xc8, 0x88, 0xf8, - 0x9b, 0xd4, 0x61, 0x41, 0x73, 0xa1, 0xdd, 0x01, 0xb3, 0x0c, 0xb9, 0xd7, 0xc5, 0x30, 0x64, 0x31, - 0x0c, 0xf3, 0xde, 0xe4, 0x3d, 0x9c, 0x6b, 0xf1, 0xa8, 0x7c, 0x08, 0xa7, 0xa4, 0x47, 0x8f, 0x64, - 0x7e, 0x56, 0x92, 0x12, 0x5c, 0x64, 0x56, 0x26, 0x30, 0xec, 0x0b, 0xfe, 0xb4, 0xbf, 0xcc, 0xa4, - 0xb7, 0xa0, 0xb4, 0xa9, 0xf4, 0x35, 0x43, 0xb6, 0x9e, 0x0c, 0xda, 0xcc, 0xb2, 0x64, 0xb5, 0x9f, - 0x18, 0xf5, 0x32, 0x4c, 0x3e, 0x95, 0x94, 0x21, 0x73, 0xce, 0xd5, 0x7e, 0xa0, 0xf3, 0x30, 0xd7, - 0x94, 0x0c, 0xe5, 0xb0, 0x6d, 0x69, 0xba, 0x2e, 0xab, 0x7d, 0x1e, 0x04, 0xfa, 0x0f, 0x01, 0x0a, - 0xbe, 0x4d, 0x1e, 0x96, 0x4b, 0x50, 0x94, 0xdc, 0x81, 0x6e, 0xc0, 0x74, 0xc1, 0x1b, 0x45, 0x1f, - 0x76, 0x61, 0xce, 0x87, 0x99, 0x36, 0x99, 0x4a, 0xa6, 0x96, 0x5d, 0xc9, 0xd7, 0x97, 0x22, 0xa1, - 0x8c, 0x72, 0x16, 0x4b, 0x52, 0xd4, 0x8b, 0xfb, 0x30, 0xcf, 0x38, 0xb7, 0xae, 0xe9, 0x90, 0xeb, - 0x9a, 0x3a, 0xeb, 0x39, 0xe7, 0x5c, 0x8b, 0xd8, 0x8b, 0x79, 0x21, 0xce, 0xb1, 0x98, 0x63, 0x7f, - 0x17, 0x20, 0xd7, 0x92, 0xcc, 0x86, 0xa6, 0x3e, 0x96, 0xfb, 0xe4, 0xff, 0xe1, 0x44, 0xdf, 0x90, - 0xf4, 0x27, 0xdd, 0x1e, 0x3e, 0xa3, 0x4b, 0xf9, 0x7a, 0x35, 0x62, 0x78, 0x9b, 0x43, 0xec, 0x15, - 0x62, 0xbe, 0xef, 0x3f, 0x90, 0x06, 0x80, 0xa6, 0x33, 0xc3, 0xae, 0x2e, 0x8c, 0x6a, 0xbe, 0x7e, - 0x21, 0xb2, 0xd8, 0xdb, 0x6c, 0x6d, 0xcf, 0x83, 0x8a, 0x81, 0x65, 0xd5, 0x2d, 0x00, 0x7f, 0x86, - 0x7c, 0x08, 0x39, 0x6f, 0xae, 0x22, 0x60, 0xdc, 0x2a, 0xd1, 0x14, 0x74, 0xe7, 0x45, 0x1f, 0x4a, - 0x75, 0xc8, 0x07, 0x68, 0x92, 0xb3, 0x00, 0xea, 0x70, 0xd0, 0x55, 0xa4, 0x43, 0x66, 0x98, 0xe8, - 0xd6, 0xa4, 0x98, 0x53, 0x87, 0x83, 0x5d, 0x1c, 0x20, 0x4b, 0x90, 0x97, 0x55, 0x7d, 0x68, 0x75, - 0x4d, 0xf9, 0xdb, 0xcc, 0xc4, 0xf3, 0x99, 0x14, 0x01, 0x87, 0xda, 0x7c, 0x84, 0x9c, 0x87, 0x13, - 0xda, 0xd0, 0xf2, 0x11, 0x59, 0x44, 0xe4, 0xed, 0x31, 0x84, 0xd0, 0xbf, 0x09, 0x90, 0xf3, 0xa8, - 0xf0, 0xf4, 0xf0, 0xc8, 0x74, 0xbd, 0xfa, 0xc9, 0x89, 0x05, 0x6f, 0x14, 0x6b, 0xf6, 0x3e, 0xcc, - 0xfa, 0x85, 0xcf, 0xcf, 0xd2, 0x0d, 0xdb, 0x72, 0x9a, 0x93, 0x6b, 0x21, 0x35, 0x31, 0x45, 0x5f, - 0x38, 0xf0, 0xb9, 0xda, 0x82, 0x62, 0x18, 0x41, 0x6e, 0x01, 0x78, 0x18, 0xd3, 0x89, 0x61, 0xaa, - 0xb0, 0x60, 0x9e, 0x04, 0xf0, 0xf4, 0xd7, 0x13, 0x50, 0x6c, 0x3e, 0xd3, 0x99, 0x21, 0x0f, 0x98, - 0x6a, 0x61, 0xea, 0xef, 0xc7, 0x49, 0xdb, 0x89, 0x72, 0x25, 0x9a, 0x81, 0xa1, 0x75, 0x47, 0x30, - 0x27, 0x1b, 0x90, 0xf3, 0x54, 0xc0, 0x89, 0x42, 0xaa, 0xda, 0x20, 0x4d, 0x1f, 0xce, 0xd7, 0x7a, - 0xc5, 0x92, 0x22, 0x7b, 0xa1, 0xf2, 0x15, 0x7d, 0x38, 0x3f, 0x2a, 0xcb, 0x90, 0x25, 0xa5, 0x6b, - 0xb1, 0x81, 0xae, 0x48, 0x16, 0x73, 0x04, 0xbc, 0x80, 0xa3, 0x1d, 0x67, 0x90, 0xbc, 0x0f, 0x27, - 0x6d, 0x09, 0x32, 0xbb, 0x3d, 0x4d, 0x51, 0x58, 0xcf, 0xd2, 0x6c, 0xef, 0x2b, 0x93, 0x08, 0x2f, - 0x3b, 0xb3, 0x0d, 0x77, 0xd2, 0x51, 0xcf, 0x32, 0x77, 0x53, 0x51, 0x98, 0xd2, 0xb5, 0x77, 0xe9, - 0x69, 0x43, 0xd5, 0xaa, 0x4c, 0x61, 0x0a, 0x12, 0x77, 0xae, 0xc3, 0xa7, 0x1a, 0x7c, 0x86, 0x5c, - 0x86, 0xd9, 0x81, 0xf4, 0x2c, 0x04, 0x9e, 0x46, 0x70, 0x61, 0x20, 0x3d, 0x0b, 0xe0, 0x6e, 0x00, - 0xa8, 0x92, 0xe9, 0x56, 0xea, 0x0c, 0xfa, 0x5c, 0x49, 0x2b, 0x36, 0x31, 0xa7, 0xba, 0x3f, 0xdf, - 0x7a, 0x86, 0xfc, 0x2a, 0x03, 0xa5, 0xc0, 0x49, 0x5b, 0x92, 0x35, 0x34, 0x79, 0xc1, 0x99, 0x96, - 0x64, 0x58, 0x5d, 0x4b, 0xf6, 0xa4, 0x31, 0x87, 0x23, 0x1d, 0x79, 0xc0, 0xc8, 0x32, 0xcc, 0xf6, - 0xb4, 0x81, 0xae, 0x30, 0xbb, 0x3e, 0x38, 0xc6, 0x16, 0xe1, 0xa2, 0x3f, 0x8c, 0xc0, 0x7d, 0xc8, - 0xf5, 0x34, 0xd5, 0x56, 0x79, 0x3c, 0xd8, 0x62, 0xfd, 0x46, 0x7a, 0x96, 0xe1, 0xde, 0x81, 0x81, - 0x86, 0xbb, 0x14, 0x6f, 0x27, 0xdf, 0x12, 0xfd, 0x02, 0x4e, 0xa5, 0xa0, 0x48, 0x1e, 0xa6, 0x1b, - 0x62, 0x73, 0xb3, 0xd3, 0xdc, 0x2a, 0xbd, 0xc3, 0x1f, 0xc4, 0xfd, 0x56, 0x6b, 0xa7, 0xb5, 0x5d, - 0x12, 0x48, 0x11, 0x40, 0x6c, 0xb6, 0x3b, 0x9b, 0x62, 0x87, 0x3f, 0x67, 0x48, 0x01, 0x72, 0xed, - 0xfd, 0x46, 0xa3, 0xd9, 0xdc, 0x6a, 0x6e, 0x95, 0xb2, 0x04, 0x60, 0xea, 0xce, 0xe6, 0xce, 0x6e, - 0x73, 0xab, 0x34, 0xc1, 0xd7, 0xed, 0xb7, 0xee, 0xb6, 0xf6, 0xbe, 0xd2, 0x2a, 0x4d, 0xd2, 0x1f, - 0x09, 0x00, 0xfe, 0x6e, 0x89, 0x57, 0xd1, 0x75, 0x98, 0xc0, 0x54, 0xb2, 0xd3, 0xfe, 0xec, 0xc8, - 0x3a, 0x12, 0x11, 0x4a, 0x6e, 0xc0, 0x94, 0x89, 0xfe, 0x3a, 0xf9, 0xbe, 0x74, 0x44, 0x58, 0x44, - 0x07, 0x4e, 0x3f, 0x85, 0x79, 0xef, 0x30, 0x37, 0x4d, 0x53, 0xee, 0xab, 0xa9, 0xb4, 0x92, 0x6f, - 0xc8, 0x3a, 0x4c, 0xd9, 0xd7, 0xed, 0x31, 0xd6, 0x3c, 0x84, 0x9c, 0xbd, 0x66, 0x57, 0x43, 0x35, - 0xe6, 0x47, 0xde, 0x35, 0x2d, 0x69, 0xa0, 0xbb, 0xc9, 0xc1, 0x47, 0xda, 0x7c, 0x80, 0x5c, 0x85, - 0x29, 0xbb, 0x96, 0x9c, 0x70, 0x2c, 0x44, 0x3c, 0xb3, 0x0d, 0x89, 0x0e, 0x88, 0x7e, 0x02, 0xf9, - 0xbd, 0x03, 0x93, 0x19, 0x4f, 0x6d, 0xe5, 0x5d, 0x87, 0x69, 0xa7, 0x12, 0x9d, 0x4c, 0x4e, 0x59, - 0xee, 0xa2, 0xe8, 0x5d, 0x28, 0x06, 0xd6, 0x73, 0x7e, 0x1f, 0x43, 0xde, 0xe9, 0x36, 0x14, 0xad, - 0x6f, 0xa6, 0x5c, 0x3b, 0x9e, 0x3b, 0x22, 0x0c, 0xdc, 0x9f, 0x26, 0xfd, 0x6e, 0x16, 0x72, 0x58, - 0xa4, 0x58, 0xfd, 0xcb, 0x30, 0xcb, 0xbc, 0x63, 0x08, 0x76, 0x09, 0x45, 0x7f, 0x18, 0xdb, 0x84, - 0x37, 0xd1, 0xbe, 0x03, 0x58, 0xf0, 0xe5, 0x58, 0xf2, 0x0e, 0xd4, 0xcd, 0x8b, 0xab, 0x11, 0x3b, - 0x1e, 0xbb, 0xb5, 0x84, 0x2c, 0x30, 0xc5, 0xb2, 0x9e, 0x30, 0x4a, 0x16, 0x61, 0xc6, 0x18, 0xaa, - 0xb6, 0xdc, 0xd9, 0xea, 0x38, 0x6d, 0x0c, 0x55, 0xf4, 0xf1, 0xb5, 0x74, 0xb1, 0xfa, 0x75, 0x28, - 0x27, 0x6d, 0x4f, 0xb6, 0x20, 0x1f, 0x74, 0xc1, 0x0e, 0x3d, 0x4d, 0xd3, 0x22, 0x7f, 0xa5, 0x18, - 0x5c, 0x46, 0xff, 0x9c, 0x81, 0xbc, 0xed, 0xe7, 0xdb, 0x55, 0xa3, 0xbb, 0x71, 0x35, 0x4a, 0x0e, - 0xaf, 0x2d, 0x44, 0x8e, 0x5a, 0x27, 0x6b, 0x10, 0xb9, 0x05, 0x79, 0xcd, 0xcf, 0x3b, 0x0c, 0x6b, - 0xbc, 0xd7, 0x0a, 0x64, 0xa6, 0x18, 0x84, 0xd3, 0x03, 0x20, 0x71, 0xf3, 0x23, 0xc4, 0x2b, 0x24, - 0x56, 0x19, 0x2e, 0x56, 0x77, 0x77, 0x76, 0x77, 0x47, 0x0b, 0xd7, 0x0b, 0x98, 0xc4, 0x3d, 0x12, - 0xeb, 0xfc, 0x4a, 0x48, 0xb2, 0x2a, 0x69, 0x59, 0xe6, 0xa8, 0x55, 0x3d, 0xa2, 0x56, 0xd5, 0xf4, - 0xb0, 0x79, 0x42, 0xf5, 0x00, 0x16, 0x45, 0xd6, 0x97, 0x4d, 0x8b, 0x19, 0xbe, 0x98, 0x89, 0xec, - 0x5b, 0x43, 0x66, 0x5a, 0xe4, 0x63, 0x00, 0xbf, 0x86, 0x9c, 0xfe, 0x63, 0x31, 0x55, 0x02, 0xc5, - 0x00, 0x98, 0x2e, 0xc2, 0xa9, 0x24, 0xbb, 0xba, 0x72, 0x48, 0xb7, 0x60, 0xe9, 0xbe, 0xc1, 0x1a, - 0x4f, 0x58, 0xef, 0x8b, 0x14, 0x08, 0x6f, 0x05, 0x7b, 0x92, 0xda, 0x35, 0x9c, 0x69, 0xdc, 0x7a, - 0x46, 0xcc, 0xf7, 0x24, 0xd5, 0x5d, 0x41, 0x6f, 0xc3, 0xa9, 0x2d, 0xa6, 0x30, 0x8b, 0xc5, 0x69, - 0x8f, 0xab, 0x08, 0xf4, 0x14, 0x2c, 0xc4, 0x6d, 0x70, 0x8a, 0x9f, 0x42, 0x79, 0x9b, 0x59, 0x6f, - 0x60, 0x79, 0x0f, 0x48, 0xc4, 0x00, 0x77, 0xeb, 0x0d, 0xe2, 0x39, 0x84, 0xb9, 0xc0, 0x65, 0x33, - 0x1c, 0x0c, 0x24, 0xe3, 0x70, 0x7c, 0xe9, 0xf3, 0xef, 0xb1, 0xcc, 0xf1, 0xee, 0xb1, 0x2a, 0x54, - 0x42, 0x7e, 0xec, 0xca, 0xa6, 0x1b, 0x0c, 0x3a, 0x80, 0x93, 0x09, 0x73, 0xdc, 0xcf, 0x36, 0x94, - 0x03, 0xbc, 0x4c, 0x64, 0x2b, 0x33, 0x57, 0x69, 0x6a, 0xe9, 0x9b, 0xdb, 0x7e, 0x89, 0xf3, 0x2c, - 0x32, 0x24, 0x33, 0x93, 0x7e, 0x5f, 0x80, 0xb3, 0xfb, 0xfa, 0x23, 0x29, 0x78, 0x5a, 0x0e, 0xdb, - 0x63, 0x9e, 0x0e, 0xf9, 0x04, 0x40, 0x65, 0x5f, 0x76, 0x8f, 0x17, 0x92, 0x9c, 0xca, 0xbe, 0xb4, - 0x7f, 0xd2, 0xb3, 0x70, 0x3a, 0x8d, 0x09, 0xcf, 0x9e, 0xdf, 0x08, 0x70, 0xc1, 0x9e, 0xf7, 0xfa, - 0xe1, 0xe6, 0x33, 0xcb, 0x90, 0x9c, 0x37, 0xcc, 0xe3, 0xf3, 0x7d, 0x08, 0x15, 0xc6, 0x0d, 0x74, - 0x63, 0xaf, 0xb9, 0xe6, 0xb8, 0xef, 0xb9, 0x27, 0xd1, 0x40, 0x74, 0xd8, 0xa4, 0x17, 0xe0, 0xfc, - 0x68, 0xaa, 0xdc, 0xa1, 0xbb, 0x50, 0xdb, 0x66, 0xd6, 0xdb, 0x71, 0x86, 0x3e, 0x87, 0x73, 0x23, - 0x8c, 0xf1, 0xf4, 0x19, 0xe5, 0xae, 0xf0, 0x66, 0xee, 0xde, 0x86, 0xb2, 0xab, 0x20, 0xa8, 0x86, - 0x2e, 0xfb, 0x55, 0x98, 0xc4, 0x97, 0x01, 0xa7, 0x28, 0xcb, 0x49, 0xca, 0x29, 0xda, 0x10, 0x5a, - 0x06, 0x12, 0xb1, 0xc1, 0x63, 0xf4, 0x1e, 0x10, 0x5b, 0x4b, 0x42, 0x76, 0x79, 0x17, 0x86, 0x2f, - 0x19, 0x81, 0x80, 0xe4, 0x70, 0x04, 0x63, 0x41, 0xa0, 0x14, 0x5a, 0xc4, 0x0d, 0x3d, 0x80, 0xf9, - 0x6d, 0x66, 0xe1, 0x40, 0xa0, 0xda, 0xc6, 0x4f, 0x96, 0x93, 0x30, 0xf5, 0x58, 0x56, 0xb8, 0x6a, - 0xda, 0xf7, 0xab, 0xf3, 0x44, 0x37, 0x61, 0x2e, 0x6c, 0x97, 0x87, 0xfa, 0x0a, 0x4c, 0x21, 0x1b, - 0x37, 0xb0, 0xc9, 0x8e, 0x3b, 0x18, 0x7a, 0x0d, 0x66, 0x5d, 0x13, 0x63, 0x3a, 0x78, 0x13, 0x0a, - 0xfe, 0x0a, 0xbe, 0xe1, 0x71, 0x02, 0x6d, 0x41, 0xc5, 0xce, 0xcd, 0xe0, 0xc5, 0x35, 0xd6, 0xbe, - 0x5c, 0x69, 0x63, 0x15, 0x3e, 0xea, 0x3a, 0x0c, 0x14, 0x77, 0x05, 0x4e, 0x26, 0xec, 0xca, 0x4f, - 0xe6, 0x7b, 0x02, 0x9c, 0x16, 0x99, 0xae, 0x19, 0x56, 0xb8, 0x97, 0x1d, 0x93, 0xd3, 0x1d, 0x98, - 0x0d, 0x34, 0x17, 0xbc, 0xed, 0x4d, 0x79, 0x15, 0x89, 0x58, 0x2f, 0x6a, 0xa1, 0x67, 0x7a, 0x9a, - 0x5f, 0xd9, 0x49, 0x2c, 0x38, 0xc7, 0x9f, 0x09, 0xa8, 0xd8, 0xaf, 0x45, 0x70, 0xc9, 0x6b, 0xc9, - 0x71, 0xde, 0x4e, 0x1f, 0xa7, 0xf1, 0x46, 0x40, 0xb8, 0xc5, 0xcb, 0x46, 0x5b, 0xbc, 0x45, 0x98, - 0x61, 0xea, 0x23, 0x7b, 0xd2, 0x69, 0x60, 0x99, 0xfa, 0x88, 0x4f, 0xd1, 0x6f, 0xe0, 0x5d, 0x91, - 0x40, 0x38, 0x29, 0x2a, 0xc2, 0xeb, 0x44, 0xe5, 0x95, 0x00, 0x0b, 0xdb, 0xcc, 0x6a, 0x0f, 0xfb, - 0x7d, 0x66, 0xda, 0x5f, 0xbc, 0x8e, 0x5b, 0x39, 0xf1, 0xcf, 0x8d, 0x99, 0xa4, 0xcf, 0x8d, 0x97, - 0xa0, 0x68, 0xd8, 0xa6, 0xbb, 0xea, 0x70, 0x70, 0xc0, 0x0c, 0x8c, 0xc4, 0xa4, 0x58, 0x70, 0x46, - 0x5b, 0x38, 0x48, 0x1b, 0x58, 0xc7, 0x21, 0x3e, 0xc7, 0xaf, 0xb8, 0x9f, 0x08, 0x50, 0x7b, 0x20, - 0x29, 0x72, 0x48, 0xa1, 0xa3, 0xd2, 0x7b, 0x27, 0xe4, 0x20, 0x36, 0x8c, 0xc2, 0x38, 0xef, 0xb8, - 0x01, 0xff, 0x53, 0x3e, 0xb7, 0x26, 0xf9, 0x4f, 0x6b, 0x70, 0x6e, 0x04, 0x25, 0x5d, 0x39, 0x5c, - 0xdd, 0x0f, 0x7c, 0x8f, 0xc7, 0x96, 0xb9, 0x04, 0x27, 0x9c, 0x8e, 0xb7, 0xdb, 0x79, 0x78, 0xbf, - 0x59, 0x7a, 0x87, 0xf7, 0xc3, 0x5b, 0x7b, 0xfb, 0xb7, 0x77, 0x9b, 0x25, 0x81, 0x4c, 0x43, 0x76, - 0xa7, 0xd5, 0x29, 0x65, 0xc8, 0x09, 0x98, 0xd9, 0xda, 0x69, 0x37, 0xc4, 0x66, 0xa7, 0x59, 0xca, - 0x92, 0x59, 0xc8, 0x37, 0x36, 0x3b, 0xcd, 0xed, 0x3d, 0x71, 0xa7, 0xb1, 0xb9, 0x5b, 0x9a, 0x58, - 0xfd, 0x28, 0xf0, 0xd9, 0xdc, 0xed, 0xc4, 0xdd, 0x46, 0xfa, 0x1d, 0xbe, 0xf8, 0xde, 0x4e, 0x6b, - 0xe7, 0xde, 0xce, 0xe7, 0xdc, 0x26, 0x7f, 0xda, 0xfc, 0xaa, 0xfd, 0x94, 0xa9, 0xff, 0xb3, 0x0c, - 0xd3, 0xf7, 0x24, 0x55, 0xea, 0x33, 0x83, 0xfc, 0x52, 0xf0, 0xf5, 0x3b, 0xf0, 0xc5, 0x60, 0x25, - 0x12, 0xab, 0xd4, 0xae, 0xb8, 0x7a, 0x79, 0x0c, 0x24, 0xde, 0x08, 0x2f, 0xff, 0xfa, 0xaf, 0x9f, - 0x66, 0xae, 0xd2, 0x25, 0xfc, 0x9b, 0x88, 0xb3, 0xfd, 0x7a, 0x1c, 0xbd, 0x11, 0xe8, 0xf3, 0xc8, - 0xef, 0x05, 0xa8, 0xa6, 0x77, 0xc7, 0xc7, 0x60, 0xb9, 0x16, 0x7d, 0x9f, 0x1b, 0xdd, 0x72, 0xd3, - 0x9b, 0xc8, 0xf6, 0x03, 0xba, 0x1c, 0x62, 0x9b, 0xbe, 0x2a, 0xc4, 0xfa, 0xe7, 0x82, 0x7b, 0x91, - 0x05, 0xb8, 0x46, 0xe3, 0x94, 0xd2, 0xae, 0x57, 0x2f, 0x1e, 0x89, 0xe3, 0xfc, 0x6e, 0x20, 0xbf, - 0xeb, 0x64, 0x3d, 0xc4, 0x2f, 0x8a, 0x5d, 0x7f, 0x1e, 0x29, 0xf5, 0x17, 0xe4, 0xc7, 0x02, 0xde, - 0x41, 0x01, 0x62, 0xd1, 0xcf, 0xe5, 0x49, 0xad, 0x7e, 0xf5, 0xfc, 0x68, 0x10, 0xa7, 0xf4, 0x3e, - 0x52, 0x5a, 0x23, 0x57, 0x42, 0x94, 0x42, 0xc0, 0x04, 0x3e, 0x3f, 0x14, 0xf0, 0x22, 0x0e, 0xf7, - 0xcd, 0x64, 0x79, 0xd4, 0x76, 0x81, 0x3e, 0xa0, 0x7a, 0xe9, 0x68, 0x20, 0xe7, 0x76, 0x19, 0xb9, - 0xd5, 0xc8, 0xb9, 0x74, 0x6e, 0xb8, 0xef, 0x1f, 0x04, 0xf7, 0xba, 0x8b, 0x7d, 0x5e, 0x8c, 0x7e, - 0x69, 0x1e, 0xd9, 0x7c, 0x57, 0x57, 0xc7, 0x44, 0x73, 0x72, 0x9f, 0x21, 0xb9, 0x8d, 0xea, 0x07, - 0x21, 0x72, 0xc9, 0x2b, 0xe2, 0x11, 0xdc, 0x10, 0x56, 0xc9, 0x5f, 0x04, 0x38, 0x33, 0xaa, 0x6f, - 0x25, 0xf5, 0x44, 0x3a, 0x23, 0x5b, 0xd8, 0xea, 0xb5, 0x63, 0xad, 0xe1, 0x8e, 0xdc, 0x41, 0x47, - 0x3e, 0xab, 0xde, 0x4c, 0x70, 0x24, 0x79, 0x5d, 0xb2, 0x3b, 0x7f, 0x14, 0x60, 0x31, 0xb5, 0x29, - 0x26, 0xeb, 0xf1, 0x23, 0x1f, 0xed, 0xc8, 0xd5, 0xf1, 0x17, 0x04, 0x8e, 0x83, 0x7c, 0x14, 0xcd, - 0x95, 0x71, 0x5d, 0x20, 0x2f, 0x05, 0x28, 0x84, 0x7a, 0xe2, 0x58, 0x8d, 0x25, 0x75, 0xdd, 0xb1, - 0x1a, 0x4b, 0x68, 0xab, 0xff, 0x0f, 0xb9, 0x5d, 0xa0, 0xd5, 0x44, 0x11, 0x45, 0xe0, 0x86, 0xdd, - 0x2e, 0x92, 0xef, 0x08, 0x90, 0x0f, 0x74, 0xd3, 0xe4, 0x7c, 0xa2, 0xae, 0x84, 0x08, 0x2c, 0x8d, - 0x82, 0xf0, 0xed, 0xaf, 0xe2, 0xf6, 0xcb, 0xe4, 0x52, 0x82, 0xea, 0x20, 0x6c, 0xfd, 0xb9, 0xdf, - 0x51, 0xbd, 0x20, 0x3f, 0x10, 0xe0, 0x44, 0xb0, 0xc9, 0x26, 0x34, 0x7e, 0x12, 0xd1, 0xce, 0xbe, - 0x5a, 0x1b, 0x89, 0x09, 0xdc, 0x24, 0xe4, 0xdd, 0xe8, 0x01, 0x79, 0xb8, 0x84, 0x33, 0xb1, 0x60, - 0xc6, 0x45, 0x90, 0x73, 0x29, 0x5b, 0xb8, 0x14, 0xce, 0xa4, 0xce, 0xf3, 0xed, 0x57, 0x71, 0xfb, - 0x8b, 0x84, 0x26, 0x6e, 0x1f, 0x8e, 0xc0, 0x2b, 0x01, 0xe6, 0x62, 0xed, 0x73, 0x4c, 0xdd, 0xd2, - 0xda, 0xfa, 0x98, 0xba, 0xa5, 0x74, 0xe2, 0x4e, 0x56, 0x54, 0xcf, 0x25, 0xd4, 0x5d, 0x00, 0xcc, - 0x4b, 0xeb, 0x17, 0x02, 0x7f, 0xe5, 0x8b, 0xb7, 0xcb, 0x64, 0x35, 0x96, 0x7c, 0xa9, 0x9d, 0x7d, - 0x75, 0x65, 0x2c, 0x2c, 0x67, 0x76, 0x05, 0x99, 0x5d, 0xa6, 0xe7, 0x23, 0xf9, 0x1a, 0xc7, 0x73, - 0x72, 0xaf, 0xec, 0xbb, 0x20, 0xc2, 0x2c, 0xe1, 0x2e, 0x48, 0xa6, 0x75, 0xe9, 0x68, 0x60, 0xb0, - 0x86, 0x62, 0x77, 0x41, 0x9c, 0xd0, 0x4b, 0x01, 0x8a, 0xe1, 0xae, 0x95, 0x5c, 0x8c, 0x6f, 0x12, - 0x6f, 0xb2, 0xab, 0xf4, 0x08, 0x54, 0xe0, 0x4e, 0xa2, 0xa7, 0xa3, 0x3c, 0x02, 0x48, 0x4e, 0xe2, - 0x77, 0x02, 0x2c, 0xa6, 0x76, 0x98, 0x31, 0x35, 0x3c, 0xaa, 0x3d, 0x8e, 0xa9, 0xe1, 0xe8, 0xe6, - 0x95, 0x5e, 0x47, 0x96, 0xef, 0xd2, 0xcb, 0x21, 0x96, 0xa9, 0x8b, 0x36, 0x84, 0xd5, 0xfa, 0xbf, - 0x05, 0x00, 0xdf, 0x07, 0xf2, 0xf9, 0x7f, 0x2f, 0x86, 0xe4, 0xf9, 0xff, 0x30, 0x34, 0xf5, 0x59, - 0x28, 0x84, 0xfe, 0xe1, 0xe1, 0x60, 0x0a, 0xff, 0xbb, 0xe7, 0xbd, 0xff, 0x04, 0x00, 0x00, 0xff, - 0xff, 0x8b, 0x40, 0x8a, 0x6f, 0x17, 0x24, 0x00, 0x00, -} diff --git a/pkg/apis/manager/v1alpha2/api.pb.gw.go b/pkg/apis/manager/v1alpha2/api.pb.gw.go deleted file mode 100644 index aa65dcbb750..00000000000 --- a/pkg/apis/manager/v1alpha2/api.pb.gw.go +++ /dev/null @@ -1,972 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: api.proto - -/* -Package api_v1_alpha2 is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package api_v1_alpha2 - -import ( - "io" - "net/http" - - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray - -func request_Manager_RegisterExperiment_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq RegisterExperimentRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Experiment); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.RegisterExperiment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_PreCheckRegisterExperiment_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq RegisterExperimentRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Experiment); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.PreCheckRegisterExperiment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_DeleteExperiment_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq DeleteExperimentRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["experiment_name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "experiment_name") - } - - protoReq.ExperimentName, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "experiment_name", err) - } - - msg, err := client.DeleteExperiment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_GetExperiment_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetExperimentRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["experiment_name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "experiment_name") - } - - protoReq.ExperimentName, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "experiment_name", err) - } - - msg, err := client.GetExperiment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_GetExperimentList_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetExperimentListRequest - var metadata runtime.ServerMetadata - - msg, err := client.GetExperimentList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_UpdateExperimentStatus_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq UpdateExperimentStatusRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["experiment_name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "experiment_name") - } - - protoReq.ExperimentName, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "experiment_name", err) - } - - msg, err := client.UpdateExperimentStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_UpdateAlgorithmExtraSettings_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq UpdateAlgorithmExtraSettingsRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["experiment_name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "experiment_name") - } - - protoReq.ExperimentName, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "experiment_name", err) - } - - msg, err := client.UpdateAlgorithmExtraSettings(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_GetAlgorithmExtraSettings_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetAlgorithmExtraSettingsRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["experiment_name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "experiment_name") - } - - protoReq.ExperimentName, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "experiment_name", err) - } - - msg, err := client.GetAlgorithmExtraSettings(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_RegisterTrial_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq RegisterTrialRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Trial); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.RegisterTrial(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_DeleteTrial_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq DeleteTrialRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["trial_name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "trial_name") - } - - protoReq.TrialName, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "trial_name", err) - } - - msg, err := client.DeleteTrial(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -var ( - filter_Manager_GetTrialList_0 = &utilities.DoubleArray{Encoding: map[string]int{"experiment_name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} -) - -func request_Manager_GetTrialList_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetTrialListRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["experiment_name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "experiment_name") - } - - protoReq.ExperimentName, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "experiment_name", err) - } - - if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_Manager_GetTrialList_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.GetTrialList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_GetTrial_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetTrialRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["trial_name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "trial_name") - } - - protoReq.TrialName, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "trial_name", err) - } - - msg, err := client.GetTrial(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_UpdateTrialStatus_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq UpdateTrialStatusRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.UpdateTrialStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_ReportObservationLog_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ReportObservationLogRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.ReportObservationLog(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_GetObservationLog_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetObservationLogRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.GetObservationLog(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_GetSuggestions_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetSuggestionsRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.GetSuggestions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_Manager_ValidateAlgorithmSettings_0(ctx context.Context, marshaler runtime.Marshaler, client ManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ValidateAlgorithmSettingsRequest - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.ValidateAlgorithmSettings(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -// RegisterManagerHandlerFromEndpoint is same as RegisterManagerHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterManagerHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterManagerHandler(ctx, mux, conn) -} - -// RegisterManagerHandler registers the http handlers for service Manager to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterManagerHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - client := NewManagerClient(conn) - - mux.Handle("POST", pattern_Manager_RegisterExperiment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_RegisterExperiment_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_RegisterExperiment_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("POST", pattern_Manager_PreCheckRegisterExperiment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_PreCheckRegisterExperiment_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_PreCheckRegisterExperiment_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Manager_DeleteExperiment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_DeleteExperiment_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_DeleteExperiment_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Manager_GetExperiment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_GetExperiment_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_GetExperiment_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Manager_GetExperimentList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_GetExperimentList_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_GetExperimentList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("PUT", pattern_Manager_UpdateExperimentStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_UpdateExperimentStatus_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_UpdateExperimentStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("PUT", pattern_Manager_UpdateAlgorithmExtraSettings_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_UpdateAlgorithmExtraSettings_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_UpdateAlgorithmExtraSettings_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Manager_GetAlgorithmExtraSettings_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_GetAlgorithmExtraSettings_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_GetAlgorithmExtraSettings_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("POST", pattern_Manager_RegisterTrial_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_RegisterTrial_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_RegisterTrial_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Manager_DeleteTrial_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_DeleteTrial_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_DeleteTrial_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Manager_GetTrialList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_GetTrialList_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_GetTrialList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Manager_GetTrial_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_GetTrial_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_GetTrial_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("PUT", pattern_Manager_UpdateTrialStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_UpdateTrialStatus_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_UpdateTrialStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("POST", pattern_Manager_ReportObservationLog_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_ReportObservationLog_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_ReportObservationLog_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("POST", pattern_Manager_GetObservationLog_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_GetObservationLog_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_GetObservationLog_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("POST", pattern_Manager_GetSuggestions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_GetSuggestions_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_GetSuggestions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("POST", pattern_Manager_ValidateAlgorithmSettings_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Manager_ValidateAlgorithmSettings_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Manager_ValidateAlgorithmSettings_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_Manager_RegisterExperiment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "Manager", "RegisterExperiment"}, "")) - - pattern_Manager_PreCheckRegisterExperiment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "Manager", "PreCheckRegisterExperiment"}, "")) - - pattern_Manager_DeleteExperiment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "Manager", "DeleteExperiment", "experiment_name"}, "")) - - pattern_Manager_GetExperiment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "Manager", "GetExperiment", "experiment_name"}, "")) - - pattern_Manager_GetExperimentList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "Manager", "GetExperimentList"}, "")) - - pattern_Manager_UpdateExperimentStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "Manager", "UpdateExperimentStatus", "experiment_name"}, "")) - - pattern_Manager_UpdateAlgorithmExtraSettings_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "Manager", "UpdateAlgorithmExtraSettings", "experiment_name"}, "")) - - pattern_Manager_GetAlgorithmExtraSettings_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "Manager", "GetAlgorithmExtraSettings", "experiment_name"}, "")) - - pattern_Manager_RegisterTrial_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "Manager", "RegisterTrial"}, "")) - - pattern_Manager_DeleteTrial_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "Manager", "DeleteTrial", "trial_name"}, "")) - - pattern_Manager_GetTrialList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "Manager", "GetTrialList", "experiment_name"}, "")) - - pattern_Manager_GetTrial_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "Manager", "GetTrial", "trial_name"}, "")) - - pattern_Manager_UpdateTrialStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "Manager", "UpdateTrialStatus"}, "")) - - pattern_Manager_ReportObservationLog_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "Manager", "ReportObservationLog"}, "")) - - pattern_Manager_GetObservationLog_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "Manager", "GetObservationLog"}, "")) - - pattern_Manager_GetSuggestions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "Manager", "GetSuggestions"}, "")) - - pattern_Manager_ValidateAlgorithmSettings_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "Manager", "ValidateAlgorithmSettings"}, "")) -) - -var ( - forward_Manager_RegisterExperiment_0 = runtime.ForwardResponseMessage - - forward_Manager_PreCheckRegisterExperiment_0 = runtime.ForwardResponseMessage - - forward_Manager_DeleteExperiment_0 = runtime.ForwardResponseMessage - - forward_Manager_GetExperiment_0 = runtime.ForwardResponseMessage - - forward_Manager_GetExperimentList_0 = runtime.ForwardResponseMessage - - forward_Manager_UpdateExperimentStatus_0 = runtime.ForwardResponseMessage - - forward_Manager_UpdateAlgorithmExtraSettings_0 = runtime.ForwardResponseMessage - - forward_Manager_GetAlgorithmExtraSettings_0 = runtime.ForwardResponseMessage - - forward_Manager_RegisterTrial_0 = runtime.ForwardResponseMessage - - forward_Manager_DeleteTrial_0 = runtime.ForwardResponseMessage - - forward_Manager_GetTrialList_0 = runtime.ForwardResponseMessage - - forward_Manager_GetTrial_0 = runtime.ForwardResponseMessage - - forward_Manager_UpdateTrialStatus_0 = runtime.ForwardResponseMessage - - forward_Manager_ReportObservationLog_0 = runtime.ForwardResponseMessage - - forward_Manager_GetObservationLog_0 = runtime.ForwardResponseMessage - - forward_Manager_GetSuggestions_0 = runtime.ForwardResponseMessage - - forward_Manager_ValidateAlgorithmSettings_0 = runtime.ForwardResponseMessage -) diff --git a/pkg/apis/manager/v1alpha2/api.proto b/pkg/apis/manager/v1alpha2/api.proto deleted file mode 100644 index 185e0259259..00000000000 --- a/pkg/apis/manager/v1alpha2/api.proto +++ /dev/null @@ -1,537 +0,0 @@ -/** - * Katib API - */ -syntax = "proto3"; - -package api.v1.alpha2; - -import "google/api/annotations.proto"; - -/** - * Service for Main API for Katib - * For each RPC service, we define mapping to HTTP REST API method. - * The mapping includes the URL path, query parameters and request body. - * https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http - */ -service Manager { - /** - * Register a Experiment to DB. - */ - rpc RegisterExperiment(RegisterExperimentRequest) returns (RegisterExperimentReply){ - option (google.api.http) = { - post: "/api/Manager/RegisterExperiment" - body: "experiment" - }; - }; - - /** - * PreCheck to register a Experiment to DB. - */ - rpc PreCheckRegisterExperiment(RegisterExperimentRequest) returns (PreCheckRegisterExperimentReply){ - option (google.api.http) = { - post: "/api/Manager/PreCheckRegisterExperiment" - body: "experiment" - }; - }; - - - /** - * Delete a Experiment from DB by name. - */ - rpc DeleteExperiment(DeleteExperimentRequest) returns (DeleteExperimentReply){ - option (google.api.http) = { - get: "/api/Manager/DeleteExperiment/{experiment_name}" - }; - }; - - /** - * Get a Experiment from DB by name. - */ - rpc GetExperiment(GetExperimentRequest) returns (GetExperimentReply){ - option (google.api.http) = { - get: "/api/Manager/GetExperiment/{experiment_name}" - }; - }; - - /** - * Get a summary list of Experiment from DB. - * The summary includes name and condition. - */ - rpc GetExperimentList(GetExperimentListRequest) returns (GetExperimentListReply){ - option (google.api.http) = { - get: "/api/Manager/GetExperimentList" - }; - }; - - /** - * Update Status of a experiment. - */ - rpc UpdateExperimentStatus(UpdateExperimentStatusRequest) returns (UpdateExperimentStatusReply){ - option (google.api.http) = { - put: "/api/Manager/UpdateExperimentStatus/{experiment_name}", - body: "*" - }; - }; - - /** - * Update AlgorithmExtraSettings. - * The ExtraSetting is created if it does not exist, otherwise it is overwrited. - */ - rpc UpdateAlgorithmExtraSettings(UpdateAlgorithmExtraSettingsRequest) returns (UpdateAlgorithmExtraSettingsReply){ - option (google.api.http) = { - put: "/api/Manager/UpdateAlgorithmExtraSettings/{experiment_name}", - body: "*" - }; - }; - - /** - * Get all AlgorithmExtraSettings. - */ - rpc GetAlgorithmExtraSettings(GetAlgorithmExtraSettingsRequest) returns (GetAlgorithmExtraSettingsReply){ - option (google.api.http) = { - get: "/api/Manager/GetAlgorithmExtraSettings/{experiment_name}", - }; - }; - - - /** - * Register a Trial to DB. - * ID will be filled by manager automatically. - */ - rpc RegisterTrial(RegisterTrialRequest) returns (RegisterTrialReply){ - option (google.api.http) = { - post: "/api/Manager/RegisterTrial" - body: "trial" - }; - }; - - /** - * Delete a Trial from DB by ID. - */ - rpc DeleteTrial(DeleteTrialRequest) returns (DeleteTrialReply){ - option (google.api.http) = { - get: "/api/Manager/DeleteTrial/{trial_name}" - }; - }; - - /** - * Get a list of Trial from DB by name of a Experiment. - */ - rpc GetTrialList(GetTrialListRequest) returns (GetTrialListReply){ - option (google.api.http) = { - get: "/api/Manager/GetTrialList/{experiment_name}" - }; - }; - - /** - * Get a Trial from DB by ID of Trial. - */ - rpc GetTrial(GetTrialRequest) returns (GetTrialReply){ - option (google.api.http) = { - get: "/api/Manager/GetTrial/{trial_name}" - }; - }; - - /** - * Update Status of a trial. - */ - rpc UpdateTrialStatus(UpdateTrialStatusRequest) returns (UpdateTrialStatusReply){ - option (google.api.http) = { - put: "/api/Manager/UpdateTrialStatus", - body: "*" - }; - }; - - /** - * Report a log of Observations for a Trial. - * The log consists of timestamp and value of metric. - * Katib store every log of metrics. - * You can see accuracy curve or other metric logs on UI. - */ - rpc ReportObservationLog(ReportObservationLogRequest) returns (ReportObservationLogReply){ - option (google.api.http) = { - post: "/api/Manager/ReportObservationLog" - body: "*" - }; - }; - - /** - * Get all log of Observations for a Trial. - */ - rpc GetObservationLog(GetObservationLogRequest) returns (GetObservationLogReply){ - option (google.api.http) = { - post: "/api/Manager/GetObservationLog" - body: "*" - }; - }; - - /** - * Get Suggestions from a Suggestion service. - */ - rpc GetSuggestions(GetSuggestionsRequest) returns (GetSuggestionsReply){ - option (google.api.http) = { - post: "/api/Manager/GetSuggestions" - body: "*" - }; - }; - - /** - * Validate AlgorithmSettings in an Experiment. - * Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid - */ - rpc ValidateAlgorithmSettings(ValidateAlgorithmSettingsRequest) returns (ValidateAlgorithmSettingsReply){ - option (google.api.http) = { - post: "/api/Manager/ValidateAlgorithmSettings" - body: "*" - }; - }; -} - -service Suggestion { - rpc GetSuggestions(GetSuggestionsRequest) returns (GetSuggestionsReply); - rpc ValidateAlgorithmSettings(ValidateAlgorithmSettingsRequest) returns (ValidateAlgorithmSettingsReply); -} - -service EarlyStopping { -//TODO -} - -/** - * Types of value for HyperParameter. - */ -enum ParameterType { - UNKNOWN_TYPE = 0; /// Undefined type and not used. - DOUBLE = 1; /// Double float type. Use "Max/Min". - INT = 2; /// Int type. Use "Max/Min". - DISCRETE = 3; /// Discrete number type. Use "List" as float. - CATEGORICAL = 4; /// Categorical type. Use "List" as string. -} - - -/** - * Feasible space for optimization. - * Int and Double type use Max/Min. - * Discrete and Categorical type use List. - */ -message FeasibleSpace { - string max = 1; /// Max Value - string min = 2; /// Minimum Value - repeated string list = 3; /// List of Values. - string step = 4; /// Step for double or int parameter -} - -/** - * Config for a Hyper parameter. - * Katib will create each Hyper parameter from this config. - */ -message ParameterSpec { - string name = 1; /// Name of the parameter. - ParameterType parameter_type = 2; /// Type of the parameter. - FeasibleSpace feasible_space = 3; /// FeasibleSpace for the parameter. -} - -/** - * Direction of optimization. Minimize or Maximize. - */ -enum ObjectiveType { - UNKNOWN = 0; /// Undefined type and not used. - MINIMIZE = 1; /// Minimize - MAXIMIZE = 2; /// Maximize -} - -message ObjectiveSpec{ - ObjectiveType type = 1; - float goal = 2; - string objective_metric_name = 3; - repeated string additional_metric_names = 4; - /// This can be empty if we only care about the objective metric. -} - -message AlgorithmSetting { - string name = 1; - string value = 2; -} - -message EarlyStoppingSpec { -//TODO -} - -message AlgorithmSpec { - string algorithm_name = 1; - repeated AlgorithmSetting algorithm_setting = 2; - EarlyStoppingSpec early_stopping_spec = 3; -} - -/** - * NasConfig contains a config of NAS job - */ - message NasConfig { - GraphConfig graph_config = 1; /// Config of DAG - message Operations { - repeated Operation operation = 1; - } - Operations operations = 2; /// List of Operation -} - -/** - * GraphConfig contains a config of DAG - */ - message GraphConfig { - int32 num_layers = 1; /// Number of layers - repeated int32 input_sizes = 2; /// Dimensions of input size - repeated int32 output_sizes = 3; /// Dimensions of output size -} - -/** - * Config for operations in DAG - */ - message Operation { - string operation_type = 1; /// Type of operation in DAG - /** - * List of ParameterSpec - */ - message ParameterSpecs { - repeated ParameterSpec parameters = 1; - } - ParameterSpecs parameter_specs = 2; -} - -/** - * Spec of a Experiment. Experiment represents a single optimization run over a feasible space. - * Each Experiment contains a configuration describing the feasible space, as well as a set of Trials. - * It is assumed that objective function f(x) does not change in the course of a Experiment. - */ -message ExperimentSpec { - /** - * List of ParameterSpec - */ - message ParameterSpecs { - repeated ParameterSpec parameters = 1; - } - ParameterSpecs parameter_specs = 1; - ObjectiveSpec objective = 2; - AlgorithmSpec algorithm = 3; - string trial_template = 4; - string metrics_collector_spec = 5; - int32 parallel_trial_count = 6; - int32 max_trial_count = 7; - NasConfig nas_config = 8; -} - -message ExperimentStatus { - enum ExperimentConditionType { - CREATED = 0; - RUNNING = 1; - RESTARTING = 2; - SUCCEEDED = 3; - FAILED = 4; - UNKNOWN = 5; - } - string start_time = 1; /// RFC3339 format - string completion_time = 2; /// RFC3339 format - ExperimentConditionType condition = 3; -} - -message Experiment { - string name = 1; /// Name of Experiment. This is unique in DB. - ExperimentSpec spec = 2; - ExperimentStatus status = 3; -} - -message ParameterAssignment { - string name = 1; - string value = 2; -} - -message Metric { - string name = 1; - string value = 2; -} - -message MetricLog { - string time_stamp = 1; /// RFC3339 format - Metric metric = 2; -} - -message Observation { - repeated Metric metrics = 1; -} - -message ObservationLog { - repeated MetricLog metric_logs = 1; -} - -message TrialSpec { - /** - * List of ParameterAssignment - */ - message ParameterAssignments{ - repeated ParameterAssignment assignments = 1; - } - string experiment_name = 1; - ObjectiveSpec objective = 2; - ParameterAssignments parameter_assignments = 3; - string run_spec = 4; - string metrics_collector_spec = 5; -} - -message TrialStatus { - enum TrialConditionType { - CREATED = 0; - RUNNING = 1; - SUCCEEDED = 2; - KILLED = 3; - FAILED = 4; - UNKNOWN = 5; - } - string start_time = 1; /// RFC3339 format - string completion_time = 2; /// RFC3339 format - TrialConditionType condition = 3; - Observation observation = 4; /// The best observation in logs. -} - -message Trial { - string name = 1; - TrialSpec spec = 2; - TrialStatus status = 3; -} - -message RegisterExperimentRequest { - Experiment experiment = 1; -} - -message RegisterExperimentReply { -} - -message PreCheckRegisterExperimentReply { - bool can_register = 1; -} -message DeleteExperimentRequest { - string experiment_name = 1; -} - -message DeleteExperimentReply { -} - -message GetExperimentRequest { - string experiment_name = 1; -} - -message GetExperimentReply { - Experiment experiment = 1; -} - -message ExperimentSummary { - string experiment_name = 1; - ExperimentStatus status = 2; -} - -message GetExperimentListRequest { -} - -message GetExperimentListReply { - repeated ExperimentSummary experiment_summaries = 1; -} - -message UpdateExperimentStatusRequest { - string experiment_name = 1; - ExperimentStatus new_status = 2; -} - -message UpdateExperimentStatusReply { -} - -message UpdateAlgorithmExtraSettingsRequest { - string experiment_name = 1; - repeated AlgorithmSetting extra_algorithm_settings = 2; -} - -message UpdateAlgorithmExtraSettingsReply { -} - -message GetAlgorithmExtraSettingsRequest { - string experiment_name = 1; -} - -message GetAlgorithmExtraSettingsReply { - repeated AlgorithmSetting extra_algorithm_settings = 1; -} - -message RegisterTrialRequest { - Trial trial = 1; -} - -message RegisterTrialReply { -} - -message DeleteTrialRequest { - string trial_name = 1; -} - -message DeleteTrialReply { -} - -message GetTrialListRequest { - string experiment_name = 1; - string filter = 2; -} - -message GetTrialListReply { - repeated Trial trials = 1; -} - -message GetTrialRequest { - string trial_name = 1; -} - -message GetTrialReply { - Trial trial = 1; -} - -message UpdateTrialStatusRequest { - string trial_name = 1; - TrialStatus new_status = 2; -} - -message UpdateTrialStatusReply { -} - -message ReportObservationLogRequest { - string trial_name = 1; - ObservationLog observation_log = 2; -} - -message ReportObservationLogReply { -} - -message GetObservationLogRequest { - string trial_name = 1; - string metric_name = 2; - string start_time = 3; ///The start of the time range. RFC3339 format - string end_time = 4; ///The end of the time range. RFC3339 format -} - -message GetObservationLogReply { - ObservationLog observation_log = 1; -} - -message GetSuggestionsRequest { - string experiment_name = 1; - string algorithm_name = 2; - int32 request_number = 3; ///The number of Suggestion you request at one time. When you set 3 to request_number, you can get three Suggestions at one time. -} - -message GetSuggestionsReply { - repeated Trial trials = 1; -} - -message ValidateAlgorithmSettingsRequest { - ExperimentSpec experiment_spec = 1; - string algorithm_name = 2; -} - -/** - * Return INVALID_ARGUMENT Error if Algorithm Settings are not Valid - */ -message ValidateAlgorithmSettingsReply { -} diff --git a/pkg/apis/manager/v1alpha2/api.swagger.json b/pkg/apis/manager/v1alpha2/api.swagger.json deleted file mode 100644 index 396c767cc09..00000000000 --- a/pkg/apis/manager/v1alpha2/api.swagger.json +++ /dev/null @@ -1,1077 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "title": "api.proto", - "version": "version not set" - }, - "schemes": [ - "http", - "https" - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "paths": { - "/api/Manager/DeleteExperiment/{experiment_name}": { - "get": { - "summary": "* \nDelete a Experiment from DB by name.", - "operationId": "DeleteExperiment", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2DeleteExperimentReply" - } - } - }, - "parameters": [ - { - "name": "experiment_name", - "in": "path", - "required": true, - "type": "string" - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/DeleteTrial/{trial_name}": { - "get": { - "summary": "* \nDelete a Trial from DB by ID.", - "operationId": "DeleteTrial", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2DeleteTrialReply" - } - } - }, - "parameters": [ - { - "name": "trial_name", - "in": "path", - "required": true, - "type": "string" - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/GetAlgorithmExtraSettings/{experiment_name}": { - "get": { - "summary": "* \nGet all AlgorithmExtraSettings.", - "operationId": "GetAlgorithmExtraSettings", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2GetAlgorithmExtraSettingsReply" - } - } - }, - "parameters": [ - { - "name": "experiment_name", - "in": "path", - "required": true, - "type": "string" - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/GetExperiment/{experiment_name}": { - "get": { - "summary": "* \nGet a Experiment from DB by name.", - "operationId": "GetExperiment", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2GetExperimentReply" - } - } - }, - "parameters": [ - { - "name": "experiment_name", - "in": "path", - "required": true, - "type": "string" - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/GetExperimentList": { - "get": { - "summary": "*\nGet a summary list of Experiment from DB.\nThe summary includes name and condition.", - "operationId": "GetExperimentList", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2GetExperimentListReply" - } - } - }, - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/GetObservationLog": { - "post": { - "summary": "*\nGet all log of Observations for a Trial.", - "operationId": "GetObservationLog", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2GetObservationLogReply" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2GetObservationLogRequest" - } - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/GetSuggestions": { - "post": { - "summary": "* \nGet Suggestions from a Suggestion service.", - "operationId": "GetSuggestions", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2GetSuggestionsReply" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2GetSuggestionsRequest" - } - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/GetTrial/{trial_name}": { - "get": { - "summary": "*\nGet a Trial from DB by ID of Trial.", - "operationId": "GetTrial", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2GetTrialReply" - } - } - }, - "parameters": [ - { - "name": "trial_name", - "in": "path", - "required": true, - "type": "string" - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/GetTrialList/{experiment_name}": { - "get": { - "summary": "* \nGet a list of Trial from DB by name of a Experiment.", - "operationId": "GetTrialList", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2GetTrialListReply" - } - } - }, - "parameters": [ - { - "name": "experiment_name", - "in": "path", - "required": true, - "type": "string" - }, - { - "name": "filter", - "in": "query", - "required": false, - "type": "string" - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/PreCheckRegisterExperiment": { - "post": { - "summary": "*\nPreCheck to register a Experiment to DB.", - "operationId": "PreCheckRegisterExperiment", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2PreCheckRegisterExperimentReply" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2Experiment" - } - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/RegisterExperiment": { - "post": { - "summary": "*\nRegister a Experiment to DB.", - "operationId": "RegisterExperiment", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2RegisterExperimentReply" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2Experiment" - } - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/RegisterTrial": { - "post": { - "summary": "*\nRegister a Trial to DB.\nID will be filled by manager automatically.", - "operationId": "RegisterTrial", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2RegisterTrialReply" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2Trial" - } - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/ReportObservationLog": { - "post": { - "summary": "* \nReport a log of Observations for a Trial.\nThe log consists of timestamp and value of metric.\nKatib store every log of metrics.\nYou can see accuracy curve or other metric logs on UI.", - "operationId": "ReportObservationLog", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2ReportObservationLogReply" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2ReportObservationLogRequest" - } - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/UpdateAlgorithmExtraSettings/{experiment_name}": { - "put": { - "summary": "* \nUpdate AlgorithmExtraSettings.\nThe ExtraSetting is created if it does not exist, otherwise it is overwrited.", - "operationId": "UpdateAlgorithmExtraSettings", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2UpdateAlgorithmExtraSettingsReply" - } - } - }, - "parameters": [ - { - "name": "experiment_name", - "in": "path", - "required": true, - "type": "string" - }, - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2UpdateAlgorithmExtraSettingsRequest" - } - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/UpdateExperimentStatus/{experiment_name}": { - "put": { - "summary": "* \nUpdate Status of a experiment.", - "operationId": "UpdateExperimentStatus", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2UpdateExperimentStatusReply" - } - } - }, - "parameters": [ - { - "name": "experiment_name", - "in": "path", - "required": true, - "type": "string" - }, - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2UpdateExperimentStatusRequest" - } - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/UpdateTrialStatus": { - "put": { - "summary": "* \nUpdate Status of a trial.", - "operationId": "UpdateTrialStatus", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2UpdateTrialStatusReply" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2UpdateTrialStatusRequest" - } - } - ], - "tags": [ - "Manager" - ] - } - }, - "/api/Manager/ValidateAlgorithmSettings": { - "post": { - "summary": "* \nValidate AlgorithmSettings in an Experiment.\nSuggestion service should return INVALID_ARGUMENT Error when the parameter is invalid", - "operationId": "ValidateAlgorithmSettings", - "responses": { - "200": { - "description": "", - "schema": { - "$ref": "#/definitions/alpha2ValidateAlgorithmSettingsReply" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/alpha2ValidateAlgorithmSettingsRequest" - } - } - ], - "tags": [ - "Manager" - ] - } - } - }, - "definitions": { - "ExperimentStatusExperimentConditionType": { - "type": "string", - "enum": [ - "CREATED", - "RUNNING", - "RESTARTING", - "SUCCEEDED", - "FAILED", - "UNKNOWN" - ], - "default": "CREATED" - }, - "NasConfigOperations": { - "type": "object", - "properties": { - "operation": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2Operation" - } - } - } - }, - "TrialSpecParameterAssignments": { - "type": "object", - "properties": { - "assignments": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2ParameterAssignment" - } - } - }, - "title": "* \nList of ParameterAssignment" - }, - "TrialStatusTrialConditionType": { - "type": "string", - "enum": [ - "CREATED", - "RUNNING", - "SUCCEEDED", - "KILLED", - "FAILED", - "UNKNOWN" - ], - "default": "CREATED" - }, - "alpha2AlgorithmSetting": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "alpha2AlgorithmSpec": { - "type": "object", - "properties": { - "algorithm_name": { - "type": "string" - }, - "algorithm_setting": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2AlgorithmSetting" - } - }, - "early_stopping_spec": { - "$ref": "#/definitions/alpha2EarlyStoppingSpec" - } - } - }, - "alpha2DeleteExperimentReply": { - "type": "object" - }, - "alpha2DeleteTrialReply": { - "type": "object" - }, - "alpha2EarlyStoppingSpec": { - "type": "object" - }, - "alpha2Experiment": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "spec": { - "$ref": "#/definitions/alpha2ExperimentSpec" - }, - "status": { - "$ref": "#/definitions/alpha2ExperimentStatus" - } - } - }, - "alpha2ExperimentSpec": { - "type": "object", - "properties": { - "parameter_specs": { - "$ref": "#/definitions/alpha2ExperimentSpecParameterSpecs" - }, - "objective": { - "$ref": "#/definitions/alpha2ObjectiveSpec" - }, - "algorithm": { - "$ref": "#/definitions/alpha2AlgorithmSpec" - }, - "trial_template": { - "type": "string" - }, - "metrics_collector_spec": { - "type": "string" - }, - "parallel_trial_count": { - "type": "integer", - "format": "int32" - }, - "max_trial_count": { - "type": "integer", - "format": "int32" - }, - "nas_config": { - "$ref": "#/definitions/alpha2NasConfig" - } - }, - "description": "*\nSpec of a Experiment. Experiment represents a single optimization run over a feasible space. \nEach Experiment contains a configuration describing the feasible space, as well as a set of Trials.\nIt is assumed that objective function f(x) does not change in the course of a Experiment." - }, - "alpha2ExperimentSpecParameterSpecs": { - "type": "object", - "properties": { - "parameters": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2ParameterSpec" - } - } - }, - "title": "* \nList of ParameterSpec" - }, - "alpha2ExperimentStatus": { - "type": "object", - "properties": { - "start_time": { - "type": "string" - }, - "completion_time": { - "type": "string" - }, - "condition": { - "$ref": "#/definitions/ExperimentStatusExperimentConditionType" - } - } - }, - "alpha2ExperimentSummary": { - "type": "object", - "properties": { - "experiment_name": { - "type": "string" - }, - "status": { - "$ref": "#/definitions/alpha2ExperimentStatus" - } - } - }, - "alpha2FeasibleSpace": { - "type": "object", - "properties": { - "max": { - "type": "string" - }, - "min": { - "type": "string" - }, - "list": { - "type": "array", - "items": { - "type": "string" - } - }, - "step": { - "type": "string" - } - }, - "description": "*\nFeasible space for optimization.\nInt and Double type use Max/Min.\nDiscrete and Categorical type use List." - }, - "alpha2GetAlgorithmExtraSettingsReply": { - "type": "object", - "properties": { - "extra_algorithm_settings": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2AlgorithmSetting" - } - } - } - }, - "alpha2GetExperimentListReply": { - "type": "object", - "properties": { - "experiment_summaries": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2ExperimentSummary" - } - } - } - }, - "alpha2GetExperimentReply": { - "type": "object", - "properties": { - "experiment": { - "$ref": "#/definitions/alpha2Experiment" - } - } - }, - "alpha2GetObservationLogReply": { - "type": "object", - "properties": { - "observation_log": { - "$ref": "#/definitions/alpha2ObservationLog" - } - } - }, - "alpha2GetObservationLogRequest": { - "type": "object", - "properties": { - "trial_name": { - "type": "string" - }, - "metric_name": { - "type": "string" - }, - "start_time": { - "type": "string" - }, - "end_time": { - "type": "string" - } - } - }, - "alpha2GetSuggestionsReply": { - "type": "object", - "properties": { - "trials": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2Trial" - } - } - } - }, - "alpha2GetSuggestionsRequest": { - "type": "object", - "properties": { - "experiment_name": { - "type": "string" - }, - "algorithm_name": { - "type": "string" - }, - "request_number": { - "type": "integer", - "format": "int32" - } - } - }, - "alpha2GetTrialListReply": { - "type": "object", - "properties": { - "trials": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2Trial" - } - } - } - }, - "alpha2GetTrialReply": { - "type": "object", - "properties": { - "trial": { - "$ref": "#/definitions/alpha2Trial" - } - } - }, - "alpha2GraphConfig": { - "type": "object", - "properties": { - "num_layers": { - "type": "integer", - "format": "int32" - }, - "input_sizes": { - "type": "array", - "items": { - "type": "integer", - "format": "int32" - } - }, - "output_sizes": { - "type": "array", - "items": { - "type": "integer", - "format": "int32" - } - } - }, - "title": "*\nGraphConfig contains a config of DAG" - }, - "alpha2Metric": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "alpha2MetricLog": { - "type": "object", - "properties": { - "time_stamp": { - "type": "string" - }, - "metric": { - "$ref": "#/definitions/alpha2Metric" - } - } - }, - "alpha2NasConfig": { - "type": "object", - "properties": { - "graph_config": { - "$ref": "#/definitions/alpha2GraphConfig" - }, - "operations": { - "$ref": "#/definitions/NasConfigOperations" - } - }, - "title": "*\nNasConfig contains a config of NAS job" - }, - "alpha2ObjectiveSpec": { - "type": "object", - "properties": { - "type": { - "$ref": "#/definitions/alpha2ObjectiveType" - }, - "goal": { - "type": "number", - "format": "float" - }, - "objective_metric_name": { - "type": "string" - }, - "additional_metric_names": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "alpha2ObjectiveType": { - "type": "string", - "enum": [ - "UNKNOWN", - "MINIMIZE", - "MAXIMIZE" - ], - "default": "UNKNOWN", - "description": "*\nDirection of optimization. Minimize or Maximize." - }, - "alpha2Observation": { - "type": "object", - "properties": { - "metrics": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2Metric" - } - } - } - }, - "alpha2ObservationLog": { - "type": "object", - "properties": { - "metric_logs": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2MetricLog" - } - } - } - }, - "alpha2Operation": { - "type": "object", - "properties": { - "operation_type": { - "type": "string" - }, - "parameter_specs": { - "$ref": "#/definitions/alpha2OperationParameterSpecs" - } - }, - "title": "*\nConfig for operations in DAG" - }, - "alpha2OperationParameterSpecs": { - "type": "object", - "properties": { - "parameters": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2ParameterSpec" - } - } - }, - "title": "* \nList of ParameterSpec" - }, - "alpha2ParameterAssignment": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "alpha2ParameterSpec": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "parameter_type": { - "$ref": "#/definitions/alpha2ParameterType" - }, - "feasible_space": { - "$ref": "#/definitions/alpha2FeasibleSpace" - } - }, - "description": "*\nConfig for a Hyper parameter.\nKatib will create each Hyper parameter from this config." - }, - "alpha2ParameterType": { - "type": "string", - "enum": [ - "UNKNOWN_TYPE", - "DOUBLE", - "INT", - "DISCRETE", - "CATEGORICAL" - ], - "default": "UNKNOWN_TYPE", - "description": "*\nTypes of value for HyperParameter." - }, - "alpha2PreCheckRegisterExperimentReply": { - "type": "object", - "properties": { - "can_register": { - "type": "boolean", - "format": "boolean" - } - } - }, - "alpha2RegisterExperimentReply": { - "type": "object" - }, - "alpha2RegisterTrialReply": { - "type": "object" - }, - "alpha2ReportObservationLogReply": { - "type": "object" - }, - "alpha2ReportObservationLogRequest": { - "type": "object", - "properties": { - "trial_name": { - "type": "string" - }, - "observation_log": { - "$ref": "#/definitions/alpha2ObservationLog" - } - } - }, - "alpha2Trial": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "spec": { - "$ref": "#/definitions/alpha2TrialSpec" - }, - "status": { - "$ref": "#/definitions/alpha2TrialStatus" - } - } - }, - "alpha2TrialSpec": { - "type": "object", - "properties": { - "experiment_name": { - "type": "string" - }, - "objective": { - "$ref": "#/definitions/alpha2ObjectiveSpec" - }, - "parameter_assignments": { - "$ref": "#/definitions/TrialSpecParameterAssignments" - }, - "run_spec": { - "type": "string" - }, - "metrics_collector_spec": { - "type": "string" - } - } - }, - "alpha2TrialStatus": { - "type": "object", - "properties": { - "start_time": { - "type": "string" - }, - "completion_time": { - "type": "string" - }, - "condition": { - "$ref": "#/definitions/TrialStatusTrialConditionType" - }, - "observation": { - "$ref": "#/definitions/alpha2Observation" - } - } - }, - "alpha2UpdateAlgorithmExtraSettingsReply": { - "type": "object" - }, - "alpha2UpdateAlgorithmExtraSettingsRequest": { - "type": "object", - "properties": { - "experiment_name": { - "type": "string" - }, - "extra_algorithm_settings": { - "type": "array", - "items": { - "$ref": "#/definitions/alpha2AlgorithmSetting" - } - } - } - }, - "alpha2UpdateExperimentStatusReply": { - "type": "object" - }, - "alpha2UpdateExperimentStatusRequest": { - "type": "object", - "properties": { - "experiment_name": { - "type": "string" - }, - "new_status": { - "$ref": "#/definitions/alpha2ExperimentStatus" - } - } - }, - "alpha2UpdateTrialStatusReply": { - "type": "object" - }, - "alpha2UpdateTrialStatusRequest": { - "type": "object", - "properties": { - "trial_name": { - "type": "string" - }, - "new_status": { - "$ref": "#/definitions/alpha2TrialStatus" - } - } - }, - "alpha2ValidateAlgorithmSettingsReply": { - "type": "object", - "title": "*\nReturn INVALID_ARGUMENT Error if Algorithm Settings are not Valid" - }, - "alpha2ValidateAlgorithmSettingsRequest": { - "type": "object", - "properties": { - "experiment_spec": { - "$ref": "#/definitions/alpha2ExperimentSpec" - }, - "algorithm_name": { - "type": "string" - } - } - } - } -} diff --git a/pkg/apis/manager/v1alpha2/build.sh b/pkg/apis/manager/v1alpha2/build.sh deleted file mode 100755 index 74a1f5b2a18..00000000000 --- a/pkg/apis/manager/v1alpha2/build.sh +++ /dev/null @@ -1,11 +0,0 @@ -set -x -set -e -for proto in api.proto; do - docker run -it --rm -v $PWD:$(pwd) -w $(pwd) znly/protoc --python_out=plugins=grpc:./python --go_out=plugins=grpc:. -I. $proto - docker run -it --rm -v $PWD:$(pwd) -w $(pwd) znly/protoc --plugin=protoc-gen-grpc=/usr/bin/grpc_python_plugin --python_out=./python --grpc_out=./python -I. $proto - docker run -it --rm -v $PWD:$(pwd) -w $(pwd) znly/protoc --grpc-gateway_out=logtostderr=true:. -I. $proto - docker run -it --rm -v $PWD:$(pwd) -w $(pwd) znly/protoc --swagger_out=logtostderr=true:. -I. $proto -done -docker build -t protoc-gen-doc gen-doc/ -docker run --rm -v $PWD/gen-doc:/out -v $PWD:/apiprotos protoc-gen-doc --doc_opt=markdown,api.md -I /protobuf -I /apiprotos api.proto -docker run --rm -v $PWD/gen-doc:/out -v $PWD:/apiprotos protoc-gen-doc --doc_opt=html,index.html -I /protobuf -I /apiprotos api.proto diff --git a/pkg/apis/manager/v1alpha2/gen-doc/Dockerfile b/pkg/apis/manager/v1alpha2/gen-doc/Dockerfile deleted file mode 100644 index afaba128816..00000000000 --- a/pkg/apis/manager/v1alpha2/gen-doc/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM pseudomuto/protoc-gen-doc -RUN apt-get -q -y update && apt-get -q -y install curl && \ - mkdir -p /protobuf/google/protobuf && \ - for f in any duration descriptor empty struct timestamp wrappers; do \ - curl -L -o /protobuf/google/protobuf/${f}.proto https://raw.githubusercontent.com/google/protobuf/master/src/google/protobuf/${f}.proto; \ - done && \ - mkdir -p /protobuf/google/api && \ - for f in annotations http; do \ - curl -L -o /protobuf/google/api/${f}.proto https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/master/third_party/googleapis/google/api/${f}.proto; \ - done && \ - mkdir -p /protobuf/github.com/gogo/protobuf/gogoproto && \ - curl -L -o /protobuf/github.com/gogo/protobuf/gogoproto/gogo.proto https://raw.githubusercontent.com/gogo/protobuf/master/gogoproto/gogo.proto && \ - mkdir -p /protobuf/github.com/mwitkow/go-proto-validators && \ - curl -L -o /protobuf/github.com/mwitkow/go-proto-validators/validator.proto https://raw.githubusercontent.com/mwitkow/go-proto-validators/master/validator.proto && \ - apt-get remove --purge -y curl && \ - apt-get -y autoremove && \ - rm -rf /var/lib/apt/lists/* diff --git a/pkg/apis/manager/v1alpha2/gen-doc/api.md b/pkg/apis/manager/v1alpha2/gen-doc/api.md deleted file mode 100644 index 7fd225dcd79..00000000000 --- a/pkg/apis/manager/v1alpha2/gen-doc/api.md +++ /dev/null @@ -1,1095 +0,0 @@ -# Protocol Documentation - - -## Table of Contents - -- [api.proto](#api.proto) - - [AlgorithmSetting](#api.v1.alpha2.AlgorithmSetting) - - [AlgorithmSpec](#api.v1.alpha2.AlgorithmSpec) - - [DeleteExperimentReply](#api.v1.alpha2.DeleteExperimentReply) - - [DeleteExperimentRequest](#api.v1.alpha2.DeleteExperimentRequest) - - [DeleteTrialReply](#api.v1.alpha2.DeleteTrialReply) - - [DeleteTrialRequest](#api.v1.alpha2.DeleteTrialRequest) - - [EarlyStoppingSpec](#api.v1.alpha2.EarlyStoppingSpec) - - [Experiment](#api.v1.alpha2.Experiment) - - [ExperimentSpec](#api.v1.alpha2.ExperimentSpec) - - [ExperimentSpec.ParameterSpecs](#api.v1.alpha2.ExperimentSpec.ParameterSpecs) - - [ExperimentStatus](#api.v1.alpha2.ExperimentStatus) - - [ExperimentSummary](#api.v1.alpha2.ExperimentSummary) - - [FeasibleSpace](#api.v1.alpha2.FeasibleSpace) - - [GetAlgorithmExtraSettingsReply](#api.v1.alpha2.GetAlgorithmExtraSettingsReply) - - [GetAlgorithmExtraSettingsRequest](#api.v1.alpha2.GetAlgorithmExtraSettingsRequest) - - [GetExperimentListReply](#api.v1.alpha2.GetExperimentListReply) - - [GetExperimentListRequest](#api.v1.alpha2.GetExperimentListRequest) - - [GetExperimentReply](#api.v1.alpha2.GetExperimentReply) - - [GetExperimentRequest](#api.v1.alpha2.GetExperimentRequest) - - [GetObservationLogReply](#api.v1.alpha2.GetObservationLogReply) - - [GetObservationLogRequest](#api.v1.alpha2.GetObservationLogRequest) - - [GetSuggestionsReply](#api.v1.alpha2.GetSuggestionsReply) - - [GetSuggestionsRequest](#api.v1.alpha2.GetSuggestionsRequest) - - [GetTrialListReply](#api.v1.alpha2.GetTrialListReply) - - [GetTrialListRequest](#api.v1.alpha2.GetTrialListRequest) - - [GetTrialReply](#api.v1.alpha2.GetTrialReply) - - [GetTrialRequest](#api.v1.alpha2.GetTrialRequest) - - [GraphConfig](#api.v1.alpha2.GraphConfig) - - [Metric](#api.v1.alpha2.Metric) - - [MetricLog](#api.v1.alpha2.MetricLog) - - [NasConfig](#api.v1.alpha2.NasConfig) - - [NasConfig.Operations](#api.v1.alpha2.NasConfig.Operations) - - [ObjectiveSpec](#api.v1.alpha2.ObjectiveSpec) - - [Observation](#api.v1.alpha2.Observation) - - [ObservationLog](#api.v1.alpha2.ObservationLog) - - [Operation](#api.v1.alpha2.Operation) - - [Operation.ParameterSpecs](#api.v1.alpha2.Operation.ParameterSpecs) - - [ParameterAssignment](#api.v1.alpha2.ParameterAssignment) - - [ParameterSpec](#api.v1.alpha2.ParameterSpec) - - [PreCheckRegisterExperimentReply](#api.v1.alpha2.PreCheckRegisterExperimentReply) - - [RegisterExperimentReply](#api.v1.alpha2.RegisterExperimentReply) - - [RegisterExperimentRequest](#api.v1.alpha2.RegisterExperimentRequest) - - [RegisterTrialReply](#api.v1.alpha2.RegisterTrialReply) - - [RegisterTrialRequest](#api.v1.alpha2.RegisterTrialRequest) - - [ReportObservationLogReply](#api.v1.alpha2.ReportObservationLogReply) - - [ReportObservationLogRequest](#api.v1.alpha2.ReportObservationLogRequest) - - [Trial](#api.v1.alpha2.Trial) - - [TrialSpec](#api.v1.alpha2.TrialSpec) - - [TrialSpec.ParameterAssignments](#api.v1.alpha2.TrialSpec.ParameterAssignments) - - [TrialStatus](#api.v1.alpha2.TrialStatus) - - [UpdateAlgorithmExtraSettingsReply](#api.v1.alpha2.UpdateAlgorithmExtraSettingsReply) - - [UpdateAlgorithmExtraSettingsRequest](#api.v1.alpha2.UpdateAlgorithmExtraSettingsRequest) - - [UpdateExperimentStatusReply](#api.v1.alpha2.UpdateExperimentStatusReply) - - [UpdateExperimentStatusRequest](#api.v1.alpha2.UpdateExperimentStatusRequest) - - [UpdateTrialStatusReply](#api.v1.alpha2.UpdateTrialStatusReply) - - [UpdateTrialStatusRequest](#api.v1.alpha2.UpdateTrialStatusRequest) - - [ValidateAlgorithmSettingsReply](#api.v1.alpha2.ValidateAlgorithmSettingsReply) - - [ValidateAlgorithmSettingsRequest](#api.v1.alpha2.ValidateAlgorithmSettingsRequest) - - - [ExperimentStatus.ExperimentConditionType](#api.v1.alpha2.ExperimentStatus.ExperimentConditionType) - - [ObjectiveType](#api.v1.alpha2.ObjectiveType) - - [ParameterType](#api.v1.alpha2.ParameterType) - - [TrialStatus.TrialConditionType](#api.v1.alpha2.TrialStatus.TrialConditionType) - - - - [EarlyStopping](#api.v1.alpha2.EarlyStopping) - - [Manager](#api.v1.alpha2.Manager) - - [Suggestion](#api.v1.alpha2.Suggestion) - - -- [Scalar Value Types](#scalar-value-types) - - - - -

Top

- -## api.proto -Katib API - - - - -### AlgorithmSetting - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | -| value | [string](#string) | | | - - - - - - - - -### AlgorithmSpec - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| algorithm_name | [string](#string) | | | -| algorithm_setting | [AlgorithmSetting](#api.v1.alpha2.AlgorithmSetting) | repeated | | -| early_stopping_spec | [EarlyStoppingSpec](#api.v1.alpha2.EarlyStoppingSpec) | | | - - - - - - - - -### DeleteExperimentReply - - - - - - - - - -### DeleteExperimentRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_name | [string](#string) | | | - - - - - - - - -### DeleteTrialReply - - - - - - - - - -### DeleteTrialRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| trial_name | [string](#string) | | | - - - - - - - - -### EarlyStoppingSpec -TODO - - - - - - - - -### Experiment - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | Name of Experiment. This is unique in DB. | -| spec | [ExperimentSpec](#api.v1.alpha2.ExperimentSpec) | | | -| status | [ExperimentStatus](#api.v1.alpha2.ExperimentStatus) | | | - - - - - - - - -### ExperimentSpec -Spec of a Experiment. Experiment represents a single optimization run over a feasible space. -Each Experiment contains a configuration describing the feasible space, as well as a set of Trials. -It is assumed that objective function f(x) does not change in the course of a Experiment. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| parameter_specs | [ExperimentSpec.ParameterSpecs](#api.v1.alpha2.ExperimentSpec.ParameterSpecs) | | | -| objective | [ObjectiveSpec](#api.v1.alpha2.ObjectiveSpec) | | | -| algorithm | [AlgorithmSpec](#api.v1.alpha2.AlgorithmSpec) | | | -| trial_template | [string](#string) | | | -| metrics_collector_spec | [string](#string) | | | -| parallel_trial_count | [int32](#int32) | | | -| max_trial_count | [int32](#int32) | | | -| nas_config | [NasConfig](#api.v1.alpha2.NasConfig) | | | - - - - - - - - -### ExperimentSpec.ParameterSpecs -List of ParameterSpec - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| parameters | [ParameterSpec](#api.v1.alpha2.ParameterSpec) | repeated | | - - - - - - - - -### ExperimentStatus - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| start_time | [string](#string) | | RFC3339 format | -| completion_time | [string](#string) | | RFC3339 format | -| condition | [ExperimentStatus.ExperimentConditionType](#api.v1.alpha2.ExperimentStatus.ExperimentConditionType) | | | - - - - - - - - -### ExperimentSummary - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_name | [string](#string) | | | -| status | [ExperimentStatus](#api.v1.alpha2.ExperimentStatus) | | | - - - - - - - - -### FeasibleSpace -Feasible space for optimization. -Int and Double type use Max/Min. -Discrete and Categorical type use List. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| max | [string](#string) | | Max Value | -| min | [string](#string) | | Minimum Value | -| list | [string](#string) | repeated | List of Values. | -| step | [string](#string) | | Step for double or int parameter | - - - - - - - - -### GetAlgorithmExtraSettingsReply - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| extra_algorithm_settings | [AlgorithmSetting](#api.v1.alpha2.AlgorithmSetting) | repeated | | - - - - - - - - -### GetAlgorithmExtraSettingsRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_name | [string](#string) | | | - - - - - - - - -### GetExperimentListReply - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_summaries | [ExperimentSummary](#api.v1.alpha2.ExperimentSummary) | repeated | | - - - - - - - - -### GetExperimentListRequest - - - - - - - - - -### GetExperimentReply - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment | [Experiment](#api.v1.alpha2.Experiment) | | | - - - - - - - - -### GetExperimentRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_name | [string](#string) | | | - - - - - - - - -### GetObservationLogReply - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| observation_log | [ObservationLog](#api.v1.alpha2.ObservationLog) | | | - - - - - - - - -### GetObservationLogRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| trial_name | [string](#string) | | | -| metric_name | [string](#string) | | | -| start_time | [string](#string) | | The start of the time range. RFC3339 format | -| end_time | [string](#string) | | The end of the time range. RFC3339 format | - - - - - - - - -### GetSuggestionsReply - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| trials | [Trial](#api.v1.alpha2.Trial) | repeated | | - - - - - - - - -### GetSuggestionsRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_name | [string](#string) | | | -| algorithm_name | [string](#string) | | | -| request_number | [int32](#int32) | | The number of Suggestion you request at one time. When you set 3 to request_number, you can get three Suggestions at one time. | - - - - - - - - -### GetTrialListReply - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| trials | [Trial](#api.v1.alpha2.Trial) | repeated | | - - - - - - - - -### GetTrialListRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_name | [string](#string) | | | -| filter | [string](#string) | | | - - - - - - - - -### GetTrialReply - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| trial | [Trial](#api.v1.alpha2.Trial) | | | - - - - - - - - -### GetTrialRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| trial_name | [string](#string) | | | - - - - - - - - -### GraphConfig -GraphConfig contains a config of DAG - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| num_layers | [int32](#int32) | | Number of layers | -| input_sizes | [int32](#int32) | repeated | Dimensions of input size | -| output_sizes | [int32](#int32) | repeated | Dimensions of output size | - - - - - - - - -### Metric - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | -| value | [string](#string) | | | - - - - - - - - -### MetricLog - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| time_stamp | [string](#string) | | RFC3339 format | -| metric | [Metric](#api.v1.alpha2.Metric) | | | - - - - - - - - -### NasConfig -NasConfig contains a config of NAS job - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| graph_config | [GraphConfig](#api.v1.alpha2.GraphConfig) | | Config of DAG | -| operations | [NasConfig.Operations](#api.v1.alpha2.NasConfig.Operations) | | List of Operation | - - - - - - - - -### NasConfig.Operations - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| operation | [Operation](#api.v1.alpha2.Operation) | repeated | | - - - - - - - - -### ObjectiveSpec - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| type | [ObjectiveType](#api.v1.alpha2.ObjectiveType) | | | -| goal | [float](#float) | | | -| objective_metric_name | [string](#string) | | | -| additional_metric_names | [string](#string) | repeated | This can be empty if we only care about the objective metric. | - - - - - - - - -### Observation - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| metrics | [Metric](#api.v1.alpha2.Metric) | repeated | | - - - - - - - - -### ObservationLog - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| metric_logs | [MetricLog](#api.v1.alpha2.MetricLog) | repeated | | - - - - - - - - -### Operation -Config for operations in DAG - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| operation_type | [string](#string) | | Type of operation in DAG | -| parameter_specs | [Operation.ParameterSpecs](#api.v1.alpha2.Operation.ParameterSpecs) | | | - - - - - - - - -### Operation.ParameterSpecs -List of ParameterSpec - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| parameters | [ParameterSpec](#api.v1.alpha2.ParameterSpec) | repeated | | - - - - - - - - -### ParameterAssignment - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | -| value | [string](#string) | | | - - - - - - - - -### ParameterSpec -Config for a Hyper parameter. -Katib will create each Hyper parameter from this config. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | Name of the parameter. | -| parameter_type | [ParameterType](#api.v1.alpha2.ParameterType) | | Type of the parameter. | -| feasible_space | [FeasibleSpace](#api.v1.alpha2.FeasibleSpace) | | FeasibleSpace for the parameter. | - - - - - - - - -### PreCheckRegisterExperimentReply - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| can_register | [bool](#bool) | | | - - - - - - - - -### RegisterExperimentReply - - - - - - - - - -### RegisterExperimentRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment | [Experiment](#api.v1.alpha2.Experiment) | | | - - - - - - - - -### RegisterTrialReply - - - - - - - - - -### RegisterTrialRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| trial | [Trial](#api.v1.alpha2.Trial) | | | - - - - - - - - -### ReportObservationLogReply - - - - - - - - - -### ReportObservationLogRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| trial_name | [string](#string) | | | -| observation_log | [ObservationLog](#api.v1.alpha2.ObservationLog) | | | - - - - - - - - -### Trial - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | -| spec | [TrialSpec](#api.v1.alpha2.TrialSpec) | | | -| status | [TrialStatus](#api.v1.alpha2.TrialStatus) | | | - - - - - - - - -### TrialSpec - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_name | [string](#string) | | | -| objective | [ObjectiveSpec](#api.v1.alpha2.ObjectiveSpec) | | | -| parameter_assignments | [TrialSpec.ParameterAssignments](#api.v1.alpha2.TrialSpec.ParameterAssignments) | | | -| run_spec | [string](#string) | | | -| metrics_collector_spec | [string](#string) | | | - - - - - - - - -### TrialSpec.ParameterAssignments -List of ParameterAssignment - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| assignments | [ParameterAssignment](#api.v1.alpha2.ParameterAssignment) | repeated | | - - - - - - - - -### TrialStatus - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| start_time | [string](#string) | | RFC3339 format | -| completion_time | [string](#string) | | RFC3339 format | -| condition | [TrialStatus.TrialConditionType](#api.v1.alpha2.TrialStatus.TrialConditionType) | | | -| observation | [Observation](#api.v1.alpha2.Observation) | | The best observation in logs. | - - - - - - - - -### UpdateAlgorithmExtraSettingsReply - - - - - - - - - -### UpdateAlgorithmExtraSettingsRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_name | [string](#string) | | | -| extra_algorithm_settings | [AlgorithmSetting](#api.v1.alpha2.AlgorithmSetting) | repeated | | - - - - - - - - -### UpdateExperimentStatusReply - - - - - - - - - -### UpdateExperimentStatusRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_name | [string](#string) | | | -| new_status | [ExperimentStatus](#api.v1.alpha2.ExperimentStatus) | | | - - - - - - - - -### UpdateTrialStatusReply - - - - - - - - - -### UpdateTrialStatusRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| trial_name | [string](#string) | | | -| new_status | [TrialStatus](#api.v1.alpha2.TrialStatus) | | | - - - - - - - - -### ValidateAlgorithmSettingsReply -Return INVALID_ARGUMENT Error if Algorithm Settings are not Valid - - - - - - - - -### ValidateAlgorithmSettingsRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| experiment_spec | [ExperimentSpec](#api.v1.alpha2.ExperimentSpec) | | | -| algorithm_name | [string](#string) | | | - - - - - - - - - - -### ExperimentStatus.ExperimentConditionType - - -| Name | Number | Description | -| ---- | ------ | ----------- | -| CREATED | 0 | | -| RUNNING | 1 | | -| RESTARTING | 2 | | -| SUCCEEDED | 3 | | -| FAILED | 4 | | -| UNKNOWN | 5 | | - - - - - -### ObjectiveType -Direction of optimization. Minimize or Maximize. - -| Name | Number | Description | -| ---- | ------ | ----------- | -| UNKNOWN | 0 | Undefined type and not used. | -| MINIMIZE | 1 | Minimize | -| MAXIMIZE | 2 | Maximize | - - - - - -### ParameterType -Types of value for HyperParameter. - -| Name | Number | Description | -| ---- | ------ | ----------- | -| UNKNOWN_TYPE | 0 | Undefined type and not used. | -| DOUBLE | 1 | Double float type. Use "Max/Min". | -| INT | 2 | Int type. Use "Max/Min". | -| DISCRETE | 3 | Discrete number type. Use "List" as float. | -| CATEGORICAL | 4 | Categorical type. Use "List" as string. | - - - - - -### TrialStatus.TrialConditionType - - -| Name | Number | Description | -| ---- | ------ | ----------- | -| CREATED | 0 | | -| RUNNING | 1 | | -| SUCCEEDED | 2 | | -| KILLED | 3 | | -| FAILED | 4 | | -| UNKNOWN | 5 | | - - - - - - - - - -### EarlyStopping -TODO - -| Method Name | Request Type | Response Type | Description | -| ----------- | ------------ | ------------- | ------------| - - - - -### Manager -Service for Main API for Katib -For each RPC service, we define mapping to HTTP REST API method. -The mapping includes the URL path, query parameters and request body. -https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http - -| Method Name | Request Type | Response Type | Description | -| ----------- | ------------ | ------------- | ------------| -| RegisterExperiment | [RegisterExperimentRequest](#api.v1.alpha2.RegisterExperimentRequest) | [RegisterExperimentReply](#api.v1.alpha2.RegisterExperimentRequest) | Register a Experiment to DB. | -| PreCheckRegisterExperiment | [RegisterExperimentRequest](#api.v1.alpha2.RegisterExperimentRequest) | [PreCheckRegisterExperimentReply](#api.v1.alpha2.RegisterExperimentRequest) | PreCheck to register a Experiment to DB. | -| DeleteExperiment | [DeleteExperimentRequest](#api.v1.alpha2.DeleteExperimentRequest) | [DeleteExperimentReply](#api.v1.alpha2.DeleteExperimentRequest) | Delete a Experiment from DB by name. | -| GetExperiment | [GetExperimentRequest](#api.v1.alpha2.GetExperimentRequest) | [GetExperimentReply](#api.v1.alpha2.GetExperimentRequest) | Get a Experiment from DB by name. | -| GetExperimentList | [GetExperimentListRequest](#api.v1.alpha2.GetExperimentListRequest) | [GetExperimentListReply](#api.v1.alpha2.GetExperimentListRequest) | Get a summary list of Experiment from DB. The summary includes name and condition. | -| UpdateExperimentStatus | [UpdateExperimentStatusRequest](#api.v1.alpha2.UpdateExperimentStatusRequest) | [UpdateExperimentStatusReply](#api.v1.alpha2.UpdateExperimentStatusRequest) | Update Status of a experiment. | -| UpdateAlgorithmExtraSettings | [UpdateAlgorithmExtraSettingsRequest](#api.v1.alpha2.UpdateAlgorithmExtraSettingsRequest) | [UpdateAlgorithmExtraSettingsReply](#api.v1.alpha2.UpdateAlgorithmExtraSettingsRequest) | Update AlgorithmExtraSettings. The ExtraSetting is created if it does not exist, otherwise it is overwrited. | -| GetAlgorithmExtraSettings | [GetAlgorithmExtraSettingsRequest](#api.v1.alpha2.GetAlgorithmExtraSettingsRequest) | [GetAlgorithmExtraSettingsReply](#api.v1.alpha2.GetAlgorithmExtraSettingsRequest) | Get all AlgorithmExtraSettings. | -| RegisterTrial | [RegisterTrialRequest](#api.v1.alpha2.RegisterTrialRequest) | [RegisterTrialReply](#api.v1.alpha2.RegisterTrialRequest) | Register a Trial to DB. ID will be filled by manager automatically. | -| DeleteTrial | [DeleteTrialRequest](#api.v1.alpha2.DeleteTrialRequest) | [DeleteTrialReply](#api.v1.alpha2.DeleteTrialRequest) | Delete a Trial from DB by ID. | -| GetTrialList | [GetTrialListRequest](#api.v1.alpha2.GetTrialListRequest) | [GetTrialListReply](#api.v1.alpha2.GetTrialListRequest) | Get a list of Trial from DB by name of a Experiment. | -| GetTrial | [GetTrialRequest](#api.v1.alpha2.GetTrialRequest) | [GetTrialReply](#api.v1.alpha2.GetTrialRequest) | Get a Trial from DB by ID of Trial. | -| UpdateTrialStatus | [UpdateTrialStatusRequest](#api.v1.alpha2.UpdateTrialStatusRequest) | [UpdateTrialStatusReply](#api.v1.alpha2.UpdateTrialStatusRequest) | Update Status of a trial. | -| ReportObservationLog | [ReportObservationLogRequest](#api.v1.alpha2.ReportObservationLogRequest) | [ReportObservationLogReply](#api.v1.alpha2.ReportObservationLogRequest) | Report a log of Observations for a Trial. The log consists of timestamp and value of metric. Katib store every log of metrics. You can see accuracy curve or other metric logs on UI. | -| GetObservationLog | [GetObservationLogRequest](#api.v1.alpha2.GetObservationLogRequest) | [GetObservationLogReply](#api.v1.alpha2.GetObservationLogRequest) | Get all log of Observations for a Trial. | -| GetSuggestions | [GetSuggestionsRequest](#api.v1.alpha2.GetSuggestionsRequest) | [GetSuggestionsReply](#api.v1.alpha2.GetSuggestionsRequest) | Get Suggestions from a Suggestion service. | -| ValidateAlgorithmSettings | [ValidateAlgorithmSettingsRequest](#api.v1.alpha2.ValidateAlgorithmSettingsRequest) | [ValidateAlgorithmSettingsReply](#api.v1.alpha2.ValidateAlgorithmSettingsRequest) | Validate AlgorithmSettings in an Experiment. Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid | - - - - -### Suggestion - - -| Method Name | Request Type | Response Type | Description | -| ----------- | ------------ | ------------- | ------------| -| GetSuggestions | [GetSuggestionsRequest](#api.v1.alpha2.GetSuggestionsRequest) | [GetSuggestionsReply](#api.v1.alpha2.GetSuggestionsRequest) | | -| ValidateAlgorithmSettings | [ValidateAlgorithmSettingsRequest](#api.v1.alpha2.ValidateAlgorithmSettingsRequest) | [ValidateAlgorithmSettingsReply](#api.v1.alpha2.ValidateAlgorithmSettingsRequest) | | - - - - - -## Scalar Value Types - -| .proto Type | Notes | C++ Type | Java Type | Python Type | -| ----------- | ----- | -------- | --------- | ----------- | -| double | | double | double | float | -| float | | float | float | float | -| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | -| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | -| uint32 | Uses variable-length encoding. | uint32 | int | int/long | -| uint64 | Uses variable-length encoding. | uint64 | long | int/long | -| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | -| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | -| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | -| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | -| sfixed32 | Always four bytes. | int32 | int | int | -| sfixed64 | Always eight bytes. | int64 | long | int/long | -| bool | | bool | boolean | boolean | -| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | -| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | - diff --git a/pkg/apis/manager/v1alpha2/gen-doc/index.html b/pkg/apis/manager/v1alpha2/gen-doc/index.html deleted file mode 100644 index 219c2eb84af..00000000000 --- a/pkg/apis/manager/v1alpha2/gen-doc/index.html +++ /dev/null @@ -1,2443 +0,0 @@ - - - - - Protocol Documentation - - - - - - - - - - -

Protocol Documentation

- -

Table of Contents

- -
- -
- - - -
-

api.proto

Top -
-

Katib API

- - -

AlgorithmSetting

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
namestring

valuestring

- - - - -

AlgorithmSpec

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
algorithm_namestring

algorithm_settingAlgorithmSettingrepeated

early_stopping_specEarlyStoppingSpec

- - - - -

DeleteExperimentReply

-

- - - - - -

DeleteExperimentRequest

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_namestring

- - - - -

DeleteTrialReply

-

- - - - - -

DeleteTrialRequest

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
trial_namestring

- - - - -

EarlyStoppingSpec

-

TODO

- - - - - -

Experiment

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
namestring

Name of Experiment. This is unique in DB.

specExperimentSpec

statusExperimentStatus

- - - - -

ExperimentSpec

-

Spec of a Experiment. Experiment represents a single optimization run over a feasible space.

Each Experiment contains a configuration describing the feasible space, as well as a set of Trials.

It is assumed that objective function f(x) does not change in the course of a Experiment.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
parameter_specsExperimentSpec.ParameterSpecs

objectiveObjectiveSpec

algorithmAlgorithmSpec

trial_templatestring

metrics_collector_specstring

parallel_trial_countint32

max_trial_countint32

nas_configNasConfig

- - - - -

ExperimentSpec.ParameterSpecs

-

List of ParameterSpec

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
parametersParameterSpecrepeated

- - - - -

ExperimentStatus

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
start_timestring

RFC3339 format

completion_timestring

RFC3339 format

conditionExperimentStatus.ExperimentConditionType

- - - - -

ExperimentSummary

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_namestring

statusExperimentStatus

- - - - -

FeasibleSpace

-

Feasible space for optimization.

Int and Double type use Max/Min.

Discrete and Categorical type use List.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
maxstring

Max Value

minstring

Minimum Value

liststringrepeated

List of Values.

stepstring

Step for double or int parameter

- - - - -

GetAlgorithmExtraSettingsReply

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
extra_algorithm_settingsAlgorithmSettingrepeated

- - - - -

GetAlgorithmExtraSettingsRequest

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_namestring

- - - - -

GetExperimentListReply

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_summariesExperimentSummaryrepeated

- - - - -

GetExperimentListRequest

-

- - - - - -

GetExperimentReply

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experimentExperiment

- - - - -

GetExperimentRequest

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_namestring

- - - - -

GetObservationLogReply

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
observation_logObservationLog

- - - - -

GetObservationLogRequest

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
trial_namestring

metric_namestring

start_timestring

The start of the time range. RFC3339 format

end_timestring

The end of the time range. RFC3339 format

- - - - -

GetSuggestionsReply

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
trialsTrialrepeated

- - - - -

GetSuggestionsRequest

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_namestring

algorithm_namestring

request_numberint32

The number of Suggestion you request at one time. When you set 3 to request_number, you can get three Suggestions at one time.

- - - - -

GetTrialListReply

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
trialsTrialrepeated

- - - - -

GetTrialListRequest

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_namestring

filterstring

- - - - -

GetTrialReply

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
trialTrial

- - - - -

GetTrialRequest

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
trial_namestring

- - - - -

GraphConfig

-

GraphConfig contains a config of DAG

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
num_layersint32

Number of layers

input_sizesint32repeated

Dimensions of input size

output_sizesint32repeated

Dimensions of output size

- - - - -

Metric

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
namestring

valuestring

- - - - -

MetricLog

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
time_stampstring

RFC3339 format

metricMetric

- - - - -

NasConfig

-

NasConfig contains a config of NAS job

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
graph_configGraphConfig

Config of DAG

operationsNasConfig.Operations

List of Operation

- - - - -

NasConfig.Operations

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
operationOperationrepeated

- - - - -

ObjectiveSpec

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
typeObjectiveType

goalfloat

objective_metric_namestring

additional_metric_namesstringrepeated

This can be empty if we only care about the objective metric.

- - - - -

Observation

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
metricsMetricrepeated

- - - - -

ObservationLog

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
metric_logsMetricLogrepeated

- - - - -

Operation

-

Config for operations in DAG

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
operation_typestring

Type of operation in DAG

parameter_specsOperation.ParameterSpecs

- - - - -

Operation.ParameterSpecs

-

List of ParameterSpec

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
parametersParameterSpecrepeated

- - - - -

ParameterAssignment

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
namestring

valuestring

- - - - -

ParameterSpec

-

Config for a Hyper parameter.

Katib will create each Hyper parameter from this config.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
namestring

Name of the parameter.

parameter_typeParameterType

Type of the parameter.

feasible_spaceFeasibleSpace

FeasibleSpace for the parameter.

- - - - -

PreCheckRegisterExperimentReply

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
can_registerbool

- - - - -

RegisterExperimentReply

-

- - - - - -

RegisterExperimentRequest

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experimentExperiment

- - - - -

RegisterTrialReply

-

- - - - - -

RegisterTrialRequest

-

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
trialTrial

- - - - -

ReportObservationLogReply

-

- - - - - -

ReportObservationLogRequest

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
trial_namestring

observation_logObservationLog

- - - - -

Trial

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
namestring

specTrialSpec

statusTrialStatus

- - - - -

TrialSpec

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_namestring

objectiveObjectiveSpec

parameter_assignmentsTrialSpec.ParameterAssignments

run_specstring

metrics_collector_specstring

- - - - -

TrialSpec.ParameterAssignments

-

List of ParameterAssignment

- - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
assignmentsParameterAssignmentrepeated

- - - - -

TrialStatus

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
start_timestring

RFC3339 format

completion_timestring

RFC3339 format

conditionTrialStatus.TrialConditionType

observationObservation

The best observation in logs.

- - - - -

UpdateAlgorithmExtraSettingsReply

-

- - - - - -

UpdateAlgorithmExtraSettingsRequest

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_namestring

extra_algorithm_settingsAlgorithmSettingrepeated

- - - - -

UpdateExperimentStatusReply

-

- - - - - -

UpdateExperimentStatusRequest

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_namestring

new_statusExperimentStatus

- - - - -

UpdateTrialStatusReply

-

- - - - - -

UpdateTrialStatusRequest

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
trial_namestring

new_statusTrialStatus

- - - - -

ValidateAlgorithmSettingsReply

-

Return INVALID_ARGUMENT Error if Algorithm Settings are not Valid

- - - - - -

ValidateAlgorithmSettingsRequest

-

- - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeLabelDescription
experiment_specExperimentSpec

algorithm_namestring

- - - - - - -

ExperimentStatus.ExperimentConditionType

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameNumberDescription
CREATED0

RUNNING1

RESTARTING2

SUCCEEDED3

FAILED4

UNKNOWN5

- -

ObjectiveType

-

Direction of optimization. Minimize or Maximize.

- - - - - - - - - - - - - - - - - - - - - - - - - -
NameNumberDescription
UNKNOWN0

Undefined type and not used.

MINIMIZE1

Minimize

MAXIMIZE2

Maximize

- -

ParameterType

-

Types of value for HyperParameter.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameNumberDescription
UNKNOWN_TYPE0

Undefined type and not used.

DOUBLE1

Double float type. Use "Max/Min".

INT2

Int type. Use "Max/Min".

DISCRETE3

Discrete number type. Use "List" as float.

CATEGORICAL4

Categorical type. Use "List" as string.

- -

TrialStatus.TrialConditionType

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameNumberDescription
CREATED0

RUNNING1

SUCCEEDED2

KILLED3

FAILED4

UNKNOWN5

- - - - - -

EarlyStopping

-

TODO

- - - - - - - -
Method NameRequest TypeResponse TypeDescription
- -

Manager

-

Service for Main API for Katib

For each RPC service, we define mapping to HTTP REST API method.

The mapping includes the URL path, query parameters and request body.

https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method NameRequest TypeResponse TypeDescription
RegisterExperimentRegisterExperimentRequestRegisterExperimentReply

Register a Experiment to DB.

PreCheckRegisterExperimentRegisterExperimentRequestPreCheckRegisterExperimentReply

PreCheck to register a Experiment to DB.

DeleteExperimentDeleteExperimentRequestDeleteExperimentReply

Delete a Experiment from DB by name.

GetExperimentGetExperimentRequestGetExperimentReply

Get a Experiment from DB by name.

GetExperimentListGetExperimentListRequestGetExperimentListReply

Get a summary list of Experiment from DB. -The summary includes name and condition.

UpdateExperimentStatusUpdateExperimentStatusRequestUpdateExperimentStatusReply

Update Status of a experiment.

UpdateAlgorithmExtraSettingsUpdateAlgorithmExtraSettingsRequestUpdateAlgorithmExtraSettingsReply

Update AlgorithmExtraSettings. -The ExtraSetting is created if it does not exist, otherwise it is overwrited.

GetAlgorithmExtraSettingsGetAlgorithmExtraSettingsRequestGetAlgorithmExtraSettingsReply

Get all AlgorithmExtraSettings.

RegisterTrialRegisterTrialRequestRegisterTrialReply

Register a Trial to DB. -ID will be filled by manager automatically.

DeleteTrialDeleteTrialRequestDeleteTrialReply

Delete a Trial from DB by ID.

GetTrialListGetTrialListRequestGetTrialListReply

Get a list of Trial from DB by name of a Experiment.

GetTrialGetTrialRequestGetTrialReply

Get a Trial from DB by ID of Trial.

UpdateTrialStatusUpdateTrialStatusRequestUpdateTrialStatusReply

Update Status of a trial.

ReportObservationLogReportObservationLogRequestReportObservationLogReply

Report a log of Observations for a Trial. -The log consists of timestamp and value of metric. -Katib store every log of metrics. -You can see accuracy curve or other metric logs on UI.

GetObservationLogGetObservationLogRequestGetObservationLogReply

Get all log of Observations for a Trial.

GetSuggestionsGetSuggestionsRequestGetSuggestionsReply

Get Suggestions from a Suggestion service.

ValidateAlgorithmSettingsValidateAlgorithmSettingsRequestValidateAlgorithmSettingsReply

Validate AlgorithmSettings in an Experiment. -Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid

- -

Suggestion

-

- - - - - - - - - - - - - - - - - - - - - -
Method NameRequest TypeResponse TypeDescription
GetSuggestionsGetSuggestionsRequestGetSuggestionsReply

ValidateAlgorithmSettingsValidateAlgorithmSettingsRequestValidateAlgorithmSettingsReply

- - - -

Scalar Value Types

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.proto TypeNotesC++ TypeJava TypePython Type
doubledoubledoublefloat
floatfloatfloatfloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32intint
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64longint/long
uint32Uses variable-length encoding.uint32intint/long
uint64Uses variable-length encoding.uint64longint/long
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32intint
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64longint/long
fixed32Always four bytes. More efficient than uint32 if values are often greater than 2^28.uint32intint
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 2^56.uint64longint/long
sfixed32Always four bytes.int32intint
sfixed64Always eight bytes.int64longint/long
boolboolbooleanboolean
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringStringstr/unicode
bytesMay contain any arbitrary sequence of bytes.stringByteStringstr
- - - diff --git a/pkg/apis/manager/v1alpha2/python/api_pb2.py b/pkg/apis/manager/v1alpha2/python/api_pb2.py deleted file mode 100644 index 77970b97be8..00000000000 --- a/pkg/apis/manager/v1alpha2/python/api_pb2.py +++ /dev/null @@ -1,3916 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: api.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='api.proto', - package='api.v1.alpha2', - syntax='proto3', - serialized_pb=_b('\n\tapi.proto\x12\rapi.v1.alpha2\x1a\x1cgoogle/api/annotations.proto\"E\n\rFeasibleSpace\x12\x0b\n\x03max\x18\x01 \x01(\t\x12\x0b\n\x03min\x18\x02 \x01(\t\x12\x0c\n\x04list\x18\x03 \x03(\t\x12\x0c\n\x04step\x18\x04 \x01(\t\"\x89\x01\n\rParameterSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x0eparameter_type\x18\x02 \x01(\x0e\x32\x1c.api.v1.alpha2.ParameterType\x12\x34\n\x0e\x66\x65\x61sible_space\x18\x03 \x01(\x0b\x32\x1c.api.v1.alpha2.FeasibleSpace\"\x89\x01\n\rObjectiveSpec\x12*\n\x04type\x18\x01 \x01(\x0e\x32\x1c.api.v1.alpha2.ObjectiveType\x12\x0c\n\x04goal\x18\x02 \x01(\x02\x12\x1d\n\x15objective_metric_name\x18\x03 \x01(\t\x12\x1f\n\x17\x61\x64\x64itional_metric_names\x18\x04 \x03(\t\"/\n\x10\x41lgorithmSetting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\x13\n\x11\x45\x61rlyStoppingSpec\"\xa2\x01\n\rAlgorithmSpec\x12\x16\n\x0e\x61lgorithm_name\x18\x01 \x01(\t\x12:\n\x11\x61lgorithm_setting\x18\x02 \x03(\x0b\x32\x1f.api.v1.alpha2.AlgorithmSetting\x12=\n\x13\x65\x61rly_stopping_spec\x18\x03 \x01(\x0b\x32 .api.v1.alpha2.EarlyStoppingSpec\"\xb1\x01\n\tNasConfig\x12\x30\n\x0cgraph_config\x18\x01 \x01(\x0b\x32\x1a.api.v1.alpha2.GraphConfig\x12\x37\n\noperations\x18\x02 \x01(\x0b\x32#.api.v1.alpha2.NasConfig.Operations\x1a\x39\n\nOperations\x12+\n\toperation\x18\x01 \x03(\x0b\x32\x18.api.v1.alpha2.Operation\"L\n\x0bGraphConfig\x12\x12\n\nnum_layers\x18\x01 \x01(\x05\x12\x13\n\x0binput_sizes\x18\x02 \x03(\x05\x12\x14\n\x0coutput_sizes\x18\x03 \x03(\x05\"\xa9\x01\n\tOperation\x12\x16\n\x0eoperation_type\x18\x01 \x01(\t\x12@\n\x0fparameter_specs\x18\x02 \x01(\x0b\x32\'.api.v1.alpha2.Operation.ParameterSpecs\x1a\x42\n\x0eParameterSpecs\x12\x30\n\nparameters\x18\x01 \x03(\x0b\x32\x1c.api.v1.alpha2.ParameterSpec\"\x9a\x03\n\x0e\x45xperimentSpec\x12\x45\n\x0fparameter_specs\x18\x01 \x01(\x0b\x32,.api.v1.alpha2.ExperimentSpec.ParameterSpecs\x12/\n\tobjective\x18\x02 \x01(\x0b\x32\x1c.api.v1.alpha2.ObjectiveSpec\x12/\n\talgorithm\x18\x03 \x01(\x0b\x32\x1c.api.v1.alpha2.AlgorithmSpec\x12\x16\n\x0etrial_template\x18\x04 \x01(\t\x12\x1e\n\x16metrics_collector_spec\x18\x05 \x01(\t\x12\x1c\n\x14parallel_trial_count\x18\x06 \x01(\x05\x12\x17\n\x0fmax_trial_count\x18\x07 \x01(\x05\x12,\n\nnas_config\x18\x08 \x01(\x0b\x32\x18.api.v1.alpha2.NasConfig\x1a\x42\n\x0eParameterSpecs\x12\x30\n\nparameters\x18\x01 \x03(\x0b\x32\x1c.api.v1.alpha2.ParameterSpec\"\xf8\x01\n\x10\x45xperimentStatus\x12\x12\n\nstart_time\x18\x01 \x01(\t\x12\x17\n\x0f\x63ompletion_time\x18\x02 \x01(\t\x12J\n\tcondition\x18\x03 \x01(\x0e\x32\x37.api.v1.alpha2.ExperimentStatus.ExperimentConditionType\"k\n\x17\x45xperimentConditionType\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07RUNNING\x10\x01\x12\x0e\n\nRESTARTING\x10\x02\x12\r\n\tSUCCEEDED\x10\x03\x12\n\n\x06\x46\x41ILED\x10\x04\x12\x0b\n\x07UNKNOWN\x10\x05\"x\n\nExperiment\x12\x0c\n\x04name\x18\x01 \x01(\t\x12+\n\x04spec\x18\x02 \x01(\x0b\x32\x1d.api.v1.alpha2.ExperimentSpec\x12/\n\x06status\x18\x03 \x01(\x0b\x32\x1f.api.v1.alpha2.ExperimentStatus\"2\n\x13ParameterAssignment\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"%\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"F\n\tMetricLog\x12\x12\n\ntime_stamp\x18\x01 \x01(\t\x12%\n\x06metric\x18\x02 \x01(\x0b\x32\x15.api.v1.alpha2.Metric\"5\n\x0bObservation\x12&\n\x07metrics\x18\x01 \x03(\x0b\x32\x15.api.v1.alpha2.Metric\"?\n\x0eObservationLog\x12-\n\x0bmetric_logs\x18\x01 \x03(\x0b\x32\x18.api.v1.alpha2.MetricLog\"\xa6\x02\n\tTrialSpec\x12\x17\n\x0f\x65xperiment_name\x18\x01 \x01(\t\x12/\n\tobjective\x18\x02 \x01(\x0b\x32\x1c.api.v1.alpha2.ObjectiveSpec\x12L\n\x15parameter_assignments\x18\x03 \x01(\x0b\x32-.api.v1.alpha2.TrialSpec.ParameterAssignments\x12\x10\n\x08run_spec\x18\x04 \x01(\t\x12\x1e\n\x16metrics_collector_spec\x18\x05 \x01(\t\x1aO\n\x14ParameterAssignments\x12\x37\n\x0b\x61ssignments\x18\x01 \x03(\x0b\x32\".api.v1.alpha2.ParameterAssignment\"\x91\x02\n\x0bTrialStatus\x12\x12\n\nstart_time\x18\x01 \x01(\t\x12\x17\n\x0f\x63ompletion_time\x18\x02 \x01(\t\x12@\n\tcondition\x18\x03 \x01(\x0e\x32-.api.v1.alpha2.TrialStatus.TrialConditionType\x12/\n\x0bobservation\x18\x04 \x01(\x0b\x32\x1a.api.v1.alpha2.Observation\"b\n\x12TrialConditionType\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07RUNNING\x10\x01\x12\r\n\tSUCCEEDED\x10\x02\x12\n\n\x06KILLED\x10\x03\x12\n\n\x06\x46\x41ILED\x10\x04\x12\x0b\n\x07UNKNOWN\x10\x05\"i\n\x05Trial\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x04spec\x18\x02 \x01(\x0b\x32\x18.api.v1.alpha2.TrialSpec\x12*\n\x06status\x18\x03 \x01(\x0b\x32\x1a.api.v1.alpha2.TrialStatus\"J\n\x19RegisterExperimentRequest\x12-\n\nexperiment\x18\x01 \x01(\x0b\x32\x19.api.v1.alpha2.Experiment\"\x19\n\x17RegisterExperimentReply\"7\n\x1fPreCheckRegisterExperimentReply\x12\x14\n\x0c\x63\x61n_register\x18\x01 \x01(\x08\"2\n\x17\x44\x65leteExperimentRequest\x12\x17\n\x0f\x65xperiment_name\x18\x01 \x01(\t\"\x17\n\x15\x44\x65leteExperimentReply\"/\n\x14GetExperimentRequest\x12\x17\n\x0f\x65xperiment_name\x18\x01 \x01(\t\"C\n\x12GetExperimentReply\x12-\n\nexperiment\x18\x01 \x01(\x0b\x32\x19.api.v1.alpha2.Experiment\"]\n\x11\x45xperimentSummary\x12\x17\n\x0f\x65xperiment_name\x18\x01 \x01(\t\x12/\n\x06status\x18\x02 \x01(\x0b\x32\x1f.api.v1.alpha2.ExperimentStatus\"\x1a\n\x18GetExperimentListRequest\"X\n\x16GetExperimentListReply\x12>\n\x14\x65xperiment_summaries\x18\x01 \x03(\x0b\x32 .api.v1.alpha2.ExperimentSummary\"m\n\x1dUpdateExperimentStatusRequest\x12\x17\n\x0f\x65xperiment_name\x18\x01 \x01(\t\x12\x33\n\nnew_status\x18\x02 \x01(\x0b\x32\x1f.api.v1.alpha2.ExperimentStatus\"\x1d\n\x1bUpdateExperimentStatusReply\"\x81\x01\n#UpdateAlgorithmExtraSettingsRequest\x12\x17\n\x0f\x65xperiment_name\x18\x01 \x01(\t\x12\x41\n\x18\x65xtra_algorithm_settings\x18\x02 \x03(\x0b\x32\x1f.api.v1.alpha2.AlgorithmSetting\"#\n!UpdateAlgorithmExtraSettingsReply\";\n GetAlgorithmExtraSettingsRequest\x12\x17\n\x0f\x65xperiment_name\x18\x01 \x01(\t\"c\n\x1eGetAlgorithmExtraSettingsReply\x12\x41\n\x18\x65xtra_algorithm_settings\x18\x01 \x03(\x0b\x32\x1f.api.v1.alpha2.AlgorithmSetting\";\n\x14RegisterTrialRequest\x12#\n\x05trial\x18\x01 \x01(\x0b\x32\x14.api.v1.alpha2.Trial\"\x14\n\x12RegisterTrialReply\"(\n\x12\x44\x65leteTrialRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\"\x12\n\x10\x44\x65leteTrialReply\">\n\x13GetTrialListRequest\x12\x17\n\x0f\x65xperiment_name\x18\x01 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x02 \x01(\t\"9\n\x11GetTrialListReply\x12$\n\x06trials\x18\x01 \x03(\x0b\x32\x14.api.v1.alpha2.Trial\"%\n\x0fGetTrialRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\"4\n\rGetTrialReply\x12#\n\x05trial\x18\x01 \x01(\x0b\x32\x14.api.v1.alpha2.Trial\"^\n\x18UpdateTrialStatusRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\x12.\n\nnew_status\x18\x02 \x01(\x0b\x32\x1a.api.v1.alpha2.TrialStatus\"\x18\n\x16UpdateTrialStatusReply\"i\n\x1bReportObservationLogRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\x12\x36\n\x0fobservation_log\x18\x02 \x01(\x0b\x32\x1d.api.v1.alpha2.ObservationLog\"\x1b\n\x19ReportObservationLogReply\"i\n\x18GetObservationLogRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\x12\x13\n\x0bmetric_name\x18\x02 \x01(\t\x12\x12\n\nstart_time\x18\x03 \x01(\t\x12\x10\n\x08\x65nd_time\x18\x04 \x01(\t\"P\n\x16GetObservationLogReply\x12\x36\n\x0fobservation_log\x18\x01 \x01(\x0b\x32\x1d.api.v1.alpha2.ObservationLog\"`\n\x15GetSuggestionsRequest\x12\x17\n\x0f\x65xperiment_name\x18\x01 \x01(\t\x12\x16\n\x0e\x61lgorithm_name\x18\x02 \x01(\t\x12\x16\n\x0erequest_number\x18\x03 \x01(\x05\";\n\x13GetSuggestionsReply\x12$\n\x06trials\x18\x01 \x03(\x0b\x32\x14.api.v1.alpha2.Trial\"r\n ValidateAlgorithmSettingsRequest\x12\x36\n\x0f\x65xperiment_spec\x18\x01 \x01(\x0b\x32\x1d.api.v1.alpha2.ExperimentSpec\x12\x16\n\x0e\x61lgorithm_name\x18\x02 \x01(\t\" \n\x1eValidateAlgorithmSettingsReply*U\n\rParameterType\x12\x10\n\x0cUNKNOWN_TYPE\x10\x00\x12\n\n\x06\x44OUBLE\x10\x01\x12\x07\n\x03INT\x10\x02\x12\x0c\n\x08\x44ISCRETE\x10\x03\x12\x0f\n\x0b\x43\x41TEGORICAL\x10\x04*8\n\rObjectiveType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0c\n\x08MINIMIZE\x10\x01\x12\x0c\n\x08MAXIMIZE\x10\x02\x32\xdc\x14\n\x07Manager\x12\x9b\x01\n\x12RegisterExperiment\x12(.api.v1.alpha2.RegisterExperimentRequest\x1a&.api.v1.alpha2.RegisterExperimentReply\"3\x82\xd3\xe4\x93\x02-\"\x1f/api/Manager/RegisterExperiment:\nexperiment\x12\xb3\x01\n\x1aPreCheckRegisterExperiment\x12(.api.v1.alpha2.RegisterExperimentRequest\x1a..api.v1.alpha2.PreCheckRegisterExperimentReply\";\x82\xd3\xe4\x93\x02\x35\"\'/api/Manager/PreCheckRegisterExperiment:\nexperiment\x12\x99\x01\n\x10\x44\x65leteExperiment\x12&.api.v1.alpha2.DeleteExperimentRequest\x1a$.api.v1.alpha2.DeleteExperimentReply\"7\x82\xd3\xe4\x93\x02\x31\x12//api/Manager/DeleteExperiment/{experiment_name}\x12\x8d\x01\n\rGetExperiment\x12#.api.v1.alpha2.GetExperimentRequest\x1a!.api.v1.alpha2.GetExperimentReply\"4\x82\xd3\xe4\x93\x02.\x12,/api/Manager/GetExperiment/{experiment_name}\x12\x8b\x01\n\x11GetExperimentList\x12\'.api.v1.alpha2.GetExperimentListRequest\x1a%.api.v1.alpha2.GetExperimentListReply\"&\x82\xd3\xe4\x93\x02 \x12\x1e/api/Manager/GetExperimentList\x12\xb4\x01\n\x16UpdateExperimentStatus\x12,.api.v1.alpha2.UpdateExperimentStatusRequest\x1a*.api.v1.alpha2.UpdateExperimentStatusReply\"@\x82\xd3\xe4\x93\x02:\x1a\x35/api/Manager/UpdateExperimentStatus/{experiment_name}:\x01*\x12\xcc\x01\n\x1cUpdateAlgorithmExtraSettings\x12\x32.api.v1.alpha2.UpdateAlgorithmExtraSettingsRequest\x1a\x30.api.v1.alpha2.UpdateAlgorithmExtraSettingsReply\"F\x82\xd3\xe4\x93\x02@\x1a;/api/Manager/UpdateAlgorithmExtraSettings/{experiment_name}:\x01*\x12\xbd\x01\n\x19GetAlgorithmExtraSettings\x12/.api.v1.alpha2.GetAlgorithmExtraSettingsRequest\x1a-.api.v1.alpha2.GetAlgorithmExtraSettingsReply\"@\x82\xd3\xe4\x93\x02:\x12\x38/api/Manager/GetAlgorithmExtraSettings/{experiment_name}\x12\x82\x01\n\rRegisterTrial\x12#.api.v1.alpha2.RegisterTrialRequest\x1a!.api.v1.alpha2.RegisterTrialReply\")\x82\xd3\xe4\x93\x02#\"\x1a/api/Manager/RegisterTrial:\x05trial\x12\x80\x01\n\x0b\x44\x65leteTrial\x12!.api.v1.alpha2.DeleteTrialRequest\x1a\x1f.api.v1.alpha2.DeleteTrialReply\"-\x82\xd3\xe4\x93\x02\'\x12%/api/Manager/DeleteTrial/{trial_name}\x12\x89\x01\n\x0cGetTrialList\x12\".api.v1.alpha2.GetTrialListRequest\x1a .api.v1.alpha2.GetTrialListReply\"3\x82\xd3\xe4\x93\x02-\x12+/api/Manager/GetTrialList/{experiment_name}\x12t\n\x08GetTrial\x12\x1e.api.v1.alpha2.GetTrialRequest\x1a\x1c.api.v1.alpha2.GetTrialReply\"*\x82\xd3\xe4\x93\x02$\x12\"/api/Manager/GetTrial/{trial_name}\x12\x8e\x01\n\x11UpdateTrialStatus\x12\'.api.v1.alpha2.UpdateTrialStatusRequest\x1a%.api.v1.alpha2.UpdateTrialStatusReply\")\x82\xd3\xe4\x93\x02#\x1a\x1e/api/Manager/UpdateTrialStatus:\x01*\x12\x9a\x01\n\x14ReportObservationLog\x12*.api.v1.alpha2.ReportObservationLogRequest\x1a(.api.v1.alpha2.ReportObservationLogReply\",\x82\xd3\xe4\x93\x02&\"!/api/Manager/ReportObservationLog:\x01*\x12\x8e\x01\n\x11GetObservationLog\x12\'.api.v1.alpha2.GetObservationLogRequest\x1a%.api.v1.alpha2.GetObservationLogReply\")\x82\xd3\xe4\x93\x02#\"\x1e/api/Manager/GetObservationLog:\x01*\x12\x82\x01\n\x0eGetSuggestions\x12$.api.v1.alpha2.GetSuggestionsRequest\x1a\".api.v1.alpha2.GetSuggestionsReply\"&\x82\xd3\xe4\x93\x02 \"\x1b/api/Manager/GetSuggestions:\x01*\x12\xae\x01\n\x19ValidateAlgorithmSettings\x12/.api.v1.alpha2.ValidateAlgorithmSettingsRequest\x1a-.api.v1.alpha2.ValidateAlgorithmSettingsReply\"1\x82\xd3\xe4\x93\x02+\"&/api/Manager/ValidateAlgorithmSettings:\x01*2\xe5\x01\n\nSuggestion\x12Z\n\x0eGetSuggestions\x12$.api.v1.alpha2.GetSuggestionsRequest\x1a\".api.v1.alpha2.GetSuggestionsReply\x12{\n\x19ValidateAlgorithmSettings\x12/.api.v1.alpha2.ValidateAlgorithmSettingsRequest\x1a-.api.v1.alpha2.ValidateAlgorithmSettingsReply2\x0f\n\rEarlyStoppingb\x06proto3') - , - dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,]) - -_PARAMETERTYPE = _descriptor.EnumDescriptor( - name='ParameterType', - full_name='api.v1.alpha2.ParameterType', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='UNKNOWN_TYPE', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='DOUBLE', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='INT', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='DISCRETE', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CATEGORICAL', index=4, number=4, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=4981, - serialized_end=5066, -) -_sym_db.RegisterEnumDescriptor(_PARAMETERTYPE) - -ParameterType = enum_type_wrapper.EnumTypeWrapper(_PARAMETERTYPE) -_OBJECTIVETYPE = _descriptor.EnumDescriptor( - name='ObjectiveType', - full_name='api.v1.alpha2.ObjectiveType', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MINIMIZE', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MAXIMIZE', index=2, number=2, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=5068, - serialized_end=5124, -) -_sym_db.RegisterEnumDescriptor(_OBJECTIVETYPE) - -ObjectiveType = enum_type_wrapper.EnumTypeWrapper(_OBJECTIVETYPE) -UNKNOWN_TYPE = 0 -DOUBLE = 1 -INT = 2 -DISCRETE = 3 -CATEGORICAL = 4 -UNKNOWN = 0 -MINIMIZE = 1 -MAXIMIZE = 2 - - -_EXPERIMENTSTATUS_EXPERIMENTCONDITIONTYPE = _descriptor.EnumDescriptor( - name='ExperimentConditionType', - full_name='api.v1.alpha2.ExperimentStatus.ExperimentConditionType', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='CREATED', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='RUNNING', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='RESTARTING', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SUCCEEDED', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FAILED', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='UNKNOWN', index=5, number=5, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=1629, - serialized_end=1736, -) -_sym_db.RegisterEnumDescriptor(_EXPERIMENTSTATUS_EXPERIMENTCONDITIONTYPE) - -_TRIALSTATUS_TRIALCONDITIONTYPE = _descriptor.EnumDescriptor( - name='TrialConditionType', - full_name='api.v1.alpha2.TrialStatus.TrialConditionType', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='CREATED', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='RUNNING', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SUCCEEDED', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='KILLED', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FAILED', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='UNKNOWN', index=5, number=5, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=2616, - serialized_end=2714, -) -_sym_db.RegisterEnumDescriptor(_TRIALSTATUS_TRIALCONDITIONTYPE) - - -_FEASIBLESPACE = _descriptor.Descriptor( - name='FeasibleSpace', - full_name='api.v1.alpha2.FeasibleSpace', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='max', full_name='api.v1.alpha2.FeasibleSpace.max', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='min', full_name='api.v1.alpha2.FeasibleSpace.min', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='list', full_name='api.v1.alpha2.FeasibleSpace.list', index=2, - number=3, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='step', full_name='api.v1.alpha2.FeasibleSpace.step', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=58, - serialized_end=127, -) - - -_PARAMETERSPEC = _descriptor.Descriptor( - name='ParameterSpec', - full_name='api.v1.alpha2.ParameterSpec', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='api.v1.alpha2.ParameterSpec.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='parameter_type', full_name='api.v1.alpha2.ParameterSpec.parameter_type', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='feasible_space', full_name='api.v1.alpha2.ParameterSpec.feasible_space', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=130, - serialized_end=267, -) - - -_OBJECTIVESPEC = _descriptor.Descriptor( - name='ObjectiveSpec', - full_name='api.v1.alpha2.ObjectiveSpec', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='type', full_name='api.v1.alpha2.ObjectiveSpec.type', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='goal', full_name='api.v1.alpha2.ObjectiveSpec.goal', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='objective_metric_name', full_name='api.v1.alpha2.ObjectiveSpec.objective_metric_name', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='additional_metric_names', full_name='api.v1.alpha2.ObjectiveSpec.additional_metric_names', index=3, - number=4, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=270, - serialized_end=407, -) - - -_ALGORITHMSETTING = _descriptor.Descriptor( - name='AlgorithmSetting', - full_name='api.v1.alpha2.AlgorithmSetting', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='api.v1.alpha2.AlgorithmSetting.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='value', full_name='api.v1.alpha2.AlgorithmSetting.value', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=409, - serialized_end=456, -) - - -_EARLYSTOPPINGSPEC = _descriptor.Descriptor( - name='EarlyStoppingSpec', - full_name='api.v1.alpha2.EarlyStoppingSpec', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=458, - serialized_end=477, -) - - -_ALGORITHMSPEC = _descriptor.Descriptor( - name='AlgorithmSpec', - full_name='api.v1.alpha2.AlgorithmSpec', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='algorithm_name', full_name='api.v1.alpha2.AlgorithmSpec.algorithm_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='algorithm_setting', full_name='api.v1.alpha2.AlgorithmSpec.algorithm_setting', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='early_stopping_spec', full_name='api.v1.alpha2.AlgorithmSpec.early_stopping_spec', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=480, - serialized_end=642, -) - - -_NASCONFIG_OPERATIONS = _descriptor.Descriptor( - name='Operations', - full_name='api.v1.alpha2.NasConfig.Operations', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='operation', full_name='api.v1.alpha2.NasConfig.Operations.operation', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=765, - serialized_end=822, -) - -_NASCONFIG = _descriptor.Descriptor( - name='NasConfig', - full_name='api.v1.alpha2.NasConfig', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='graph_config', full_name='api.v1.alpha2.NasConfig.graph_config', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='operations', full_name='api.v1.alpha2.NasConfig.operations', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[_NASCONFIG_OPERATIONS, ], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=645, - serialized_end=822, -) - - -_GRAPHCONFIG = _descriptor.Descriptor( - name='GraphConfig', - full_name='api.v1.alpha2.GraphConfig', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='num_layers', full_name='api.v1.alpha2.GraphConfig.num_layers', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='input_sizes', full_name='api.v1.alpha2.GraphConfig.input_sizes', index=1, - number=2, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='output_sizes', full_name='api.v1.alpha2.GraphConfig.output_sizes', index=2, - number=3, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=824, - serialized_end=900, -) - - -_OPERATION_PARAMETERSPECS = _descriptor.Descriptor( - name='ParameterSpecs', - full_name='api.v1.alpha2.Operation.ParameterSpecs', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='parameters', full_name='api.v1.alpha2.Operation.ParameterSpecs.parameters', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1006, - serialized_end=1072, -) - -_OPERATION = _descriptor.Descriptor( - name='Operation', - full_name='api.v1.alpha2.Operation', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='operation_type', full_name='api.v1.alpha2.Operation.operation_type', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='parameter_specs', full_name='api.v1.alpha2.Operation.parameter_specs', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[_OPERATION_PARAMETERSPECS, ], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=903, - serialized_end=1072, -) - - -_EXPERIMENTSPEC_PARAMETERSPECS = _descriptor.Descriptor( - name='ParameterSpecs', - full_name='api.v1.alpha2.ExperimentSpec.ParameterSpecs', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='parameters', full_name='api.v1.alpha2.ExperimentSpec.ParameterSpecs.parameters', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1006, - serialized_end=1072, -) - -_EXPERIMENTSPEC = _descriptor.Descriptor( - name='ExperimentSpec', - full_name='api.v1.alpha2.ExperimentSpec', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='parameter_specs', full_name='api.v1.alpha2.ExperimentSpec.parameter_specs', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='objective', full_name='api.v1.alpha2.ExperimentSpec.objective', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='algorithm', full_name='api.v1.alpha2.ExperimentSpec.algorithm', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='trial_template', full_name='api.v1.alpha2.ExperimentSpec.trial_template', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='metrics_collector_spec', full_name='api.v1.alpha2.ExperimentSpec.metrics_collector_spec', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='parallel_trial_count', full_name='api.v1.alpha2.ExperimentSpec.parallel_trial_count', index=5, - number=6, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='max_trial_count', full_name='api.v1.alpha2.ExperimentSpec.max_trial_count', index=6, - number=7, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='nas_config', full_name='api.v1.alpha2.ExperimentSpec.nas_config', index=7, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[_EXPERIMENTSPEC_PARAMETERSPECS, ], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1075, - serialized_end=1485, -) - - -_EXPERIMENTSTATUS = _descriptor.Descriptor( - name='ExperimentStatus', - full_name='api.v1.alpha2.ExperimentStatus', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='start_time', full_name='api.v1.alpha2.ExperimentStatus.start_time', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='completion_time', full_name='api.v1.alpha2.ExperimentStatus.completion_time', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='condition', full_name='api.v1.alpha2.ExperimentStatus.condition', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _EXPERIMENTSTATUS_EXPERIMENTCONDITIONTYPE, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1488, - serialized_end=1736, -) - - -_EXPERIMENT = _descriptor.Descriptor( - name='Experiment', - full_name='api.v1.alpha2.Experiment', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='api.v1.alpha2.Experiment.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='spec', full_name='api.v1.alpha2.Experiment.spec', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='status', full_name='api.v1.alpha2.Experiment.status', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1738, - serialized_end=1858, -) - - -_PARAMETERASSIGNMENT = _descriptor.Descriptor( - name='ParameterAssignment', - full_name='api.v1.alpha2.ParameterAssignment', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='api.v1.alpha2.ParameterAssignment.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='value', full_name='api.v1.alpha2.ParameterAssignment.value', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1860, - serialized_end=1910, -) - - -_METRIC = _descriptor.Descriptor( - name='Metric', - full_name='api.v1.alpha2.Metric', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='api.v1.alpha2.Metric.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='value', full_name='api.v1.alpha2.Metric.value', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1912, - serialized_end=1949, -) - - -_METRICLOG = _descriptor.Descriptor( - name='MetricLog', - full_name='api.v1.alpha2.MetricLog', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='time_stamp', full_name='api.v1.alpha2.MetricLog.time_stamp', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='metric', full_name='api.v1.alpha2.MetricLog.metric', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1951, - serialized_end=2021, -) - - -_OBSERVATION = _descriptor.Descriptor( - name='Observation', - full_name='api.v1.alpha2.Observation', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='metrics', full_name='api.v1.alpha2.Observation.metrics', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2023, - serialized_end=2076, -) - - -_OBSERVATIONLOG = _descriptor.Descriptor( - name='ObservationLog', - full_name='api.v1.alpha2.ObservationLog', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='metric_logs', full_name='api.v1.alpha2.ObservationLog.metric_logs', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2078, - serialized_end=2141, -) - - -_TRIALSPEC_PARAMETERASSIGNMENTS = _descriptor.Descriptor( - name='ParameterAssignments', - full_name='api.v1.alpha2.TrialSpec.ParameterAssignments', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='assignments', full_name='api.v1.alpha2.TrialSpec.ParameterAssignments.assignments', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2359, - serialized_end=2438, -) - -_TRIALSPEC = _descriptor.Descriptor( - name='TrialSpec', - full_name='api.v1.alpha2.TrialSpec', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_name', full_name='api.v1.alpha2.TrialSpec.experiment_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='objective', full_name='api.v1.alpha2.TrialSpec.objective', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='parameter_assignments', full_name='api.v1.alpha2.TrialSpec.parameter_assignments', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='run_spec', full_name='api.v1.alpha2.TrialSpec.run_spec', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='metrics_collector_spec', full_name='api.v1.alpha2.TrialSpec.metrics_collector_spec', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[_TRIALSPEC_PARAMETERASSIGNMENTS, ], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2144, - serialized_end=2438, -) - - -_TRIALSTATUS = _descriptor.Descriptor( - name='TrialStatus', - full_name='api.v1.alpha2.TrialStatus', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='start_time', full_name='api.v1.alpha2.TrialStatus.start_time', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='completion_time', full_name='api.v1.alpha2.TrialStatus.completion_time', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='condition', full_name='api.v1.alpha2.TrialStatus.condition', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='observation', full_name='api.v1.alpha2.TrialStatus.observation', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _TRIALSTATUS_TRIALCONDITIONTYPE, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2441, - serialized_end=2714, -) - - -_TRIAL = _descriptor.Descriptor( - name='Trial', - full_name='api.v1.alpha2.Trial', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='api.v1.alpha2.Trial.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='spec', full_name='api.v1.alpha2.Trial.spec', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='status', full_name='api.v1.alpha2.Trial.status', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2716, - serialized_end=2821, -) - - -_REGISTEREXPERIMENTREQUEST = _descriptor.Descriptor( - name='RegisterExperimentRequest', - full_name='api.v1.alpha2.RegisterExperimentRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment', full_name='api.v1.alpha2.RegisterExperimentRequest.experiment', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2823, - serialized_end=2897, -) - - -_REGISTEREXPERIMENTREPLY = _descriptor.Descriptor( - name='RegisterExperimentReply', - full_name='api.v1.alpha2.RegisterExperimentReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2899, - serialized_end=2924, -) - - -_PRECHECKREGISTEREXPERIMENTREPLY = _descriptor.Descriptor( - name='PreCheckRegisterExperimentReply', - full_name='api.v1.alpha2.PreCheckRegisterExperimentReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='can_register', full_name='api.v1.alpha2.PreCheckRegisterExperimentReply.can_register', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2926, - serialized_end=2981, -) - - -_DELETEEXPERIMENTREQUEST = _descriptor.Descriptor( - name='DeleteExperimentRequest', - full_name='api.v1.alpha2.DeleteExperimentRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_name', full_name='api.v1.alpha2.DeleteExperimentRequest.experiment_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2983, - serialized_end=3033, -) - - -_DELETEEXPERIMENTREPLY = _descriptor.Descriptor( - name='DeleteExperimentReply', - full_name='api.v1.alpha2.DeleteExperimentReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3035, - serialized_end=3058, -) - - -_GETEXPERIMENTREQUEST = _descriptor.Descriptor( - name='GetExperimentRequest', - full_name='api.v1.alpha2.GetExperimentRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_name', full_name='api.v1.alpha2.GetExperimentRequest.experiment_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3060, - serialized_end=3107, -) - - -_GETEXPERIMENTREPLY = _descriptor.Descriptor( - name='GetExperimentReply', - full_name='api.v1.alpha2.GetExperimentReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment', full_name='api.v1.alpha2.GetExperimentReply.experiment', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3109, - serialized_end=3176, -) - - -_EXPERIMENTSUMMARY = _descriptor.Descriptor( - name='ExperimentSummary', - full_name='api.v1.alpha2.ExperimentSummary', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_name', full_name='api.v1.alpha2.ExperimentSummary.experiment_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='status', full_name='api.v1.alpha2.ExperimentSummary.status', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3178, - serialized_end=3271, -) - - -_GETEXPERIMENTLISTREQUEST = _descriptor.Descriptor( - name='GetExperimentListRequest', - full_name='api.v1.alpha2.GetExperimentListRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3273, - serialized_end=3299, -) - - -_GETEXPERIMENTLISTREPLY = _descriptor.Descriptor( - name='GetExperimentListReply', - full_name='api.v1.alpha2.GetExperimentListReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_summaries', full_name='api.v1.alpha2.GetExperimentListReply.experiment_summaries', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3301, - serialized_end=3389, -) - - -_UPDATEEXPERIMENTSTATUSREQUEST = _descriptor.Descriptor( - name='UpdateExperimentStatusRequest', - full_name='api.v1.alpha2.UpdateExperimentStatusRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_name', full_name='api.v1.alpha2.UpdateExperimentStatusRequest.experiment_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='new_status', full_name='api.v1.alpha2.UpdateExperimentStatusRequest.new_status', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3391, - serialized_end=3500, -) - - -_UPDATEEXPERIMENTSTATUSREPLY = _descriptor.Descriptor( - name='UpdateExperimentStatusReply', - full_name='api.v1.alpha2.UpdateExperimentStatusReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3502, - serialized_end=3531, -) - - -_UPDATEALGORITHMEXTRASETTINGSREQUEST = _descriptor.Descriptor( - name='UpdateAlgorithmExtraSettingsRequest', - full_name='api.v1.alpha2.UpdateAlgorithmExtraSettingsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_name', full_name='api.v1.alpha2.UpdateAlgorithmExtraSettingsRequest.experiment_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='extra_algorithm_settings', full_name='api.v1.alpha2.UpdateAlgorithmExtraSettingsRequest.extra_algorithm_settings', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3534, - serialized_end=3663, -) - - -_UPDATEALGORITHMEXTRASETTINGSREPLY = _descriptor.Descriptor( - name='UpdateAlgorithmExtraSettingsReply', - full_name='api.v1.alpha2.UpdateAlgorithmExtraSettingsReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3665, - serialized_end=3700, -) - - -_GETALGORITHMEXTRASETTINGSREQUEST = _descriptor.Descriptor( - name='GetAlgorithmExtraSettingsRequest', - full_name='api.v1.alpha2.GetAlgorithmExtraSettingsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_name', full_name='api.v1.alpha2.GetAlgorithmExtraSettingsRequest.experiment_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3702, - serialized_end=3761, -) - - -_GETALGORITHMEXTRASETTINGSREPLY = _descriptor.Descriptor( - name='GetAlgorithmExtraSettingsReply', - full_name='api.v1.alpha2.GetAlgorithmExtraSettingsReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='extra_algorithm_settings', full_name='api.v1.alpha2.GetAlgorithmExtraSettingsReply.extra_algorithm_settings', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3763, - serialized_end=3862, -) - - -_REGISTERTRIALREQUEST = _descriptor.Descriptor( - name='RegisterTrialRequest', - full_name='api.v1.alpha2.RegisterTrialRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='trial', full_name='api.v1.alpha2.RegisterTrialRequest.trial', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3864, - serialized_end=3923, -) - - -_REGISTERTRIALREPLY = _descriptor.Descriptor( - name='RegisterTrialReply', - full_name='api.v1.alpha2.RegisterTrialReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3925, - serialized_end=3945, -) - - -_DELETETRIALREQUEST = _descriptor.Descriptor( - name='DeleteTrialRequest', - full_name='api.v1.alpha2.DeleteTrialRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='trial_name', full_name='api.v1.alpha2.DeleteTrialRequest.trial_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3947, - serialized_end=3987, -) - - -_DELETETRIALREPLY = _descriptor.Descriptor( - name='DeleteTrialReply', - full_name='api.v1.alpha2.DeleteTrialReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3989, - serialized_end=4007, -) - - -_GETTRIALLISTREQUEST = _descriptor.Descriptor( - name='GetTrialListRequest', - full_name='api.v1.alpha2.GetTrialListRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_name', full_name='api.v1.alpha2.GetTrialListRequest.experiment_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='filter', full_name='api.v1.alpha2.GetTrialListRequest.filter', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4009, - serialized_end=4071, -) - - -_GETTRIALLISTREPLY = _descriptor.Descriptor( - name='GetTrialListReply', - full_name='api.v1.alpha2.GetTrialListReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='trials', full_name='api.v1.alpha2.GetTrialListReply.trials', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4073, - serialized_end=4130, -) - - -_GETTRIALREQUEST = _descriptor.Descriptor( - name='GetTrialRequest', - full_name='api.v1.alpha2.GetTrialRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='trial_name', full_name='api.v1.alpha2.GetTrialRequest.trial_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4132, - serialized_end=4169, -) - - -_GETTRIALREPLY = _descriptor.Descriptor( - name='GetTrialReply', - full_name='api.v1.alpha2.GetTrialReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='trial', full_name='api.v1.alpha2.GetTrialReply.trial', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4171, - serialized_end=4223, -) - - -_UPDATETRIALSTATUSREQUEST = _descriptor.Descriptor( - name='UpdateTrialStatusRequest', - full_name='api.v1.alpha2.UpdateTrialStatusRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='trial_name', full_name='api.v1.alpha2.UpdateTrialStatusRequest.trial_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='new_status', full_name='api.v1.alpha2.UpdateTrialStatusRequest.new_status', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4225, - serialized_end=4319, -) - - -_UPDATETRIALSTATUSREPLY = _descriptor.Descriptor( - name='UpdateTrialStatusReply', - full_name='api.v1.alpha2.UpdateTrialStatusReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4321, - serialized_end=4345, -) - - -_REPORTOBSERVATIONLOGREQUEST = _descriptor.Descriptor( - name='ReportObservationLogRequest', - full_name='api.v1.alpha2.ReportObservationLogRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='trial_name', full_name='api.v1.alpha2.ReportObservationLogRequest.trial_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='observation_log', full_name='api.v1.alpha2.ReportObservationLogRequest.observation_log', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4347, - serialized_end=4452, -) - - -_REPORTOBSERVATIONLOGREPLY = _descriptor.Descriptor( - name='ReportObservationLogReply', - full_name='api.v1.alpha2.ReportObservationLogReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4454, - serialized_end=4481, -) - - -_GETOBSERVATIONLOGREQUEST = _descriptor.Descriptor( - name='GetObservationLogRequest', - full_name='api.v1.alpha2.GetObservationLogRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='trial_name', full_name='api.v1.alpha2.GetObservationLogRequest.trial_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='metric_name', full_name='api.v1.alpha2.GetObservationLogRequest.metric_name', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='start_time', full_name='api.v1.alpha2.GetObservationLogRequest.start_time', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='end_time', full_name='api.v1.alpha2.GetObservationLogRequest.end_time', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4483, - serialized_end=4588, -) - - -_GETOBSERVATIONLOGREPLY = _descriptor.Descriptor( - name='GetObservationLogReply', - full_name='api.v1.alpha2.GetObservationLogReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='observation_log', full_name='api.v1.alpha2.GetObservationLogReply.observation_log', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4590, - serialized_end=4670, -) - - -_GETSUGGESTIONSREQUEST = _descriptor.Descriptor( - name='GetSuggestionsRequest', - full_name='api.v1.alpha2.GetSuggestionsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_name', full_name='api.v1.alpha2.GetSuggestionsRequest.experiment_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='algorithm_name', full_name='api.v1.alpha2.GetSuggestionsRequest.algorithm_name', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='request_number', full_name='api.v1.alpha2.GetSuggestionsRequest.request_number', index=2, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4672, - serialized_end=4768, -) - - -_GETSUGGESTIONSREPLY = _descriptor.Descriptor( - name='GetSuggestionsReply', - full_name='api.v1.alpha2.GetSuggestionsReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='trials', full_name='api.v1.alpha2.GetSuggestionsReply.trials', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4770, - serialized_end=4829, -) - - -_VALIDATEALGORITHMSETTINGSREQUEST = _descriptor.Descriptor( - name='ValidateAlgorithmSettingsRequest', - full_name='api.v1.alpha2.ValidateAlgorithmSettingsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='experiment_spec', full_name='api.v1.alpha2.ValidateAlgorithmSettingsRequest.experiment_spec', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='algorithm_name', full_name='api.v1.alpha2.ValidateAlgorithmSettingsRequest.algorithm_name', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4831, - serialized_end=4945, -) - - -_VALIDATEALGORITHMSETTINGSREPLY = _descriptor.Descriptor( - name='ValidateAlgorithmSettingsReply', - full_name='api.v1.alpha2.ValidateAlgorithmSettingsReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4947, - serialized_end=4979, -) - -_PARAMETERSPEC.fields_by_name['parameter_type'].enum_type = _PARAMETERTYPE -_PARAMETERSPEC.fields_by_name['feasible_space'].message_type = _FEASIBLESPACE -_OBJECTIVESPEC.fields_by_name['type'].enum_type = _OBJECTIVETYPE -_ALGORITHMSPEC.fields_by_name['algorithm_setting'].message_type = _ALGORITHMSETTING -_ALGORITHMSPEC.fields_by_name['early_stopping_spec'].message_type = _EARLYSTOPPINGSPEC -_NASCONFIG_OPERATIONS.fields_by_name['operation'].message_type = _OPERATION -_NASCONFIG_OPERATIONS.containing_type = _NASCONFIG -_NASCONFIG.fields_by_name['graph_config'].message_type = _GRAPHCONFIG -_NASCONFIG.fields_by_name['operations'].message_type = _NASCONFIG_OPERATIONS -_OPERATION_PARAMETERSPECS.fields_by_name['parameters'].message_type = _PARAMETERSPEC -_OPERATION_PARAMETERSPECS.containing_type = _OPERATION -_OPERATION.fields_by_name['parameter_specs'].message_type = _OPERATION_PARAMETERSPECS -_EXPERIMENTSPEC_PARAMETERSPECS.fields_by_name['parameters'].message_type = _PARAMETERSPEC -_EXPERIMENTSPEC_PARAMETERSPECS.containing_type = _EXPERIMENTSPEC -_EXPERIMENTSPEC.fields_by_name['parameter_specs'].message_type = _EXPERIMENTSPEC_PARAMETERSPECS -_EXPERIMENTSPEC.fields_by_name['objective'].message_type = _OBJECTIVESPEC -_EXPERIMENTSPEC.fields_by_name['algorithm'].message_type = _ALGORITHMSPEC -_EXPERIMENTSPEC.fields_by_name['nas_config'].message_type = _NASCONFIG -_EXPERIMENTSTATUS.fields_by_name['condition'].enum_type = _EXPERIMENTSTATUS_EXPERIMENTCONDITIONTYPE -_EXPERIMENTSTATUS_EXPERIMENTCONDITIONTYPE.containing_type = _EXPERIMENTSTATUS -_EXPERIMENT.fields_by_name['spec'].message_type = _EXPERIMENTSPEC -_EXPERIMENT.fields_by_name['status'].message_type = _EXPERIMENTSTATUS -_METRICLOG.fields_by_name['metric'].message_type = _METRIC -_OBSERVATION.fields_by_name['metrics'].message_type = _METRIC -_OBSERVATIONLOG.fields_by_name['metric_logs'].message_type = _METRICLOG -_TRIALSPEC_PARAMETERASSIGNMENTS.fields_by_name['assignments'].message_type = _PARAMETERASSIGNMENT -_TRIALSPEC_PARAMETERASSIGNMENTS.containing_type = _TRIALSPEC -_TRIALSPEC.fields_by_name['objective'].message_type = _OBJECTIVESPEC -_TRIALSPEC.fields_by_name['parameter_assignments'].message_type = _TRIALSPEC_PARAMETERASSIGNMENTS -_TRIALSTATUS.fields_by_name['condition'].enum_type = _TRIALSTATUS_TRIALCONDITIONTYPE -_TRIALSTATUS.fields_by_name['observation'].message_type = _OBSERVATION -_TRIALSTATUS_TRIALCONDITIONTYPE.containing_type = _TRIALSTATUS -_TRIAL.fields_by_name['spec'].message_type = _TRIALSPEC -_TRIAL.fields_by_name['status'].message_type = _TRIALSTATUS -_REGISTEREXPERIMENTREQUEST.fields_by_name['experiment'].message_type = _EXPERIMENT -_GETEXPERIMENTREPLY.fields_by_name['experiment'].message_type = _EXPERIMENT -_EXPERIMENTSUMMARY.fields_by_name['status'].message_type = _EXPERIMENTSTATUS -_GETEXPERIMENTLISTREPLY.fields_by_name['experiment_summaries'].message_type = _EXPERIMENTSUMMARY -_UPDATEEXPERIMENTSTATUSREQUEST.fields_by_name['new_status'].message_type = _EXPERIMENTSTATUS -_UPDATEALGORITHMEXTRASETTINGSREQUEST.fields_by_name['extra_algorithm_settings'].message_type = _ALGORITHMSETTING -_GETALGORITHMEXTRASETTINGSREPLY.fields_by_name['extra_algorithm_settings'].message_type = _ALGORITHMSETTING -_REGISTERTRIALREQUEST.fields_by_name['trial'].message_type = _TRIAL -_GETTRIALLISTREPLY.fields_by_name['trials'].message_type = _TRIAL -_GETTRIALREPLY.fields_by_name['trial'].message_type = _TRIAL -_UPDATETRIALSTATUSREQUEST.fields_by_name['new_status'].message_type = _TRIALSTATUS -_REPORTOBSERVATIONLOGREQUEST.fields_by_name['observation_log'].message_type = _OBSERVATIONLOG -_GETOBSERVATIONLOGREPLY.fields_by_name['observation_log'].message_type = _OBSERVATIONLOG -_GETSUGGESTIONSREPLY.fields_by_name['trials'].message_type = _TRIAL -_VALIDATEALGORITHMSETTINGSREQUEST.fields_by_name['experiment_spec'].message_type = _EXPERIMENTSPEC -DESCRIPTOR.message_types_by_name['FeasibleSpace'] = _FEASIBLESPACE -DESCRIPTOR.message_types_by_name['ParameterSpec'] = _PARAMETERSPEC -DESCRIPTOR.message_types_by_name['ObjectiveSpec'] = _OBJECTIVESPEC -DESCRIPTOR.message_types_by_name['AlgorithmSetting'] = _ALGORITHMSETTING -DESCRIPTOR.message_types_by_name['EarlyStoppingSpec'] = _EARLYSTOPPINGSPEC -DESCRIPTOR.message_types_by_name['AlgorithmSpec'] = _ALGORITHMSPEC -DESCRIPTOR.message_types_by_name['NasConfig'] = _NASCONFIG -DESCRIPTOR.message_types_by_name['GraphConfig'] = _GRAPHCONFIG -DESCRIPTOR.message_types_by_name['Operation'] = _OPERATION -DESCRIPTOR.message_types_by_name['ExperimentSpec'] = _EXPERIMENTSPEC -DESCRIPTOR.message_types_by_name['ExperimentStatus'] = _EXPERIMENTSTATUS -DESCRIPTOR.message_types_by_name['Experiment'] = _EXPERIMENT -DESCRIPTOR.message_types_by_name['ParameterAssignment'] = _PARAMETERASSIGNMENT -DESCRIPTOR.message_types_by_name['Metric'] = _METRIC -DESCRIPTOR.message_types_by_name['MetricLog'] = _METRICLOG -DESCRIPTOR.message_types_by_name['Observation'] = _OBSERVATION -DESCRIPTOR.message_types_by_name['ObservationLog'] = _OBSERVATIONLOG -DESCRIPTOR.message_types_by_name['TrialSpec'] = _TRIALSPEC -DESCRIPTOR.message_types_by_name['TrialStatus'] = _TRIALSTATUS -DESCRIPTOR.message_types_by_name['Trial'] = _TRIAL -DESCRIPTOR.message_types_by_name['RegisterExperimentRequest'] = _REGISTEREXPERIMENTREQUEST -DESCRIPTOR.message_types_by_name['RegisterExperimentReply'] = _REGISTEREXPERIMENTREPLY -DESCRIPTOR.message_types_by_name['PreCheckRegisterExperimentReply'] = _PRECHECKREGISTEREXPERIMENTREPLY -DESCRIPTOR.message_types_by_name['DeleteExperimentRequest'] = _DELETEEXPERIMENTREQUEST -DESCRIPTOR.message_types_by_name['DeleteExperimentReply'] = _DELETEEXPERIMENTREPLY -DESCRIPTOR.message_types_by_name['GetExperimentRequest'] = _GETEXPERIMENTREQUEST -DESCRIPTOR.message_types_by_name['GetExperimentReply'] = _GETEXPERIMENTREPLY -DESCRIPTOR.message_types_by_name['ExperimentSummary'] = _EXPERIMENTSUMMARY -DESCRIPTOR.message_types_by_name['GetExperimentListRequest'] = _GETEXPERIMENTLISTREQUEST -DESCRIPTOR.message_types_by_name['GetExperimentListReply'] = _GETEXPERIMENTLISTREPLY -DESCRIPTOR.message_types_by_name['UpdateExperimentStatusRequest'] = _UPDATEEXPERIMENTSTATUSREQUEST -DESCRIPTOR.message_types_by_name['UpdateExperimentStatusReply'] = _UPDATEEXPERIMENTSTATUSREPLY -DESCRIPTOR.message_types_by_name['UpdateAlgorithmExtraSettingsRequest'] = _UPDATEALGORITHMEXTRASETTINGSREQUEST -DESCRIPTOR.message_types_by_name['UpdateAlgorithmExtraSettingsReply'] = _UPDATEALGORITHMEXTRASETTINGSREPLY -DESCRIPTOR.message_types_by_name['GetAlgorithmExtraSettingsRequest'] = _GETALGORITHMEXTRASETTINGSREQUEST -DESCRIPTOR.message_types_by_name['GetAlgorithmExtraSettingsReply'] = _GETALGORITHMEXTRASETTINGSREPLY -DESCRIPTOR.message_types_by_name['RegisterTrialRequest'] = _REGISTERTRIALREQUEST -DESCRIPTOR.message_types_by_name['RegisterTrialReply'] = _REGISTERTRIALREPLY -DESCRIPTOR.message_types_by_name['DeleteTrialRequest'] = _DELETETRIALREQUEST -DESCRIPTOR.message_types_by_name['DeleteTrialReply'] = _DELETETRIALREPLY -DESCRIPTOR.message_types_by_name['GetTrialListRequest'] = _GETTRIALLISTREQUEST -DESCRIPTOR.message_types_by_name['GetTrialListReply'] = _GETTRIALLISTREPLY -DESCRIPTOR.message_types_by_name['GetTrialRequest'] = _GETTRIALREQUEST -DESCRIPTOR.message_types_by_name['GetTrialReply'] = _GETTRIALREPLY -DESCRIPTOR.message_types_by_name['UpdateTrialStatusRequest'] = _UPDATETRIALSTATUSREQUEST -DESCRIPTOR.message_types_by_name['UpdateTrialStatusReply'] = _UPDATETRIALSTATUSREPLY -DESCRIPTOR.message_types_by_name['ReportObservationLogRequest'] = _REPORTOBSERVATIONLOGREQUEST -DESCRIPTOR.message_types_by_name['ReportObservationLogReply'] = _REPORTOBSERVATIONLOGREPLY -DESCRIPTOR.message_types_by_name['GetObservationLogRequest'] = _GETOBSERVATIONLOGREQUEST -DESCRIPTOR.message_types_by_name['GetObservationLogReply'] = _GETOBSERVATIONLOGREPLY -DESCRIPTOR.message_types_by_name['GetSuggestionsRequest'] = _GETSUGGESTIONSREQUEST -DESCRIPTOR.message_types_by_name['GetSuggestionsReply'] = _GETSUGGESTIONSREPLY -DESCRIPTOR.message_types_by_name['ValidateAlgorithmSettingsRequest'] = _VALIDATEALGORITHMSETTINGSREQUEST -DESCRIPTOR.message_types_by_name['ValidateAlgorithmSettingsReply'] = _VALIDATEALGORITHMSETTINGSREPLY -DESCRIPTOR.enum_types_by_name['ParameterType'] = _PARAMETERTYPE -DESCRIPTOR.enum_types_by_name['ObjectiveType'] = _OBJECTIVETYPE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -FeasibleSpace = _reflection.GeneratedProtocolMessageType('FeasibleSpace', (_message.Message,), dict( - DESCRIPTOR = _FEASIBLESPACE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.FeasibleSpace) - )) -_sym_db.RegisterMessage(FeasibleSpace) - -ParameterSpec = _reflection.GeneratedProtocolMessageType('ParameterSpec', (_message.Message,), dict( - DESCRIPTOR = _PARAMETERSPEC, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ParameterSpec) - )) -_sym_db.RegisterMessage(ParameterSpec) - -ObjectiveSpec = _reflection.GeneratedProtocolMessageType('ObjectiveSpec', (_message.Message,), dict( - DESCRIPTOR = _OBJECTIVESPEC, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ObjectiveSpec) - )) -_sym_db.RegisterMessage(ObjectiveSpec) - -AlgorithmSetting = _reflection.GeneratedProtocolMessageType('AlgorithmSetting', (_message.Message,), dict( - DESCRIPTOR = _ALGORITHMSETTING, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.AlgorithmSetting) - )) -_sym_db.RegisterMessage(AlgorithmSetting) - -EarlyStoppingSpec = _reflection.GeneratedProtocolMessageType('EarlyStoppingSpec', (_message.Message,), dict( - DESCRIPTOR = _EARLYSTOPPINGSPEC, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.EarlyStoppingSpec) - )) -_sym_db.RegisterMessage(EarlyStoppingSpec) - -AlgorithmSpec = _reflection.GeneratedProtocolMessageType('AlgorithmSpec', (_message.Message,), dict( - DESCRIPTOR = _ALGORITHMSPEC, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.AlgorithmSpec) - )) -_sym_db.RegisterMessage(AlgorithmSpec) - -NasConfig = _reflection.GeneratedProtocolMessageType('NasConfig', (_message.Message,), dict( - - Operations = _reflection.GeneratedProtocolMessageType('Operations', (_message.Message,), dict( - DESCRIPTOR = _NASCONFIG_OPERATIONS, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.NasConfig.Operations) - )) - , - DESCRIPTOR = _NASCONFIG, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.NasConfig) - )) -_sym_db.RegisterMessage(NasConfig) -_sym_db.RegisterMessage(NasConfig.Operations) - -GraphConfig = _reflection.GeneratedProtocolMessageType('GraphConfig', (_message.Message,), dict( - DESCRIPTOR = _GRAPHCONFIG, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GraphConfig) - )) -_sym_db.RegisterMessage(GraphConfig) - -Operation = _reflection.GeneratedProtocolMessageType('Operation', (_message.Message,), dict( - - ParameterSpecs = _reflection.GeneratedProtocolMessageType('ParameterSpecs', (_message.Message,), dict( - DESCRIPTOR = _OPERATION_PARAMETERSPECS, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.Operation.ParameterSpecs) - )) - , - DESCRIPTOR = _OPERATION, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.Operation) - )) -_sym_db.RegisterMessage(Operation) -_sym_db.RegisterMessage(Operation.ParameterSpecs) - -ExperimentSpec = _reflection.GeneratedProtocolMessageType('ExperimentSpec', (_message.Message,), dict( - - ParameterSpecs = _reflection.GeneratedProtocolMessageType('ParameterSpecs', (_message.Message,), dict( - DESCRIPTOR = _EXPERIMENTSPEC_PARAMETERSPECS, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ExperimentSpec.ParameterSpecs) - )) - , - DESCRIPTOR = _EXPERIMENTSPEC, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ExperimentSpec) - )) -_sym_db.RegisterMessage(ExperimentSpec) -_sym_db.RegisterMessage(ExperimentSpec.ParameterSpecs) - -ExperimentStatus = _reflection.GeneratedProtocolMessageType('ExperimentStatus', (_message.Message,), dict( - DESCRIPTOR = _EXPERIMENTSTATUS, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ExperimentStatus) - )) -_sym_db.RegisterMessage(ExperimentStatus) - -Experiment = _reflection.GeneratedProtocolMessageType('Experiment', (_message.Message,), dict( - DESCRIPTOR = _EXPERIMENT, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.Experiment) - )) -_sym_db.RegisterMessage(Experiment) - -ParameterAssignment = _reflection.GeneratedProtocolMessageType('ParameterAssignment', (_message.Message,), dict( - DESCRIPTOR = _PARAMETERASSIGNMENT, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ParameterAssignment) - )) -_sym_db.RegisterMessage(ParameterAssignment) - -Metric = _reflection.GeneratedProtocolMessageType('Metric', (_message.Message,), dict( - DESCRIPTOR = _METRIC, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.Metric) - )) -_sym_db.RegisterMessage(Metric) - -MetricLog = _reflection.GeneratedProtocolMessageType('MetricLog', (_message.Message,), dict( - DESCRIPTOR = _METRICLOG, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.MetricLog) - )) -_sym_db.RegisterMessage(MetricLog) - -Observation = _reflection.GeneratedProtocolMessageType('Observation', (_message.Message,), dict( - DESCRIPTOR = _OBSERVATION, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.Observation) - )) -_sym_db.RegisterMessage(Observation) - -ObservationLog = _reflection.GeneratedProtocolMessageType('ObservationLog', (_message.Message,), dict( - DESCRIPTOR = _OBSERVATIONLOG, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ObservationLog) - )) -_sym_db.RegisterMessage(ObservationLog) - -TrialSpec = _reflection.GeneratedProtocolMessageType('TrialSpec', (_message.Message,), dict( - - ParameterAssignments = _reflection.GeneratedProtocolMessageType('ParameterAssignments', (_message.Message,), dict( - DESCRIPTOR = _TRIALSPEC_PARAMETERASSIGNMENTS, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.TrialSpec.ParameterAssignments) - )) - , - DESCRIPTOR = _TRIALSPEC, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.TrialSpec) - )) -_sym_db.RegisterMessage(TrialSpec) -_sym_db.RegisterMessage(TrialSpec.ParameterAssignments) - -TrialStatus = _reflection.GeneratedProtocolMessageType('TrialStatus', (_message.Message,), dict( - DESCRIPTOR = _TRIALSTATUS, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.TrialStatus) - )) -_sym_db.RegisterMessage(TrialStatus) - -Trial = _reflection.GeneratedProtocolMessageType('Trial', (_message.Message,), dict( - DESCRIPTOR = _TRIAL, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.Trial) - )) -_sym_db.RegisterMessage(Trial) - -RegisterExperimentRequest = _reflection.GeneratedProtocolMessageType('RegisterExperimentRequest', (_message.Message,), dict( - DESCRIPTOR = _REGISTEREXPERIMENTREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.RegisterExperimentRequest) - )) -_sym_db.RegisterMessage(RegisterExperimentRequest) - -RegisterExperimentReply = _reflection.GeneratedProtocolMessageType('RegisterExperimentReply', (_message.Message,), dict( - DESCRIPTOR = _REGISTEREXPERIMENTREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.RegisterExperimentReply) - )) -_sym_db.RegisterMessage(RegisterExperimentReply) - -PreCheckRegisterExperimentReply = _reflection.GeneratedProtocolMessageType('PreCheckRegisterExperimentReply', (_message.Message,), dict( - DESCRIPTOR = _PRECHECKREGISTEREXPERIMENTREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.PreCheckRegisterExperimentReply) - )) -_sym_db.RegisterMessage(PreCheckRegisterExperimentReply) - -DeleteExperimentRequest = _reflection.GeneratedProtocolMessageType('DeleteExperimentRequest', (_message.Message,), dict( - DESCRIPTOR = _DELETEEXPERIMENTREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.DeleteExperimentRequest) - )) -_sym_db.RegisterMessage(DeleteExperimentRequest) - -DeleteExperimentReply = _reflection.GeneratedProtocolMessageType('DeleteExperimentReply', (_message.Message,), dict( - DESCRIPTOR = _DELETEEXPERIMENTREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.DeleteExperimentReply) - )) -_sym_db.RegisterMessage(DeleteExperimentReply) - -GetExperimentRequest = _reflection.GeneratedProtocolMessageType('GetExperimentRequest', (_message.Message,), dict( - DESCRIPTOR = _GETEXPERIMENTREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetExperimentRequest) - )) -_sym_db.RegisterMessage(GetExperimentRequest) - -GetExperimentReply = _reflection.GeneratedProtocolMessageType('GetExperimentReply', (_message.Message,), dict( - DESCRIPTOR = _GETEXPERIMENTREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetExperimentReply) - )) -_sym_db.RegisterMessage(GetExperimentReply) - -ExperimentSummary = _reflection.GeneratedProtocolMessageType('ExperimentSummary', (_message.Message,), dict( - DESCRIPTOR = _EXPERIMENTSUMMARY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ExperimentSummary) - )) -_sym_db.RegisterMessage(ExperimentSummary) - -GetExperimentListRequest = _reflection.GeneratedProtocolMessageType('GetExperimentListRequest', (_message.Message,), dict( - DESCRIPTOR = _GETEXPERIMENTLISTREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetExperimentListRequest) - )) -_sym_db.RegisterMessage(GetExperimentListRequest) - -GetExperimentListReply = _reflection.GeneratedProtocolMessageType('GetExperimentListReply', (_message.Message,), dict( - DESCRIPTOR = _GETEXPERIMENTLISTREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetExperimentListReply) - )) -_sym_db.RegisterMessage(GetExperimentListReply) - -UpdateExperimentStatusRequest = _reflection.GeneratedProtocolMessageType('UpdateExperimentStatusRequest', (_message.Message,), dict( - DESCRIPTOR = _UPDATEEXPERIMENTSTATUSREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.UpdateExperimentStatusRequest) - )) -_sym_db.RegisterMessage(UpdateExperimentStatusRequest) - -UpdateExperimentStatusReply = _reflection.GeneratedProtocolMessageType('UpdateExperimentStatusReply', (_message.Message,), dict( - DESCRIPTOR = _UPDATEEXPERIMENTSTATUSREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.UpdateExperimentStatusReply) - )) -_sym_db.RegisterMessage(UpdateExperimentStatusReply) - -UpdateAlgorithmExtraSettingsRequest = _reflection.GeneratedProtocolMessageType('UpdateAlgorithmExtraSettingsRequest', (_message.Message,), dict( - DESCRIPTOR = _UPDATEALGORITHMEXTRASETTINGSREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.UpdateAlgorithmExtraSettingsRequest) - )) -_sym_db.RegisterMessage(UpdateAlgorithmExtraSettingsRequest) - -UpdateAlgorithmExtraSettingsReply = _reflection.GeneratedProtocolMessageType('UpdateAlgorithmExtraSettingsReply', (_message.Message,), dict( - DESCRIPTOR = _UPDATEALGORITHMEXTRASETTINGSREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.UpdateAlgorithmExtraSettingsReply) - )) -_sym_db.RegisterMessage(UpdateAlgorithmExtraSettingsReply) - -GetAlgorithmExtraSettingsRequest = _reflection.GeneratedProtocolMessageType('GetAlgorithmExtraSettingsRequest', (_message.Message,), dict( - DESCRIPTOR = _GETALGORITHMEXTRASETTINGSREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetAlgorithmExtraSettingsRequest) - )) -_sym_db.RegisterMessage(GetAlgorithmExtraSettingsRequest) - -GetAlgorithmExtraSettingsReply = _reflection.GeneratedProtocolMessageType('GetAlgorithmExtraSettingsReply', (_message.Message,), dict( - DESCRIPTOR = _GETALGORITHMEXTRASETTINGSREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetAlgorithmExtraSettingsReply) - )) -_sym_db.RegisterMessage(GetAlgorithmExtraSettingsReply) - -RegisterTrialRequest = _reflection.GeneratedProtocolMessageType('RegisterTrialRequest', (_message.Message,), dict( - DESCRIPTOR = _REGISTERTRIALREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.RegisterTrialRequest) - )) -_sym_db.RegisterMessage(RegisterTrialRequest) - -RegisterTrialReply = _reflection.GeneratedProtocolMessageType('RegisterTrialReply', (_message.Message,), dict( - DESCRIPTOR = _REGISTERTRIALREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.RegisterTrialReply) - )) -_sym_db.RegisterMessage(RegisterTrialReply) - -DeleteTrialRequest = _reflection.GeneratedProtocolMessageType('DeleteTrialRequest', (_message.Message,), dict( - DESCRIPTOR = _DELETETRIALREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.DeleteTrialRequest) - )) -_sym_db.RegisterMessage(DeleteTrialRequest) - -DeleteTrialReply = _reflection.GeneratedProtocolMessageType('DeleteTrialReply', (_message.Message,), dict( - DESCRIPTOR = _DELETETRIALREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.DeleteTrialReply) - )) -_sym_db.RegisterMessage(DeleteTrialReply) - -GetTrialListRequest = _reflection.GeneratedProtocolMessageType('GetTrialListRequest', (_message.Message,), dict( - DESCRIPTOR = _GETTRIALLISTREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetTrialListRequest) - )) -_sym_db.RegisterMessage(GetTrialListRequest) - -GetTrialListReply = _reflection.GeneratedProtocolMessageType('GetTrialListReply', (_message.Message,), dict( - DESCRIPTOR = _GETTRIALLISTREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetTrialListReply) - )) -_sym_db.RegisterMessage(GetTrialListReply) - -GetTrialRequest = _reflection.GeneratedProtocolMessageType('GetTrialRequest', (_message.Message,), dict( - DESCRIPTOR = _GETTRIALREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetTrialRequest) - )) -_sym_db.RegisterMessage(GetTrialRequest) - -GetTrialReply = _reflection.GeneratedProtocolMessageType('GetTrialReply', (_message.Message,), dict( - DESCRIPTOR = _GETTRIALREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetTrialReply) - )) -_sym_db.RegisterMessage(GetTrialReply) - -UpdateTrialStatusRequest = _reflection.GeneratedProtocolMessageType('UpdateTrialStatusRequest', (_message.Message,), dict( - DESCRIPTOR = _UPDATETRIALSTATUSREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.UpdateTrialStatusRequest) - )) -_sym_db.RegisterMessage(UpdateTrialStatusRequest) - -UpdateTrialStatusReply = _reflection.GeneratedProtocolMessageType('UpdateTrialStatusReply', (_message.Message,), dict( - DESCRIPTOR = _UPDATETRIALSTATUSREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.UpdateTrialStatusReply) - )) -_sym_db.RegisterMessage(UpdateTrialStatusReply) - -ReportObservationLogRequest = _reflection.GeneratedProtocolMessageType('ReportObservationLogRequest', (_message.Message,), dict( - DESCRIPTOR = _REPORTOBSERVATIONLOGREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ReportObservationLogRequest) - )) -_sym_db.RegisterMessage(ReportObservationLogRequest) - -ReportObservationLogReply = _reflection.GeneratedProtocolMessageType('ReportObservationLogReply', (_message.Message,), dict( - DESCRIPTOR = _REPORTOBSERVATIONLOGREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ReportObservationLogReply) - )) -_sym_db.RegisterMessage(ReportObservationLogReply) - -GetObservationLogRequest = _reflection.GeneratedProtocolMessageType('GetObservationLogRequest', (_message.Message,), dict( - DESCRIPTOR = _GETOBSERVATIONLOGREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetObservationLogRequest) - )) -_sym_db.RegisterMessage(GetObservationLogRequest) - -GetObservationLogReply = _reflection.GeneratedProtocolMessageType('GetObservationLogReply', (_message.Message,), dict( - DESCRIPTOR = _GETOBSERVATIONLOGREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetObservationLogReply) - )) -_sym_db.RegisterMessage(GetObservationLogReply) - -GetSuggestionsRequest = _reflection.GeneratedProtocolMessageType('GetSuggestionsRequest', (_message.Message,), dict( - DESCRIPTOR = _GETSUGGESTIONSREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetSuggestionsRequest) - )) -_sym_db.RegisterMessage(GetSuggestionsRequest) - -GetSuggestionsReply = _reflection.GeneratedProtocolMessageType('GetSuggestionsReply', (_message.Message,), dict( - DESCRIPTOR = _GETSUGGESTIONSREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.GetSuggestionsReply) - )) -_sym_db.RegisterMessage(GetSuggestionsReply) - -ValidateAlgorithmSettingsRequest = _reflection.GeneratedProtocolMessageType('ValidateAlgorithmSettingsRequest', (_message.Message,), dict( - DESCRIPTOR = _VALIDATEALGORITHMSETTINGSREQUEST, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ValidateAlgorithmSettingsRequest) - )) -_sym_db.RegisterMessage(ValidateAlgorithmSettingsRequest) - -ValidateAlgorithmSettingsReply = _reflection.GeneratedProtocolMessageType('ValidateAlgorithmSettingsReply', (_message.Message,), dict( - DESCRIPTOR = _VALIDATEALGORITHMSETTINGSREPLY, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:api.v1.alpha2.ValidateAlgorithmSettingsReply) - )) -_sym_db.RegisterMessage(ValidateAlgorithmSettingsReply) - - - -_MANAGER = _descriptor.ServiceDescriptor( - name='Manager', - full_name='api.v1.alpha2.Manager', - file=DESCRIPTOR, - index=0, - options=None, - serialized_start=5127, - serialized_end=7779, - methods=[ - _descriptor.MethodDescriptor( - name='RegisterExperiment', - full_name='api.v1.alpha2.Manager.RegisterExperiment', - index=0, - containing_service=None, - input_type=_REGISTEREXPERIMENTREQUEST, - output_type=_REGISTEREXPERIMENTREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002-\"\037/api/Manager/RegisterExperiment:\nexperiment')), - ), - _descriptor.MethodDescriptor( - name='PreCheckRegisterExperiment', - full_name='api.v1.alpha2.Manager.PreCheckRegisterExperiment', - index=1, - containing_service=None, - input_type=_REGISTEREXPERIMENTREQUEST, - output_type=_PRECHECKREGISTEREXPERIMENTREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\0025\"\'/api/Manager/PreCheckRegisterExperiment:\nexperiment')), - ), - _descriptor.MethodDescriptor( - name='DeleteExperiment', - full_name='api.v1.alpha2.Manager.DeleteExperiment', - index=2, - containing_service=None, - input_type=_DELETEEXPERIMENTREQUEST, - output_type=_DELETEEXPERIMENTREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\0021\022//api/Manager/DeleteExperiment/{experiment_name}')), - ), - _descriptor.MethodDescriptor( - name='GetExperiment', - full_name='api.v1.alpha2.Manager.GetExperiment', - index=3, - containing_service=None, - input_type=_GETEXPERIMENTREQUEST, - output_type=_GETEXPERIMENTREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002.\022,/api/Manager/GetExperiment/{experiment_name}')), - ), - _descriptor.MethodDescriptor( - name='GetExperimentList', - full_name='api.v1.alpha2.Manager.GetExperimentList', - index=4, - containing_service=None, - input_type=_GETEXPERIMENTLISTREQUEST, - output_type=_GETEXPERIMENTLISTREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002 \022\036/api/Manager/GetExperimentList')), - ), - _descriptor.MethodDescriptor( - name='UpdateExperimentStatus', - full_name='api.v1.alpha2.Manager.UpdateExperimentStatus', - index=5, - containing_service=None, - input_type=_UPDATEEXPERIMENTSTATUSREQUEST, - output_type=_UPDATEEXPERIMENTSTATUSREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002:\0325/api/Manager/UpdateExperimentStatus/{experiment_name}:\001*')), - ), - _descriptor.MethodDescriptor( - name='UpdateAlgorithmExtraSettings', - full_name='api.v1.alpha2.Manager.UpdateAlgorithmExtraSettings', - index=6, - containing_service=None, - input_type=_UPDATEALGORITHMEXTRASETTINGSREQUEST, - output_type=_UPDATEALGORITHMEXTRASETTINGSREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002@\032;/api/Manager/UpdateAlgorithmExtraSettings/{experiment_name}:\001*')), - ), - _descriptor.MethodDescriptor( - name='GetAlgorithmExtraSettings', - full_name='api.v1.alpha2.Manager.GetAlgorithmExtraSettings', - index=7, - containing_service=None, - input_type=_GETALGORITHMEXTRASETTINGSREQUEST, - output_type=_GETALGORITHMEXTRASETTINGSREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002:\0228/api/Manager/GetAlgorithmExtraSettings/{experiment_name}')), - ), - _descriptor.MethodDescriptor( - name='RegisterTrial', - full_name='api.v1.alpha2.Manager.RegisterTrial', - index=8, - containing_service=None, - input_type=_REGISTERTRIALREQUEST, - output_type=_REGISTERTRIALREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002#\"\032/api/Manager/RegisterTrial:\005trial')), - ), - _descriptor.MethodDescriptor( - name='DeleteTrial', - full_name='api.v1.alpha2.Manager.DeleteTrial', - index=9, - containing_service=None, - input_type=_DELETETRIALREQUEST, - output_type=_DELETETRIALREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\'\022%/api/Manager/DeleteTrial/{trial_name}')), - ), - _descriptor.MethodDescriptor( - name='GetTrialList', - full_name='api.v1.alpha2.Manager.GetTrialList', - index=10, - containing_service=None, - input_type=_GETTRIALLISTREQUEST, - output_type=_GETTRIALLISTREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002-\022+/api/Manager/GetTrialList/{experiment_name}')), - ), - _descriptor.MethodDescriptor( - name='GetTrial', - full_name='api.v1.alpha2.Manager.GetTrial', - index=11, - containing_service=None, - input_type=_GETTRIALREQUEST, - output_type=_GETTRIALREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002$\022\"/api/Manager/GetTrial/{trial_name}')), - ), - _descriptor.MethodDescriptor( - name='UpdateTrialStatus', - full_name='api.v1.alpha2.Manager.UpdateTrialStatus', - index=12, - containing_service=None, - input_type=_UPDATETRIALSTATUSREQUEST, - output_type=_UPDATETRIALSTATUSREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002#\032\036/api/Manager/UpdateTrialStatus:\001*')), - ), - _descriptor.MethodDescriptor( - name='ReportObservationLog', - full_name='api.v1.alpha2.Manager.ReportObservationLog', - index=13, - containing_service=None, - input_type=_REPORTOBSERVATIONLOGREQUEST, - output_type=_REPORTOBSERVATIONLOGREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002&\"!/api/Manager/ReportObservationLog:\001*')), - ), - _descriptor.MethodDescriptor( - name='GetObservationLog', - full_name='api.v1.alpha2.Manager.GetObservationLog', - index=14, - containing_service=None, - input_type=_GETOBSERVATIONLOGREQUEST, - output_type=_GETOBSERVATIONLOGREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002#\"\036/api/Manager/GetObservationLog:\001*')), - ), - _descriptor.MethodDescriptor( - name='GetSuggestions', - full_name='api.v1.alpha2.Manager.GetSuggestions', - index=15, - containing_service=None, - input_type=_GETSUGGESTIONSREQUEST, - output_type=_GETSUGGESTIONSREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002 \"\033/api/Manager/GetSuggestions:\001*')), - ), - _descriptor.MethodDescriptor( - name='ValidateAlgorithmSettings', - full_name='api.v1.alpha2.Manager.ValidateAlgorithmSettings', - index=16, - containing_service=None, - input_type=_VALIDATEALGORITHMSETTINGSREQUEST, - output_type=_VALIDATEALGORITHMSETTINGSREPLY, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002+\"&/api/Manager/ValidateAlgorithmSettings:\001*')), - ), -]) -_sym_db.RegisterServiceDescriptor(_MANAGER) - -DESCRIPTOR.services_by_name['Manager'] = _MANAGER - - -_SUGGESTION = _descriptor.ServiceDescriptor( - name='Suggestion', - full_name='api.v1.alpha2.Suggestion', - file=DESCRIPTOR, - index=1, - options=None, - serialized_start=7782, - serialized_end=8011, - methods=[ - _descriptor.MethodDescriptor( - name='GetSuggestions', - full_name='api.v1.alpha2.Suggestion.GetSuggestions', - index=0, - containing_service=None, - input_type=_GETSUGGESTIONSREQUEST, - output_type=_GETSUGGESTIONSREPLY, - options=None, - ), - _descriptor.MethodDescriptor( - name='ValidateAlgorithmSettings', - full_name='api.v1.alpha2.Suggestion.ValidateAlgorithmSettings', - index=1, - containing_service=None, - input_type=_VALIDATEALGORITHMSETTINGSREQUEST, - output_type=_VALIDATEALGORITHMSETTINGSREPLY, - options=None, - ), -]) -_sym_db.RegisterServiceDescriptor(_SUGGESTION) - -DESCRIPTOR.services_by_name['Suggestion'] = _SUGGESTION - - -_EARLYSTOPPING = _descriptor.ServiceDescriptor( - name='EarlyStopping', - full_name='api.v1.alpha2.EarlyStopping', - file=DESCRIPTOR, - index=2, - options=None, - serialized_start=8013, - serialized_end=8028, - methods=[ -]) -_sym_db.RegisterServiceDescriptor(_EARLYSTOPPING) - -DESCRIPTOR.services_by_name['EarlyStopping'] = _EARLYSTOPPING - -try: - # THESE ELEMENTS WILL BE DEPRECATED. - # Please use the generated *_pb2_grpc.py files instead. - import grpc - from grpc.beta import implementations as beta_implementations - from grpc.beta import interfaces as beta_interfaces - from grpc.framework.common import cardinality - from grpc.framework.interfaces.face import utilities as face_utilities - - - class ManagerStub(object): - """* - Service for Main API for Katib - For each RPC service, we define mapping to HTTP REST API method. - The mapping includes the URL path, query parameters and request body. - https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.RegisterExperiment = channel.unary_unary( - '/api.v1.alpha2.Manager/RegisterExperiment', - request_serializer=RegisterExperimentRequest.SerializeToString, - response_deserializer=RegisterExperimentReply.FromString, - ) - self.PreCheckRegisterExperiment = channel.unary_unary( - '/api.v1.alpha2.Manager/PreCheckRegisterExperiment', - request_serializer=RegisterExperimentRequest.SerializeToString, - response_deserializer=PreCheckRegisterExperimentReply.FromString, - ) - self.DeleteExperiment = channel.unary_unary( - '/api.v1.alpha2.Manager/DeleteExperiment', - request_serializer=DeleteExperimentRequest.SerializeToString, - response_deserializer=DeleteExperimentReply.FromString, - ) - self.GetExperiment = channel.unary_unary( - '/api.v1.alpha2.Manager/GetExperiment', - request_serializer=GetExperimentRequest.SerializeToString, - response_deserializer=GetExperimentReply.FromString, - ) - self.GetExperimentList = channel.unary_unary( - '/api.v1.alpha2.Manager/GetExperimentList', - request_serializer=GetExperimentListRequest.SerializeToString, - response_deserializer=GetExperimentListReply.FromString, - ) - self.UpdateExperimentStatus = channel.unary_unary( - '/api.v1.alpha2.Manager/UpdateExperimentStatus', - request_serializer=UpdateExperimentStatusRequest.SerializeToString, - response_deserializer=UpdateExperimentStatusReply.FromString, - ) - self.UpdateAlgorithmExtraSettings = channel.unary_unary( - '/api.v1.alpha2.Manager/UpdateAlgorithmExtraSettings', - request_serializer=UpdateAlgorithmExtraSettingsRequest.SerializeToString, - response_deserializer=UpdateAlgorithmExtraSettingsReply.FromString, - ) - self.GetAlgorithmExtraSettings = channel.unary_unary( - '/api.v1.alpha2.Manager/GetAlgorithmExtraSettings', - request_serializer=GetAlgorithmExtraSettingsRequest.SerializeToString, - response_deserializer=GetAlgorithmExtraSettingsReply.FromString, - ) - self.RegisterTrial = channel.unary_unary( - '/api.v1.alpha2.Manager/RegisterTrial', - request_serializer=RegisterTrialRequest.SerializeToString, - response_deserializer=RegisterTrialReply.FromString, - ) - self.DeleteTrial = channel.unary_unary( - '/api.v1.alpha2.Manager/DeleteTrial', - request_serializer=DeleteTrialRequest.SerializeToString, - response_deserializer=DeleteTrialReply.FromString, - ) - self.GetTrialList = channel.unary_unary( - '/api.v1.alpha2.Manager/GetTrialList', - request_serializer=GetTrialListRequest.SerializeToString, - response_deserializer=GetTrialListReply.FromString, - ) - self.GetTrial = channel.unary_unary( - '/api.v1.alpha2.Manager/GetTrial', - request_serializer=GetTrialRequest.SerializeToString, - response_deserializer=GetTrialReply.FromString, - ) - self.UpdateTrialStatus = channel.unary_unary( - '/api.v1.alpha2.Manager/UpdateTrialStatus', - request_serializer=UpdateTrialStatusRequest.SerializeToString, - response_deserializer=UpdateTrialStatusReply.FromString, - ) - self.ReportObservationLog = channel.unary_unary( - '/api.v1.alpha2.Manager/ReportObservationLog', - request_serializer=ReportObservationLogRequest.SerializeToString, - response_deserializer=ReportObservationLogReply.FromString, - ) - self.GetObservationLog = channel.unary_unary( - '/api.v1.alpha2.Manager/GetObservationLog', - request_serializer=GetObservationLogRequest.SerializeToString, - response_deserializer=GetObservationLogReply.FromString, - ) - self.GetSuggestions = channel.unary_unary( - '/api.v1.alpha2.Manager/GetSuggestions', - request_serializer=GetSuggestionsRequest.SerializeToString, - response_deserializer=GetSuggestionsReply.FromString, - ) - self.ValidateAlgorithmSettings = channel.unary_unary( - '/api.v1.alpha2.Manager/ValidateAlgorithmSettings', - request_serializer=ValidateAlgorithmSettingsRequest.SerializeToString, - response_deserializer=ValidateAlgorithmSettingsReply.FromString, - ) - - - class ManagerServicer(object): - """* - Service for Main API for Katib - For each RPC service, we define mapping to HTTP REST API method. - The mapping includes the URL path, query parameters and request body. - https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http - """ - - def RegisterExperiment(self, request, context): - """* - Register a Experiment to DB. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PreCheckRegisterExperiment(self, request, context): - """* - PreCheck to register a Experiment to DB. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteExperiment(self, request, context): - """* - Delete a Experiment from DB by name. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetExperiment(self, request, context): - """* - Get a Experiment from DB by name. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetExperimentList(self, request, context): - """* - Get a summary list of Experiment from DB. - The summary includes name and condition. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateExperimentStatus(self, request, context): - """* - Update Status of a experiment. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateAlgorithmExtraSettings(self, request, context): - """* - Update AlgorithmExtraSettings. - The ExtraSetting is created if it does not exist, otherwise it is overwrited. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetAlgorithmExtraSettings(self, request, context): - """* - Get all AlgorithmExtraSettings. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def RegisterTrial(self, request, context): - """* - Register a Trial to DB. - ID will be filled by manager automatically. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteTrial(self, request, context): - """* - Delete a Trial from DB by ID. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetTrialList(self, request, context): - """* - Get a list of Trial from DB by name of a Experiment. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetTrial(self, request, context): - """* - Get a Trial from DB by ID of Trial. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateTrialStatus(self, request, context): - """* - Update Status of a trial. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ReportObservationLog(self, request, context): - """* - Report a log of Observations for a Trial. - The log consists of timestamp and value of metric. - Katib store every log of metrics. - You can see accuracy curve or other metric logs on UI. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetObservationLog(self, request, context): - """* - Get all log of Observations for a Trial. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetSuggestions(self, request, context): - """* - Get Suggestions from a Suggestion service. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ValidateAlgorithmSettings(self, request, context): - """* - Validate AlgorithmSettings in an Experiment. - Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - - def add_ManagerServicer_to_server(servicer, server): - rpc_method_handlers = { - 'RegisterExperiment': grpc.unary_unary_rpc_method_handler( - servicer.RegisterExperiment, - request_deserializer=RegisterExperimentRequest.FromString, - response_serializer=RegisterExperimentReply.SerializeToString, - ), - 'PreCheckRegisterExperiment': grpc.unary_unary_rpc_method_handler( - servicer.PreCheckRegisterExperiment, - request_deserializer=RegisterExperimentRequest.FromString, - response_serializer=PreCheckRegisterExperimentReply.SerializeToString, - ), - 'DeleteExperiment': grpc.unary_unary_rpc_method_handler( - servicer.DeleteExperiment, - request_deserializer=DeleteExperimentRequest.FromString, - response_serializer=DeleteExperimentReply.SerializeToString, - ), - 'GetExperiment': grpc.unary_unary_rpc_method_handler( - servicer.GetExperiment, - request_deserializer=GetExperimentRequest.FromString, - response_serializer=GetExperimentReply.SerializeToString, - ), - 'GetExperimentList': grpc.unary_unary_rpc_method_handler( - servicer.GetExperimentList, - request_deserializer=GetExperimentListRequest.FromString, - response_serializer=GetExperimentListReply.SerializeToString, - ), - 'UpdateExperimentStatus': grpc.unary_unary_rpc_method_handler( - servicer.UpdateExperimentStatus, - request_deserializer=UpdateExperimentStatusRequest.FromString, - response_serializer=UpdateExperimentStatusReply.SerializeToString, - ), - 'UpdateAlgorithmExtraSettings': grpc.unary_unary_rpc_method_handler( - servicer.UpdateAlgorithmExtraSettings, - request_deserializer=UpdateAlgorithmExtraSettingsRequest.FromString, - response_serializer=UpdateAlgorithmExtraSettingsReply.SerializeToString, - ), - 'GetAlgorithmExtraSettings': grpc.unary_unary_rpc_method_handler( - servicer.GetAlgorithmExtraSettings, - request_deserializer=GetAlgorithmExtraSettingsRequest.FromString, - response_serializer=GetAlgorithmExtraSettingsReply.SerializeToString, - ), - 'RegisterTrial': grpc.unary_unary_rpc_method_handler( - servicer.RegisterTrial, - request_deserializer=RegisterTrialRequest.FromString, - response_serializer=RegisterTrialReply.SerializeToString, - ), - 'DeleteTrial': grpc.unary_unary_rpc_method_handler( - servicer.DeleteTrial, - request_deserializer=DeleteTrialRequest.FromString, - response_serializer=DeleteTrialReply.SerializeToString, - ), - 'GetTrialList': grpc.unary_unary_rpc_method_handler( - servicer.GetTrialList, - request_deserializer=GetTrialListRequest.FromString, - response_serializer=GetTrialListReply.SerializeToString, - ), - 'GetTrial': grpc.unary_unary_rpc_method_handler( - servicer.GetTrial, - request_deserializer=GetTrialRequest.FromString, - response_serializer=GetTrialReply.SerializeToString, - ), - 'UpdateTrialStatus': grpc.unary_unary_rpc_method_handler( - servicer.UpdateTrialStatus, - request_deserializer=UpdateTrialStatusRequest.FromString, - response_serializer=UpdateTrialStatusReply.SerializeToString, - ), - 'ReportObservationLog': grpc.unary_unary_rpc_method_handler( - servicer.ReportObservationLog, - request_deserializer=ReportObservationLogRequest.FromString, - response_serializer=ReportObservationLogReply.SerializeToString, - ), - 'GetObservationLog': grpc.unary_unary_rpc_method_handler( - servicer.GetObservationLog, - request_deserializer=GetObservationLogRequest.FromString, - response_serializer=GetObservationLogReply.SerializeToString, - ), - 'GetSuggestions': grpc.unary_unary_rpc_method_handler( - servicer.GetSuggestions, - request_deserializer=GetSuggestionsRequest.FromString, - response_serializer=GetSuggestionsReply.SerializeToString, - ), - 'ValidateAlgorithmSettings': grpc.unary_unary_rpc_method_handler( - servicer.ValidateAlgorithmSettings, - request_deserializer=ValidateAlgorithmSettingsRequest.FromString, - response_serializer=ValidateAlgorithmSettingsReply.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'api.v1.alpha2.Manager', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - class SuggestionStub(object): - # missing associated documentation comment in .proto file - pass - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetSuggestions = channel.unary_unary( - '/api.v1.alpha2.Suggestion/GetSuggestions', - request_serializer=GetSuggestionsRequest.SerializeToString, - response_deserializer=GetSuggestionsReply.FromString, - ) - self.ValidateAlgorithmSettings = channel.unary_unary( - '/api.v1.alpha2.Suggestion/ValidateAlgorithmSettings', - request_serializer=ValidateAlgorithmSettingsRequest.SerializeToString, - response_deserializer=ValidateAlgorithmSettingsReply.FromString, - ) - - - class SuggestionServicer(object): - # missing associated documentation comment in .proto file - pass - - def GetSuggestions(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ValidateAlgorithmSettings(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - - def add_SuggestionServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetSuggestions': grpc.unary_unary_rpc_method_handler( - servicer.GetSuggestions, - request_deserializer=GetSuggestionsRequest.FromString, - response_serializer=GetSuggestionsReply.SerializeToString, - ), - 'ValidateAlgorithmSettings': grpc.unary_unary_rpc_method_handler( - servicer.ValidateAlgorithmSettings, - request_deserializer=ValidateAlgorithmSettingsRequest.FromString, - response_serializer=ValidateAlgorithmSettingsReply.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'api.v1.alpha2.Suggestion', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - class EarlyStoppingStub(object): - """TODO - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - - - class EarlyStoppingServicer(object): - """TODO - """ - - - def add_EarlyStoppingServicer_to_server(servicer, server): - rpc_method_handlers = { - } - generic_handler = grpc.method_handlers_generic_handler( - 'api.v1.alpha2.EarlyStopping', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - class BetaManagerServicer(object): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This class was generated - only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.""" - """* - Service for Main API for Katib - For each RPC service, we define mapping to HTTP REST API method. - The mapping includes the URL path, query parameters and request body. - https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http - """ - def RegisterExperiment(self, request, context): - """* - Register a Experiment to DB. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def PreCheckRegisterExperiment(self, request, context): - """* - PreCheck to register a Experiment to DB. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def DeleteExperiment(self, request, context): - """* - Delete a Experiment from DB by name. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def GetExperiment(self, request, context): - """* - Get a Experiment from DB by name. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def GetExperimentList(self, request, context): - """* - Get a summary list of Experiment from DB. - The summary includes name and condition. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def UpdateExperimentStatus(self, request, context): - """* - Update Status of a experiment. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def UpdateAlgorithmExtraSettings(self, request, context): - """* - Update AlgorithmExtraSettings. - The ExtraSetting is created if it does not exist, otherwise it is overwrited. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def GetAlgorithmExtraSettings(self, request, context): - """* - Get all AlgorithmExtraSettings. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def RegisterTrial(self, request, context): - """* - Register a Trial to DB. - ID will be filled by manager automatically. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def DeleteTrial(self, request, context): - """* - Delete a Trial from DB by ID. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def GetTrialList(self, request, context): - """* - Get a list of Trial from DB by name of a Experiment. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def GetTrial(self, request, context): - """* - Get a Trial from DB by ID of Trial. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def UpdateTrialStatus(self, request, context): - """* - Update Status of a trial. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def ReportObservationLog(self, request, context): - """* - Report a log of Observations for a Trial. - The log consists of timestamp and value of metric. - Katib store every log of metrics. - You can see accuracy curve or other metric logs on UI. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def GetObservationLog(self, request, context): - """* - Get all log of Observations for a Trial. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def GetSuggestions(self, request, context): - """* - Get Suggestions from a Suggestion service. - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def ValidateAlgorithmSettings(self, request, context): - """* - Validate AlgorithmSettings in an Experiment. - Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid - """ - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - - - class BetaManagerStub(object): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This class was generated - only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.""" - """* - Service for Main API for Katib - For each RPC service, we define mapping to HTTP REST API method. - The mapping includes the URL path, query parameters and request body. - https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http - """ - def RegisterExperiment(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Register a Experiment to DB. - """ - raise NotImplementedError() - RegisterExperiment.future = None - def PreCheckRegisterExperiment(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - PreCheck to register a Experiment to DB. - """ - raise NotImplementedError() - PreCheckRegisterExperiment.future = None - def DeleteExperiment(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Delete a Experiment from DB by name. - """ - raise NotImplementedError() - DeleteExperiment.future = None - def GetExperiment(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Get a Experiment from DB by name. - """ - raise NotImplementedError() - GetExperiment.future = None - def GetExperimentList(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Get a summary list of Experiment from DB. - The summary includes name and condition. - """ - raise NotImplementedError() - GetExperimentList.future = None - def UpdateExperimentStatus(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Update Status of a experiment. - """ - raise NotImplementedError() - UpdateExperimentStatus.future = None - def UpdateAlgorithmExtraSettings(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Update AlgorithmExtraSettings. - The ExtraSetting is created if it does not exist, otherwise it is overwrited. - """ - raise NotImplementedError() - UpdateAlgorithmExtraSettings.future = None - def GetAlgorithmExtraSettings(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Get all AlgorithmExtraSettings. - """ - raise NotImplementedError() - GetAlgorithmExtraSettings.future = None - def RegisterTrial(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Register a Trial to DB. - ID will be filled by manager automatically. - """ - raise NotImplementedError() - RegisterTrial.future = None - def DeleteTrial(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Delete a Trial from DB by ID. - """ - raise NotImplementedError() - DeleteTrial.future = None - def GetTrialList(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Get a list of Trial from DB by name of a Experiment. - """ - raise NotImplementedError() - GetTrialList.future = None - def GetTrial(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Get a Trial from DB by ID of Trial. - """ - raise NotImplementedError() - GetTrial.future = None - def UpdateTrialStatus(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Update Status of a trial. - """ - raise NotImplementedError() - UpdateTrialStatus.future = None - def ReportObservationLog(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Report a log of Observations for a Trial. - The log consists of timestamp and value of metric. - Katib store every log of metrics. - You can see accuracy curve or other metric logs on UI. - """ - raise NotImplementedError() - ReportObservationLog.future = None - def GetObservationLog(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Get all log of Observations for a Trial. - """ - raise NotImplementedError() - GetObservationLog.future = None - def GetSuggestions(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Get Suggestions from a Suggestion service. - """ - raise NotImplementedError() - GetSuggestions.future = None - def ValidateAlgorithmSettings(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - """* - Validate AlgorithmSettings in an Experiment. - Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid - """ - raise NotImplementedError() - ValidateAlgorithmSettings.future = None - - - def beta_create_Manager_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This function was - generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0""" - request_deserializers = { - ('api.v1.alpha2.Manager', 'DeleteExperiment'): DeleteExperimentRequest.FromString, - ('api.v1.alpha2.Manager', 'DeleteTrial'): DeleteTrialRequest.FromString, - ('api.v1.alpha2.Manager', 'GetAlgorithmExtraSettings'): GetAlgorithmExtraSettingsRequest.FromString, - ('api.v1.alpha2.Manager', 'GetExperiment'): GetExperimentRequest.FromString, - ('api.v1.alpha2.Manager', 'GetExperimentList'): GetExperimentListRequest.FromString, - ('api.v1.alpha2.Manager', 'GetObservationLog'): GetObservationLogRequest.FromString, - ('api.v1.alpha2.Manager', 'GetSuggestions'): GetSuggestionsRequest.FromString, - ('api.v1.alpha2.Manager', 'GetTrial'): GetTrialRequest.FromString, - ('api.v1.alpha2.Manager', 'GetTrialList'): GetTrialListRequest.FromString, - ('api.v1.alpha2.Manager', 'PreCheckRegisterExperiment'): RegisterExperimentRequest.FromString, - ('api.v1.alpha2.Manager', 'RegisterExperiment'): RegisterExperimentRequest.FromString, - ('api.v1.alpha2.Manager', 'RegisterTrial'): RegisterTrialRequest.FromString, - ('api.v1.alpha2.Manager', 'ReportObservationLog'): ReportObservationLogRequest.FromString, - ('api.v1.alpha2.Manager', 'UpdateAlgorithmExtraSettings'): UpdateAlgorithmExtraSettingsRequest.FromString, - ('api.v1.alpha2.Manager', 'UpdateExperimentStatus'): UpdateExperimentStatusRequest.FromString, - ('api.v1.alpha2.Manager', 'UpdateTrialStatus'): UpdateTrialStatusRequest.FromString, - ('api.v1.alpha2.Manager', 'ValidateAlgorithmSettings'): ValidateAlgorithmSettingsRequest.FromString, - } - response_serializers = { - ('api.v1.alpha2.Manager', 'DeleteExperiment'): DeleteExperimentReply.SerializeToString, - ('api.v1.alpha2.Manager', 'DeleteTrial'): DeleteTrialReply.SerializeToString, - ('api.v1.alpha2.Manager', 'GetAlgorithmExtraSettings'): GetAlgorithmExtraSettingsReply.SerializeToString, - ('api.v1.alpha2.Manager', 'GetExperiment'): GetExperimentReply.SerializeToString, - ('api.v1.alpha2.Manager', 'GetExperimentList'): GetExperimentListReply.SerializeToString, - ('api.v1.alpha2.Manager', 'GetObservationLog'): GetObservationLogReply.SerializeToString, - ('api.v1.alpha2.Manager', 'GetSuggestions'): GetSuggestionsReply.SerializeToString, - ('api.v1.alpha2.Manager', 'GetTrial'): GetTrialReply.SerializeToString, - ('api.v1.alpha2.Manager', 'GetTrialList'): GetTrialListReply.SerializeToString, - ('api.v1.alpha2.Manager', 'PreCheckRegisterExperiment'): PreCheckRegisterExperimentReply.SerializeToString, - ('api.v1.alpha2.Manager', 'RegisterExperiment'): RegisterExperimentReply.SerializeToString, - ('api.v1.alpha2.Manager', 'RegisterTrial'): RegisterTrialReply.SerializeToString, - ('api.v1.alpha2.Manager', 'ReportObservationLog'): ReportObservationLogReply.SerializeToString, - ('api.v1.alpha2.Manager', 'UpdateAlgorithmExtraSettings'): UpdateAlgorithmExtraSettingsReply.SerializeToString, - ('api.v1.alpha2.Manager', 'UpdateExperimentStatus'): UpdateExperimentStatusReply.SerializeToString, - ('api.v1.alpha2.Manager', 'UpdateTrialStatus'): UpdateTrialStatusReply.SerializeToString, - ('api.v1.alpha2.Manager', 'ValidateAlgorithmSettings'): ValidateAlgorithmSettingsReply.SerializeToString, - } - method_implementations = { - ('api.v1.alpha2.Manager', 'DeleteExperiment'): face_utilities.unary_unary_inline(servicer.DeleteExperiment), - ('api.v1.alpha2.Manager', 'DeleteTrial'): face_utilities.unary_unary_inline(servicer.DeleteTrial), - ('api.v1.alpha2.Manager', 'GetAlgorithmExtraSettings'): face_utilities.unary_unary_inline(servicer.GetAlgorithmExtraSettings), - ('api.v1.alpha2.Manager', 'GetExperiment'): face_utilities.unary_unary_inline(servicer.GetExperiment), - ('api.v1.alpha2.Manager', 'GetExperimentList'): face_utilities.unary_unary_inline(servicer.GetExperimentList), - ('api.v1.alpha2.Manager', 'GetObservationLog'): face_utilities.unary_unary_inline(servicer.GetObservationLog), - ('api.v1.alpha2.Manager', 'GetSuggestions'): face_utilities.unary_unary_inline(servicer.GetSuggestions), - ('api.v1.alpha2.Manager', 'GetTrial'): face_utilities.unary_unary_inline(servicer.GetTrial), - ('api.v1.alpha2.Manager', 'GetTrialList'): face_utilities.unary_unary_inline(servicer.GetTrialList), - ('api.v1.alpha2.Manager', 'PreCheckRegisterExperiment'): face_utilities.unary_unary_inline(servicer.PreCheckRegisterExperiment), - ('api.v1.alpha2.Manager', 'RegisterExperiment'): face_utilities.unary_unary_inline(servicer.RegisterExperiment), - ('api.v1.alpha2.Manager', 'RegisterTrial'): face_utilities.unary_unary_inline(servicer.RegisterTrial), - ('api.v1.alpha2.Manager', 'ReportObservationLog'): face_utilities.unary_unary_inline(servicer.ReportObservationLog), - ('api.v1.alpha2.Manager', 'UpdateAlgorithmExtraSettings'): face_utilities.unary_unary_inline(servicer.UpdateAlgorithmExtraSettings), - ('api.v1.alpha2.Manager', 'UpdateExperimentStatus'): face_utilities.unary_unary_inline(servicer.UpdateExperimentStatus), - ('api.v1.alpha2.Manager', 'UpdateTrialStatus'): face_utilities.unary_unary_inline(servicer.UpdateTrialStatus), - ('api.v1.alpha2.Manager', 'ValidateAlgorithmSettings'): face_utilities.unary_unary_inline(servicer.ValidateAlgorithmSettings), - } - server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) - return beta_implementations.server(method_implementations, options=server_options) - - - def beta_create_Manager_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This function was - generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0""" - request_serializers = { - ('api.v1.alpha2.Manager', 'DeleteExperiment'): DeleteExperimentRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'DeleteTrial'): DeleteTrialRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'GetAlgorithmExtraSettings'): GetAlgorithmExtraSettingsRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'GetExperiment'): GetExperimentRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'GetExperimentList'): GetExperimentListRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'GetObservationLog'): GetObservationLogRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'GetSuggestions'): GetSuggestionsRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'GetTrial'): GetTrialRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'GetTrialList'): GetTrialListRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'PreCheckRegisterExperiment'): RegisterExperimentRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'RegisterExperiment'): RegisterExperimentRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'RegisterTrial'): RegisterTrialRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'ReportObservationLog'): ReportObservationLogRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'UpdateAlgorithmExtraSettings'): UpdateAlgorithmExtraSettingsRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'UpdateExperimentStatus'): UpdateExperimentStatusRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'UpdateTrialStatus'): UpdateTrialStatusRequest.SerializeToString, - ('api.v1.alpha2.Manager', 'ValidateAlgorithmSettings'): ValidateAlgorithmSettingsRequest.SerializeToString, - } - response_deserializers = { - ('api.v1.alpha2.Manager', 'DeleteExperiment'): DeleteExperimentReply.FromString, - ('api.v1.alpha2.Manager', 'DeleteTrial'): DeleteTrialReply.FromString, - ('api.v1.alpha2.Manager', 'GetAlgorithmExtraSettings'): GetAlgorithmExtraSettingsReply.FromString, - ('api.v1.alpha2.Manager', 'GetExperiment'): GetExperimentReply.FromString, - ('api.v1.alpha2.Manager', 'GetExperimentList'): GetExperimentListReply.FromString, - ('api.v1.alpha2.Manager', 'GetObservationLog'): GetObservationLogReply.FromString, - ('api.v1.alpha2.Manager', 'GetSuggestions'): GetSuggestionsReply.FromString, - ('api.v1.alpha2.Manager', 'GetTrial'): GetTrialReply.FromString, - ('api.v1.alpha2.Manager', 'GetTrialList'): GetTrialListReply.FromString, - ('api.v1.alpha2.Manager', 'PreCheckRegisterExperiment'): PreCheckRegisterExperimentReply.FromString, - ('api.v1.alpha2.Manager', 'RegisterExperiment'): RegisterExperimentReply.FromString, - ('api.v1.alpha2.Manager', 'RegisterTrial'): RegisterTrialReply.FromString, - ('api.v1.alpha2.Manager', 'ReportObservationLog'): ReportObservationLogReply.FromString, - ('api.v1.alpha2.Manager', 'UpdateAlgorithmExtraSettings'): UpdateAlgorithmExtraSettingsReply.FromString, - ('api.v1.alpha2.Manager', 'UpdateExperimentStatus'): UpdateExperimentStatusReply.FromString, - ('api.v1.alpha2.Manager', 'UpdateTrialStatus'): UpdateTrialStatusReply.FromString, - ('api.v1.alpha2.Manager', 'ValidateAlgorithmSettings'): ValidateAlgorithmSettingsReply.FromString, - } - cardinalities = { - 'DeleteExperiment': cardinality.Cardinality.UNARY_UNARY, - 'DeleteTrial': cardinality.Cardinality.UNARY_UNARY, - 'GetAlgorithmExtraSettings': cardinality.Cardinality.UNARY_UNARY, - 'GetExperiment': cardinality.Cardinality.UNARY_UNARY, - 'GetExperimentList': cardinality.Cardinality.UNARY_UNARY, - 'GetObservationLog': cardinality.Cardinality.UNARY_UNARY, - 'GetSuggestions': cardinality.Cardinality.UNARY_UNARY, - 'GetTrial': cardinality.Cardinality.UNARY_UNARY, - 'GetTrialList': cardinality.Cardinality.UNARY_UNARY, - 'PreCheckRegisterExperiment': cardinality.Cardinality.UNARY_UNARY, - 'RegisterExperiment': cardinality.Cardinality.UNARY_UNARY, - 'RegisterTrial': cardinality.Cardinality.UNARY_UNARY, - 'ReportObservationLog': cardinality.Cardinality.UNARY_UNARY, - 'UpdateAlgorithmExtraSettings': cardinality.Cardinality.UNARY_UNARY, - 'UpdateExperimentStatus': cardinality.Cardinality.UNARY_UNARY, - 'UpdateTrialStatus': cardinality.Cardinality.UNARY_UNARY, - 'ValidateAlgorithmSettings': cardinality.Cardinality.UNARY_UNARY, - } - stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size) - return beta_implementations.dynamic_stub(channel, 'api.v1.alpha2.Manager', cardinalities, options=stub_options) - - - class BetaSuggestionServicer(object): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This class was generated - only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.""" - # missing associated documentation comment in .proto file - pass - def GetSuggestions(self, request, context): - # missing associated documentation comment in .proto file - pass - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - def ValidateAlgorithmSettings(self, request, context): - # missing associated documentation comment in .proto file - pass - context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) - - - class BetaSuggestionStub(object): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This class was generated - only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.""" - # missing associated documentation comment in .proto file - pass - def GetSuggestions(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - # missing associated documentation comment in .proto file - pass - raise NotImplementedError() - GetSuggestions.future = None - def ValidateAlgorithmSettings(self, request, timeout, metadata=None, with_call=False, protocol_options=None): - # missing associated documentation comment in .proto file - pass - raise NotImplementedError() - ValidateAlgorithmSettings.future = None - - - def beta_create_Suggestion_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This function was - generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0""" - request_deserializers = { - ('api.v1.alpha2.Suggestion', 'GetSuggestions'): GetSuggestionsRequest.FromString, - ('api.v1.alpha2.Suggestion', 'ValidateAlgorithmSettings'): ValidateAlgorithmSettingsRequest.FromString, - } - response_serializers = { - ('api.v1.alpha2.Suggestion', 'GetSuggestions'): GetSuggestionsReply.SerializeToString, - ('api.v1.alpha2.Suggestion', 'ValidateAlgorithmSettings'): ValidateAlgorithmSettingsReply.SerializeToString, - } - method_implementations = { - ('api.v1.alpha2.Suggestion', 'GetSuggestions'): face_utilities.unary_unary_inline(servicer.GetSuggestions), - ('api.v1.alpha2.Suggestion', 'ValidateAlgorithmSettings'): face_utilities.unary_unary_inline(servicer.ValidateAlgorithmSettings), - } - server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) - return beta_implementations.server(method_implementations, options=server_options) - - - def beta_create_Suggestion_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This function was - generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0""" - request_serializers = { - ('api.v1.alpha2.Suggestion', 'GetSuggestions'): GetSuggestionsRequest.SerializeToString, - ('api.v1.alpha2.Suggestion', 'ValidateAlgorithmSettings'): ValidateAlgorithmSettingsRequest.SerializeToString, - } - response_deserializers = { - ('api.v1.alpha2.Suggestion', 'GetSuggestions'): GetSuggestionsReply.FromString, - ('api.v1.alpha2.Suggestion', 'ValidateAlgorithmSettings'): ValidateAlgorithmSettingsReply.FromString, - } - cardinalities = { - 'GetSuggestions': cardinality.Cardinality.UNARY_UNARY, - 'ValidateAlgorithmSettings': cardinality.Cardinality.UNARY_UNARY, - } - stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size) - return beta_implementations.dynamic_stub(channel, 'api.v1.alpha2.Suggestion', cardinalities, options=stub_options) - - - class BetaEarlyStoppingServicer(object): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This class was generated - only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.""" - """TODO - """ - - - class BetaEarlyStoppingStub(object): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This class was generated - only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.""" - """TODO - """ - - - def beta_create_EarlyStopping_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This function was - generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0""" - request_deserializers = { - } - response_serializers = { - } - method_implementations = { - } - server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) - return beta_implementations.server(method_implementations, options=server_options) - - - def beta_create_EarlyStopping_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): - """The Beta API is deprecated for 0.15.0 and later. - - It is recommended to use the GA API (classes and functions in this - file not marked beta) for all further purposes. This function was - generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0""" - request_serializers = { - } - response_deserializers = { - } - cardinalities = { - } - stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size) - return beta_implementations.dynamic_stub(channel, 'api.v1.alpha2.EarlyStopping', cardinalities, options=stub_options) -except ImportError: - pass -# @@protoc_insertion_point(module_scope) diff --git a/pkg/apis/manager/v1alpha2/python/api_pb2_grpc.py b/pkg/apis/manager/v1alpha2/python/api_pb2_grpc.py deleted file mode 100644 index ea61b19b29a..00000000000 --- a/pkg/apis/manager/v1alpha2/python/api_pb2_grpc.py +++ /dev/null @@ -1,434 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - -import api_pb2 as api__pb2 - - -class ManagerStub(object): - """* - Service for Main API for Katib - For each RPC service, we define mapping to HTTP REST API method. - The mapping includes the URL path, query parameters and request body. - https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.RegisterExperiment = channel.unary_unary( - '/api.v1.alpha2.Manager/RegisterExperiment', - request_serializer=api__pb2.RegisterExperimentRequest.SerializeToString, - response_deserializer=api__pb2.RegisterExperimentReply.FromString, - ) - self.PreCheckRegisterExperiment = channel.unary_unary( - '/api.v1.alpha2.Manager/PreCheckRegisterExperiment', - request_serializer=api__pb2.RegisterExperimentRequest.SerializeToString, - response_deserializer=api__pb2.PreCheckRegisterExperimentReply.FromString, - ) - self.DeleteExperiment = channel.unary_unary( - '/api.v1.alpha2.Manager/DeleteExperiment', - request_serializer=api__pb2.DeleteExperimentRequest.SerializeToString, - response_deserializer=api__pb2.DeleteExperimentReply.FromString, - ) - self.GetExperiment = channel.unary_unary( - '/api.v1.alpha2.Manager/GetExperiment', - request_serializer=api__pb2.GetExperimentRequest.SerializeToString, - response_deserializer=api__pb2.GetExperimentReply.FromString, - ) - self.GetExperimentList = channel.unary_unary( - '/api.v1.alpha2.Manager/GetExperimentList', - request_serializer=api__pb2.GetExperimentListRequest.SerializeToString, - response_deserializer=api__pb2.GetExperimentListReply.FromString, - ) - self.UpdateExperimentStatus = channel.unary_unary( - '/api.v1.alpha2.Manager/UpdateExperimentStatus', - request_serializer=api__pb2.UpdateExperimentStatusRequest.SerializeToString, - response_deserializer=api__pb2.UpdateExperimentStatusReply.FromString, - ) - self.UpdateAlgorithmExtraSettings = channel.unary_unary( - '/api.v1.alpha2.Manager/UpdateAlgorithmExtraSettings', - request_serializer=api__pb2.UpdateAlgorithmExtraSettingsRequest.SerializeToString, - response_deserializer=api__pb2.UpdateAlgorithmExtraSettingsReply.FromString, - ) - self.GetAlgorithmExtraSettings = channel.unary_unary( - '/api.v1.alpha2.Manager/GetAlgorithmExtraSettings', - request_serializer=api__pb2.GetAlgorithmExtraSettingsRequest.SerializeToString, - response_deserializer=api__pb2.GetAlgorithmExtraSettingsReply.FromString, - ) - self.RegisterTrial = channel.unary_unary( - '/api.v1.alpha2.Manager/RegisterTrial', - request_serializer=api__pb2.RegisterTrialRequest.SerializeToString, - response_deserializer=api__pb2.RegisterTrialReply.FromString, - ) - self.DeleteTrial = channel.unary_unary( - '/api.v1.alpha2.Manager/DeleteTrial', - request_serializer=api__pb2.DeleteTrialRequest.SerializeToString, - response_deserializer=api__pb2.DeleteTrialReply.FromString, - ) - self.GetTrialList = channel.unary_unary( - '/api.v1.alpha2.Manager/GetTrialList', - request_serializer=api__pb2.GetTrialListRequest.SerializeToString, - response_deserializer=api__pb2.GetTrialListReply.FromString, - ) - self.GetTrial = channel.unary_unary( - '/api.v1.alpha2.Manager/GetTrial', - request_serializer=api__pb2.GetTrialRequest.SerializeToString, - response_deserializer=api__pb2.GetTrialReply.FromString, - ) - self.UpdateTrialStatus = channel.unary_unary( - '/api.v1.alpha2.Manager/UpdateTrialStatus', - request_serializer=api__pb2.UpdateTrialStatusRequest.SerializeToString, - response_deserializer=api__pb2.UpdateTrialStatusReply.FromString, - ) - self.ReportObservationLog = channel.unary_unary( - '/api.v1.alpha2.Manager/ReportObservationLog', - request_serializer=api__pb2.ReportObservationLogRequest.SerializeToString, - response_deserializer=api__pb2.ReportObservationLogReply.FromString, - ) - self.GetObservationLog = channel.unary_unary( - '/api.v1.alpha2.Manager/GetObservationLog', - request_serializer=api__pb2.GetObservationLogRequest.SerializeToString, - response_deserializer=api__pb2.GetObservationLogReply.FromString, - ) - self.GetSuggestions = channel.unary_unary( - '/api.v1.alpha2.Manager/GetSuggestions', - request_serializer=api__pb2.GetSuggestionsRequest.SerializeToString, - response_deserializer=api__pb2.GetSuggestionsReply.FromString, - ) - self.ValidateAlgorithmSettings = channel.unary_unary( - '/api.v1.alpha2.Manager/ValidateAlgorithmSettings', - request_serializer=api__pb2.ValidateAlgorithmSettingsRequest.SerializeToString, - response_deserializer=api__pb2.ValidateAlgorithmSettingsReply.FromString, - ) - - -class ManagerServicer(object): - """* - Service for Main API for Katib - For each RPC service, we define mapping to HTTP REST API method. - The mapping includes the URL path, query parameters and request body. - https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http - """ - - def RegisterExperiment(self, request, context): - """* - Register a Experiment to DB. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PreCheckRegisterExperiment(self, request, context): - """* - PreCheck to register a Experiment to DB. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteExperiment(self, request, context): - """* - Delete a Experiment from DB by name. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetExperiment(self, request, context): - """* - Get a Experiment from DB by name. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetExperimentList(self, request, context): - """* - Get a summary list of Experiment from DB. - The summary includes name and condition. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateExperimentStatus(self, request, context): - """* - Update Status of a experiment. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateAlgorithmExtraSettings(self, request, context): - """* - Update AlgorithmExtraSettings. - The ExtraSetting is created if it does not exist, otherwise it is overwrited. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetAlgorithmExtraSettings(self, request, context): - """* - Get all AlgorithmExtraSettings. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def RegisterTrial(self, request, context): - """* - Register a Trial to DB. - ID will be filled by manager automatically. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteTrial(self, request, context): - """* - Delete a Trial from DB by ID. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetTrialList(self, request, context): - """* - Get a list of Trial from DB by name of a Experiment. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetTrial(self, request, context): - """* - Get a Trial from DB by ID of Trial. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateTrialStatus(self, request, context): - """* - Update Status of a trial. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ReportObservationLog(self, request, context): - """* - Report a log of Observations for a Trial. - The log consists of timestamp and value of metric. - Katib store every log of metrics. - You can see accuracy curve or other metric logs on UI. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetObservationLog(self, request, context): - """* - Get all log of Observations for a Trial. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetSuggestions(self, request, context): - """* - Get Suggestions from a Suggestion service. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ValidateAlgorithmSettings(self, request, context): - """* - Validate AlgorithmSettings in an Experiment. - Suggestion service should return INVALID_ARGUMENT Error when the parameter is invalid - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_ManagerServicer_to_server(servicer, server): - rpc_method_handlers = { - 'RegisterExperiment': grpc.unary_unary_rpc_method_handler( - servicer.RegisterExperiment, - request_deserializer=api__pb2.RegisterExperimentRequest.FromString, - response_serializer=api__pb2.RegisterExperimentReply.SerializeToString, - ), - 'PreCheckRegisterExperiment': grpc.unary_unary_rpc_method_handler( - servicer.PreCheckRegisterExperiment, - request_deserializer=api__pb2.RegisterExperimentRequest.FromString, - response_serializer=api__pb2.PreCheckRegisterExperimentReply.SerializeToString, - ), - 'DeleteExperiment': grpc.unary_unary_rpc_method_handler( - servicer.DeleteExperiment, - request_deserializer=api__pb2.DeleteExperimentRequest.FromString, - response_serializer=api__pb2.DeleteExperimentReply.SerializeToString, - ), - 'GetExperiment': grpc.unary_unary_rpc_method_handler( - servicer.GetExperiment, - request_deserializer=api__pb2.GetExperimentRequest.FromString, - response_serializer=api__pb2.GetExperimentReply.SerializeToString, - ), - 'GetExperimentList': grpc.unary_unary_rpc_method_handler( - servicer.GetExperimentList, - request_deserializer=api__pb2.GetExperimentListRequest.FromString, - response_serializer=api__pb2.GetExperimentListReply.SerializeToString, - ), - 'UpdateExperimentStatus': grpc.unary_unary_rpc_method_handler( - servicer.UpdateExperimentStatus, - request_deserializer=api__pb2.UpdateExperimentStatusRequest.FromString, - response_serializer=api__pb2.UpdateExperimentStatusReply.SerializeToString, - ), - 'UpdateAlgorithmExtraSettings': grpc.unary_unary_rpc_method_handler( - servicer.UpdateAlgorithmExtraSettings, - request_deserializer=api__pb2.UpdateAlgorithmExtraSettingsRequest.FromString, - response_serializer=api__pb2.UpdateAlgorithmExtraSettingsReply.SerializeToString, - ), - 'GetAlgorithmExtraSettings': grpc.unary_unary_rpc_method_handler( - servicer.GetAlgorithmExtraSettings, - request_deserializer=api__pb2.GetAlgorithmExtraSettingsRequest.FromString, - response_serializer=api__pb2.GetAlgorithmExtraSettingsReply.SerializeToString, - ), - 'RegisterTrial': grpc.unary_unary_rpc_method_handler( - servicer.RegisterTrial, - request_deserializer=api__pb2.RegisterTrialRequest.FromString, - response_serializer=api__pb2.RegisterTrialReply.SerializeToString, - ), - 'DeleteTrial': grpc.unary_unary_rpc_method_handler( - servicer.DeleteTrial, - request_deserializer=api__pb2.DeleteTrialRequest.FromString, - response_serializer=api__pb2.DeleteTrialReply.SerializeToString, - ), - 'GetTrialList': grpc.unary_unary_rpc_method_handler( - servicer.GetTrialList, - request_deserializer=api__pb2.GetTrialListRequest.FromString, - response_serializer=api__pb2.GetTrialListReply.SerializeToString, - ), - 'GetTrial': grpc.unary_unary_rpc_method_handler( - servicer.GetTrial, - request_deserializer=api__pb2.GetTrialRequest.FromString, - response_serializer=api__pb2.GetTrialReply.SerializeToString, - ), - 'UpdateTrialStatus': grpc.unary_unary_rpc_method_handler( - servicer.UpdateTrialStatus, - request_deserializer=api__pb2.UpdateTrialStatusRequest.FromString, - response_serializer=api__pb2.UpdateTrialStatusReply.SerializeToString, - ), - 'ReportObservationLog': grpc.unary_unary_rpc_method_handler( - servicer.ReportObservationLog, - request_deserializer=api__pb2.ReportObservationLogRequest.FromString, - response_serializer=api__pb2.ReportObservationLogReply.SerializeToString, - ), - 'GetObservationLog': grpc.unary_unary_rpc_method_handler( - servicer.GetObservationLog, - request_deserializer=api__pb2.GetObservationLogRequest.FromString, - response_serializer=api__pb2.GetObservationLogReply.SerializeToString, - ), - 'GetSuggestions': grpc.unary_unary_rpc_method_handler( - servicer.GetSuggestions, - request_deserializer=api__pb2.GetSuggestionsRequest.FromString, - response_serializer=api__pb2.GetSuggestionsReply.SerializeToString, - ), - 'ValidateAlgorithmSettings': grpc.unary_unary_rpc_method_handler( - servicer.ValidateAlgorithmSettings, - request_deserializer=api__pb2.ValidateAlgorithmSettingsRequest.FromString, - response_serializer=api__pb2.ValidateAlgorithmSettingsReply.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'api.v1.alpha2.Manager', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - -class SuggestionStub(object): - # missing associated documentation comment in .proto file - pass - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetSuggestions = channel.unary_unary( - '/api.v1.alpha2.Suggestion/GetSuggestions', - request_serializer=api__pb2.GetSuggestionsRequest.SerializeToString, - response_deserializer=api__pb2.GetSuggestionsReply.FromString, - ) - self.ValidateAlgorithmSettings = channel.unary_unary( - '/api.v1.alpha2.Suggestion/ValidateAlgorithmSettings', - request_serializer=api__pb2.ValidateAlgorithmSettingsRequest.SerializeToString, - response_deserializer=api__pb2.ValidateAlgorithmSettingsReply.FromString, - ) - - -class SuggestionServicer(object): - # missing associated documentation comment in .proto file - pass - - def GetSuggestions(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ValidateAlgorithmSettings(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_SuggestionServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetSuggestions': grpc.unary_unary_rpc_method_handler( - servicer.GetSuggestions, - request_deserializer=api__pb2.GetSuggestionsRequest.FromString, - response_serializer=api__pb2.GetSuggestionsReply.SerializeToString, - ), - 'ValidateAlgorithmSettings': grpc.unary_unary_rpc_method_handler( - servicer.ValidateAlgorithmSettings, - request_deserializer=api__pb2.ValidateAlgorithmSettingsRequest.FromString, - response_serializer=api__pb2.ValidateAlgorithmSettingsReply.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'api.v1.alpha2.Suggestion', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - -class EarlyStoppingStub(object): - """TODO - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - - -class EarlyStoppingServicer(object): - """TODO - """ - - -def add_EarlyStoppingServicer_to_server(servicer, server): - rpc_method_handlers = { - } - generic_handler = grpc.method_handlers_generic_handler( - 'api.v1.alpha2.EarlyStopping', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) diff --git a/pkg/common/v1alpha2/common.go b/pkg/common/v1alpha2/common.go deleted file mode 100644 index 1861ab6153e..00000000000 --- a/pkg/common/v1alpha2/common.go +++ /dev/null @@ -1,54 +0,0 @@ -package v1alpha2 - -import ( - "time" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -func GetSupportedJobList() []schema.GroupVersionKind { - supportedJobList := []schema.GroupVersionKind{ - { - Group: "batch", - Version: "v1", - Kind: "Job", - }, - { - Group: "kubeflow.org", - Version: "v1", - Kind: "TFJob", - }, - { - Group: "kubeflow.org", - Version: "v1", - Kind: "PyTorchJob", - }, - } - return supportedJobList -} - -func ConvertTime2RFC3339(t *metav1.Time) string { - if t != nil { - return t.UTC().Format(time.RFC3339) - } else { - zero := &metav1.Time{} - return zero.UTC().Format(time.RFC3339) - } -} - -func GetJobLabelMap(jobKind string, trialName string) map[string]string { - labelMap := make(map[string]string) - - if jobKind == "TFJob" { - labelMap["job-name"] = trialName - labelMap["job-role"] = "master" - } else if jobKind == "PyTorchJob" { - labelMap["job-name"] = trialName - labelMap["job-role"] = "master" - } else { - labelMap["job-name"] = trialName - } - - return labelMap -} diff --git a/pkg/common/v1alpha2/katib_manager_util.go b/pkg/common/v1alpha2/katib_manager_util.go deleted file mode 100644 index 32f64d79faf..00000000000 --- a/pkg/common/v1alpha2/katib_manager_util.go +++ /dev/null @@ -1,181 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha2 - -import ( - "context" - "os" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - "google.golang.org/grpc" -) - -const ( - KatibManagerServiceIPEnvName = "KATIB_MANAGER_PORT_6789_TCP_ADDR" - KatibManagerServicePortEnvName = "KATIB_MANAGER_PORT_6789_TCP_PORT" - KatibManagerServiceNamespaceEnvName = "KATIB_MANAGER_NAMESPACE" - KatibManagerService = "katib-manager" - KatibManagerPort = "6789" - ManagerAddr = KatibManagerService + ":" + KatibManagerPort -) - -type katibManagerClientAndConn struct { - Conn *grpc.ClientConn - KatibManagerClient api_pb.ManagerClient -} - -func GetManagerAddr() string { - ns := os.Getenv(experimentsv1alpha2.DefaultKatibNamespaceEnvName) - if len(ns) == 0 { - addr := os.Getenv(KatibManagerServiceIPEnvName) - port := os.Getenv(KatibManagerServicePortEnvName) - if len(addr) > 0 && len(port) > 0 { - return addr + ":" + port - } else { - return ManagerAddr - } - } else { - return KatibManagerService + "." + ns + ":" + KatibManagerPort - } -} - -func getKatibManagerClientAndConn() (*katibManagerClientAndConn, error) { - addr := GetManagerAddr() - conn, err := grpc.Dial(addr, grpc.WithInsecure()) - if err != nil { - return nil, err - } - kcc := &katibManagerClientAndConn{ - Conn: conn, - KatibManagerClient: api_pb.NewManagerClient(conn), - } - return kcc, nil -} - -func closeKatibManagerConnection(kcc *katibManagerClientAndConn) { - kcc.Conn.Close() -} - -func RegisterExperiment(request *api_pb.RegisterExperimentRequest) (*api_pb.RegisterExperimentReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.RegisterExperiment(ctx, request) -} - -func DeleteExperiment(request *api_pb.DeleteExperimentRequest) (*api_pb.DeleteExperimentReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.DeleteExperiment(ctx, request) -} - -func UpdateExperimentStatus(request *api_pb.UpdateExperimentStatusRequest) (*api_pb.UpdateExperimentStatusReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.UpdateExperimentStatus(ctx, request) -} - -func UpdateAlgorithmExtraSettings(request *api_pb.UpdateAlgorithmExtraSettingsRequest) (*api_pb.UpdateAlgorithmExtraSettingsReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.UpdateAlgorithmExtraSettings(ctx, request) -} - -func RegisterTrial(request *api_pb.RegisterTrialRequest) (*api_pb.RegisterTrialReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.RegisterTrial(ctx, request) -} - -func UpdateTrialStatus(request *api_pb.UpdateTrialStatusRequest) (*api_pb.UpdateTrialStatusReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.UpdateTrialStatus(ctx, request) -} - -func GetSuggestions(request *api_pb.GetSuggestionsRequest) (*api_pb.GetSuggestionsReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.GetSuggestions(ctx, request) -} - -func PreCheckRegisterExperiment(request *api_pb.RegisterExperimentRequest) (*api_pb.PreCheckRegisterExperimentReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.PreCheckRegisterExperiment(ctx, request) -} - -func GetObservationLog(request *api_pb.GetObservationLogRequest) (*api_pb.GetObservationLogReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.GetObservationLog(ctx, request) -} - -func ValidateAlgorithmSettings(request *api_pb.ValidateAlgorithmSettingsRequest) (*api_pb.ValidateAlgorithmSettingsReply, error) { - ctx := context.Background() - kcc, err := getKatibManagerClientAndConn() - if err != nil { - return nil, err - } - defer closeKatibManagerConnection(kcc) - kc := kcc.KatibManagerClient - return kc.ValidateAlgorithmSettings(ctx, request) -} diff --git a/pkg/controller.v1alpha2/add_experiment.go b/pkg/controller.v1alpha2/add_experiment.go deleted file mode 100644 index f58bf829ac0..00000000000 --- a/pkg/controller.v1alpha2/add_experiment.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, experiment.Add) -} diff --git a/pkg/controller.v1alpha2/add_trial.go b/pkg/controller.v1alpha2/add_trial.go deleted file mode 100644 index 2a0dfc08080..00000000000 --- a/pkg/controller.v1alpha2/add_trial.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "github.com/kubeflow/katib/pkg/controller.v1alpha2/trial" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, trial.Add) -} diff --git a/pkg/controller.v1alpha2/consts/const.go b/pkg/controller.v1alpha2/consts/const.go deleted file mode 100644 index 4cb1795e733..00000000000 --- a/pkg/controller.v1alpha2/consts/const.go +++ /dev/null @@ -1,7 +0,0 @@ -package consts - -const ( - ConfigExperimentSuggestionName = "experiment-suggestion-name" - - LabelExperimentName = "experiment" -) diff --git a/pkg/controller.v1alpha2/controller.go b/pkg/controller.v1alpha2/controller.go deleted file mode 100644 index b2acc50372b..00000000000 --- a/pkg/controller.v1alpha2/controller.go +++ /dev/null @@ -1,33 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -// AddToManagerFuncs is a list of functions to add all Controllers to the Manager -var AddToManagerFuncs []func(manager.Manager) error - -// AddToManager adds all Controllers to the Manager -func AddToManager(m manager.Manager) error { - for _, f := range AddToManagerFuncs { - if err := f(m); err != nil { - return err - } - } - return nil -} diff --git a/pkg/controller.v1alpha2/experiment/experiment_controller.go b/pkg/controller.v1alpha2/experiment/experiment_controller.go deleted file mode 100644 index 658a1d90c6b..00000000000 --- a/pkg/controller.v1alpha2/experiment/experiment_controller.go +++ /dev/null @@ -1,337 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package experiment - -import ( - "context" - "sort" - - "github.com/spf13/viper" - "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - "sigs.k8s.io/controller-runtime/pkg/source" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/consts" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/managerclient" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/manifest" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/suggestion" - suggestionfake "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/suggestion/fake" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/util" -) - -var log = logf.Log.WithName("experiment-controller") - -/** -* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller -* business logic. Delete these comments after modifying this file.* - */ - -// Add creates a new Experiment Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, newReconciler(mgr)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager) reconcile.Reconciler { - r := &ReconcileExperiment{ - Client: mgr.GetClient(), - scheme: mgr.GetScheme(), - ManagerClient: managerclient.New(), - } - imp := viper.GetString(consts.ConfigExperimentSuggestionName) - r.Suggestion = newSuggestion(imp) - - r.Generator = manifest.New(r.Client) - r.updateStatusHandler = r.updateStatus - return r -} - -// newSuggestion returns the new Suggestion for the given config. -func newSuggestion(config string) suggestion.Suggestion { - // Use different implementation according to the configuration. - switch config { - case "fake": - log.Info("Using the fake suggestion implementation") - return suggestionfake.New() - case "default": - log.Info("Using the default suggestion implementation") - return suggestion.New() - default: - log.Info("No valid name specified, using the default suggestion implementation", - "implementation", config) - return suggestion.New() - } -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New("experiment-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - log.Error(err, "Failed to create experiment controller") - return err - } - - if err = addWatch(mgr, c); err != nil { - log.Error(err, "Trial watch failed") - return err - } - - log.Info("Experiment controller created") - return nil -} - -// addWatch adds a new Controller to mgr with r as the reconcile.Reconciler -func addWatch(mgr manager.Manager, c controller.Controller) error { - // Watch for changes to Experiment - err := c.Watch(&source.Kind{Type: &experimentsv1alpha2.Experiment{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - log.Error(err, "Experiment watch failed") - return err - } - - // Watch for trials for the experiments - err = c.Watch( - &source.Kind{Type: &trialsv1alpha2.Trial{}}, - &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &experimentsv1alpha2.Experiment{}, - }) - - if err != nil { - log.Error(err, "Trial watch failed") - return err - } - return nil -} - -var _ reconcile.Reconciler = &ReconcileExperiment{} - -// ReconcileExperiment reconciles a Experiment object -type ReconcileExperiment struct { - client.Client - scheme *runtime.Scheme - - suggestion.Suggestion - manifest.Generator - managerclient.ManagerClient - // updateStatusHandler is defined for test purpose. - updateStatusHandler updateStatusFunc -} - -// Reconcile reads that state of the cluster for a Experiment object and makes changes based on the state read -// and what is in the Experiment.Spec -// +kubebuilder:rbac:groups=experiments.kubeflow.org,resources=experiments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=experiments.kubeflow.org,resources=experiments/status,verbs=get;update;patch -func (r *ReconcileExperiment) Reconcile(request reconcile.Request) (reconcile.Result, error) { - // Fetch the Experiment instance - logger := log.WithValues("Experiment", request.NamespacedName) - original := &experimentsv1alpha2.Experiment{} - err := r.Get(context.TODO(), request.NamespacedName, original) - if err != nil { - if errors.IsNotFound(err) { - // Object not found, return. Created objects are automatically garbage collected. - // For additional cleanup logic use finalizers. - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - logger.Error(err, "Experiment Get error") - return reconcile.Result{}, err - } - instance := original.DeepCopy() - - if needUpdate, finalizers := instance.NeedUpdateFinalizers(); needUpdate { - return r.updateFinalizers(instance, finalizers) - } - - if instance.IsCompleted() { - - return reconcile.Result{}, nil - - } - if !instance.IsCreated() { - //Experiment not created in DB - if instance.Status.StartTime == nil { - now := metav1.Now() - instance.Status.StartTime = &now - } - if instance.Status.CompletionTime == nil { - instance.Status.CompletionTime = &metav1.Time{} - } - err = r.CreateExperimentInDB(instance) - if err != nil { - logger.Error(err, "Create experiment in DB error") - return reconcile.Result{ - Requeue: true, - }, err - } - msg := "Experiment is created" - instance.MarkExperimentStatusCreated(util.ExperimentCreatedReason, msg) - } else { - // Experiment already created in DB - err := r.ReconcileExperiment(instance) - if err != nil { - logger.Error(err, "Reconcile experiment error") - return reconcile.Result{}, err - } - } - - if !equality.Semantic.DeepEqual(original.Status, instance.Status) { - //assuming that only status change - err = r.UpdateExperimentStatusInDB(instance) - if err != nil { - logger.Error(err, "Update experiment status in DB error") - return reconcile.Result{}, err - } - err = r.updateStatusHandler(instance) - if err != nil { - logger.Error(err, "Update experiment instance status error") - return reconcile.Result{}, err - } - } - - return reconcile.Result{}, nil -} - -func (r *ReconcileExperiment) ReconcileExperiment(instance *experimentsv1alpha2.Experiment) error { - logger := log.WithValues("Experiment", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) - trials := &trialsv1alpha2.TrialList{} - labels := map[string]string{consts.LabelExperimentName: instance.Name} - lo := &client.ListOptions{} - lo.MatchingLabels(labels).InNamespace(instance.Namespace) - - if err := r.List(context.TODO(), lo, trials); err != nil { - logger.Error(err, "Trial List error") - return err - } - if len(trials.Items) > 0 { - if err := util.UpdateExperimentStatus(instance, trials); err != nil { - logger.Error(err, "Update experiment status error") - return err - } - } - reconcileRequired := !instance.IsCompleted() - if reconcileRequired { - r.ReconcileTrials(instance, trials.Items) - } - return nil -} - -func (r *ReconcileExperiment) ReconcileTrials(instance *experimentsv1alpha2.Experiment, trials []trialsv1alpha2.Trial) error { - - logger := log.WithValues("Experiment", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) - - parallelCount := *instance.Spec.ParallelTrialCount - activeCount := instance.Status.TrialsPending + instance.Status.TrialsRunning - completedCount := instance.Status.TrialsSucceeded + instance.Status.TrialsFailed + instance.Status.TrialsKilled - - if activeCount > parallelCount { - deleteCount := activeCount - parallelCount - if deleteCount > 0 { - //delete 'deleteCount' number of trails. Sort them? - logger.Info("DeleteTrials", "deleteCount", deleteCount) - if err := r.deleteTrials(instance, trials, deleteCount); err != nil { - logger.Error(err, "Delete trials error") - return err - } - } - - } else if activeCount < parallelCount { - var requiredActiveCount int32 - if instance.Spec.MaxTrialCount == nil { - requiredActiveCount = parallelCount - } else { - requiredActiveCount = *instance.Spec.MaxTrialCount - completedCount - if requiredActiveCount > parallelCount { - requiredActiveCount = parallelCount - } - } - - addCount := requiredActiveCount - activeCount - if addCount < 0 { - logger.Info("Invalid setting", "requiredActiveCount", requiredActiveCount, "MaxTrialCount", - *instance.Spec.MaxTrialCount, "CompletedCount", completedCount) - addCount = 0 - } - - //skip if no trials need to be created - if addCount > 0 { - //create "addCount" number of trials - logger.Info("CreateTrials", "addCount", addCount) - if err := r.createTrials(instance, addCount); err != nil { - logger.Error(err, "Create trials error") - return err - } - } - } - - return nil - -} - -func (r *ReconcileExperiment) createTrials(instance *experimentsv1alpha2.Experiment, addCount int32) error { - - logger := log.WithValues("Experiment", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) - trials, err := r.GetSuggestions(instance, addCount) - if err != nil { - logger.Error(err, "Get suggestions error") - return err - } - if len(trials) == 0 { - // for some suggestion services, such as hyperband, it will stop generating new trial once some condition satisfied - util.UpdateExperimentStatusCondition(instance, false, true) - } - for _, trial := range trials { - if err = r.createTrialInstance(instance, trial); err != nil { - logger.Error(err, "Create trial instance error", "trial", trial) - continue - } - } - return nil -} - -func (r *ReconcileExperiment) deleteTrials(instance *experimentsv1alpha2.Experiment, - trials []trialsv1alpha2.Trial, - deleteCount int32) error { - logger := log.WithValues("Experiment", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) - - trialSlice := trials - sort.Slice(trialSlice, func(i, j int) bool { - return trialSlice[i].CreationTimestamp.Time. - After(trialSlice[j].CreationTimestamp.Time) - }) - - for i := 0; i < int(deleteCount); i++ { - if err := r.Delete(context.TODO(), &trialSlice[i]); err != nil { - logger.Error(err, "Trial Delete error") - return err - } - } - return nil -} diff --git a/pkg/controller.v1alpha2/experiment/experiment_controller_suite_test.go b/pkg/controller.v1alpha2/experiment/experiment_controller_suite_test.go deleted file mode 100644 index be510d8f3b7..00000000000 --- a/pkg/controller.v1alpha2/experiment/experiment_controller_suite_test.go +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package experiment - -import ( - stdlog "log" - "os" - "path/filepath" - "sync" - "testing" - "time" - - "github.com/onsi/gomega" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - apis "github.com/kubeflow/katib/pkg/apis/controller" -) - -var ( - cfg *rest.Config - controlPlaneStartTimeout = 60 * time.Second - controlPlaneStopTimeout = 60 * time.Second -) - -func TestMain(m *testing.M) { - t := &envtest.Environment{ - ControlPlaneStartTimeout: controlPlaneStartTimeout, - ControlPlaneStopTimeout: controlPlaneStopTimeout, - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "manifests", "v1alpha2", "katib-controller"), - filepath.Join("..", "..", "..", "test", "unit", "v1alpha2", "crds"), - }, - } - apis.AddToScheme(scheme.Scheme) - - var err error - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - - code := m.Run() - t.Stop() - os.Exit(code) -} - -// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner. -func SetupTestReconcile(inner reconcile.Reconciler) reconcile.Reconciler { - fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { - result, err := inner.Reconcile(req) - return result, err - }) - return fn -} - -// StartTestManager adds recFn -func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { - stop := make(chan struct{}) - wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) - }() - return stop, wg -} - -// addForTestPurpose adds a new Controller to mgr with r as the reconcile.Reconciler. -func addForTestPurpose(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New("test-experiment-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - log.Error(err, "Failed to create experiment controller for test purpose.") - return err - } - - if err = addWatch(mgr, c); err != nil { - log.Error(err, "Trial watch failed") - return err - } - - log.Info("Experiment controller created") - return nil -} diff --git a/pkg/controller.v1alpha2/experiment/experiment_controller_test.go b/pkg/controller.v1alpha2/experiment/experiment_controller_test.go deleted file mode 100644 index e423c2351c6..00000000000 --- a/pkg/controller.v1alpha2/experiment/experiment_controller_test.go +++ /dev/null @@ -1,307 +0,0 @@ -package experiment - -import ( - "context" - "testing" - "time" - - "github.com/golang/mock/gomock" - "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - - commonapiv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/consts" - managerclientmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/experiment/managerclient" - manifestmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/experiment/manifest" - suggestionmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/experiment/suggestion" -) - -const ( - experimentName = "foo" - namespace = "default" - - timeout = time.Second * 40 -) - -var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: experimentName, Namespace: namespace}} -var trialKey = types.NamespacedName{Name: "test", Namespace: namespace} - -func init() { - logf.SetLogger(logf.ZapLogger(true)) -} - -func TestCreateExperiment(t *testing.T) { - g := gomega.NewGomegaWithT(t) - instance := newFakeInstance() - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - mc := managerclientmock.NewMockManagerClient(mockCtrl) - mc.EXPECT().CreateExperimentInDB(gomock.Any()).Return(nil).AnyTimes() - mc.EXPECT().UpdateExperimentStatusInDB(gomock.Any()).Return(nil).AnyTimes() - mc.EXPECT().DeleteExperimentInDB(gomock.Any()).Return(nil).AnyTimes() - - mockCtrl2 := gomock.NewController(t) - defer mockCtrl2.Finish() - suggestion := suggestionmock.NewMockSuggestion(mockCtrl) - - mockCtrl3 := gomock.NewController(t) - defer mockCtrl3.Finish() - generator := manifestmock.NewMockGenerator(mockCtrl) - - // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a - // channel when it is finished. - mgr, err := manager.New(cfg, manager.Options{}) - g.Expect(err).NotTo(gomega.HaveOccurred()) - c := mgr.GetClient() - - recFn := SetupTestReconcile(&ReconcileExperiment{ - Client: mgr.GetClient(), - scheme: mgr.GetScheme(), - ManagerClient: mc, - Suggestion: suggestion, - Generator: generator, - updateStatusHandler: func(instance *experimentsv1alpha2.Experiment) error { - if !instance.IsCreated() { - t.Errorf("Expected got condition created") - } - return nil - }, - }) - g.Expect(addForTestPurpose(mgr, recFn)).NotTo(gomega.HaveOccurred()) - - stopMgr, mgrStopped := StartTestManager(mgr, g) - - defer func() { - close(stopMgr) - mgrStopped.Wait() - }() - - // Create the Trial object and expect the Reconcile and Deployment to be created - err = c.Create(context.TODO(), instance) - // The instance object may not be a valid object because it might be missing some required fields. - // Please modify the instance object by adding required fields and then remove the following if statement. - if apierrors.IsInvalid(err) { - t.Logf("failed to create object, got an invalid object error: %v", err) - return - } - g.Expect(err).NotTo(gomega.HaveOccurred()) - - g.Expect(c.Delete(context.TODO(), instance)).NotTo(gomega.HaveOccurred()) - g.Eventually(func() bool { - return errors.IsNotFound(c.Get(context.TODO(), - expectedRequest.NamespacedName, instance)) - }, timeout).Should(gomega.BeTrue()) -} - -func TestReconcileExperiment(t *testing.T) { - g := gomega.NewGomegaWithT(t) - testName := "tn" - instance := newFakeInstance() - instance.Name = testName - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - mc := managerclientmock.NewMockManagerClient(mockCtrl) - mc.EXPECT().CreateExperimentInDB(gomock.Any()).Return(nil).AnyTimes() - mc.EXPECT().UpdateExperimentStatusInDB(gomock.Any()).Return(nil).AnyTimes() - mc.EXPECT().DeleteExperimentInDB(gomock.Any()).Return(nil).AnyTimes() - - mockCtrl2 := gomock.NewController(t) - defer mockCtrl2.Finish() - suggestion := suggestionmock.NewMockSuggestion(mockCtrl) - suggestion.EXPECT().GetSuggestions(gomock.Any(), gomock.Any()).Return([]*api_pb.Trial{ - { - Name: trialKey.Name, - Spec: &api_pb.TrialSpec{}, - }, - }, nil).AnyTimes() - - mockCtrl3 := gomock.NewController(t) - defer mockCtrl3.Finish() - generator := manifestmock.NewMockGenerator(mockCtrl) - generator.EXPECT().GetRunSpecWithHyperParameters(gomock.Any(), gomock.Any(), - gomock.Any(), gomock.Any(), gomock.Any()).Return(`apiVersion: "kubeflow.org/v1" -kind: "TFJob" -metadata: - name: "test" - namespace: "default" -spec: - tfReplicaSpecs: - PS: - replicas: 2 - restartPolicy: Never - template: - spec: - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 - Worker: - replicas: 4 - restartPolicy: Never - template: - spec: - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0`, nil).AnyTimes() - generator.EXPECT().GetMetricsCollectorManifest( - gomock.Any(), gomock.Any(), - gomock.Any(), gomock.Any(), - gomock.Any(), gomock.Any()).Return(`apiVersion: batch/v1beta1 -kind: CronJob -metadata: - name: test - namespace: default -spec: - schedule: "*/1 * * * *" - successfulJobsHistoryLimit: 0 - failedJobsHistoryLimit: 1 - jobTemplate: - spec: - backoffLimit: 0 - template: - spec: - serviceAccountName: metrics-collector - containers: - - name: test - image: katib/metrics-collector - args: - - "./metricscollector.v1alpha2" - - "-e" - - "teste" - - "-t" - - "test" - - "-k" - - "TFJob" - - "-n" - - "default" - - "-m" - - "test" - - "-mn" - - "test" - restartPolicy: Never`, nil).AnyTimes() - - mgr, err := manager.New(cfg, manager.Options{}) - g.Expect(err).NotTo(gomega.HaveOccurred()) - c := mgr.GetClient() - - r := &ReconcileExperiment{ - Client: mgr.GetClient(), - scheme: mgr.GetScheme(), - ManagerClient: mc, - Suggestion: suggestion, - Generator: generator, - } - r.updateStatusHandler = func(instance *experimentsv1alpha2.Experiment) error { - if !instance.IsCreated() { - t.Errorf("Expected got condition created") - } - return r.updateStatus(instance) - } - - recFn := SetupTestReconcile(r) - g.Expect(addForTestPurpose(mgr, recFn)).NotTo(gomega.HaveOccurred()) - - stopMgr, mgrStopped := StartTestManager(mgr, g) - - defer func() { - close(stopMgr) - mgrStopped.Wait() - }() - - // Create the Trial object and expect the Reconcile and Deployment to be created - err = c.Create(context.TODO(), instance) - // The instance object may not be a valid object because it might be missing some required fields. - // Please modify the instance object by adding required fields and then remove the following if statement. - if apierrors.IsInvalid(err) { - t.Logf("failed to create object, got an invalid object error: %v", err) - return - } - g.Expect(err).NotTo(gomega.HaveOccurred()) - - trials := &trialsv1alpha2.TrialList{} - g.Eventually(func() int { - label := labels.Set{ - consts.LabelExperimentName: testName, - } - c.List(context.TODO(), &client.ListOptions{ - LabelSelector: label.AsSelector(), - }, trials) - return len(trials.Items) - }, timeout). - Should(gomega.Equal(1)) - - g.Expect(c.Delete(context.TODO(), instance)).NotTo(gomega.HaveOccurred()) - g.Eventually(func() bool { - return errors.IsNotFound(c.Get(context.TODO(), - types.NamespacedName{Namespace: instance.Namespace, Name: instance.Name}, instance)) - }, timeout).Should(gomega.BeTrue()) -} - -func newFakeInstance() *experimentsv1alpha2.Experiment { - var parallelCount int32 = 1 - var goal float64 = 99.9 - return &experimentsv1alpha2.Experiment{ - ObjectMeta: metav1.ObjectMeta{ - Name: experimentName, - Namespace: namespace, - }, - Spec: experimentsv1alpha2.ExperimentSpec{ - RetainHistoricalData: false, - ParallelTrialCount: ¶llelCount, - MaxTrialCount: ¶llelCount, - Objective: &commonapiv1alpha2.ObjectiveSpec{ - Type: commonapiv1alpha2.ObjectiveTypeMaximize, - Goal: &goal, - ObjectiveMetricName: "accuracy", - }, - TrialTemplate: &experimentsv1alpha2.TrialTemplate{ - GoTemplate: &experimentsv1alpha2.GoTemplate{ - RawTemplate: `apiVersion: "kubeflow.org/v1" -kind: TFJob -metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} -spec: - tfReplicaSpecs: - Worker: - replicas: 1 - restartPolicy: OnFailure - template: - spec: - containers: - - name: tensorflow - image: gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0 - imagePullPolicy: Always - command: - - "python" - - "/var/tf_mnist/mnist_with_summaries.py" - - "--log_dir=/train/{{.Trial}}" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}} - volumeMounts: - - mountPath: "/train" - name: "train" - volumes: - - name: "train" - persistentVolumeClaim: - claimName: "tfevent-volume"`, - }, - }, - }, - } -} diff --git a/pkg/controller.v1alpha2/experiment/experiment_status.go b/pkg/controller.v1alpha2/experiment/experiment_status.go deleted file mode 100644 index 7acb120cd1e..00000000000 --- a/pkg/controller.v1alpha2/experiment/experiment_status.go +++ /dev/null @@ -1,17 +0,0 @@ -package experiment - -import ( - "context" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" -) - -type updateStatusFunc func(instance *experimentsv1alpha2.Experiment) error - -func (r *ReconcileExperiment) updateStatus(instance *experimentsv1alpha2.Experiment) error { - err := r.Status().Update(context.TODO(), instance) - if err != nil { - return err - } - return nil -} diff --git a/pkg/controller.v1alpha2/experiment/experiment_util.go b/pkg/controller.v1alpha2/experiment/experiment_util.go deleted file mode 100644 index 72a8bf7f888..00000000000 --- a/pkg/controller.v1alpha2/experiment/experiment_util.go +++ /dev/null @@ -1,108 +0,0 @@ -package experiment - -import ( - "bytes" - "context" - "fmt" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - utilrand "k8s.io/apimachinery/pkg/util/rand" - k8syaml "k8s.io/apimachinery/pkg/util/yaml" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - common "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - apiv1alpha2 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/consts" -) - -func (r *ReconcileExperiment) createTrialInstance(expInstance *experimentsv1alpha2.Experiment, trialInstance *apiv1alpha2.Trial) error { - BUFSIZE := 1024 - logger := log.WithValues("Experiment", types.NamespacedName{Name: expInstance.GetName(), Namespace: expInstance.GetNamespace()}) - - trial := &trialsv1alpha2.Trial{} - trial.Name = fmt.Sprintf("%s-%s", expInstance.GetName(), utilrand.String(8)) - trial.Namespace = expInstance.GetNamespace() - trial.Labels = map[string]string{consts.LabelExperimentName: expInstance.GetName()} - - if err := controllerutil.SetControllerReference(expInstance, trial, r.scheme); err != nil { - logger.Error(err, "Set controller reference error") - return err - } - - trial.Spec.Objective = expInstance.Spec.Objective - - hps := make([]*apiv1alpha2.ParameterAssignment, 0) - if trialInstance.Spec != nil && trialInstance.Spec.ParameterAssignments != nil { - for _, p := range trialInstance.Spec.ParameterAssignments.Assignments { - hps = append(hps, p) - pa := common.ParameterAssignment{ - Name: p.Name, - Value: p.Value, - } - trial.Spec.ParameterAssignments = append(trial.Spec.ParameterAssignments, pa) - } - } - - runSpec, err := r.GetRunSpecWithHyperParameters(expInstance, expInstance.GetName(), trial.Name, trial.Namespace, hps) - if err != nil { - logger.Error(err, "Fail to get RunSpec from experiment", expInstance.Name) - return err - } - - trial.Spec.RunSpec = runSpec - if expInstance.Spec.TrialTemplate != nil { - trial.Spec.RetainRun = expInstance.Spec.TrialTemplate.Retain - } - - buf := bytes.NewBufferString(runSpec) - job := &unstructured.Unstructured{} - if err := k8syaml.NewYAMLOrJSONDecoder(buf, BUFSIZE).Decode(job); err != nil { - return fmt.Errorf("Invalid spec.trialTemplate: %v.", err) - } - - var metricNames []string - metricNames = append(metricNames, expInstance.Spec.Objective.ObjectiveMetricName) - for _, mn := range expInstance.Spec.Objective.AdditionalMetricNames { - metricNames = append(metricNames, mn) - } - - mcSpec, err := r.GetMetricsCollectorManifest(expInstance.GetName(), trial.Name, job.GetKind(), trial.Namespace, metricNames, expInstance.Spec.MetricsCollectorSpec) - if err != nil { - logger.Error(err, "Error getting metrics collector manifest") - return err - } - trial.Spec.MetricsCollectorSpec = mcSpec - - if expInstance.Spec.MetricsCollectorSpec != nil { - trial.Spec.RetainMetricsCollector = expInstance.Spec.MetricsCollectorSpec.Retain - } - - if err := r.Create(context.TODO(), trial); err != nil { - logger.Error(err, "Trial create error", "Trial name", trial.Name) - return err - } - return nil - -} - -func (r *ReconcileExperiment) updateFinalizers(instance *experimentsv1alpha2.Experiment, finalizers []string) (reconcile.Result, error) { - logger := log.WithValues("Experiment", types.NamespacedName{Name: instance.Name, Namespace: instance.Namespace}) - if !instance.ObjectMeta.DeletionTimestamp.IsZero() { - if err := r.DeleteExperimentInDB(instance); err != nil { - logger.Error(err, "Fail to delete data in DB") - return reconcile.Result{}, err - } - } - instance.SetFinalizers(finalizers) - if err := r.Update(context.TODO(), instance); err != nil { - logger.Error(err, "Fail to update finalizers") - return reconcile.Result{}, err - } else { - // Need to requeue because finalizer update does not change metadata.generation - return reconcile.Result{Requeue: true}, err - } -} diff --git a/pkg/controller.v1alpha2/experiment/managerclient/managerclient.go b/pkg/controller.v1alpha2/experiment/managerclient/managerclient.go deleted file mode 100644 index 2c71d414fcb..00000000000 --- a/pkg/controller.v1alpha2/experiment/managerclient/managerclient.go +++ /dev/null @@ -1,261 +0,0 @@ -package managerclient - -import ( - commonapiv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - commonv1alpha2 "github.com/kubeflow/katib/pkg/common/v1alpha2" -) - -// ManagerClient is the interface for katib manager client -// in experiment controller. -type ManagerClient interface { - CreateExperimentInDB(instance *experimentsv1alpha2.Experiment) error - DeleteExperimentInDB(instance *experimentsv1alpha2.Experiment) error - UpdateExperimentStatusInDB(instance *experimentsv1alpha2.Experiment) error - PreCheckRegisterExperimentInDB(inst *experimentsv1alpha2.Experiment) (*api_pb.PreCheckRegisterExperimentReply, error) - ValidateAlgorithmSettings(inst *experimentsv1alpha2.Experiment) (*api_pb.ValidateAlgorithmSettingsReply, error) -} - -// DefaultClient implements the Client interface. -type DefaultClient struct { -} - -// New creates a new ManagerClient. -func New() ManagerClient { - return &DefaultClient{} -} - -func (d *DefaultClient) CreateExperimentInDB(instance *experimentsv1alpha2.Experiment) error { - experiment := getExperimentConf(instance) - request := &api_pb.RegisterExperimentRequest{ - Experiment: experiment, - } - if _, err := commonv1alpha2.RegisterExperiment(request); err != nil { - return err - } - if len(experiment.Spec.Algorithm.AlgorithmSetting) > 0 { - req := &api_pb.UpdateAlgorithmExtraSettingsRequest{ - ExperimentName: experiment.Name, - ExtraAlgorithmSettings: experiment.Spec.Algorithm.AlgorithmSetting, - } - - if _, err := commonv1alpha2.UpdateAlgorithmExtraSettings(req); err != nil { - return err - } - - } - return nil -} - -func (d *DefaultClient) DeleteExperimentInDB(instance *experimentsv1alpha2.Experiment) error { - request := &api_pb.DeleteExperimentRequest{ - ExperimentName: instance.Name, - } - if _, err := commonv1alpha2.DeleteExperiment(request); err != nil { - return err - } - return nil -} - -func (d *DefaultClient) UpdateExperimentStatusInDB(instance *experimentsv1alpha2.Experiment) error { - newStatus := &api_pb.ExperimentStatus{ - StartTime: commonv1alpha2.ConvertTime2RFC3339(instance.Status.StartTime), - CompletionTime: commonv1alpha2.ConvertTime2RFC3339(instance.Status.CompletionTime), - Condition: getCondition(instance), - } - request := &api_pb.UpdateExperimentStatusRequest{ - NewStatus: newStatus, - ExperimentName: instance.Name, - } - if _, err := commonv1alpha2.UpdateExperimentStatus(request); err != nil { - return err - } - return nil -} - -func (d *DefaultClient) PreCheckRegisterExperimentInDB(inst *experimentsv1alpha2.Experiment) (*api_pb.PreCheckRegisterExperimentReply, error) { - experiment := getExperimentConf(inst) - request := &api_pb.RegisterExperimentRequest{ - Experiment: experiment, - } - return commonv1alpha2.PreCheckRegisterExperiment(request) -} - -func (d *DefaultClient) ValidateAlgorithmSettings(inst *experimentsv1alpha2.Experiment) (*api_pb.ValidateAlgorithmSettingsReply, error) { - algorithmName := inst.Spec.Algorithm.AlgorithmName - request := &api_pb.ValidateAlgorithmSettingsRequest{ - AlgorithmName: algorithmName, - ExperimentSpec: getExperimentSpec(inst), - } - - return commonv1alpha2.ValidateAlgorithmSettings(request) - -} - -func getExperimentConf(instance *experimentsv1alpha2.Experiment) *api_pb.Experiment { - experiment := &api_pb.Experiment{ - Spec: getExperimentSpec(instance), - Status: &api_pb.ExperimentStatus{ - StartTime: commonv1alpha2.ConvertTime2RFC3339(instance.Status.StartTime), - CompletionTime: commonv1alpha2.ConvertTime2RFC3339(instance.Status.CompletionTime), - Condition: getCondition(instance), - }, - } - experiment.Name = instance.Name - - return experiment - -} - -func getCondition(inst *experimentsv1alpha2.Experiment) api_pb.ExperimentStatus_ExperimentConditionType { - condition, _ := inst.GetLastConditionType() - switch condition { - case experimentsv1alpha2.ExperimentCreated: - return api_pb.ExperimentStatus_CREATED - case experimentsv1alpha2.ExperimentRunning: - return api_pb.ExperimentStatus_RUNNING - case experimentsv1alpha2.ExperimentRestarting: - return api_pb.ExperimentStatus_RESTARTING - case experimentsv1alpha2.ExperimentSucceeded: - return api_pb.ExperimentStatus_SUCCEEDED - case experimentsv1alpha2.ExperimentFailed: - return api_pb.ExperimentStatus_FAILED - default: - return api_pb.ExperimentStatus_UNKNOWN - } -} - -func getExperimentSpec(instance *experimentsv1alpha2.Experiment) *api_pb.ExperimentSpec { - - experimentSpec := &api_pb.ExperimentSpec{ - Objective: &api_pb.ObjectiveSpec{ - AdditionalMetricNames: []string{}, - }, - Algorithm: &api_pb.AlgorithmSpec{ - AlgorithmSetting: []*api_pb.AlgorithmSetting{}, - }, - ParallelTrialCount: *instance.Spec.ParallelTrialCount, - } - - //Populate Objective - switch instance.Spec.Objective.Type { - case commonapiv1alpha2.ObjectiveTypeMaximize: - experimentSpec.Objective.Type = api_pb.ObjectiveType_MAXIMIZE - case commonapiv1alpha2.ObjectiveTypeMinimize: - experimentSpec.Objective.Type = api_pb.ObjectiveType_MINIMIZE - default: - experimentSpec.Objective.Type = api_pb.ObjectiveType_UNKNOWN - - } - experimentSpec.Objective.Goal = float32(*instance.Spec.Objective.Goal) - experimentSpec.Objective.ObjectiveMetricName = instance.Spec.Objective.ObjectiveMetricName - for _, m := range instance.Spec.Objective.AdditionalMetricNames { - experimentSpec.Objective.AdditionalMetricNames = append(experimentSpec.Objective.AdditionalMetricNames, m) - } - - //Populate Algorithm Spec - experimentSpec.Algorithm.AlgorithmName = instance.Spec.Algorithm.AlgorithmName - - for _, as := range instance.Spec.Algorithm.AlgorithmSettings { - experimentSpec.Algorithm.AlgorithmSetting = append( - experimentSpec.Algorithm.AlgorithmSetting, - &api_pb.AlgorithmSetting{ - Name: as.Name, - Value: as.Value, - }) - } - - //Populate HP Experiment - if instance.Spec.Parameters != nil { - parameterSpecs := &api_pb.ExperimentSpec_ParameterSpecs{ - Parameters: []*api_pb.ParameterSpec{}, - } - for _, p := range instance.Spec.Parameters { - parameter := &api_pb.ParameterSpec{ - FeasibleSpace: &api_pb.FeasibleSpace{}, - } - parameter.Name = p.Name - parameter.FeasibleSpace.Min = p.FeasibleSpace.Min - parameter.FeasibleSpace.Max = p.FeasibleSpace.Max - parameter.FeasibleSpace.List = p.FeasibleSpace.List - parameter.FeasibleSpace.Step = p.FeasibleSpace.Step - - switch p.ParameterType { - case experimentsv1alpha2.ParameterTypeCategorical: - parameter.ParameterType = api_pb.ParameterType_CATEGORICAL - case experimentsv1alpha2.ParameterTypeDiscrete: - parameter.ParameterType = api_pb.ParameterType_DISCRETE - case experimentsv1alpha2.ParameterTypeDouble: - parameter.ParameterType = api_pb.ParameterType_DOUBLE - case experimentsv1alpha2.ParameterTypeInt: - parameter.ParameterType = api_pb.ParameterType_INT - case experimentsv1alpha2.ParameterTypeUnknown: - parameter.ParameterType = api_pb.ParameterType_UNKNOWN_TYPE - } - parameterSpecs.Parameters = append(parameterSpecs.Parameters, parameter) - } - experimentSpec.ParameterSpecs = parameterSpecs - } - - //Populate NAS Experiment - if instance.Spec.NasConfig != nil { - - nasConfig := &api_pb.NasConfig{ - GraphConfig: &api_pb.GraphConfig{}, - Operations: &api_pb.NasConfig_Operations{ - Operation: []*api_pb.Operation{}, - }, - } - - nasConfig.GraphConfig.NumLayers = *instance.Spec.NasConfig.GraphConfig.NumLayers - - for _, i := range instance.Spec.NasConfig.GraphConfig.InputSizes { - nasConfig.GraphConfig.InputSizes = append(nasConfig.GraphConfig.InputSizes, i) - } - - for _, o := range instance.Spec.NasConfig.GraphConfig.OutputSizes { - nasConfig.GraphConfig.OutputSizes = append(nasConfig.GraphConfig.OutputSizes, o) - } - - for _, op := range instance.Spec.NasConfig.Operations { - operation := &api_pb.Operation{ - ParameterSpecs: &api_pb.Operation_ParameterSpecs{ - Parameters: []*api_pb.ParameterSpec{}, - }, - } - - operation.OperationType = op.OperationType - - for _, p := range op.Parameters { - parameter := &api_pb.ParameterSpec{ - FeasibleSpace: &api_pb.FeasibleSpace{}, - } - parameter.Name = p.Name - parameter.FeasibleSpace.Min = p.FeasibleSpace.Min - parameter.FeasibleSpace.Max = p.FeasibleSpace.Max - parameter.FeasibleSpace.List = p.FeasibleSpace.List - parameter.FeasibleSpace.Step = p.FeasibleSpace.Step - - switch p.ParameterType { - case experimentsv1alpha2.ParameterTypeCategorical: - parameter.ParameterType = api_pb.ParameterType_CATEGORICAL - case experimentsv1alpha2.ParameterTypeDiscrete: - parameter.ParameterType = api_pb.ParameterType_DISCRETE - case experimentsv1alpha2.ParameterTypeDouble: - parameter.ParameterType = api_pb.ParameterType_DOUBLE - case experimentsv1alpha2.ParameterTypeInt: - parameter.ParameterType = api_pb.ParameterType_INT - case experimentsv1alpha2.ParameterTypeUnknown: - parameter.ParameterType = api_pb.ParameterType_UNKNOWN_TYPE - } - operation.ParameterSpecs.Parameters = append(operation.ParameterSpecs.Parameters, parameter) - } - nasConfig.Operations.Operation = append(nasConfig.Operations.Operation, operation) - } - - experimentSpec.NasConfig = nasConfig - } - - return experimentSpec -} diff --git a/pkg/controller.v1alpha2/experiment/manifest/generator.go b/pkg/controller.v1alpha2/experiment/manifest/generator.go deleted file mode 100644 index cd04f329fa4..00000000000 --- a/pkg/controller.v1alpha2/experiment/manifest/generator.go +++ /dev/null @@ -1,160 +0,0 @@ -package manifest - -import ( - "bytes" - "errors" - "fmt" - "strings" - "text/template" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - apiv1alpha2 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - commonv1alpha2 "github.com/kubeflow/katib/pkg/common/v1alpha2" - "github.com/kubeflow/katib/pkg/util/v1alpha2/katibclient" -) - -const ( - defaultMetricsCollectorTemplateName = "defaultMetricsCollectorTemplate.yaml" -) - -// Generator is the type for manifests Generator. -type Generator interface { - InjectClient(c client.Client) - GetRunSpec(e *experimentsv1alpha2.Experiment, experiment, trial, namespace string) (string, error) - GetRunSpecWithHyperParameters(e *experimentsv1alpha2.Experiment, experiment, trial, namespace string, hps []*apiv1alpha2.ParameterAssignment) (string, error) - GetMetricsCollectorManifest(experimentName string, trialName string, jobKind string, namespace string, metricNames []string, mcs *experimentsv1alpha2.MetricsCollectorSpec) (string, error) -} - -// DefaultGenerator is the default implementation of Generator. -type DefaultGenerator struct { - client katibclient.Client -} - -// New creates a new Generator. -func New(c client.Client) Generator { - katibClient := katibclient.NewWithGivenClient(c) - return &DefaultGenerator{ - client: katibClient, - } -} - -func (g *DefaultGenerator) InjectClient(c client.Client) { - g.client.InjectClient(c) -} - -func (g *DefaultGenerator) GetMetricsCollectorManifest(experimentName string, trialName string, jobKind string, namespace string, metricNames []string, mcs *experimentsv1alpha2.MetricsCollectorSpec) (string, error) { - var mtp *template.Template = nil - var err error - tmpValues := map[string]string{ - "Experiment": experimentName, - "Trial": trialName, - "JobKind": jobKind, - "NameSpace": namespace, - "ManagerService": commonv1alpha2.GetManagerAddr(), - "MetricNames": strings.Join(metricNames, ";"), - } - if mcs != nil && mcs.GoTemplate.RawTemplate != "" { - mtp, err = template.New("MetricsCollector").Parse(mcs.GoTemplate.RawTemplate) - } else { - mctp := defaultMetricsCollectorTemplateName - if mcs != nil && mcs.GoTemplate.TemplateSpec != nil { - mctp = mcs.GoTemplate.TemplateSpec.TemplatePath - } - mtl, err := g.client.GetMetricsCollectorTemplates() - if err != nil { - return "", err - } - if mt, ok := mtl[mctp]; !ok { - return "", fmt.Errorf("No MetricsCollector template name %s", mctp) - } else { - mtp, err = template.New("MetricsCollector").Parse(mt) - } - } - if err != nil { - return "", err - } - var b bytes.Buffer - err = mtp.Execute(&b, tmpValues) - if err != nil { - return "", err - } - return b.String(), nil -} - -// GetRunSpec get the specification for trial. -func (g *DefaultGenerator) GetRunSpec(e *experimentsv1alpha2.Experiment, experiment, trial, namespace string) (string, error) { - params := trialTemplateParams{ - Experiment: experiment, - Trial: trial, - NameSpace: namespace, - } - return g.getRunSpec(e, params) -} - -// GetRunSpecWithHyperParameters get the specification for trial with hyperparameters. -func (g *DefaultGenerator) GetRunSpecWithHyperParameters(e *experimentsv1alpha2.Experiment, experiment, trial, namespace string, hps []*apiv1alpha2.ParameterAssignment) (string, error) { - params := trialTemplateParams{ - Experiment: experiment, - Trial: trial, - NameSpace: namespace, - HyperParameters: hps, - } - return g.getRunSpec(e, params) -} - -func (g *DefaultGenerator) getRunSpec(e *experimentsv1alpha2.Experiment, params trialTemplateParams) (string, error) { - var buf bytes.Buffer - trialTemplate, err := g.getTrialTemplate(e) - if err != nil { - return "", err - } - if err := trialTemplate.Execute(&buf, params); err != nil { - return "", err - } - return buf.String(), nil -} - -func (g *DefaultGenerator) getTrialTemplate(instance *experimentsv1alpha2.Experiment) (*template.Template, error) { - var err error - var tpl *template.Template = nil - - trialTemplate := instance.Spec.TrialTemplate - if trialTemplate.GoTemplate.RawTemplate != "" { - tpl, err = template.New("Trial").Parse(trialTemplate.GoTemplate.RawTemplate) - if err != nil { - return nil, err - } - } else { - templateSpec := trialTemplate.GoTemplate.TemplateSpec - configMapNS := templateSpec.ConfigMapNamespace - configMapName := templateSpec.ConfigMapName - templatePath := templateSpec.TemplatePath - - configMap, err := g.client.GetConfigMap(configMapName, configMapNS) - if err != nil { - return nil, err - } - - if configMapTemplate, ok := configMap[templatePath]; !ok { - err = errors.New(string(metav1.StatusReasonNotFound)) - return nil, err - } else { - tpl, err = template.New("Trial").Parse(configMapTemplate) - if err != nil { - return nil, err - } - } - } - - return tpl, nil -} - -type trialTemplateParams struct { - Experiment string - Trial string - NameSpace string - HyperParameters []*apiv1alpha2.ParameterAssignment -} diff --git a/pkg/controller.v1alpha2/experiment/manifest/generator_test.go b/pkg/controller.v1alpha2/experiment/manifest/generator_test.go deleted file mode 100644 index 9761bacdf5e..00000000000 --- a/pkg/controller.v1alpha2/experiment/manifest/generator_test.go +++ /dev/null @@ -1,295 +0,0 @@ -package manifest - -import ( - "reflect" - "testing" - "text/template" - - "github.com/golang/mock/gomock" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - apiv1alpha2 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - katibclientmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/util/katibclient" -) - -const ( - rawTemplate = `apiVersion: batch/v1 -kind: Job -metadata: -name: {{.Trial}} -namespace: {{.NameSpace}} -spec: - template: - spec: - containers: - - name: {{.Trial}} - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - {{- with .HyperParameters}} - {{- range .}} - - "{{.Name}}={{.Value}}" - {{- end}} - {{- end}}` - rawMetricsCollector = `apiVersion: v1 -kind: ConfigMap -metadata: - name: metrics-collector-template - namespace: kubeflow -data: - defaultMetricsCollectorTemplate.yaml : |- - apiVersion: batch/v1beta1 - kind: CronJob - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - schedule: "*/1 * * * *" - successfulJobsHistoryLimit: 0 - failedJobsHistoryLimit: 1 - jobTemplate: - spec: - backoffLimit: 0 - template: - spec: - serviceAccountName: metrics-collector - containers: - - name: {{.Trial}} - image: katib/metrics-collector - args: - - "./metricscollector.v1alpha2" - - "-e" - - "{{.Experiment}}" - - "-t" - - "{{.Trial}}" - - "-k" - - "{{.JobKind}}" - - "-n" - - "{{.NameSpace}}" - - "-mn" - - "{{.MetricNames}}"` -) - -func TestGetMetricsCollectorManifest(t *testing.T) { - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - c := katibclientmock.NewMockClient(mockCtrl) - - p := &DefaultGenerator{ - client: c, - } - - c.EXPECT().GetMetricsCollectorTemplates(gomock.Any()).Return(map[string]string{ - defaultMetricsCollectorTemplateName: rawMetricsCollector, - }, nil) - - instance := newFakeInstance() - - actual, err := p.GetMetricsCollectorManifest("test", "test", "Job", "fakens", []string{"test"}, instance.Spec.MetricsCollectorSpec) - if err != nil { - t.Errorf("Expected nil, got %v", err) - } - expected := `apiVersion: v1 -kind: ConfigMap -metadata: - name: metrics-collector-template - namespace: kubeflow -data: - defaultMetricsCollectorTemplate.yaml : |- - apiVersion: batch/v1beta1 - kind: CronJob - metadata: - name: test - namespace: fakens - spec: - schedule: "*/1 * * * *" - successfulJobsHistoryLimit: 0 - failedJobsHistoryLimit: 1 - jobTemplate: - spec: - backoffLimit: 0 - template: - spec: - serviceAccountName: metrics-collector - containers: - - name: test - image: katib/metrics-collector - args: - - "./metricscollector.v1alpha2" - - "-e" - - "test" - - "-t" - - "test" - - "-k" - - "Job" - - "-n" - - "fakens" - - "-mn" - - "test"` - - if expected != actual { - t.Errorf("Expected %s, got %s", expected, actual) - } -} - -func TestGetTrialTemplateConfigMap(t *testing.T) { - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - c := katibclientmock.NewMockClient(mockCtrl) - - p := &DefaultGenerator{ - client: c, - } - - templatePath := "test.yaml" - - c.EXPECT().GetConfigMap(gomock.Any(), gomock.Any()).Return(map[string]string{ - templatePath: rawTemplate, - }, nil) - - instance := newFakeInstance() - instance.Spec.TrialTemplate.GoTemplate.TemplateSpec = &experimentsv1alpha2.TemplateSpec{ - TemplatePath: templatePath, - } - instance.Spec.TrialTemplate.GoTemplate.RawTemplate = "" - actual, err := p.getTrialTemplate(instance) - if err != nil { - t.Errorf("Expected nil, got %v", err) - } - expected, err := template.New("Trial").Parse(rawTemplate) - if err != nil { - t.Errorf("Expected nil, got %v", err) - } - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Expected %v, got %v", *expected, *actual) - } -} - -func TestGetTrialTemplate(t *testing.T) { - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - c := katibclientmock.NewMockClient(mockCtrl) - - p := &DefaultGenerator{ - client: c, - } - - tc := newFakeInstance() - - expected, err := template.New("Trial"). - Parse(tc.Spec.TrialTemplate.GoTemplate.RawTemplate) - if err != nil { - t.Errorf("Failed to compose expected result") - } - - actual, err := p.getTrialTemplate(tc) - if err != nil { - t.Errorf("Expected nil, got %v", err) - } - - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Expected %v, got %v", *expected, *actual) - } -} - -func TestGetRunSpec(t *testing.T) { - tc := newFakeInstance() - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - c := katibclientmock.NewMockClient(mockCtrl) - - p := &DefaultGenerator{ - client: c, - } - - actual, err := p.GetRunSpec(tc, "", "test", "testns") - if err != nil { - t.Errorf("Expected nil, got %v", err) - } - expected := `apiVersion: batch/v1 -kind: Job -metadata: -name: test -namespace: testns -spec: - template: - spec: - containers: - - name: test - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64"` - if expected != actual { - t.Errorf("Expected %s, got %s", expected, actual) - } -} - -func TestGetRunSpecWithHP(t *testing.T) { - tc := newFakeInstance() - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - c := katibclientmock.NewMockClient(mockCtrl) - - p := &DefaultGenerator{ - client: c, - } - - actual, err := p.GetRunSpecWithHyperParameters(tc, "", "test", "testns", []*apiv1alpha2.ParameterAssignment{ - { - Name: "testname", - Value: "testvalue", - }, - }) - if err != nil { - t.Errorf("Expected nil, got %v", err) - } - expected := `apiVersion: batch/v1 -kind: Job -metadata: -name: test -namespace: testns -spec: - template: - spec: - containers: - - name: test - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - - "testname=testvalue"` - if expected != actual { - t.Errorf("Expected %s, got %s", expected, actual) - } -} - -func newFakeInstance() *experimentsv1alpha2.Experiment { - return &experimentsv1alpha2.Experiment{ - Spec: experimentsv1alpha2.ExperimentSpec{ - TrialTemplate: &experimentsv1alpha2.TrialTemplate{ - GoTemplate: &experimentsv1alpha2.GoTemplate{ - RawTemplate: rawTemplate, - }, - }, - MetricsCollectorSpec: &experimentsv1alpha2.MetricsCollectorSpec{ - GoTemplate: experimentsv1alpha2.GoTemplate{ - TemplateSpec: &experimentsv1alpha2.TemplateSpec{ - TemplatePath: defaultMetricsCollectorTemplateName, - }, - }, - }, - }, - } -} diff --git a/pkg/controller.v1alpha2/experiment/suggestion/fake/fake.go b/pkg/controller.v1alpha2/experiment/suggestion/fake/fake.go deleted file mode 100644 index 1549b011d3a..00000000000 --- a/pkg/controller.v1alpha2/experiment/suggestion/fake/fake.go +++ /dev/null @@ -1,18 +0,0 @@ -package fake - -import ( - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/suggestion" -) - -type Fake struct { -} - -func New() suggestion.Suggestion { - return &Fake{} -} - -func (k *Fake) GetSuggestions(instance *experimentsv1alpha2.Experiment, addCount int32) ([]*api_pb.Trial, error) { - return nil, nil -} diff --git a/pkg/controller.v1alpha2/experiment/suggestion/suggestion.go b/pkg/controller.v1alpha2/experiment/suggestion/suggestion.go deleted file mode 100644 index 179c2ee33ac..00000000000 --- a/pkg/controller.v1alpha2/experiment/suggestion/suggestion.go +++ /dev/null @@ -1,31 +0,0 @@ -package suggestion - -import ( - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - common "github.com/kubeflow/katib/pkg/common/v1alpha2" -) - -type Suggestion interface { - GetSuggestions(instance *experimentsv1alpha2.Experiment, addCount int32) ([]*api_pb.Trial, error) -} - -type General struct { -} - -func New() Suggestion { - return &General{} -} - -func (g *General) GetSuggestions(instance *experimentsv1alpha2.Experiment, addCount int32) ([]*api_pb.Trial, error) { - request := &api_pb.GetSuggestionsRequest{ - ExperimentName: instance.Name, - AlgorithmName: instance.Spec.Algorithm.AlgorithmName, - RequestNumber: addCount, - } - if reply, err := common.GetSuggestions(request); err != nil { - return nil, err - } else { - return reply.Trials, nil - } -} diff --git a/pkg/controller.v1alpha2/experiment/util/status_util.go b/pkg/controller.v1alpha2/experiment/util/status_util.go deleted file mode 100644 index 1fda2ade1ee..00000000000 --- a/pkg/controller.v1alpha2/experiment/util/status_util.go +++ /dev/null @@ -1,173 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - - commonv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -var log = logf.Log.WithName("experiment-status-util") - -const ( - ExperimentCreatedReason = "ExperimentCreated" - ExperimentRunningReason = "ExperimentRunning" - ExperimentSucceededReason = "ExperimentSucceeded" - ExperimentFailedReason = "ExperimentFailed" - ExperimentKilledReason = "ExperimentKilled" -) - -func UpdateExperimentStatus(instance *experimentsv1alpha2.Experiment, trials *trialsv1alpha2.TrialList) error { - - isObjectiveGoalReached := updateTrialsSummary(instance, trials) - - UpdateExperimentStatusCondition(instance, isObjectiveGoalReached, false) - return nil - -} - -func updateTrialsSummary(instance *experimentsv1alpha2.Experiment, trials *trialsv1alpha2.TrialList) bool { - - var totalTrials, trialsPending, trialsRunning, trialsSucceeded, trialsFailed, trialsKilled int32 - var bestTrialValue float64 - bestTrialIndex := -1 - isObjectiveGoalReached := false - objectiveValueGoal := *instance.Spec.Objective.Goal - objectiveType := instance.Spec.Objective.Type - objectiveMetricName := instance.Spec.Objective.ObjectiveMetricName - - for index, trial := range trials.Items { - totalTrials++ - if trial.IsKilled() { - trialsKilled++ - } else if trial.IsFailed() { - trialsFailed++ - } else if trial.IsSucceeded() { - trialsSucceeded++ - } else if trial.IsRunning() { - trialsRunning++ - } else { - trialsPending++ - } - - objectiveMetricValue := getObjectiveMetricValue(trial, objectiveMetricName) - if objectiveMetricValue == nil { - log.Info("Objective metric name not found", "trial", trial.GetName()) - continue - } - - //intialize vars to objective metric value of the first trial - if bestTrialIndex == -1 { - bestTrialValue = *objectiveMetricValue - bestTrialIndex = index - } - - if objectiveType == commonv1alpha2.ObjectiveTypeMinimize { - if *objectiveMetricValue < bestTrialValue { - bestTrialValue = *objectiveMetricValue - bestTrialIndex = index - } - if bestTrialValue <= objectiveValueGoal { - isObjectiveGoalReached = true - } - } else if objectiveType == commonv1alpha2.ObjectiveTypeMaximize { - if *objectiveMetricValue > bestTrialValue { - bestTrialValue = *objectiveMetricValue - bestTrialIndex = index - } - if bestTrialValue >= objectiveValueGoal { - isObjectiveGoalReached = true - } - } - } - - instance.Status.Trials = totalTrials - instance.Status.TrialsPending = trialsPending - instance.Status.TrialsRunning = trialsRunning - instance.Status.TrialsSucceeded = trialsSucceeded - instance.Status.TrialsFailed = trialsFailed - instance.Status.TrialsKilled = trialsKilled - - // if best trial is set - if bestTrialIndex != -1 { - bestTrial := trials.Items[bestTrialIndex] - - instance.Status.CurrentOptimalTrial.ParameterAssignments = []commonv1alpha2.ParameterAssignment{} - for _, parameterAssigment := range bestTrial.Spec.ParameterAssignments { - instance.Status.CurrentOptimalTrial.ParameterAssignments = append(instance.Status.CurrentOptimalTrial.ParameterAssignments, parameterAssigment) - } - - instance.Status.CurrentOptimalTrial.Observation.Metrics = []commonv1alpha2.Metric{} - for _, metric := range bestTrial.Status.Observation.Metrics { - instance.Status.CurrentOptimalTrial.Observation.Metrics = append(instance.Status.CurrentOptimalTrial.Observation.Metrics, metric) - } - } - return isObjectiveGoalReached -} - -func getObjectiveMetricValue(trial trialsv1alpha2.Trial, objectiveMetricName string) *float64 { - if trial.Status.Observation == nil { - return nil - } - for _, metric := range trial.Status.Observation.Metrics { - if objectiveMetricName == metric.Name { - return &metric.Value - } - } - return nil -} - -func UpdateExperimentStatusCondition(instance *experimentsv1alpha2.Experiment, isObjectiveGoalReached bool, getSuggestionDone bool) { - - completedTrialsCount := instance.Status.TrialsSucceeded + instance.Status.TrialsFailed + instance.Status.TrialsKilled - failedTrialsCount := instance.Status.TrialsFailed - now := metav1.Now() - - if isObjectiveGoalReached { - msg := "Experiment has succeeded because Objective goal has reached" - instance.MarkExperimentStatusSucceeded(ExperimentSucceededReason, msg) - instance.Status.CompletionTime = &now - return - } - - if (instance.Spec.MaxTrialCount != nil) && (completedTrialsCount >= *instance.Spec.MaxTrialCount) { - msg := "Experiment has succeeded because max trial count has reached" - instance.MarkExperimentStatusSucceeded(ExperimentSucceededReason, msg) - instance.Status.CompletionTime = &now - return - } - - if getSuggestionDone && (instance.Status.TrialsPending+instance.Status.TrialsRunning) == 0 { - msg := "Experiment has succeeded because suggestion service has reached the end" - instance.MarkExperimentStatusSucceeded(ExperimentSucceededReason, msg) - instance.Status.CompletionTime = &now - return - } - - if (instance.Spec.MaxFailedTrialCount != nil) && (failedTrialsCount >= *instance.Spec.MaxFailedTrialCount) { - msg := "Experiment has failed because max failed count has reached" - instance.MarkExperimentStatusFailed(ExperimentFailedReason, msg) - instance.Status.CompletionTime = &now - return - } - - msg := "Experiment is running" - instance.MarkExperimentStatusRunning(ExperimentRunningReason, msg) -} diff --git a/pkg/controller.v1alpha2/trial/managerclient/managerclient.go b/pkg/controller.v1alpha2/trial/managerclient/managerclient.go deleted file mode 100644 index 03f4e9364b4..00000000000 --- a/pkg/controller.v1alpha2/trial/managerclient/managerclient.go +++ /dev/null @@ -1,159 +0,0 @@ -package managerclient - -import ( - "fmt" - - commonv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - common "github.com/kubeflow/katib/pkg/common/v1alpha2" -) - -// ManagerClient is the interface for katib manager client in trial controller. -type ManagerClient interface { - CreateTrialInDB(instance *trialsv1alpha2.Trial) error - UpdateTrialStatusInDB(instance *trialsv1alpha2.Trial) error - GetTrialObservation(instance *trialsv1alpha2.Trial) error - GetTrialObservationLog( - instance *trialsv1alpha2.Trial) (*api_pb.GetObservationLogReply, error) - GetTrialConf(instance *trialsv1alpha2.Trial) *api_pb.Trial -} - -// DefaultClient implements the Client interface. -type DefaultClient struct { -} - -// New creates a new ManagerClient. -func New() ManagerClient { - return &DefaultClient{} -} - -func (d *DefaultClient) CreateTrialInDB(instance *trialsv1alpha2.Trial) error { - trial := d.GetTrialConf(instance) - request := &api_pb.RegisterTrialRequest{ - Trial: trial, - } - if _, err := common.RegisterTrial(request); err != nil { - return err - } - return nil -} - -func (d *DefaultClient) UpdateTrialStatusInDB(instance *trialsv1alpha2.Trial) error { - newStatus := &api_pb.TrialStatus{ - StartTime: common.ConvertTime2RFC3339(instance.Status.StartTime), - CompletionTime: common.ConvertTime2RFC3339(instance.Status.CompletionTime), - Condition: getCondition(instance), - } - if instance.Status.Observation != nil { - observation := &api_pb.Observation{ - Metrics: []*api_pb.Metric{}, - } - for _, m := range instance.Status.Observation.Metrics { - metric := &api_pb.Metric{ - Name: m.Name, - Value: fmt.Sprintf("%f", m.Value), - } - observation.Metrics = append(observation.Metrics, metric) - } - newStatus.Observation = observation - } - request := &api_pb.UpdateTrialStatusRequest{ - NewStatus: newStatus, - TrialName: instance.Name, - } - if _, err := common.UpdateTrialStatus(request); err != nil { - return err - } - return nil -} - -func (d *DefaultClient) GetTrialObservationLog( - instance *trialsv1alpha2.Trial) (*api_pb.GetObservationLogReply, error) { - // read GetObservationLog call and update observation field - objectiveMetricName := instance.Spec.Objective.ObjectiveMetricName - request := &api_pb.GetObservationLogRequest{ - TrialName: instance.Name, - MetricName: objectiveMetricName, - } - reply, err := common.GetObservationLog(request) - if err != nil { - return nil, err - } - return reply, nil -} - -func (d *DefaultClient) GetTrialObservation(instance *trialsv1alpha2.Trial) error { - return nil -} - -func (d *DefaultClient) GetTrialConf(instance *trialsv1alpha2.Trial) *api_pb.Trial { - trial := &api_pb.Trial{ - Spec: &api_pb.TrialSpec{ - Objective: &api_pb.ObjectiveSpec{ - AdditionalMetricNames: []string{}, - }, - ParameterAssignments: &api_pb.TrialSpec_ParameterAssignments{ - Assignments: []*api_pb.ParameterAssignment{}, - }, - }, - Status: &api_pb.TrialStatus{ - StartTime: common.ConvertTime2RFC3339(instance.Status.StartTime), - CompletionTime: common.ConvertTime2RFC3339(instance.Status.CompletionTime), - Condition: getCondition(instance), - }, - } - trial.Name = instance.Name - - trial.Spec.ExperimentName = instance.Labels["experiment"] - - //Populate Objective - switch instance.Spec.Objective.Type { - case commonv1alpha2.ObjectiveTypeMaximize: - trial.Spec.Objective.Type = api_pb.ObjectiveType_MAXIMIZE - case commonv1alpha2.ObjectiveTypeMinimize: - trial.Spec.Objective.Type = api_pb.ObjectiveType_MINIMIZE - default: - trial.Spec.Objective.Type = api_pb.ObjectiveType_UNKNOWN - - } - trial.Spec.Objective.Goal = float32(*instance.Spec.Objective.Goal) - trial.Spec.Objective.ObjectiveMetricName = instance.Spec.Objective.ObjectiveMetricName - for _, m := range instance.Spec.Objective.AdditionalMetricNames { - trial.Spec.Objective.AdditionalMetricNames = append(trial.Spec.Objective.AdditionalMetricNames, m) - } - - //Populate Parameter Assignments - for _, p := range instance.Spec.ParameterAssignments { - trial.Spec.ParameterAssignments.Assignments = append( - trial.Spec.ParameterAssignments.Assignments, - &api_pb.ParameterAssignment{ - Name: p.Name, - Value: p.Value, - }) - } - - trial.Spec.RunSpec = instance.Spec.RunSpec - - trial.Spec.MetricsCollectorSpec = instance.Spec.MetricsCollectorSpec - - return trial -} - -func getCondition(inst *trialsv1alpha2.Trial) api_pb.TrialStatus_TrialConditionType { - condition, _ := inst.GetLastConditionType() - switch condition { - case trialsv1alpha2.TrialCreated: - return api_pb.TrialStatus_CREATED - case trialsv1alpha2.TrialRunning: - return api_pb.TrialStatus_RUNNING - case trialsv1alpha2.TrialKilled: - return api_pb.TrialStatus_KILLED - case trialsv1alpha2.TrialSucceeded: - return api_pb.TrialStatus_SUCCEEDED - case trialsv1alpha2.TrialFailed: - return api_pb.TrialStatus_FAILED - default: - return api_pb.TrialStatus_UNKNOWN - } -} diff --git a/pkg/controller.v1alpha2/trial/trial_controller.go b/pkg/controller.v1alpha2/trial/trial_controller.go deleted file mode 100644 index b5a7e41f37b..00000000000 --- a/pkg/controller.v1alpha2/trial/trial_controller.go +++ /dev/null @@ -1,364 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package trial - -import ( - "bytes" - "context" - - batchv1beta "k8s.io/api/batch/v1beta1" - "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" - k8syaml "k8s.io/apimachinery/pkg/util/yaml" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - "sigs.k8s.io/controller-runtime/pkg/source" - - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - commonv1alpha2 "github.com/kubeflow/katib/pkg/common/v1alpha2" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/trial/managerclient" -) - -var ( - log = logf.Log.WithName("trial-controller") -) - -/** -* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller -* business logic. Delete these comments after modifying this file.* - */ - -// Add creates a new Trial Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, newReconciler(mgr)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager) reconcile.Reconciler { - r := &ReconcileTrial{ - Client: mgr.GetClient(), - scheme: mgr.GetScheme(), - ManagerClient: managerclient.New(), - } - r.updateStatusHandler = r.updateStatus - return r -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New("trial-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - log.Error(err, "Create trial controller error") - return err - } - - // Watch for changes to Trial - err = c.Watch(&source.Kind{Type: &trialsv1alpha2.Trial{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - log.Error(err, "Trial watch error") - return err - } - - // Watch for changes to Cronjob - err = c.Watch( - &source.Kind{Type: &batchv1beta.CronJob{}}, - &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &trialsv1alpha2.Trial{}, - }) - - if err != nil { - log.Error(err, "CronJob watch error") - return err - } - - for _, gvk := range commonv1alpha2.GetSupportedJobList() { - unstructuredJob := &unstructured.Unstructured{} - unstructuredJob.SetGroupVersionKind(gvk) - err = c.Watch( - &source.Kind{Type: unstructuredJob}, - &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &trialsv1alpha2.Trial{}, - }) - if err != nil { - if meta.IsNoMatchError(err) { - log.Info("Job watch error. CRD might be missing. Please install CRD and restart katib-controller", "CRD Kind", gvk.Kind) - continue - } - return err - } else { - log.Info("Job watch added successfully", "CRD Kind", gvk.Kind) - } - } - log.Info("Trial controller created") - return nil -} - -var _ reconcile.Reconciler = &ReconcileTrial{} - -// ReconcileTrial reconciles a Trial object -type ReconcileTrial struct { - client.Client - scheme *runtime.Scheme - - managerclient.ManagerClient - // updateStatusHandler is defined for test purpose. - updateStatusHandler updateStatusFunc -} - -// Reconcile reads that state of the cluster for a Trial object and makes changes based on the state read -// and what is in the Trial.Spec -// +kubebuilder:rbac:groups=trials.kubeflow.org,resources=trials,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=trials.kubeflow.org,resources=trials/status,verbs=get;update;patch -func (r *ReconcileTrial) Reconcile(request reconcile.Request) (reconcile.Result, error) { - // Fetch the Trial instance - logger := log.WithValues("Trial", request.NamespacedName) - original := &trialsv1alpha2.Trial{} - err := r.Get(context.TODO(), request.NamespacedName, original) - if err != nil { - if errors.IsNotFound(err) { - // Object not found, return. Created objects are automatically garbage collected. - // For additional cleanup logic use finalizers. - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - logger.Error(err, "Trial Get error") - return reconcile.Result{}, err - } - - instance := original.DeepCopy() - - if !instance.IsCreated() { - if instance.Status.StartTime == nil { - now := metav1.Now() - instance.Status.StartTime = &now - } - if instance.Status.CompletionTime == nil { - instance.Status.CompletionTime = &metav1.Time{} - } - err = r.CreateTrialInDB(instance) - if err != nil { - logger.Error(err, "Create trial in DB error") - return reconcile.Result{ - Requeue: true, - }, err - } - msg := "Trial is created" - instance.MarkTrialStatusCreated(TrialCreatedReason, msg) - } else { - // Trial already created in DB - err := r.reconcileTrial(instance) - if err != nil { - logger.Error(err, "Reconcile trial error") - return reconcile.Result{}, err - } - } - - if !equality.Semantic.DeepEqual(original.Status, instance.Status) { - //assuming that only status change - err = r.UpdateTrialStatusInDB(instance) - if err != nil { - logger.Error(err, "Update trial status in DB error") - return reconcile.Result{}, err - } - err = r.updateStatusHandler(instance) - if err != nil { - logger.Error(err, "Update trial instance status error") - return reconcile.Result{}, err - } - } - - return reconcile.Result{}, nil -} - -func (r *ReconcileTrial) reconcileTrial(instance *trialsv1alpha2.Trial) error { - - var err error - logger := log.WithValues("Trial", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) - desiredJob, err := r.getDesiredJobSpec(instance) - if err != nil { - logger.Error(err, "Job Spec Get error") - return err - } - desiredMetricsCollector, err := r.getDesiredMetricsCollectorSpec(instance) - if err != nil { - logger.Error(err, "Metrics Collector Get error") - return err - } - - deployedJob, err := r.reconcileJob(instance, desiredJob) - if err != nil { - logger.Error(err, "Reconcile job error") - return err - } - _, err = r.reconcileMetricsCollector(instance, desiredMetricsCollector) - if err != nil { - logger.Error(err, "Reconcile Metrics Collector error") - return err - } - - //Job already exists - //TODO Can desired Spec differ from deployedSpec? - if deployedJob != nil { - if err = r.UpdateTrialStatusObservation(instance, deployedJob); err != nil { - logger.Error(err, "Update trial status observation error") - return err - } - // Update Trial job status only if observation field is available. - // This will ensure that trial is set to be complete only if metric is collected at least once - if isTrialObservationAvailable(instance) { - if err = r.UpdateTrialStatusCondition(instance, deployedJob); err != nil { - logger.Error(err, "Update trial status condition error") - return err - } - } - } - return nil -} - -func (r *ReconcileTrial) reconcileJob(instance *trialsv1alpha2.Trial, desiredJob *unstructured.Unstructured) (*unstructured.Unstructured, error) { - var err error - logger := log.WithValues("Trial", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) - apiVersion := desiredJob.GetAPIVersion() - kind := desiredJob.GetKind() - gvk := schema.FromAPIVersionAndKind(apiVersion, kind) - - deployedJob := &unstructured.Unstructured{} - deployedJob.SetGroupVersionKind(gvk) - err = r.Get(context.TODO(), types.NamespacedName{Name: desiredJob.GetName(), Namespace: desiredJob.GetNamespace()}, deployedJob) - if err != nil { - if errors.IsNotFound(err) { - if instance.IsCompleted() { - return nil, nil - } - logger.Info("Creating Job", "kind", kind, - "name", desiredJob.GetName()) - err = r.Create(context.TODO(), desiredJob) - if err != nil { - logger.Error(err, "Create job error") - return nil, err - } - msg := "Trial is running" - instance.MarkTrialStatusRunning(TrialRunningReason, msg) - } else { - logger.Error(err, "Trial Get error") - return nil, err - } - } else { - if instance.IsCompleted() && !instance.Spec.RetainRun { - if err = r.Delete(context.TODO(), desiredJob, client.PropagationPolicy(metav1.DeletePropagationForeground)); err != nil { - logger.Error(err, "Delete job error") - return nil, err - } else { - return nil, nil - } - } - } - - return deployedJob, nil -} - -func (r *ReconcileTrial) getDesiredJobSpec(instance *trialsv1alpha2.Trial) (*unstructured.Unstructured, error) { - - bufSize := 1024 - logger := log.WithValues("Trial", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) - buf := bytes.NewBufferString(instance.Spec.RunSpec) - - desiredJobSpec := &unstructured.Unstructured{} - if err := k8syaml.NewYAMLOrJSONDecoder(buf, bufSize).Decode(desiredJobSpec); err != nil { - logger.Error(err, "Yaml decode error") - return nil, err - } - if err := controllerutil.SetControllerReference(instance, desiredJobSpec, r.scheme); err != nil { - logger.Error(err, "Set controller reference error") - return nil, err - } - - return desiredJobSpec, nil -} - -func (r *ReconcileTrial) getDesiredMetricsCollectorSpec(instance *trialsv1alpha2.Trial) (*batchv1beta.CronJob, error) { - mcjob := &batchv1beta.CronJob{} - bufSize := 1024 - logger := log.WithValues("Metrics collector for Trial", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) - buf := bytes.NewBufferString(instance.Spec.MetricsCollectorSpec) - - if err := k8syaml.NewYAMLOrJSONDecoder(buf, bufSize).Decode(mcjob); err != nil { - logger.Error(err, "Yaml decode error") - return nil, err - } - if err := controllerutil.SetControllerReference(instance, mcjob, r.scheme); err != nil { - logger.Error(err, "Set controller reference error") - return nil, err - } - return mcjob, nil -} - -func (r *ReconcileTrial) reconcileMetricsCollector(instance *trialsv1alpha2.Trial, - desiredMetricsCollector *batchv1beta.CronJob) (*batchv1beta.CronJob, error) { - var err error - logger := log.WithValues("Trial", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) - - deployedMetricsCollector := &batchv1beta.CronJob{} - err = r.Get(context.TODO(), types.NamespacedName{ - Name: desiredMetricsCollector.GetName(), - Namespace: desiredMetricsCollector.GetNamespace(), - }, deployedMetricsCollector) - if err != nil { - if errors.IsNotFound(err) { - if instance.IsCompleted() { - return nil, nil - } - logger.Info("Creating Metrics Collector", - "name", desiredMetricsCollector.GetName(), - "namespace", desiredMetricsCollector.GetNamespace()) - err = r.Create(context.TODO(), desiredMetricsCollector) - if err != nil { - logger.Error(err, "Create Metrics Collector error") - return nil, err - } - } else { - logger.Error(err, "Metrics Collector Get error") - return nil, err - } - } else { - if instance.IsCompleted() && !instance.Spec.RetainMetricsCollector { - if err = r.Delete(context.TODO(), desiredMetricsCollector, client.PropagationPolicy(metav1.DeletePropagationForeground)); err != nil { - logger.Error(err, "Delete Metrics Collector error") - return nil, err - } else { - return nil, nil - } - } - } - - return deployedMetricsCollector, nil -} diff --git a/pkg/controller.v1alpha2/trial/trial_controller_consts.go b/pkg/controller.v1alpha2/trial/trial_controller_consts.go deleted file mode 100644 index 80c08f688f2..00000000000 --- a/pkg/controller.v1alpha2/trial/trial_controller_consts.go +++ /dev/null @@ -1,10 +0,0 @@ -package trial - -const ( - DefaultJobKind = "Job" - TrialCreatedReason = "TrialCreated" - TrialRunningReason = "TrialRunning" - TrialSucceededReason = "TrialSucceeded" - TrialFailedReason = "TrialFailed" - TrialKilledReason = "TrialKilled" -) diff --git a/pkg/controller.v1alpha2/trial/trial_controller_status.go b/pkg/controller.v1alpha2/trial/trial_controller_status.go deleted file mode 100644 index 06d72719b98..00000000000 --- a/pkg/controller.v1alpha2/trial/trial_controller_status.go +++ /dev/null @@ -1,17 +0,0 @@ -package trial - -import ( - "context" - - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" -) - -type updateStatusFunc func(instance *trialsv1alpha2.Trial) error - -func (r *ReconcileTrial) updateStatus(instance *trialsv1alpha2.Trial) error { - err := r.Status().Update(context.TODO(), instance) - if err != nil { - return err - } - return nil -} diff --git a/pkg/controller.v1alpha2/trial/trial_controller_suite_test.go b/pkg/controller.v1alpha2/trial/trial_controller_suite_test.go deleted file mode 100644 index 69060bf8260..00000000000 --- a/pkg/controller.v1alpha2/trial/trial_controller_suite_test.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package trial - -import ( - stdlog "log" - "os" - "path/filepath" - "sync" - "testing" - "time" - - "github.com/onsi/gomega" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - apis "github.com/kubeflow/katib/pkg/apis/controller" -) - -var ( - cfg *rest.Config - controlPlaneStartTimeout = 60 * time.Second - controlPlaneStopTimeout = 60 * time.Second -) - -func TestMain(m *testing.M) { - t := &envtest.Environment{ - ControlPlaneStartTimeout: controlPlaneStartTimeout, - ControlPlaneStopTimeout: controlPlaneStopTimeout, - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "manifests", "v1alpha2", "katib-controller"), - filepath.Join("..", "..", "..", "test", "unit", "v1alpha2", "crds"), - }, - } - apis.AddToScheme(scheme.Scheme) - - var err error - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - - code := m.Run() - t.Stop() - os.Exit(code) -} - -// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner. -func SetupTestReconcile(inner reconcile.Reconciler) reconcile.Reconciler { - fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { - result, err := inner.Reconcile(req) - return result, err - }) - return fn -} - -// StartTestManager adds recFn -func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { - stop := make(chan struct{}) - wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) - }() - return stop, wg -} diff --git a/pkg/controller.v1alpha2/trial/trial_controller_test.go b/pkg/controller.v1alpha2/trial/trial_controller_test.go deleted file mode 100644 index 950ae04b81c..00000000000 --- a/pkg/controller.v1alpha2/trial/trial_controller_test.go +++ /dev/null @@ -1,357 +0,0 @@ -package trial - -import ( - "bytes" - "fmt" - "testing" - "time" - - "github.com/golang/mock/gomock" - "github.com/onsi/gomega" - "golang.org/x/net/context" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - k8syaml "k8s.io/apimachinery/pkg/util/yaml" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - - commonv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - managerclientmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/trial/managerclient" -) - -const ( - trialName = "foo" - namespace = "default" - - timeout = time.Second * 40 -) - -var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: trialName, Namespace: namespace}} -var expectedResult = reconcile.Result{Requeue: true} -var tfJobKey = types.NamespacedName{Name: "test", Namespace: namespace} - -func init() { - logf.SetLogger(logf.ZapLogger(true)) -} - -func TestCreateTFJobTrial(t *testing.T) { - g := gomega.NewGomegaWithT(t) - instance := newFakeTrialWithTFJob() - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - mc := managerclientmock.NewMockManagerClient(mockCtrl) - mc.EXPECT().CreateTrialInDB(gomock.Any()).Return(nil).AnyTimes() - mc.EXPECT().UpdateTrialStatusInDB(gomock.Any()).Return(nil).AnyTimes() - - // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a - // channel when it is finished. - mgr, err := manager.New(cfg, manager.Options{}) - g.Expect(err).NotTo(gomega.HaveOccurred()) - c := mgr.GetClient() - - recFn := SetupTestReconcile(&ReconcileTrial{ - Client: mgr.GetClient(), - scheme: mgr.GetScheme(), - ManagerClient: mc, - updateStatusHandler: func(instance *trialsv1alpha2.Trial) error { - if !instance.IsCreated() { - t.Errorf("Expected got condition created") - } - return nil - }, - }) - g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) - - stopMgr, mgrStopped := StartTestManager(mgr, g) - - defer func() { - close(stopMgr) - mgrStopped.Wait() - }() - - // Create the Trial object and expect the Reconcile and Deployment to be created - err = c.Create(context.TODO(), instance) - // The instance object may not be a valid object because it might be missing some required fields. - // Please modify the instance object by adding required fields and then remove the following if statement. - if apierrors.IsInvalid(err) { - t.Logf("failed to create object, got an invalid object error: %v", err) - return - } - g.Expect(err).NotTo(gomega.HaveOccurred()) - g.Expect(c.Delete(context.TODO(), instance)).NotTo(gomega.HaveOccurred()) -} - -func TestReconcileTFJobTrial(t *testing.T) { - g := gomega.NewGomegaWithT(t) - instance := newFakeTrialWithTFJob() - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - mc := managerclientmock.NewMockManagerClient(mockCtrl) - mc.EXPECT().CreateTrialInDB(gomock.Any()).Return(nil).AnyTimes() - mc.EXPECT().UpdateTrialStatusInDB(gomock.Any()).Return(nil).AnyTimes() - mc.EXPECT().GetTrialObservationLog(gomock.Any()).Return(&api_pb.GetObservationLogReply{ - ObservationLog: nil, - }, nil).AnyTimes() - - // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a - // channel when it is finished. - mgr, err := manager.New(cfg, manager.Options{}) - g.Expect(err).NotTo(gomega.HaveOccurred()) - c := mgr.GetClient() - - r := &ReconcileTrial{ - Client: mgr.GetClient(), - scheme: mgr.GetScheme(), - ManagerClient: mc, - } - - r.updateStatusHandler = func(instance *trialsv1alpha2.Trial) error { - if !instance.IsCreated() { - t.Errorf("Expected got condition created") - } - return r.updateStatus(instance) - } - - recFn := SetupTestReconcile(r) - g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) - - stopMgr, mgrStopped := StartTestManager(mgr, g) - - defer func() { - close(stopMgr) - mgrStopped.Wait() - }() - - // Create the Trial object and expect the Reconcile and Deployment to be created - err = c.Create(context.TODO(), instance) - // The instance object may not be a valid object because it might be missing some required fields. - // Please modify the instance object by adding required fields and then remove the following if statement. - if apierrors.IsInvalid(err) { - t.Logf("failed to create object, got an invalid object error: %v", err) - return - } - g.Expect(err).NotTo(gomega.HaveOccurred()) - - tfJob := &unstructured.Unstructured{} - bufSize := 1024 - buf := bytes.NewBufferString(instance.Spec.RunSpec) - if err := k8syaml.NewYAMLOrJSONDecoder(buf, bufSize).Decode(tfJob); err != nil { - t.Errorf("Expected nil, got %v", err) - } - g.Eventually(func() error { return c.Get(context.TODO(), tfJobKey, tfJob) }, timeout). - Should(gomega.Succeed()) - - // Delete the TFJob and expect Reconcile to be called for TFJob deletion - g.Expect(c.Delete(context.TODO(), tfJob)).NotTo(gomega.HaveOccurred()) - g.Eventually(func() error { return c.Get(context.TODO(), tfJobKey, tfJob) }, timeout). - Should(gomega.Succeed()) - - // Manually delete TFJob since GC isn't enabled in the test control plane - g.Eventually(func() error { return c.Delete(context.TODO(), tfJob) }, timeout). - Should(gomega.MatchError("tfjobs.kubeflow.org \"test\" not found")) - g.Expect(c.Delete(context.TODO(), instance)).NotTo(gomega.HaveOccurred()) -} - -func TestReconcileCompletedTFJobTrial(t *testing.T) { - g := gomega.NewGomegaWithT(t) - instance := newFakeTrialWithTFJob() - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - mc := managerclientmock.NewMockManagerClient(mockCtrl) - mc.EXPECT().CreateTrialInDB(gomock.Any()).Return(nil).AnyTimes() - mc.EXPECT().UpdateTrialStatusInDB(gomock.Any()).Return(nil).AnyTimes() - mc.EXPECT().GetTrialObservationLog(gomock.Any()).Return(&api_pb.GetObservationLogReply{ - ObservationLog: nil, - }, nil).AnyTimes() - - // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a - // channel when it is finished. - mgr, err := manager.New(cfg, manager.Options{}) - g.Expect(err).NotTo(gomega.HaveOccurred()) - c := mgr.GetClient() - - r := &ReconcileTrial{ - Client: mgr.GetClient(), - scheme: mgr.GetScheme(), - ManagerClient: mc, - } - - r.updateStatusHandler = func(instance *trialsv1alpha2.Trial) error { - if !instance.IsCreated() { - t.Errorf("Expected got condition created") - } - return r.updateStatus(instance) - } - - recFn := SetupTestReconcile(r) - g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) - - stopMgr, mgrStopped := StartTestManager(mgr, g) - - defer func() { - close(stopMgr) - mgrStopped.Wait() - }() - - // Create the Trial object and expect the Reconcile and Deployment to be created - err = c.Create(context.TODO(), instance) - // The instance object may not be a valid object because it might be missing some required fields. - // Please modify the instance object by adding required fields and then remove the following if statement. - if apierrors.IsInvalid(err) { - t.Logf("failed to create object, got an invalid object error: %v", err) - return - } - g.Expect(err).NotTo(gomega.HaveOccurred()) - defer c.Delete(context.TODO(), instance) - - g.Eventually(func() error { - return c.Get(context.TODO(), expectedRequest.NamespacedName, instance) - }, timeout). - Should(gomega.Succeed()) - instance.MarkTrialStatusSucceeded("", "") - g.Expect(c.Status().Update(context.TODO(), instance)).NotTo(gomega.HaveOccurred()) - g.Eventually(func() bool { - err := c.Get(context.TODO(), expectedRequest.NamespacedName, instance) - if err == nil && instance.IsCompleted() { - return true - } - return false - }, timeout). - Should(gomega.BeTrue()) -} - -func TestFailedToCreateTrialInDB(t *testing.T) { - g := gomega.NewGomegaWithT(t) - instance := newFakeTrialWithTFJob() - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - mc := managerclientmock.NewMockManagerClient(mockCtrl) - expectedErr := fmt.Errorf("test") - mc.EXPECT().CreateTrialInDB(gomock.Any()).Return(expectedErr).AnyTimes() - - // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a - // channel when it is finished. - mgr, err := manager.New(cfg, manager.Options{}) - g.Expect(err).NotTo(gomega.HaveOccurred()) - c := mgr.GetClient() - - r := &ReconcileTrial{ - Client: mgr.GetClient(), - scheme: mgr.GetScheme(), - ManagerClient: mc, - } - - r.updateStatusHandler = r.updateStatus - - recFn := SetupTestReconcile(r) - g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) - - stopMgr, mgrStopped := StartTestManager(mgr, g) - - defer func() { - close(stopMgr) - mgrStopped.Wait() - }() - - // Create the Trial object and expect the Reconcile and Deployment to be created - err = c.Create(context.TODO(), instance) - // The instance object may not be a valid object because it might be missing some required fields. - // Please modify the instance object by adding required fields and then remove the following if statement. - if apierrors.IsInvalid(err) { - t.Logf("failed to create object, got an invalid object error: %v", err) - return - } - g.Expect(err).NotTo(gomega.HaveOccurred()) - g.Eventually(func() error { - return c.Get(context.TODO(), expectedRequest.NamespacedName, instance) - }, timeout). - Should(gomega.Succeed()) - if instance.IsCreated() { - t.Errorf("Expected not to got condition created") - } - g.Expect(c.Delete(context.TODO(), instance)).NotTo(gomega.HaveOccurred()) -} - -func newFakeTrialWithTFJob() *trialsv1alpha2.Trial { - objectiveSpec := commonv1alpha2.ObjectiveSpec{ObjectiveMetricName: "test"} - t := &trialsv1alpha2.Trial{ - ObjectMeta: metav1.ObjectMeta{ - Name: trialName, - Namespace: namespace, - }, - Spec: trialsv1alpha2.TrialSpec{ - Objective: &objectiveSpec, - MetricsCollectorSpec: `apiVersion: batch/v1beta1 -kind: CronJob -metadata: - name: test - namespace: default -spec: - schedule: "*/1 * * * *" - successfulJobsHistoryLimit: 0 - failedJobsHistoryLimit: 1 - jobTemplate: - spec: - backoffLimit: 0 - template: - spec: - serviceAccountName: metrics-collector - containers: - - name: test - image: katib/metrics-collector - args: - - "./metricscollector.v1alpha2" - - "-e" - - "teste" - - "-t" - - "test" - - "-k" - - "TFJob" - - "-n" - - "default" - - "-m" - - "test" - - "-mn" - - "test" - restartPolicy: Never`, - RunSpec: `apiVersion: "kubeflow.org/v1" -kind: "TFJob" -metadata: - name: "test" - namespace: "default" -spec: - tfReplicaSpecs: - PS: - replicas: 2 - restartPolicy: Never - template: - spec: - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 - Worker: - replicas: 4 - restartPolicy: Never - template: - spec: - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 -`, - }, - } - return t -} diff --git a/pkg/controller.v1alpha2/trial/trial_controller_util.go b/pkg/controller.v1alpha2/trial/trial_controller_util.go deleted file mode 100644 index 6eee7d59f06..00000000000 --- a/pkg/controller.v1alpha2/trial/trial_controller_util.go +++ /dev/null @@ -1,145 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package trial - -import ( - "strconv" - - batchv1 "k8s.io/api/batch/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - - commonv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - commonv1 "github.com/kubeflow/tf-operator/pkg/apis/common/v1" -) - -func (r *ReconcileTrial) UpdateTrialStatusCondition(instance *trialsv1alpha2.Trial, deployedJob *unstructured.Unstructured) error { - - kind := deployedJob.GetKind() - status, ok, unerr := unstructured.NestedFieldCopy(deployedJob.Object, "status") - now := metav1.Now() - - if ok { - statusMap := status.(map[string]interface{}) - switch kind { - - case DefaultJobKind: - jobStatus := batchv1.JobStatus{} - err := runtime.DefaultUnstructuredConverter.FromUnstructured(statusMap, &jobStatus) - if err != nil { - log.Error(err, "Convert unstructured to status error") - return err - } - if jobStatus.Active == 0 && jobStatus.Succeeded > 0 { - msg := "Trial has succeeded" - instance.MarkTrialStatusSucceeded(TrialSucceededReason, msg) - instance.Status.CompletionTime = &now - } else if jobStatus.Failed > 0 { - msg := "Trial has failed" - instance.MarkTrialStatusFailed(TrialFailedReason, msg) - instance.Status.CompletionTime = &now - } - default: - jobStatus := commonv1.JobStatus{} - err := runtime.DefaultUnstructuredConverter.FromUnstructured(statusMap, &jobStatus) - - if err != nil { - log.Error(err, "Convert unstructured to status error") - return err - } - if len(jobStatus.Conditions) > 0 { - lc := jobStatus.Conditions[len(jobStatus.Conditions)-1] - if lc.Type == commonv1.JobSucceeded { - msg := "Trial has succeeded" - instance.MarkTrialStatusSucceeded(TrialSucceededReason, msg) - instance.Status.CompletionTime = &now - } else if lc.Type == commonv1.JobFailed { - msg := "Trial has failed" - instance.MarkTrialStatusFailed(TrialFailedReason, msg) - instance.Status.CompletionTime = &now - } - } - } - } else if unerr != nil { - log.Error(unerr, "NestedFieldCopy unstructured to status error") - return unerr - } - return nil -} - -func (r *ReconcileTrial) UpdateTrialStatusObservation(instance *trialsv1alpha2.Trial, deployedJob *unstructured.Unstructured) error { - objectiveMetricName := instance.Spec.Objective.ObjectiveMetricName - reply, err := r.GetTrialObservationLog(instance) - if err != nil { - log.Error(err, "Get trial observation log error") - return err - } - if reply.ObservationLog != nil { - bestObjectiveValue := getBestObjectiveMetricValue(reply.ObservationLog.MetricLogs, instance.Spec.Objective.Type) - if bestObjectiveValue != nil { - if instance.Status.Observation == nil { - instance.Status.Observation = &commonv1alpha2.Observation{} - metric := commonv1alpha2.Metric{Name: objectiveMetricName, Value: *bestObjectiveValue} - instance.Status.Observation.Metrics = []commonv1alpha2.Metric{metric} - } else { - for index, metric := range instance.Status.Observation.Metrics { - if metric.Name == objectiveMetricName { - instance.Status.Observation.Metrics[index].Value = *bestObjectiveValue - } - } - } - } - } - return nil -} - -func isTrialObservationAvailable(instance *trialsv1alpha2.Trial) bool { - objectiveMetricName := instance.Spec.Objective.ObjectiveMetricName - if instance.Status.Observation != nil && instance.Status.Observation.Metrics != nil { - for _, metric := range instance.Status.Observation.Metrics { - if metric.Name == objectiveMetricName { - return true - } - } - } - return false -} - -func getBestObjectiveMetricValue(metricLogs []*api_pb.MetricLog, objectiveType commonv1alpha2.ObjectiveType) *float64 { - metricLogSize := len(metricLogs) - if metricLogSize == 0 { - return nil - } - - bestObjectiveValue, _ := strconv.ParseFloat(metricLogs[0].Metric.Value, 32) - for _, metricLog := range metricLogs[1:] { - objectiveMetricValue, _ := strconv.ParseFloat(metricLog.Metric.Value, 32) - if objectiveType == commonv1alpha2.ObjectiveTypeMinimize { - if objectiveMetricValue < bestObjectiveValue { - bestObjectiveValue = objectiveMetricValue - } - } else if objectiveType == commonv1alpha2.ObjectiveTypeMaximize { - if objectiveMetricValue > bestObjectiveValue { - bestObjectiveValue = objectiveMetricValue - } - } - - } - return &bestObjectiveValue -} diff --git a/pkg/db/v1alpha2/db_init.go b/pkg/db/v1alpha2/db_init.go deleted file mode 100644 index 45a11207312..00000000000 --- a/pkg/db/v1alpha2/db_init.go +++ /dev/null @@ -1,78 +0,0 @@ -package db - -import ( - "fmt" - - "k8s.io/klog" -) - -func (d *dbConn) DBInit() { - db := d.db - - _, err := db.Exec(`CREATE TABLE IF NOT EXISTS experiments - (id INT AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(255) NOT NULL UNIQUE, - parameters TEXT, - objective TEXT, - algorithm TEXT, - trial_template TEXT, - metrics_collector_spec TEXT, - parallel_trial_count INT, - max_trial_count INT, - status TINYINT, - start_time DATETIME(6), - completion_time DATETIME(6), - nas_config TEXT)`) - //TODO add nas config(may be it will be included in algorithm) - if err != nil { - klog.Fatalf("Error creating experiments table: %v", err) - } - - _, err = db.Exec(`CREATE TABLE IF NOT EXISTS trials - (id INT AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(255) NOT NULL UNIQUE, - experiment_name VARCHAR(255) NOT NULL, - objective TEXT, - parameter_assignments TEXT, - run_spec TEXT, - metrics_collector_spec TEXT, - observation TEXT, - status TINYINT, - start_time DATETIME(6), - completion_time DATETIME(6), - FOREIGN KEY(experiment_name) REFERENCES experiments(name) ON DELETE CASCADE)`) - if err != nil { - klog.Fatalf("Error creating trials table: %v", err) - } - - _, err = db.Exec(`CREATE TABLE IF NOT EXISTS observation_logs - (trial_name VARCHAR(255) NOT NULL, - id INT AUTO_INCREMENT PRIMARY KEY, - time DATETIME(6), - metric_name VARCHAR(255) NOT NULL, - value TEXT NOT NULL, - FOREIGN KEY (trial_name) REFERENCES trials(name) ON DELETE CASCADE)`) - if err != nil { - klog.Fatalf("Error creating observation_logs table: %v", err) - } - - _, err = db.Exec(`CREATE TABLE IF NOT EXISTS extra_algorithm_settings - (experiment_name VARCHAR(255) NOT NULL, - id INT AUTO_INCREMENT PRIMARY KEY, - setting_name VARCHAR(255) NOT NULL, - value TEXT NOT NULL, - FOREIGN KEY (experiment_name) REFERENCES experiments(name) ON DELETE CASCADE)`) - if err != nil { - klog.Fatalf("Error creating extra_algorithm_settings table: %v", err) - } - -} - -func (d *dbConn) SelectOne() error { - db := d.db - _, err := db.Exec(`SELECT 1`) - if err != nil { - return fmt.Errorf("Error `SELECT 1` probing: %v", err) - } - return nil -} diff --git a/pkg/db/v1alpha2/interface.go b/pkg/db/v1alpha2/interface.go deleted file mode 100644 index 003ce106027..00000000000 --- a/pkg/db/v1alpha2/interface.go +++ /dev/null @@ -1,790 +0,0 @@ -package db - -import ( - crand "crypto/rand" - "database/sql" - "fmt" - "math/big" - "math/rand" - "os" - "time" - - _ "github.com/go-sql-driver/mysql" - "github.com/golang/protobuf/jsonpb" - "k8s.io/klog" - - v1alpha2 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" -) - -const ( - dbDriver = "mysql" - dbNameTmpl = "root:%s@tcp(katib-db:3306)/katib?timeout=5s" - mysqlTimeFmt = "2006-01-02 15:04:05.999999" - - connectInterval = 5 * time.Second - connectTimeout = 60 * time.Second -) - -type GetWorkerLogOpts struct { - Name string - SinceTime *time.Time - Descending bool - Limit int32 - Objective bool -} - -type WorkerLog struct { - Time time.Time - Name string - Value string -} - -type KatibDBInterface interface { - DBInit() - SelectOne() error - - RegisterExperiment(experiment *v1alpha2.Experiment) error - PreCheckRegisterExperiment(experiment *v1alpha2.Experiment) (bool, error) - DeleteExperiment(experimentName string) error - GetExperiment(experimentName string) (*v1alpha2.Experiment, error) - GetExperimentList() ([]*v1alpha2.ExperimentSummary, error) - UpdateExperimentStatus(experimentName string, newStatus *v1alpha2.ExperimentStatus) error - - UpdateAlgorithmExtraSettings(experimentName string, extraAlgorithmSetting []*v1alpha2.AlgorithmSetting) error - GetAlgorithmExtraSettings(experimentName string) ([]*v1alpha2.AlgorithmSetting, error) - - RegisterTrial(trial *v1alpha2.Trial) error - GetTrialList(experimentName string, filter string) ([]*v1alpha2.Trial, error) - GetTrial(trialName string) (*v1alpha2.Trial, error) - UpdateTrialStatus(trialName string, newStatus *v1alpha2.TrialStatus) error - DeleteTrial(trialName string) error - - RegisterObservationLog(trialName string, observationLog *v1alpha2.ObservationLog) error - GetObservationLog(trialName string, metricName string, startTime string, endTime string) (*v1alpha2.ObservationLog, error) -} - -type dbConn struct { - db *sql.DB -} - -var rs1Letters = []rune("abcdefghijklmnopqrstuvwxyz") - -func getDbName() string { - dbPass := os.Getenv("MYSQL_ROOT_PASSWORD") - if dbPass == "" { - klog.Info("WARN: Env var MYSQL_ROOT_PASSWORD is empty. Falling back to \"test\".") - - // For backward compatibility, e.g. in case that all but vizier-core - // is older ones so we do not have Secret nor upgraded vizier-db. - dbPass = "test" - } - - return fmt.Sprintf(dbNameTmpl, dbPass) -} - -func openSQLConn(driverName string, dataSourceName string, interval time.Duration, - timeout time.Duration) (*sql.DB, error) { - ticker := time.NewTicker(interval) - defer ticker.Stop() - - timeoutC := time.After(timeout) - for { - select { - case <-ticker.C: - if db, err := sql.Open(driverName, dataSourceName); err == nil { - if err = db.Ping(); err == nil { - return db, nil - } - klog.Errorf("Ping to Katib db failed: %v", err) - } else { - klog.Errorf("Open sql connection failed: %v", err) - } - case <-timeoutC: - return nil, fmt.Errorf("Timeout waiting for DB conn successfully opened.") - } - } -} - -func NewWithSQLConn(db *sql.DB) (KatibDBInterface, error) { - d := new(dbConn) - d.db = db - seed, err := crand.Int(crand.Reader, big.NewInt(1<<63-1)) - if err != nil { - return nil, fmt.Errorf("RNG initialization failed: %v", err) - } - // We can do the following instead, but it creates a locking issue - //d.rng = rand.New(rand.NewSource(seed.Int64())) - rand.Seed(seed.Int64()) - - return d, nil -} - -func New() (KatibDBInterface, error) { - db, err := openSQLConn(dbDriver, getDbName(), connectInterval, connectTimeout) - if err != nil { - return nil, fmt.Errorf("DB open failed: %v", err) - } - return NewWithSQLConn(db) -} - -func (d *dbConn) RegisterExperiment(experiment *v1alpha2.Experiment) error { - var paramSpecs string - var objSpec string - var algoSpec string - var nasConfig string - var start_time string - var completion_time string - var err error - if experiment.Spec != nil { - if experiment.Spec.ParameterSpecs != nil { - paramSpecs, err = (&jsonpb.Marshaler{}).MarshalToString(experiment.Spec.ParameterSpecs) - if err != nil { - return fmt.Errorf("Error marshaling Parameters: %v", err) - } - } - if experiment.Spec.Objective != nil { - objSpec, err = (&jsonpb.Marshaler{}).MarshalToString(experiment.Spec.Objective) - if err != nil { - return fmt.Errorf("Error marshaling Objective: %v", err) - } - } - if experiment.Spec.Algorithm != nil { - algoSpec, err = (&jsonpb.Marshaler{}).MarshalToString(experiment.Spec.Algorithm) - if err != nil { - return fmt.Errorf("Error marshaling Algorithm: %v", err) - } - } - if experiment.Spec.NasConfig != nil { - nasConfig, err = (&jsonpb.Marshaler{}).MarshalToString(experiment.Spec.NasConfig) - if err != nil { - return fmt.Errorf("Error marshaling NasConfig: %v", err) - } - } - } else { - return fmt.Errorf("Invalid experiment: spec is nil.") - } - - start_time = time.Now().UTC().Format(mysqlTimeFmt) - completion_time = time.Time{}.UTC().Format(mysqlTimeFmt) - if experiment.Status != nil { - if experiment.Status.StartTime != "" { - s_time, err := time.Parse(time.RFC3339Nano, experiment.Status.StartTime) - if err != nil { - return fmt.Errorf("Error parsing start time %s: %v", experiment.Status.StartTime, err) - } - start_time = s_time.UTC().Format(mysqlTimeFmt) - } - if experiment.Status.CompletionTime != "" { - c_time, err := time.Parse(time.RFC3339Nano, experiment.Status.CompletionTime) - if err != nil { - return fmt.Errorf("Error parsing completion time %s: %v", experiment.Status.CompletionTime, err) - } - completion_time = c_time.UTC().Format(mysqlTimeFmt) - } - } - - _, err = d.db.Exec( - `INSERT INTO experiments ( - name, - parameters, - objective, - algorithm, - trial_template, - metrics_collector_spec, - parallel_trial_count, - max_trial_count, - status, - start_time, - completion_time, - nas_config) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - experiment.Name, - paramSpecs, - objSpec, - algoSpec, - experiment.Spec.TrialTemplate, - experiment.Spec.MetricsCollectorSpec, - experiment.Spec.ParallelTrialCount, - experiment.Spec.MaxTrialCount, - experiment.Status.Condition, - start_time, - completion_time, - nasConfig, - ) - return err -} - -func (d *dbConn) DeleteExperiment(experimentName string) error { - _, err := d.db.Exec("DELETE FROM experiments WHERE name = ?", experimentName) - return err -} - -func (d *dbConn) PreCheckRegisterExperiment(experiment *v1alpha2.Experiment) (bool, error) { - _, err := d.GetExperiment(experiment.Name) - if err != nil { - if err == sql.ErrNoRows { - return true, nil - } - return false, err - } else { - return false, nil - } -} - -func (d *dbConn) GetExperiment(experimentName string) (*v1alpha2.Experiment, error) { - var id string - var paramSpecs string - var objSpec string - var algoSpec string - var nasConfig string - var start_time string - var completion_time string - - experiment := &v1alpha2.Experiment{ - Spec: &v1alpha2.ExperimentSpec{}, - Status: &v1alpha2.ExperimentStatus{}, - } - row := d.db.QueryRow("SELECT * FROM experiments WHERE name = ?", experimentName) - err := row.Scan( - &id, - &experiment.Name, - ¶mSpecs, - &objSpec, - &algoSpec, - &experiment.Spec.TrialTemplate, - &experiment.Spec.MetricsCollectorSpec, - &experiment.Spec.ParallelTrialCount, - &experiment.Spec.MaxTrialCount, - &experiment.Status.Condition, - &start_time, - &completion_time, - &nasConfig, - ) - if err != nil { - return nil, err - } - if paramSpecs != "" { - experiment.Spec.ParameterSpecs = new(v1alpha2.ExperimentSpec_ParameterSpecs) - err = jsonpb.UnmarshalString(paramSpecs, experiment.Spec.ParameterSpecs) - if err != nil { - return nil, err - } - } - if objSpec != "" { - experiment.Spec.Objective = new(v1alpha2.ObjectiveSpec) - err = jsonpb.UnmarshalString(objSpec, experiment.Spec.Objective) - if err != nil { - return nil, err - } - } - if algoSpec != "" { - experiment.Spec.Algorithm = new(v1alpha2.AlgorithmSpec) - err = jsonpb.UnmarshalString(algoSpec, experiment.Spec.Algorithm) - if err != nil { - return nil, err - } - } - if nasConfig != "" { - experiment.Spec.NasConfig = new(v1alpha2.NasConfig) - err = jsonpb.UnmarshalString(nasConfig, experiment.Spec.NasConfig) - if err != nil { - return nil, err - } - } - if start_time != "" { - start_timeMysql, err := time.Parse(mysqlTimeFmt, start_time) - if err != nil { - return nil, fmt.Errorf("Error parsing Trial start time %s to mysqlFormat: %v", start_time, err) - } - experiment.Status.StartTime = start_timeMysql.UTC().Format(time.RFC3339Nano) - } - if completion_time != "" { - completion_timeMysql, err := time.Parse(mysqlTimeFmt, completion_time) - if err != nil { - return nil, fmt.Errorf("Error parsing Trial completion time %s to mysqlFormat: %v", completion_time, err) - } - experiment.Status.CompletionTime = completion_timeMysql.UTC().Format(time.RFC3339Nano) - } - return experiment, nil -} - -func (d *dbConn) GetExperimentList() ([]*v1alpha2.ExperimentSummary, error) { - rows, err := d.db.Query(`SELECT name, status, start_time, completion_time FROM experiments`) - if err != nil { - return nil, err - } - defer rows.Close() - var result []*v1alpha2.ExperimentSummary - var start_time string - var completion_time string - for rows.Next() { - experiment_sum := v1alpha2.ExperimentSummary{ - ExperimentName: "", - Status: &v1alpha2.ExperimentStatus{}, - } - err = rows.Scan( - &experiment_sum.ExperimentName, - &experiment_sum.Status.Condition, - &start_time, - &completion_time, - ) - if err != nil { - return nil, fmt.Errorf("Fail to get Experiment from DB. %v", err) - } - if start_time != "" { - start_timeMysql, err := time.Parse(mysqlTimeFmt, start_time) - if err != nil { - return nil, fmt.Errorf("Error parsing Trial start time %s to mysqlFormat: %v", start_time, err) - } - experiment_sum.Status.StartTime = start_timeMysql.UTC().Format(time.RFC3339Nano) - } - if completion_time != "" { - completion_timeMysql, err := time.Parse(mysqlTimeFmt, completion_time) - if err != nil { - return nil, fmt.Errorf("Error parsing Trial completion time %s to mysqlFormat: %v", completion_time, err) - } - experiment_sum.Status.CompletionTime = completion_timeMysql.UTC().Format(time.RFC3339Nano) - } - result = append(result, &experiment_sum) - } - return result, nil -} - -func (d *dbConn) UpdateExperimentStatus(experimentName string, newStatus *v1alpha2.ExperimentStatus) error { - start_time := "" - completion_time := "" - var err error - if newStatus.StartTime != "" { - s_time, err := time.Parse(time.RFC3339Nano, newStatus.StartTime) - if err != nil { - return fmt.Errorf("Error parsing start time %s: %v", newStatus.StartTime, err) - } - start_time = s_time.UTC().Format(mysqlTimeFmt) - } - if newStatus.CompletionTime != "" { - c_time, err := time.Parse(time.RFC3339Nano, newStatus.CompletionTime) - if err != nil { - return fmt.Errorf("Error parsing completion time %s: %v", newStatus.CompletionTime, err) - } - completion_time = c_time.UTC().Format(mysqlTimeFmt) - } - _, err = d.db.Exec(`UPDATE experiments SET status = ?, - start_time = ?, - completion_time = ? WHERE name = ?`, - newStatus.Condition, - start_time, - completion_time, - experimentName) - return err -} - -func (d *dbConn) UpdateAlgorithmExtraSettings(experimentName string, extraAlgorithmSetting []*v1alpha2.AlgorithmSetting) error { - aesList, err := d.GetAlgorithmExtraSettings(experimentName) - if err != nil { - return fmt.Errorf("Failed to get current state %v", err) - } - for _, neas := range extraAlgorithmSetting { - isin := false - for _, ceas := range aesList { - if ceas.Name == neas.Name { - _, err = d.db.Exec(`UPDATE extra_algorithm_settings SET value = ? - WHERE experiment_name = ? AND setting_name = ?`, - neas.Value, experimentName, ceas.Name) - if err != nil { - return fmt.Errorf("Failed to update state %v", err) - } - isin = true - break - } - } - if !isin { - _, err = d.db.Exec( - `INSERT INTO extra_algorithm_settings ( - experiment_name, - setting_name, - value) VALUES (?, ?, ?)`, - experimentName, - neas.Name, - neas.Value, - ) - if err != nil { - return fmt.Errorf("Failed to update state %v", err) - } - } - } - return nil -} - -func (d *dbConn) GetAlgorithmExtraSettings(experimentName string) ([]*v1alpha2.AlgorithmSetting, error) { - rows, err := d.db.Query("SELECT setting_name, value FROM extra_algorithm_settings WHERE experiment_name = ?", experimentName) - if err != nil { - return nil, err - } - defer rows.Close() - var result []*v1alpha2.AlgorithmSetting - for rows.Next() { - as := new(v1alpha2.AlgorithmSetting) - err := rows.Scan( - &as.Name, - &as.Value, - ) - if err != nil { - return nil, fmt.Errorf("Failed to scan ExtraSetting %v", err) - } - result = append(result, as) - } - return result, nil -} - -func (d *dbConn) RegisterTrial(trial *v1alpha2.Trial) error { - var objSpec string - var paramAssignment string - var start_time string - var completion_time string - var observation string - var err error - if trial.Spec != nil { - if trial.Spec.Objective != nil { - objSpec, err = (&jsonpb.Marshaler{}).MarshalToString(trial.Spec.Objective) - if err != nil { - return fmt.Errorf("Error marshaling Objective: %v", err) - } - } - if trial.Spec.ParameterAssignments != nil { - paramAssignment, err = (&jsonpb.Marshaler{}).MarshalToString(trial.Spec.ParameterAssignments) - if err != nil { - return fmt.Errorf("Error marshaling Parameters: %v", err) - } - } - } else { - return fmt.Errorf("Invalid trial: spec is nil.") - } - - start_time = time.Now().UTC().Format(mysqlTimeFmt) - completion_time = time.Time{}.UTC().Format(mysqlTimeFmt) - - if trial.Status != nil { - if trial.Status.Observation != nil { - observation, err = (&jsonpb.Marshaler{}).MarshalToString(trial.Status.Observation) - if err != nil { - return fmt.Errorf("Error marshaling Objective: %v", err) - } - } - if trial.Status.StartTime != "" { - s_time, err := time.Parse(time.RFC3339Nano, trial.Status.StartTime) - if err != nil { - return fmt.Errorf("Error parsing start time %s: %v", trial.Status.StartTime, err) - } - start_time = s_time.UTC().Format(mysqlTimeFmt) - } - if trial.Status.CompletionTime != "" { - c_time, err := time.Parse(time.RFC3339Nano, trial.Status.CompletionTime) - if err != nil { - return fmt.Errorf("Error parsing completion time %s: %v", trial.Status.CompletionTime, err) - } - completion_time = c_time.UTC().Format(mysqlTimeFmt) - } - } - _, err = d.db.Exec( - `INSERT INTO trials ( - name, - experiment_name, - objective, - parameter_assignments, - run_spec, - metrics_collector_spec, - observation, - status, - start_time, - completion_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - trial.Name, - trial.Spec.ExperimentName, - objSpec, - paramAssignment, - trial.Spec.RunSpec, - trial.Spec.MetricsCollectorSpec, - observation, - trial.Status.Condition, - start_time, - completion_time, - ) - return err -} - -func (d *dbConn) GetTrialList(experimentName string, filter string) ([]*v1alpha2.Trial, error) { - var id string - var objSpec string - var paramAssignment string - var start_time string - var completion_time string - var observation string - var qstr = "SELECT * FROM trials WHERE experiment_name = ?" - var qfield = []interface{}{experimentName} - if filter != "" { - //Currently only support filter by name. - //TODO support other type of fiter - //e.g. - //* filter:name=foo - //* filter:start_time>x - //*filter:end_time<=y - qstr += " AND name LIKE '%?%'" - qfield = append(qfield, filter) - } - rows, err := d.db.Query(qstr, qfield...) - if err != nil { - return nil, err - } - defer rows.Close() - var result []*v1alpha2.Trial - for rows.Next() { - trial := &v1alpha2.Trial{ - Spec: &v1alpha2.TrialSpec{}, - Status: &v1alpha2.TrialStatus{}, - } - err := rows.Scan( - &id, - &trial.Name, - &trial.Spec.ExperimentName, - &objSpec, - ¶mAssignment, - &trial.Spec.RunSpec, - &trial.Spec.MetricsCollectorSpec, - &observation, - &trial.Status.Condition, - &start_time, - &completion_time, - ) - if err != nil { - return nil, fmt.Errorf("Failed to scan trial %v", err) - } - if objSpec != "" { - trial.Spec.Objective = new(v1alpha2.ObjectiveSpec) - err = jsonpb.UnmarshalString(objSpec, trial.Spec.Objective) - if err != nil { - return nil, err - } - } - if paramAssignment != "" { - trial.Spec.ParameterAssignments = new(v1alpha2.TrialSpec_ParameterAssignments) - err = jsonpb.UnmarshalString(paramAssignment, trial.Spec.ParameterAssignments) - if err != nil { - return nil, err - } - } - if observation != "" { - trial.Status.Observation = new(v1alpha2.Observation) - err = jsonpb.UnmarshalString(observation, trial.Status.Observation) - if err != nil { - return nil, err - } - } - if start_time != "" { - start_timeMysql, err := time.Parse(mysqlTimeFmt, start_time) - if err != nil { - return nil, fmt.Errorf("Error parsing Trial start time %s to mysqlFormat: %v", start_time, err) - } - trial.Status.StartTime = start_timeMysql.UTC().Format(time.RFC3339Nano) - } - if completion_time != "" { - completion_timeMysql, err := time.Parse(mysqlTimeFmt, completion_time) - if err != nil { - return nil, fmt.Errorf("Error parsing Trial completion time %s to mysqlFormat: %v", completion_time, err) - } - trial.Status.CompletionTime = completion_timeMysql.UTC().Format(time.RFC3339Nano) - } - result = append(result, trial) - } - return result, nil -} - -func (d *dbConn) GetTrial(trialName string) (*v1alpha2.Trial, error) { - var id string - var objSpec string - var paramAssignment string - var start_time string - var completion_time string - var observation string - trial := &v1alpha2.Trial{ - Spec: &v1alpha2.TrialSpec{}, - Status: &v1alpha2.TrialStatus{}, - } - row := d.db.QueryRow("SELECT * FROM trials WHERE name = ?", trialName) - err := row.Scan( - &id, - &trial.Name, - &trial.Spec.ExperimentName, - &objSpec, - ¶mAssignment, - &trial.Spec.RunSpec, - &trial.Spec.MetricsCollectorSpec, - &observation, - &trial.Status.Condition, - &start_time, - &completion_time, - ) - if objSpec != "" { - trial.Spec.Objective = new(v1alpha2.ObjectiveSpec) - err = jsonpb.UnmarshalString(objSpec, trial.Spec.Objective) - if err != nil { - return nil, err - } - } - if paramAssignment != "" { - trial.Spec.ParameterAssignments = new(v1alpha2.TrialSpec_ParameterAssignments) - err = jsonpb.UnmarshalString(paramAssignment, trial.Spec.ParameterAssignments) - if err != nil { - return nil, err - } - } - if observation != "" { - trial.Status.Observation = new(v1alpha2.Observation) - err = jsonpb.UnmarshalString(observation, trial.Status.Observation) - if err != nil { - return nil, err - } - } - if start_time != "" { - start_timeMysql, err := time.Parse(mysqlTimeFmt, start_time) - if err != nil { - return nil, fmt.Errorf("Error parsing Trial start time %s to mysqlFormat: %v", start_time, err) - } - trial.Status.StartTime = start_timeMysql.UTC().Format(time.RFC3339Nano) - } - if completion_time != "" { - completion_timeMysql, err := time.Parse(mysqlTimeFmt, completion_time) - if err != nil { - return nil, fmt.Errorf("Error parsing Trial completion time %s to mysqlFormat: %v", completion_time, err) - } - trial.Status.CompletionTime = completion_timeMysql.UTC().Format(time.RFC3339Nano) - } - - return trial, nil -} - -func (d *dbConn) UpdateTrialStatus(trialName string, newStatus *v1alpha2.TrialStatus) error { - var observation string = "" - var formattedStartTime, formattedCompletionTime string = "", "" - var err error - if newStatus.Observation != nil { - observation, err = (&jsonpb.Marshaler{}).MarshalToString(newStatus.Observation) - if err != nil { - return fmt.Errorf("Error marshaling Objective: %v", err) - } - } - - if newStatus.StartTime != "" { - start_time, err := time.Parse(time.RFC3339Nano, newStatus.StartTime) - if err != nil { - return fmt.Errorf("Error parsing start time %s: %v", newStatus.StartTime, err) - } - formattedStartTime = start_time.UTC().Format(mysqlTimeFmt) - } - if newStatus.CompletionTime != "" { - completion_time, err := time.Parse(time.RFC3339Nano, newStatus.CompletionTime) - if err != nil { - return fmt.Errorf("Error parsing completion time %s: %v", newStatus.CompletionTime, err) - } - formattedCompletionTime = completion_time.UTC().Format(mysqlTimeFmt) - } - _, err = d.db.Exec(`UPDATE trials SET status = ?, - start_time = ?, - completion_time = ?, - observation = ? WHERE name = ?`, - newStatus.Condition, - formattedStartTime, - formattedCompletionTime, - observation, - trialName) - return err -} -func (d *dbConn) DeleteTrial(trialName string) error { - _, err := d.db.Exec("DELETE FROM trials WHERE name = ?", trialName) - return err -} - -func (d *dbConn) RegisterObservationLog(trialName string, observationLog *v1alpha2.ObservationLog) error { - var mname, mvalue string - for _, mlog := range observationLog.MetricLogs { - mname = mlog.Metric.Name - mvalue = mlog.Metric.Value - if mlog.TimeStamp == "" { - continue - } - t, err := time.Parse(time.RFC3339Nano, mlog.TimeStamp) - if err != nil { - return fmt.Errorf("Error parsing start time %s: %v", mlog.TimeStamp, err) - } - sqlTimeStr := t.UTC().Format(mysqlTimeFmt) - _, err = d.db.Exec( - `INSERT INTO observation_logs ( - trial_name, - time, - metric_name, - value - ) VALUES (?, ?, ?, ?)`, - trialName, - sqlTimeStr, - mname, - mvalue, - ) - if err != nil { - return err - } - } - return nil -} -func (d *dbConn) GetObservationLog(trialName string, metricName string, startTime string, endTime string) (*v1alpha2.ObservationLog, error) { - qfield := []interface{}{trialName} - qstr := "" - if metricName != "" { - qstr += " AND metric_name = ?" - qfield = append(qfield, metricName) - } - if startTime != "" { - s_time, err := time.Parse(time.RFC3339Nano, startTime) - if err != nil { - return nil, fmt.Errorf("Error parsing start time %s: %v", startTime, err) - } - formattedStartTime := s_time.UTC().Format(mysqlTimeFmt) - qstr += " AND time >= ?" - qfield = append(qfield, formattedStartTime) - } - if endTime != "" { - e_time, err := time.Parse(time.RFC3339Nano, endTime) - if err != nil { - return nil, fmt.Errorf("Error parsing completion time %s: %v", endTime, err) - } - formattedEndTime := e_time.UTC().Format(mysqlTimeFmt) - qstr += " AND time <= ?" - qfield = append(qfield, formattedEndTime) - } - rows, err := d.db.Query("SELECT time, metric_name, value FROM observation_logs WHERE trial_name = ?"+qstr+" ORDER BY time", - qfield...) - if err != nil { - return nil, fmt.Errorf("Failed to get ObservationLogs %v", err) - } - result := &v1alpha2.ObservationLog{ - MetricLogs: []*v1alpha2.MetricLog{}, - } - for rows.Next() { - var mname, mvalue, sqlTimeStr string - err := rows.Scan(&sqlTimeStr, &mname, &mvalue) - if err != nil { - klog.Errorf("Error scanning log: %v", err) - continue - } - ptime, err := time.Parse(mysqlTimeFmt, sqlTimeStr) - if err != nil { - klog.Errorf("Error parsing time %s: %v", sqlTimeStr, err) - continue - } - timeStamp := ptime.UTC().Format(time.RFC3339Nano) - result.MetricLogs = append(result.MetricLogs, &v1alpha2.MetricLog{ - TimeStamp: timeStamp, - Metric: &v1alpha2.Metric{ - Name: mname, - Value: mvalue, - }, - }) - } - return result, nil -} diff --git a/pkg/db/v1alpha2/interface_test.go b/pkg/db/v1alpha2/interface_test.go deleted file mode 100644 index 405d7ffb166..00000000000 --- a/pkg/db/v1alpha2/interface_test.go +++ /dev/null @@ -1,531 +0,0 @@ -package db - -import ( - // "database/sql" - // "database/sql/driver" - // "errors" - "fmt" - "os" - "testing" - - //"time" - - _ "github.com/go-sql-driver/mysql" - // "github.com/golang/protobuf/jsonpb" - - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - sqlmock "gopkg.in/DATA-DOG/go-sqlmock.v1" -) - -var dbInterface, mysqlInterface KatibDBInterface -var mock sqlmock.Sqlmock - -var experimentColums = []string{ - "id", - "name", - "parameters", - "objective", - "algorithm", - "trial_template", - "metrics_collector_spec", - "parallel_trial_count", - "max_trial_count", - "status", - "start_time", - "completion_time", - "nas_config", -} -var trialColumns = []string{ - "id", - "name", - "experiment_name", - "objective", - "parameter_assignments", - "run_spec", - "metrics_collector_spec", - "observation", - "status", - "start_time", - "completion_time", -} - -var observationLogsColumns = []string{ - "trial_name", - "id", - "time", - "metric_name", - "value", -} - -var extraAlgorithmSettingsColumns = []string{ - "experiment_name", - "id", - "setting_name", - "value", -} - -func TestMain(m *testing.M) { - db, sm, err := sqlmock.New() - mock = sm - if err != nil { - fmt.Printf("error opening db: %v\n", err) - os.Exit(1) - } - dbInterface, err = NewWithSQLConn(db) - if err != nil { - fmt.Printf("error NewWithSQLConn: %v\n", err) - } - mock.ExpectExec("CREATE TABLE IF NOT EXISTS experiments").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec("CREATE TABLE IF NOT EXISTS trials").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec("CREATE TABLE IF NOT EXISTS observation_logs").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec("CREATE TABLE IF NOT EXISTS extra_algorithm_settings").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) - dbInterface.DBInit() - err = dbInterface.SelectOne() - if err != nil { - fmt.Printf("error `SELECT 1` probing: %v\n", err) - } - os.Exit(m.Run()) -} - -func TestRegisterExperiment(t *testing.T) { - experiment := &api_pb.Experiment{ - Name: "test1", - Spec: &api_pb.ExperimentSpec{ - ParameterSpecs: &api_pb.ExperimentSpec_ParameterSpecs{ - Parameters: []*api_pb.ParameterSpec{}, - }, - Objective: &api_pb.ObjectiveSpec{ - Type: api_pb.ObjectiveType_UNKNOWN, - Goal: 0.99, - ObjectiveMetricName: "f1_score", - AdditionalMetricNames: []string{"loss", "precision", "recall"}, - }, - Algorithm: &api_pb.AlgorithmSpec{}, - TrialTemplate: "", - ParallelTrialCount: 10, - MaxTrialCount: 100, - }, - Status: &api_pb.ExperimentStatus{ - Condition: api_pb.ExperimentStatus_CREATED, - StartTime: "2016-12-31T20:02:05.123456Z", - CompletionTime: "2016-12-31T20:02:06.123456Z", - }, - } - mock.ExpectExec( - `INSERT INTO experiments \( - name, - parameters, - objective, - algorithm, - trial_template, - metrics_collector_spec, - parallel_trial_count, - max_trial_count, - status, - start_time, - completion_time, - nas_config\)`, - ).WithArgs( - "test1", - "{\"parameters\":[]}", - "{\"goal\":0.99,\"objectiveMetricName\":\"f1_score\",\"additionalMetricNames\":[\"loss\",\"precision\",\"recall\"]}", - "{}", - experiment.Spec.TrialTemplate, - experiment.Spec.MetricsCollectorSpec, - experiment.Spec.ParallelTrialCount, - experiment.Spec.MaxTrialCount, - experiment.Status.Condition, - "2016-12-31 20:02:05.123456", - "2016-12-31 20:02:06.123456", - "", - ).WillReturnResult(sqlmock.NewResult(1, 1)) - err := dbInterface.RegisterExperiment(experiment) - if err != nil { - t.Errorf("RegisterExperiment failed: %v", err) - } -} - -func TestGetExperiment(t *testing.T) { - mock.ExpectQuery("SELECT").WillReturnRows( - sqlmock.NewRows(experimentColums).AddRow( - 1, - "test1", - "{\"parameters\":[]}", - "{\"goal\":0.99,\"objectiveMetricName\":\"f1_score\",\"additionalMetricNames\":[\"loss\",\"precision\",\"recall\"]}", - "{}", - "", - "", - 10, - 100, - api_pb.ExperimentStatus_CREATED, - "2016-12-31 20:02:05.123456", - "2016-12-31 20:02:06.123456", - "", - ), - ) - experiment, err := dbInterface.GetExperiment("test1") - if err != nil { - t.Errorf("GetExperiment failed %v", err) - } else if experiment.Name != "test1" { - t.Errorf("GetExperiment incorrect return %v", experiment) - } -} - -func TestGetExperimentList(t *testing.T) { - mock.ExpectQuery("SELECT name, status, start_time, completion_time FROM experiments").WillReturnRows( - sqlmock.NewRows([]string{"name", "status", "start_time", "completion_time"}).AddRow( - "test1", - api_pb.ExperimentStatus_CREATED, - "2016-12-31 20:02:05.123456", - "2016-12-31 20:02:06.123456", - ).AddRow( - "test2", - api_pb.ExperimentStatus_SUCCEEDED, - "2016-12-31 20:02:05.123456", - "2016-12-31 20:05:05.123456", - ), - ) - experiments, err := dbInterface.GetExperimentList() - if err != nil { - t.Errorf("GetExperimentList failed %v", err) - } else if len(experiments) != 2 { - t.Errorf("Wrong Experiment number %d", len(experiments)) - } else if experiments[0].ExperimentName != "test1" || experiments[1].ExperimentName != "test2" { - t.Errorf("GetExperimentList incorrect return %v", experiments) - } -} - -func TestUpdateExperimentStatus(t *testing.T) { - condition := api_pb.ExperimentStatus_RUNNING - exp_name := "test1" - start_time := "2016-12-31 20:02:05.123456" - completion_time := "2016-12-31 20:02:06.123456" - - mock.ExpectExec(`UPDATE experiments SET status = \?, - start_time = \?, - completion_time = \? WHERE name = \?`, - ).WithArgs(condition, start_time, completion_time, exp_name).WillReturnResult(sqlmock.NewResult(1, 1)) - - err := dbInterface.UpdateExperimentStatus(exp_name, - &api_pb.ExperimentStatus{ - Condition: condition, - StartTime: "2016-12-31T20:02:05.123456Z", - CompletionTime: "2016-12-31T20:02:06.123456Z", - }, - ) - if err != nil { - t.Errorf("UpdateExperiment failed %v", err) - } -} - -func TestUpdateAlgorithmExtraSettings(t *testing.T) { - //TestUpdateAlgorithmExtraSettings inclueds TestGetAlgorithmExtraSettings - //settin1 is already stored and setting2 is not exist in DB. - exp_name := "test1" - exAlgoSet := []*api_pb.AlgorithmSetting{ - { - Name: "setting1", - Value: "100", - }, - { - Name: "setting2", - Value: "0.2", - }, - } - mock.ExpectQuery("SELECT").WillReturnRows( - sqlmock.NewRows([]string{"setting_name", "value"}).AddRow( - "setting1", - "50", - ), - ) - - mock.ExpectExec(`UPDATE extra_algorithm_settings SET value = \? - WHERE experiment_name = \? AND setting_name = \?`, - ).WithArgs(exAlgoSet[0].Value, exp_name, exAlgoSet[0].Name).WillReturnResult(sqlmock.NewResult(1, 1)) - - mock.ExpectExec(`INSERT INTO extra_algorithm_settings \( - experiment_name, - setting_name, - value\)`, - ).WithArgs(exp_name, exAlgoSet[1].Name, exAlgoSet[1].Value).WillReturnResult(sqlmock.NewResult(1, 1)) - err := dbInterface.UpdateAlgorithmExtraSettings(exp_name, exAlgoSet) - if err != nil { - t.Errorf("UpdateAlgorithmExtraSettings failed %v", err) - } - -} - -func TestRegisterTrial(t *testing.T) { - trial := &api_pb.Trial{ - Name: "test1_trial1", - Spec: &api_pb.TrialSpec{ - ExperimentName: "test1", - Objective: &api_pb.ObjectiveSpec{ - Type: api_pb.ObjectiveType_UNKNOWN, - Goal: 0.99, - ObjectiveMetricName: "f1_score", - AdditionalMetricNames: []string{"loss", "precision", "recall"}, - }, - ParameterAssignments: &api_pb.TrialSpec_ParameterAssignments{ - Assignments: []*api_pb.ParameterAssignment{ - { - Name: "param1", - Value: "0.9", - }, - { - Name: "param2", - Value: "10", - }, - }, - }, - RunSpec: "", - }, - Status: &api_pb.TrialStatus{ - Condition: api_pb.TrialStatus_RUNNING, - Observation: &api_pb.Observation{ - Metrics: []*api_pb.Metric{ - { - Name: "f1_score", - Value: "88.95", - }, - { - Name: "loss", - Value: "0.5", - }, - { - Name: "precision", - Value: "88.7", - }, - { - Name: "recall", - Value: "89.2", - }, - }, - }, - StartTime: "2016-12-31T20:02:05.123456Z", - CompletionTime: "2016-12-31T20:02:06.123456Z", - }, - } - mock.ExpectExec( - `INSERT INTO trials \( - name, - experiment_name, - objective, - parameter_assignments, - run_spec, - metrics_collector_spec, - observation, - status, - start_time, - completion_time\)`, - ).WithArgs( - "test1_trial1", - "test1", - "{\"goal\":0.99,\"objectiveMetricName\":\"f1_score\",\"additionalMetricNames\":[\"loss\",\"precision\",\"recall\"]}", - "{\"assignments\":[{\"name\":\"param1\",\"value\":\"0.9\"},{\"name\":\"param2\",\"value\":\"10\"}]}", - "", - "", - "{\"metrics\":[{\"name\":\"f1_score\",\"value\":\"88.95\"},{\"name\":\"loss\",\"value\":\"0.5\"},{\"name\":\"precision\",\"value\":\"88.7\"},{\"name\":\"recall\",\"value\":\"89.2\"}]}", - trial.Status.Condition, - "2016-12-31 20:02:05.123456", - "2016-12-31 20:02:06.123456", - ).WillReturnResult(sqlmock.NewResult(1, 1)) - err := dbInterface.RegisterTrial(trial) - if err != nil { - t.Errorf("RegisterTrial failed: %v", err) - } - -} - -func TestGetTrialList(t *testing.T) { - mock.ExpectQuery(`SELECT`).WillReturnRows( - sqlmock.NewRows(trialColumns).AddRow( - 1, - "test1_trial1", - "test1", - "{\"goal\":0.99,\"objectiveMetricName\":\"f1_score\",\"additionalMetricNames\":[\"loss\",\"precision\",\"recall\"]}", - "{\"assignments\":[{\"name\":\"param1\",\"value\":\"0.9\"},{\"name\":\"param2\",\"value\":\"10\"}]}", - "", - "", - "{\"metrics\":[{\"name\":\"f1_score\",\"value\":\"88.95\"},{\"name\":\"loss\",\"value\":\"0.5\"},{\"name\":\"precision\",\"value\":\"88.7\"},{\"name\":\"recall\",\"value\":\"89.2\"}]}", - api_pb.TrialStatus_RUNNING, - "2016-12-31 20:02:05.123456", - "2016-12-31 20:02:06.123456", - ).AddRow( - 2, - "test1_trial2", - "test1", - "{\"goal\":0.99,\"objectiveMetricName\":\"f1_score\",\"additionalMetricNames\":[\"loss\",\"precision\",\"recall\"]}", - "{\"assignments\":[{\"name\":\"param1\",\"value\":\"0.8\"},{\"name\":\"param2\",\"value\":\"20\"}]}", - "", - "", - "{\"metrics\":[{\"name\":\"f1_score\",\"value\":\"88.5\"},{\"name\":\"loss\",\"value\":\"0.8\"},{\"name\":\"precision\",\"value\":\"88.2\"},{\"name\":\"recall\",\"value\":\"89.0\"}]}", - api_pb.TrialStatus_SUCCEEDED, - "2016-12-31 20:02:05.123456", - "2016-12-31 20:02:06.123456", - ), - ) - trials, err := dbInterface.GetTrialList("test1", "trial") - if err != nil { - t.Errorf("GetTrialList failed %v", err) - } else if len(trials) != 2 { - t.Errorf("Wrong trial number %d", len(trials)) - } else if trials[0].Name != "test1_trial1" || trials[1].Name != "test1_trial2" { - t.Errorf("GetTrialList incorrect return %v", trials) - } -} - -func TestGetTrial(t *testing.T) { - mock.ExpectQuery(`SELECT \* FROM trials WHERE name = \?`).WillReturnRows( - sqlmock.NewRows(trialColumns).AddRow( - 1, - "test1_trial1", - "test1", - "{\"goal\":0.99,\"objectiveMetricName\":\"f1_score\",\"additionalMetricNames\":[\"loss\",\"precision\",\"recall\"]}", - "{\"assignments\":[{\"name\":\"param1\",\"value\":\"0.9\"},{\"name\":\"param2\",\"value\":\"10\"}]}", - "", - "", - "{\"metrics\":[{\"name\":\"f1_score\",\"value\":\"88.95\"},{\"name\":\"loss\",\"value\":\"0.5\"},{\"name\":\"precision\",\"value\":\"88.7\"},{\"name\":\"recall\",\"value\":\"89.2\"}]}", - api_pb.TrialStatus_RUNNING, - "2016-12-31 20:02:05.123456", - "2016-12-31 20:02:06.123456", - ), - ) - trial, err := dbInterface.GetTrial("test1_trial1") - if err != nil { - t.Errorf("GetTria failed %v", err) - } else if trial.Name != "test1_trial1" { - t.Errorf("GetTrial incorrect return %v", trial) - } -} - -func TestUpdateTrialStatus(t *testing.T) { - condition := api_pb.TrialStatus_RUNNING - trial_name := "test1_trial1" - start_time := "2016-12-31 20:02:05.123456" - completion_time := "2016-12-31 20:02:06.123456" - - mock.ExpectExec(`UPDATE trials SET status = \?, - start_time = \?, - completion_time = \?, - observation = \? WHERE name = \?`, - ).WithArgs( - condition, - start_time, - completion_time, - "{\"metrics\":[{\"name\":\"f1_score\",\"value\":\"88.95\"},{\"name\":\"loss\",\"value\":\"0.5\"},{\"name\":\"precision\",\"value\":\"88.7\"},{\"name\":\"recall\",\"value\":\"89.2\"}]}", - trial_name).WillReturnResult(sqlmock.NewResult(1, 1)) - - err := dbInterface.UpdateTrialStatus( - trial_name, - &api_pb.TrialStatus{ - Condition: condition, - StartTime: "2016-12-31T20:02:05.123456Z", - CompletionTime: "2016-12-31T20:02:06.123456Z", - Observation: &api_pb.Observation{ - Metrics: []*api_pb.Metric{ - { - Name: "f1_score", - Value: "88.95", - }, - { - Name: "loss", - Value: "0.5", - }, - { - Name: "precision", - Value: "88.7", - }, - { - Name: "recall", - Value: "89.2", - }, - }, - }, - }, - ) - if err != nil { - t.Errorf("UpdateTrial failed %v", err) - } -} - -func TestRegisterObservationLog(t *testing.T) { - obsLog := &api_pb.ObservationLog{ - MetricLogs: []*api_pb.MetricLog{ - { - TimeStamp: "2016-12-31T20:02:05.123456Z", - Metric: &api_pb.Metric{ - Name: "f1_score", - Value: "88.95", - }, - }, - { - TimeStamp: "2016-12-31T20:02:05.123456Z", - Metric: &api_pb.Metric{ - Name: "loss", - Value: "0.5", - }, - }, - { - TimeStamp: "2016-12-31T20:02:05.123456Z", - Metric: &api_pb.Metric{ - Name: "precision", - Value: "88.7", - }, - }, - { - TimeStamp: "2016-12-31T20:02:05.123456Z", - Metric: &api_pb.Metric{ - Name: "recall", - Value: "89.2", - }, - }, - }, - } - for _, m := range obsLog.MetricLogs { - mock.ExpectExec( - `INSERT INTO observation_logs \( - trial_name, - time, - metric_name, - value - \)`, - ).WithArgs( - "test1_trial1", - "2016-12-31 20:02:05.123456", - m.Metric.Name, - m.Metric.Value, - ).WillReturnResult(sqlmock.NewResult(1, 1)) - } - err := dbInterface.RegisterObservationLog("test1_trial1", obsLog) - if err != nil { - t.Errorf("RegisterExperiment failed: %v", err) - } - -} - -func TestGetObservationLog(t *testing.T) { - mock.ExpectQuery("SELECT").WillReturnRows( - sqlmock.NewRows([]string{"time", "metric_name", "value"}).AddRow( - "2016-12-31 21:02:05.123456", - "loss", - "0.9", - ).AddRow( - "2016-12-31 22:02:05.123456", - "loss", - "0.9", - ), - ) - obsLog, err := dbInterface.GetObservationLog( - "test1_trial1", - "", - "2016-12-31T21:01:05.123456Z", - "", - ) - if err != nil { - t.Errorf("GetObservationLog failed %v", err) - } else if len(obsLog.MetricLogs) != 2 { - t.Errorf("GetObservationLog incorrect return %v", obsLog) - } - -} diff --git a/pkg/mock/v1alpha2/api/manager.go b/pkg/mock/v1alpha2/api/manager.go deleted file mode 100644 index 34aed0c0280..00000000000 --- a/pkg/mock/v1alpha2/api/manager.go +++ /dev/null @@ -1,376 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/kubeflow/katib/pkg/apis/manager/v1alpha2 (interfaces: ManagerClient) - -// Package mock is a generated GoMock package. -package mock - -import ( - context "context" - gomock "github.com/golang/mock/gomock" - v1alpha2 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - grpc "google.golang.org/grpc" - reflect "reflect" -) - -// MockManagerClient is a mock of ManagerClient interface -type MockManagerClient struct { - ctrl *gomock.Controller - recorder *MockManagerClientMockRecorder -} - -// MockManagerClientMockRecorder is the mock recorder for MockManagerClient -type MockManagerClientMockRecorder struct { - mock *MockManagerClient -} - -// NewMockManagerClient creates a new mock instance -func NewMockManagerClient(ctrl *gomock.Controller) *MockManagerClient { - mock := &MockManagerClient{ctrl: ctrl} - mock.recorder = &MockManagerClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockManagerClient) EXPECT() *MockManagerClientMockRecorder { - return m.recorder -} - -// DeleteExperiment mocks base method -func (m *MockManagerClient) DeleteExperiment(arg0 context.Context, arg1 *v1alpha2.DeleteExperimentRequest, arg2 ...grpc.CallOption) (*v1alpha2.DeleteExperimentReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "DeleteExperiment", varargs...) - ret0, _ := ret[0].(*v1alpha2.DeleteExperimentReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DeleteExperiment indicates an expected call of DeleteExperiment -func (mr *MockManagerClientMockRecorder) DeleteExperiment(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteExperiment", reflect.TypeOf((*MockManagerClient)(nil).DeleteExperiment), varargs...) -} - -// DeleteTrial mocks base method -func (m *MockManagerClient) DeleteTrial(arg0 context.Context, arg1 *v1alpha2.DeleteTrialRequest, arg2 ...grpc.CallOption) (*v1alpha2.DeleteTrialReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "DeleteTrial", varargs...) - ret0, _ := ret[0].(*v1alpha2.DeleteTrialReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DeleteTrial indicates an expected call of DeleteTrial -func (mr *MockManagerClientMockRecorder) DeleteTrial(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTrial", reflect.TypeOf((*MockManagerClient)(nil).DeleteTrial), varargs...) -} - -// GetAlgorithmExtraSettings mocks base method -func (m *MockManagerClient) GetAlgorithmExtraSettings(arg0 context.Context, arg1 *v1alpha2.GetAlgorithmExtraSettingsRequest, arg2 ...grpc.CallOption) (*v1alpha2.GetAlgorithmExtraSettingsReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetAlgorithmExtraSettings", varargs...) - ret0, _ := ret[0].(*v1alpha2.GetAlgorithmExtraSettingsReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAlgorithmExtraSettings indicates an expected call of GetAlgorithmExtraSettings -func (mr *MockManagerClientMockRecorder) GetAlgorithmExtraSettings(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlgorithmExtraSettings", reflect.TypeOf((*MockManagerClient)(nil).GetAlgorithmExtraSettings), varargs...) -} - -// GetExperiment mocks base method -func (m *MockManagerClient) GetExperiment(arg0 context.Context, arg1 *v1alpha2.GetExperimentRequest, arg2 ...grpc.CallOption) (*v1alpha2.GetExperimentReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetExperiment", varargs...) - ret0, _ := ret[0].(*v1alpha2.GetExperimentReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetExperiment indicates an expected call of GetExperiment -func (mr *MockManagerClientMockRecorder) GetExperiment(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExperiment", reflect.TypeOf((*MockManagerClient)(nil).GetExperiment), varargs...) -} - -// GetExperimentList mocks base method -func (m *MockManagerClient) GetExperimentList(arg0 context.Context, arg1 *v1alpha2.GetExperimentListRequest, arg2 ...grpc.CallOption) (*v1alpha2.GetExperimentListReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetExperimentList", varargs...) - ret0, _ := ret[0].(*v1alpha2.GetExperimentListReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetExperimentList indicates an expected call of GetExperimentList -func (mr *MockManagerClientMockRecorder) GetExperimentList(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExperimentList", reflect.TypeOf((*MockManagerClient)(nil).GetExperimentList), varargs...) -} - -// GetObservationLog mocks base method -func (m *MockManagerClient) GetObservationLog(arg0 context.Context, arg1 *v1alpha2.GetObservationLogRequest, arg2 ...grpc.CallOption) (*v1alpha2.GetObservationLogReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetObservationLog", varargs...) - ret0, _ := ret[0].(*v1alpha2.GetObservationLogReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetObservationLog indicates an expected call of GetObservationLog -func (mr *MockManagerClientMockRecorder) GetObservationLog(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObservationLog", reflect.TypeOf((*MockManagerClient)(nil).GetObservationLog), varargs...) -} - -// GetSuggestions mocks base method -func (m *MockManagerClient) GetSuggestions(arg0 context.Context, arg1 *v1alpha2.GetSuggestionsRequest, arg2 ...grpc.CallOption) (*v1alpha2.GetSuggestionsReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetSuggestions", varargs...) - ret0, _ := ret[0].(*v1alpha2.GetSuggestionsReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSuggestions indicates an expected call of GetSuggestions -func (mr *MockManagerClientMockRecorder) GetSuggestions(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestions", reflect.TypeOf((*MockManagerClient)(nil).GetSuggestions), varargs...) -} - -// GetTrial mocks base method -func (m *MockManagerClient) GetTrial(arg0 context.Context, arg1 *v1alpha2.GetTrialRequest, arg2 ...grpc.CallOption) (*v1alpha2.GetTrialReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetTrial", varargs...) - ret0, _ := ret[0].(*v1alpha2.GetTrialReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTrial indicates an expected call of GetTrial -func (mr *MockManagerClientMockRecorder) GetTrial(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrial", reflect.TypeOf((*MockManagerClient)(nil).GetTrial), varargs...) -} - -// GetTrialList mocks base method -func (m *MockManagerClient) GetTrialList(arg0 context.Context, arg1 *v1alpha2.GetTrialListRequest, arg2 ...grpc.CallOption) (*v1alpha2.GetTrialListReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetTrialList", varargs...) - ret0, _ := ret[0].(*v1alpha2.GetTrialListReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTrialList indicates an expected call of GetTrialList -func (mr *MockManagerClientMockRecorder) GetTrialList(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialList", reflect.TypeOf((*MockManagerClient)(nil).GetTrialList), varargs...) -} - -// PreCheckRegisterExperiment mocks base method -func (m *MockManagerClient) PreCheckRegisterExperiment(arg0 context.Context, arg1 *v1alpha2.RegisterExperimentRequest, arg2 ...grpc.CallOption) (*v1alpha2.PreCheckRegisterExperimentReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "PreCheckRegisterExperiment", varargs...) - ret0, _ := ret[0].(*v1alpha2.PreCheckRegisterExperimentReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// PreCheckRegisterExperiment indicates an expected call of PreCheckRegisterExperiment -func (mr *MockManagerClientMockRecorder) PreCheckRegisterExperiment(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PreCheckRegisterExperiment", reflect.TypeOf((*MockManagerClient)(nil).PreCheckRegisterExperiment), varargs...) -} - -// RegisterExperiment mocks base method -func (m *MockManagerClient) RegisterExperiment(arg0 context.Context, arg1 *v1alpha2.RegisterExperimentRequest, arg2 ...grpc.CallOption) (*v1alpha2.RegisterExperimentReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "RegisterExperiment", varargs...) - ret0, _ := ret[0].(*v1alpha2.RegisterExperimentReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RegisterExperiment indicates an expected call of RegisterExperiment -func (mr *MockManagerClientMockRecorder) RegisterExperiment(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterExperiment", reflect.TypeOf((*MockManagerClient)(nil).RegisterExperiment), varargs...) -} - -// RegisterTrial mocks base method -func (m *MockManagerClient) RegisterTrial(arg0 context.Context, arg1 *v1alpha2.RegisterTrialRequest, arg2 ...grpc.CallOption) (*v1alpha2.RegisterTrialReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "RegisterTrial", varargs...) - ret0, _ := ret[0].(*v1alpha2.RegisterTrialReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RegisterTrial indicates an expected call of RegisterTrial -func (mr *MockManagerClientMockRecorder) RegisterTrial(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterTrial", reflect.TypeOf((*MockManagerClient)(nil).RegisterTrial), varargs...) -} - -// ReportObservationLog mocks base method -func (m *MockManagerClient) ReportObservationLog(arg0 context.Context, arg1 *v1alpha2.ReportObservationLogRequest, arg2 ...grpc.CallOption) (*v1alpha2.ReportObservationLogReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "ReportObservationLog", varargs...) - ret0, _ := ret[0].(*v1alpha2.ReportObservationLogReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ReportObservationLog indicates an expected call of ReportObservationLog -func (mr *MockManagerClientMockRecorder) ReportObservationLog(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReportObservationLog", reflect.TypeOf((*MockManagerClient)(nil).ReportObservationLog), varargs...) -} - -// UpdateAlgorithmExtraSettings mocks base method -func (m *MockManagerClient) UpdateAlgorithmExtraSettings(arg0 context.Context, arg1 *v1alpha2.UpdateAlgorithmExtraSettingsRequest, arg2 ...grpc.CallOption) (*v1alpha2.UpdateAlgorithmExtraSettingsReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "UpdateAlgorithmExtraSettings", varargs...) - ret0, _ := ret[0].(*v1alpha2.UpdateAlgorithmExtraSettingsReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// UpdateAlgorithmExtraSettings indicates an expected call of UpdateAlgorithmExtraSettings -func (mr *MockManagerClientMockRecorder) UpdateAlgorithmExtraSettings(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAlgorithmExtraSettings", reflect.TypeOf((*MockManagerClient)(nil).UpdateAlgorithmExtraSettings), varargs...) -} - -// UpdateExperimentStatus mocks base method -func (m *MockManagerClient) UpdateExperimentStatus(arg0 context.Context, arg1 *v1alpha2.UpdateExperimentStatusRequest, arg2 ...grpc.CallOption) (*v1alpha2.UpdateExperimentStatusReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "UpdateExperimentStatus", varargs...) - ret0, _ := ret[0].(*v1alpha2.UpdateExperimentStatusReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// UpdateExperimentStatus indicates an expected call of UpdateExperimentStatus -func (mr *MockManagerClientMockRecorder) UpdateExperimentStatus(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateExperimentStatus", reflect.TypeOf((*MockManagerClient)(nil).UpdateExperimentStatus), varargs...) -} - -// UpdateTrialStatus mocks base method -func (m *MockManagerClient) UpdateTrialStatus(arg0 context.Context, arg1 *v1alpha2.UpdateTrialStatusRequest, arg2 ...grpc.CallOption) (*v1alpha2.UpdateTrialStatusReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "UpdateTrialStatus", varargs...) - ret0, _ := ret[0].(*v1alpha2.UpdateTrialStatusReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// UpdateTrialStatus indicates an expected call of UpdateTrialStatus -func (mr *MockManagerClientMockRecorder) UpdateTrialStatus(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTrialStatus", reflect.TypeOf((*MockManagerClient)(nil).UpdateTrialStatus), varargs...) -} - -// ValidateAlgorithmSettings mocks base method -func (m *MockManagerClient) ValidateAlgorithmSettings(arg0 context.Context, arg1 *v1alpha2.ValidateAlgorithmSettingsRequest, arg2 ...grpc.CallOption) (*v1alpha2.ValidateAlgorithmSettingsReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "ValidateAlgorithmSettings", varargs...) - ret0, _ := ret[0].(*v1alpha2.ValidateAlgorithmSettingsReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ValidateAlgorithmSettings indicates an expected call of ValidateAlgorithmSettings -func (mr *MockManagerClientMockRecorder) ValidateAlgorithmSettings(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateAlgorithmSettings", reflect.TypeOf((*MockManagerClient)(nil).ValidateAlgorithmSettings), varargs...) -} diff --git a/pkg/mock/v1alpha2/api/suggestion.go b/pkg/mock/v1alpha2/api/suggestion.go deleted file mode 100644 index d3ef886bc91..00000000000 --- a/pkg/mock/v1alpha2/api/suggestion.go +++ /dev/null @@ -1,76 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/kubeflow/katib/pkg/apis/manager/v1alpha2 (interfaces: SuggestionClient) - -// Package mock is a generated GoMock package. -package mock - -import ( - context "context" - gomock "github.com/golang/mock/gomock" - v1alpha2 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - grpc "google.golang.org/grpc" - reflect "reflect" -) - -// MockSuggestionClient is a mock of SuggestionClient interface -type MockSuggestionClient struct { - ctrl *gomock.Controller - recorder *MockSuggestionClientMockRecorder -} - -// MockSuggestionClientMockRecorder is the mock recorder for MockSuggestionClient -type MockSuggestionClientMockRecorder struct { - mock *MockSuggestionClient -} - -// NewMockSuggestionClient creates a new mock instance -func NewMockSuggestionClient(ctrl *gomock.Controller) *MockSuggestionClient { - mock := &MockSuggestionClient{ctrl: ctrl} - mock.recorder = &MockSuggestionClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockSuggestionClient) EXPECT() *MockSuggestionClientMockRecorder { - return m.recorder -} - -// GetSuggestions mocks base method -func (m *MockSuggestionClient) GetSuggestions(arg0 context.Context, arg1 *v1alpha2.GetSuggestionsRequest, arg2 ...grpc.CallOption) (*v1alpha2.GetSuggestionsReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetSuggestions", varargs...) - ret0, _ := ret[0].(*v1alpha2.GetSuggestionsReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSuggestions indicates an expected call of GetSuggestions -func (mr *MockSuggestionClientMockRecorder) GetSuggestions(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestions", reflect.TypeOf((*MockSuggestionClient)(nil).GetSuggestions), varargs...) -} - -// ValidateAlgorithmSettings mocks base method -func (m *MockSuggestionClient) ValidateAlgorithmSettings(arg0 context.Context, arg1 *v1alpha2.ValidateAlgorithmSettingsRequest, arg2 ...grpc.CallOption) (*v1alpha2.ValidateAlgorithmSettingsReply, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "ValidateAlgorithmSettings", varargs...) - ret0, _ := ret[0].(*v1alpha2.ValidateAlgorithmSettingsReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ValidateAlgorithmSettings indicates an expected call of ValidateAlgorithmSettings -func (mr *MockSuggestionClientMockRecorder) ValidateAlgorithmSettings(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateAlgorithmSettings", reflect.TypeOf((*MockSuggestionClient)(nil).ValidateAlgorithmSettings), varargs...) -} diff --git a/pkg/mock/v1alpha2/db/db.go b/pkg/mock/v1alpha2/db/db.go deleted file mode 100644 index b87626498ed..00000000000 --- a/pkg/mock/v1alpha2/db/db.go +++ /dev/null @@ -1,277 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/kubeflow/katib/pkg/db/v1alpha2 (interfaces: KatibDBInterface) - -// Package mock is a generated GoMock package. -package mock - -import ( - gomock "github.com/golang/mock/gomock" - v1alpha2 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - reflect "reflect" -) - -// MockKatibDBInterface is a mock of KatibDBInterface interface -type MockKatibDBInterface struct { - ctrl *gomock.Controller - recorder *MockKatibDBInterfaceMockRecorder -} - -// MockKatibDBInterfaceMockRecorder is the mock recorder for MockKatibDBInterface -type MockKatibDBInterfaceMockRecorder struct { - mock *MockKatibDBInterface -} - -// NewMockKatibDBInterface creates a new mock instance -func NewMockKatibDBInterface(ctrl *gomock.Controller) *MockKatibDBInterface { - mock := &MockKatibDBInterface{ctrl: ctrl} - mock.recorder = &MockKatibDBInterfaceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockKatibDBInterface) EXPECT() *MockKatibDBInterfaceMockRecorder { - return m.recorder -} - -// DBInit mocks base method -func (m *MockKatibDBInterface) DBInit() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DBInit") -} - -// DBInit indicates an expected call of DBInit -func (mr *MockKatibDBInterfaceMockRecorder) DBInit() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DBInit", reflect.TypeOf((*MockKatibDBInterface)(nil).DBInit)) -} - -// DeleteExperiment mocks base method -func (m *MockKatibDBInterface) DeleteExperiment(arg0 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteExperiment", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteExperiment indicates an expected call of DeleteExperiment -func (mr *MockKatibDBInterfaceMockRecorder) DeleteExperiment(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteExperiment", reflect.TypeOf((*MockKatibDBInterface)(nil).DeleteExperiment), arg0) -} - -// DeleteTrial mocks base method -func (m *MockKatibDBInterface) DeleteTrial(arg0 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteTrial", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteTrial indicates an expected call of DeleteTrial -func (mr *MockKatibDBInterfaceMockRecorder) DeleteTrial(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTrial", reflect.TypeOf((*MockKatibDBInterface)(nil).DeleteTrial), arg0) -} - -// GetAlgorithmExtraSettings mocks base method -func (m *MockKatibDBInterface) GetAlgorithmExtraSettings(arg0 string) ([]*v1alpha2.AlgorithmSetting, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAlgorithmExtraSettings", arg0) - ret0, _ := ret[0].([]*v1alpha2.AlgorithmSetting) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAlgorithmExtraSettings indicates an expected call of GetAlgorithmExtraSettings -func (mr *MockKatibDBInterfaceMockRecorder) GetAlgorithmExtraSettings(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlgorithmExtraSettings", reflect.TypeOf((*MockKatibDBInterface)(nil).GetAlgorithmExtraSettings), arg0) -} - -// GetExperiment mocks base method -func (m *MockKatibDBInterface) GetExperiment(arg0 string) (*v1alpha2.Experiment, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetExperiment", arg0) - ret0, _ := ret[0].(*v1alpha2.Experiment) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetExperiment indicates an expected call of GetExperiment -func (mr *MockKatibDBInterfaceMockRecorder) GetExperiment(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExperiment", reflect.TypeOf((*MockKatibDBInterface)(nil).GetExperiment), arg0) -} - -// GetExperimentList mocks base method -func (m *MockKatibDBInterface) GetExperimentList() ([]*v1alpha2.ExperimentSummary, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetExperimentList") - ret0, _ := ret[0].([]*v1alpha2.ExperimentSummary) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetExperimentList indicates an expected call of GetExperimentList -func (mr *MockKatibDBInterfaceMockRecorder) GetExperimentList() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExperimentList", reflect.TypeOf((*MockKatibDBInterface)(nil).GetExperimentList)) -} - -// GetObservationLog mocks base method -func (m *MockKatibDBInterface) GetObservationLog(arg0, arg1, arg2, arg3 string) (*v1alpha2.ObservationLog, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetObservationLog", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*v1alpha2.ObservationLog) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetObservationLog indicates an expected call of GetObservationLog -func (mr *MockKatibDBInterfaceMockRecorder) GetObservationLog(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObservationLog", reflect.TypeOf((*MockKatibDBInterface)(nil).GetObservationLog), arg0, arg1, arg2, arg3) -} - -// GetTrial mocks base method -func (m *MockKatibDBInterface) GetTrial(arg0 string) (*v1alpha2.Trial, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTrial", arg0) - ret0, _ := ret[0].(*v1alpha2.Trial) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTrial indicates an expected call of GetTrial -func (mr *MockKatibDBInterfaceMockRecorder) GetTrial(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrial", reflect.TypeOf((*MockKatibDBInterface)(nil).GetTrial), arg0) -} - -// GetTrialList mocks base method -func (m *MockKatibDBInterface) GetTrialList(arg0, arg1 string) ([]*v1alpha2.Trial, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTrialList", arg0, arg1) - ret0, _ := ret[0].([]*v1alpha2.Trial) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTrialList indicates an expected call of GetTrialList -func (mr *MockKatibDBInterfaceMockRecorder) GetTrialList(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialList", reflect.TypeOf((*MockKatibDBInterface)(nil).GetTrialList), arg0, arg1) -} - -// PreCheckRegisterExperiment mocks base method -func (m *MockKatibDBInterface) PreCheckRegisterExperiment(arg0 *v1alpha2.Experiment) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PreCheckRegisterExperiment", arg0) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// PreCheckRegisterExperiment indicates an expected call of PreCheckRegisterExperiment -func (mr *MockKatibDBInterfaceMockRecorder) PreCheckRegisterExperiment(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PreCheckRegisterExperiment", reflect.TypeOf((*MockKatibDBInterface)(nil).PreCheckRegisterExperiment), arg0) -} - -// RegisterExperiment mocks base method -func (m *MockKatibDBInterface) RegisterExperiment(arg0 *v1alpha2.Experiment) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterExperiment", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// RegisterExperiment indicates an expected call of RegisterExperiment -func (mr *MockKatibDBInterfaceMockRecorder) RegisterExperiment(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterExperiment", reflect.TypeOf((*MockKatibDBInterface)(nil).RegisterExperiment), arg0) -} - -// RegisterObservationLog mocks base method -func (m *MockKatibDBInterface) RegisterObservationLog(arg0 string, arg1 *v1alpha2.ObservationLog) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterObservationLog", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// RegisterObservationLog indicates an expected call of RegisterObservationLog -func (mr *MockKatibDBInterfaceMockRecorder) RegisterObservationLog(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterObservationLog", reflect.TypeOf((*MockKatibDBInterface)(nil).RegisterObservationLog), arg0, arg1) -} - -// RegisterTrial mocks base method -func (m *MockKatibDBInterface) RegisterTrial(arg0 *v1alpha2.Trial) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterTrial", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// RegisterTrial indicates an expected call of RegisterTrial -func (mr *MockKatibDBInterfaceMockRecorder) RegisterTrial(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterTrial", reflect.TypeOf((*MockKatibDBInterface)(nil).RegisterTrial), arg0) -} - -// SelectOne mocks base method -func (m *MockKatibDBInterface) SelectOne() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SelectOne") - ret0, _ := ret[0].(error) - return ret0 -} - -// SelectOne indicates an expected call of SelectOne -func (mr *MockKatibDBInterfaceMockRecorder) SelectOne() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectOne", reflect.TypeOf((*MockKatibDBInterface)(nil).SelectOne)) -} - -// UpdateAlgorithmExtraSettings mocks base method -func (m *MockKatibDBInterface) UpdateAlgorithmExtraSettings(arg0 string, arg1 []*v1alpha2.AlgorithmSetting) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateAlgorithmExtraSettings", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateAlgorithmExtraSettings indicates an expected call of UpdateAlgorithmExtraSettings -func (mr *MockKatibDBInterfaceMockRecorder) UpdateAlgorithmExtraSettings(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAlgorithmExtraSettings", reflect.TypeOf((*MockKatibDBInterface)(nil).UpdateAlgorithmExtraSettings), arg0, arg1) -} - -// UpdateExperimentStatus mocks base method -func (m *MockKatibDBInterface) UpdateExperimentStatus(arg0 string, arg1 *v1alpha2.ExperimentStatus) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateExperimentStatus", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateExperimentStatus indicates an expected call of UpdateExperimentStatus -func (mr *MockKatibDBInterfaceMockRecorder) UpdateExperimentStatus(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateExperimentStatus", reflect.TypeOf((*MockKatibDBInterface)(nil).UpdateExperimentStatus), arg0, arg1) -} - -// UpdateTrialStatus mocks base method -func (m *MockKatibDBInterface) UpdateTrialStatus(arg0 string, arg1 *v1alpha2.TrialStatus) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateTrialStatus", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateTrialStatus indicates an expected call of UpdateTrialStatus -func (mr *MockKatibDBInterfaceMockRecorder) UpdateTrialStatus(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTrialStatus", reflect.TypeOf((*MockKatibDBInterface)(nil).UpdateTrialStatus), arg0, arg1) -} diff --git a/pkg/mock/v1alpha2/experiment/managerclient/managerclient.go b/pkg/mock/v1alpha2/experiment/managerclient/managerclient.go deleted file mode 100644 index fedf416329f..00000000000 --- a/pkg/mock/v1alpha2/experiment/managerclient/managerclient.go +++ /dev/null @@ -1,107 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/managerclient (interfaces: ManagerClient) - -// Package mock is a generated GoMock package. -package mock - -import ( - gomock "github.com/golang/mock/gomock" - v1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - v1alpha20 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - reflect "reflect" -) - -// MockManagerClient is a mock of ManagerClient interface -type MockManagerClient struct { - ctrl *gomock.Controller - recorder *MockManagerClientMockRecorder -} - -// MockManagerClientMockRecorder is the mock recorder for MockManagerClient -type MockManagerClientMockRecorder struct { - mock *MockManagerClient -} - -// NewMockManagerClient creates a new mock instance -func NewMockManagerClient(ctrl *gomock.Controller) *MockManagerClient { - mock := &MockManagerClient{ctrl: ctrl} - mock.recorder = &MockManagerClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockManagerClient) EXPECT() *MockManagerClientMockRecorder { - return m.recorder -} - -// CreateExperimentInDB mocks base method -func (m *MockManagerClient) CreateExperimentInDB(arg0 *v1alpha2.Experiment) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateExperimentInDB", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// CreateExperimentInDB indicates an expected call of CreateExperimentInDB -func (mr *MockManagerClientMockRecorder) CreateExperimentInDB(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateExperimentInDB", reflect.TypeOf((*MockManagerClient)(nil).CreateExperimentInDB), arg0) -} - -// DeleteExperimentInDB mocks base method -func (m *MockManagerClient) DeleteExperimentInDB(arg0 *v1alpha2.Experiment) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteExperimentInDB", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteExperimentInDB indicates an expected call of DeleteExperimentInDB -func (mr *MockManagerClientMockRecorder) DeleteExperimentInDB(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteExperimentInDB", reflect.TypeOf((*MockManagerClient)(nil).DeleteExperimentInDB), arg0) -} - -// PreCheckRegisterExperimentInDB mocks base method -func (m *MockManagerClient) PreCheckRegisterExperimentInDB(arg0 *v1alpha2.Experiment) (*v1alpha20.PreCheckRegisterExperimentReply, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PreCheckRegisterExperimentInDB", arg0) - ret0, _ := ret[0].(*v1alpha20.PreCheckRegisterExperimentReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// PreCheckRegisterExperimentInDB indicates an expected call of PreCheckRegisterExperimentInDB -func (mr *MockManagerClientMockRecorder) PreCheckRegisterExperimentInDB(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PreCheckRegisterExperimentInDB", reflect.TypeOf((*MockManagerClient)(nil).PreCheckRegisterExperimentInDB), arg0) -} - -// UpdateExperimentStatusInDB mocks base method -func (m *MockManagerClient) UpdateExperimentStatusInDB(arg0 *v1alpha2.Experiment) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateExperimentStatusInDB", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateExperimentStatusInDB indicates an expected call of UpdateExperimentStatusInDB -func (mr *MockManagerClientMockRecorder) UpdateExperimentStatusInDB(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateExperimentStatusInDB", reflect.TypeOf((*MockManagerClient)(nil).UpdateExperimentStatusInDB), arg0) -} - -// ValidateAlgorithmSettings mocks base method -func (m *MockManagerClient) ValidateAlgorithmSettings(arg0 *v1alpha2.Experiment) (*v1alpha20.ValidateAlgorithmSettingsReply, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ValidateAlgorithmSettings", arg0) - ret0, _ := ret[0].(*v1alpha20.ValidateAlgorithmSettingsReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ValidateAlgorithmSettings indicates an expected call of ValidateAlgorithmSettings -func (mr *MockManagerClientMockRecorder) ValidateAlgorithmSettings(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateAlgorithmSettings", reflect.TypeOf((*MockManagerClient)(nil).ValidateAlgorithmSettings), arg0) -} diff --git a/pkg/mock/v1alpha2/experiment/manifest/generator.go b/pkg/mock/v1alpha2/experiment/manifest/generator.go deleted file mode 100644 index 794ca666365..00000000000 --- a/pkg/mock/v1alpha2/experiment/manifest/generator.go +++ /dev/null @@ -1,93 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/manifest (interfaces: Generator) - -// Package mock is a generated GoMock package. -package mock - -import ( - gomock "github.com/golang/mock/gomock" - v1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - v1alpha20 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - reflect "reflect" - client "sigs.k8s.io/controller-runtime/pkg/client" -) - -// MockGenerator is a mock of Generator interface -type MockGenerator struct { - ctrl *gomock.Controller - recorder *MockGeneratorMockRecorder -} - -// MockGeneratorMockRecorder is the mock recorder for MockGenerator -type MockGeneratorMockRecorder struct { - mock *MockGenerator -} - -// NewMockGenerator creates a new mock instance -func NewMockGenerator(ctrl *gomock.Controller) *MockGenerator { - mock := &MockGenerator{ctrl: ctrl} - mock.recorder = &MockGeneratorMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockGenerator) EXPECT() *MockGeneratorMockRecorder { - return m.recorder -} - -// GetMetricsCollectorManifest mocks base method -func (m *MockGenerator) GetMetricsCollectorManifest(arg0, arg1, arg2, arg3 string, arg4 []string, arg5 *v1alpha2.MetricsCollectorSpec) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMetricsCollectorManifest", arg0, arg1, arg2, arg3, arg4, arg5) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetMetricsCollectorManifest indicates an expected call of GetMetricsCollectorManifest -func (mr *MockGeneratorMockRecorder) GetMetricsCollectorManifest(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMetricsCollectorManifest", reflect.TypeOf((*MockGenerator)(nil).GetMetricsCollectorManifest), arg0, arg1, arg2, arg3, arg4, arg5) -} - -// GetRunSpec mocks base method -func (m *MockGenerator) GetRunSpec(arg0 *v1alpha2.Experiment, arg1, arg2, arg3 string) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRunSpec", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRunSpec indicates an expected call of GetRunSpec -func (mr *MockGeneratorMockRecorder) GetRunSpec(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRunSpec", reflect.TypeOf((*MockGenerator)(nil).GetRunSpec), arg0, arg1, arg2, arg3) -} - -// GetRunSpecWithHyperParameters mocks base method -func (m *MockGenerator) GetRunSpecWithHyperParameters(arg0 *v1alpha2.Experiment, arg1, arg2, arg3 string, arg4 []*v1alpha20.ParameterAssignment) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRunSpecWithHyperParameters", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRunSpecWithHyperParameters indicates an expected call of GetRunSpecWithHyperParameters -func (mr *MockGeneratorMockRecorder) GetRunSpecWithHyperParameters(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRunSpecWithHyperParameters", reflect.TypeOf((*MockGenerator)(nil).GetRunSpecWithHyperParameters), arg0, arg1, arg2, arg3, arg4) -} - -// InjectClient mocks base method -func (m *MockGenerator) InjectClient(arg0 client.Client) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "InjectClient", arg0) -} - -// InjectClient indicates an expected call of InjectClient -func (mr *MockGeneratorMockRecorder) InjectClient(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InjectClient", reflect.TypeOf((*MockGenerator)(nil).InjectClient), arg0) -} diff --git a/pkg/mock/v1alpha2/experiment/suggestion/suggestion.go b/pkg/mock/v1alpha2/experiment/suggestion/suggestion.go deleted file mode 100644 index a0918c23b7b..00000000000 --- a/pkg/mock/v1alpha2/experiment/suggestion/suggestion.go +++ /dev/null @@ -1,50 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/suggestion (interfaces: Suggestion) - -// Package mock is a generated GoMock package. -package mock - -import ( - gomock "github.com/golang/mock/gomock" - v1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - v1alpha20 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - reflect "reflect" -) - -// MockSuggestion is a mock of Suggestion interface -type MockSuggestion struct { - ctrl *gomock.Controller - recorder *MockSuggestionMockRecorder -} - -// MockSuggestionMockRecorder is the mock recorder for MockSuggestion -type MockSuggestionMockRecorder struct { - mock *MockSuggestion -} - -// NewMockSuggestion creates a new mock instance -func NewMockSuggestion(ctrl *gomock.Controller) *MockSuggestion { - mock := &MockSuggestion{ctrl: ctrl} - mock.recorder = &MockSuggestionMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockSuggestion) EXPECT() *MockSuggestionMockRecorder { - return m.recorder -} - -// GetSuggestions mocks base method -func (m *MockSuggestion) GetSuggestions(arg0 *v1alpha2.Experiment, arg1 int32) ([]*v1alpha20.Trial, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSuggestions", arg0, arg1) - ret0, _ := ret[0].([]*v1alpha20.Trial) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSuggestions indicates an expected call of GetSuggestions -func (mr *MockSuggestionMockRecorder) GetSuggestions(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestions", reflect.TypeOf((*MockSuggestion)(nil).GetSuggestions), arg0, arg1) -} diff --git a/pkg/mock/v1alpha2/trial/managerclient/katibmanager.go b/pkg/mock/v1alpha2/trial/managerclient/katibmanager.go deleted file mode 100644 index cc14e33d9c0..00000000000 --- a/pkg/mock/v1alpha2/trial/managerclient/katibmanager.go +++ /dev/null @@ -1,106 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/kubeflow/katib/pkg/controller.v1alpha2/trial/managerclient (interfaces: ManagerClient) - -// Package mock is a generated GoMock package. -package mock - -import ( - gomock "github.com/golang/mock/gomock" - v1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - v1alpha20 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - reflect "reflect" -) - -// MockManagerClient is a mock of ManagerClient interface -type MockManagerClient struct { - ctrl *gomock.Controller - recorder *MockManagerClientMockRecorder -} - -// MockManagerClientMockRecorder is the mock recorder for MockManagerClient -type MockManagerClientMockRecorder struct { - mock *MockManagerClient -} - -// NewMockManagerClient creates a new mock instance -func NewMockManagerClient(ctrl *gomock.Controller) *MockManagerClient { - mock := &MockManagerClient{ctrl: ctrl} - mock.recorder = &MockManagerClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockManagerClient) EXPECT() *MockManagerClientMockRecorder { - return m.recorder -} - -// CreateTrialInDB mocks base method -func (m *MockManagerClient) CreateTrialInDB(arg0 *v1alpha2.Trial) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateTrialInDB", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// CreateTrialInDB indicates an expected call of CreateTrialInDB -func (mr *MockManagerClientMockRecorder) CreateTrialInDB(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTrialInDB", reflect.TypeOf((*MockManagerClient)(nil).CreateTrialInDB), arg0) -} - -// GetTrialConf mocks base method -func (m *MockManagerClient) GetTrialConf(arg0 *v1alpha2.Trial) *v1alpha20.Trial { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTrialConf", arg0) - ret0, _ := ret[0].(*v1alpha20.Trial) - return ret0 -} - -// GetTrialConf indicates an expected call of GetTrialConf -func (mr *MockManagerClientMockRecorder) GetTrialConf(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialConf", reflect.TypeOf((*MockManagerClient)(nil).GetTrialConf), arg0) -} - -// GetTrialObservation mocks base method -func (m *MockManagerClient) GetTrialObservation(arg0 *v1alpha2.Trial) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTrialObservation", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// GetTrialObservation indicates an expected call of GetTrialObservation -func (mr *MockManagerClientMockRecorder) GetTrialObservation(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialObservation", reflect.TypeOf((*MockManagerClient)(nil).GetTrialObservation), arg0) -} - -// GetTrialObservationLog mocks base method -func (m *MockManagerClient) GetTrialObservationLog(arg0 *v1alpha2.Trial) (*v1alpha20.GetObservationLogReply, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTrialObservationLog", arg0) - ret0, _ := ret[0].(*v1alpha20.GetObservationLogReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTrialObservationLog indicates an expected call of GetTrialObservationLog -func (mr *MockManagerClientMockRecorder) GetTrialObservationLog(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialObservationLog", reflect.TypeOf((*MockManagerClient)(nil).GetTrialObservationLog), arg0) -} - -// UpdateTrialStatusInDB mocks base method -func (m *MockManagerClient) UpdateTrialStatusInDB(arg0 *v1alpha2.Trial) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateTrialStatusInDB", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateTrialStatusInDB indicates an expected call of UpdateTrialStatusInDB -func (mr *MockManagerClientMockRecorder) UpdateTrialStatusInDB(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTrialStatusInDB", reflect.TypeOf((*MockManagerClient)(nil).UpdateTrialStatusInDB), arg0) -} diff --git a/pkg/mock/v1alpha2/util/katibclient/katibclient.go b/pkg/mock/v1alpha2/util/katibclient/katibclient.go deleted file mode 100644 index fb0ed8a3333..00000000000 --- a/pkg/mock/v1alpha2/util/katibclient/katibclient.go +++ /dev/null @@ -1,241 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/kubeflow/katib/pkg/util/v1alpha2/katibclient (interfaces: Client) - -// Package mock is a generated GoMock package. -package mock - -import ( - gomock "github.com/golang/mock/gomock" - v1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - v1alpha20 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - reflect "reflect" - client "sigs.k8s.io/controller-runtime/pkg/client" -) - -// MockClient is a mock of Client interface -type MockClient struct { - ctrl *gomock.Controller - recorder *MockClientMockRecorder -} - -// MockClientMockRecorder is the mock recorder for MockClient -type MockClientMockRecorder struct { - mock *MockClient -} - -// NewMockClient creates a new mock instance -func NewMockClient(ctrl *gomock.Controller) *MockClient { - mock := &MockClient{ctrl: ctrl} - mock.recorder = &MockClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockClient) EXPECT() *MockClientMockRecorder { - return m.recorder -} - -// CreateExperiment mocks base method -func (m *MockClient) CreateExperiment(arg0 *v1alpha2.Experiment, arg1 ...string) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "CreateExperiment", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// CreateExperiment indicates an expected call of CreateExperiment -func (mr *MockClientMockRecorder) CreateExperiment(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateExperiment", reflect.TypeOf((*MockClient)(nil).CreateExperiment), varargs...) -} - -// DeleteExperiment mocks base method -func (m *MockClient) DeleteExperiment(arg0 *v1alpha2.Experiment, arg1 ...string) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "DeleteExperiment", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteExperiment indicates an expected call of DeleteExperiment -func (mr *MockClientMockRecorder) DeleteExperiment(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteExperiment", reflect.TypeOf((*MockClient)(nil).DeleteExperiment), varargs...) -} - -// GetConfigMap mocks base method -func (m *MockClient) GetConfigMap(arg0 string, arg1 ...string) (map[string]string, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetConfigMap", varargs...) - ret0, _ := ret[0].(map[string]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetConfigMap indicates an expected call of GetConfigMap -func (mr *MockClientMockRecorder) GetConfigMap(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConfigMap", reflect.TypeOf((*MockClient)(nil).GetConfigMap), varargs...) -} - -// GetExperiment mocks base method -func (m *MockClient) GetExperiment(arg0 string, arg1 ...string) (*v1alpha2.Experiment, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetExperiment", varargs...) - ret0, _ := ret[0].(*v1alpha2.Experiment) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetExperiment indicates an expected call of GetExperiment -func (mr *MockClientMockRecorder) GetExperiment(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExperiment", reflect.TypeOf((*MockClient)(nil).GetExperiment), varargs...) -} - -// GetExperimentList mocks base method -func (m *MockClient) GetExperimentList(arg0 ...string) (*v1alpha2.ExperimentList, error) { - m.ctrl.T.Helper() - varargs := []interface{}{} - for _, a := range arg0 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetExperimentList", varargs...) - ret0, _ := ret[0].(*v1alpha2.ExperimentList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetExperimentList indicates an expected call of GetExperimentList -func (mr *MockClientMockRecorder) GetExperimentList(arg0 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExperimentList", reflect.TypeOf((*MockClient)(nil).GetExperimentList), arg0...) -} - -// GetMetricsCollectorTemplates mocks base method -func (m *MockClient) GetMetricsCollectorTemplates(arg0 ...string) (map[string]string, error) { - m.ctrl.T.Helper() - varargs := []interface{}{} - for _, a := range arg0 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetMetricsCollectorTemplates", varargs...) - ret0, _ := ret[0].(map[string]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetMetricsCollectorTemplates indicates an expected call of GetMetricsCollectorTemplates -func (mr *MockClientMockRecorder) GetMetricsCollectorTemplates(arg0 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMetricsCollectorTemplates", reflect.TypeOf((*MockClient)(nil).GetMetricsCollectorTemplates), arg0...) -} - -// GetTrialList mocks base method -func (m *MockClient) GetTrialList(arg0 string, arg1 ...string) (*v1alpha20.TrialList, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetTrialList", varargs...) - ret0, _ := ret[0].(*v1alpha20.TrialList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTrialList indicates an expected call of GetTrialList -func (mr *MockClientMockRecorder) GetTrialList(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialList", reflect.TypeOf((*MockClient)(nil).GetTrialList), varargs...) -} - -// GetTrialTemplates mocks base method -func (m *MockClient) GetTrialTemplates(arg0 ...string) (map[string]string, error) { - m.ctrl.T.Helper() - varargs := []interface{}{} - for _, a := range arg0 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetTrialTemplates", varargs...) - ret0, _ := ret[0].(map[string]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTrialTemplates indicates an expected call of GetTrialTemplates -func (mr *MockClientMockRecorder) GetTrialTemplates(arg0 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialTemplates", reflect.TypeOf((*MockClient)(nil).GetTrialTemplates), arg0...) -} - -// InjectClient mocks base method -func (m *MockClient) InjectClient(arg0 client.Client) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "InjectClient", arg0) -} - -// InjectClient indicates an expected call of InjectClient -func (mr *MockClientMockRecorder) InjectClient(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InjectClient", reflect.TypeOf((*MockClient)(nil).InjectClient), arg0) -} - -// UpdateMetricsCollectorTemplates mocks base method -func (m *MockClient) UpdateMetricsCollectorTemplates(arg0 map[string]string, arg1 ...string) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "UpdateMetricsCollectorTemplates", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateMetricsCollectorTemplates indicates an expected call of UpdateMetricsCollectorTemplates -func (mr *MockClientMockRecorder) UpdateMetricsCollectorTemplates(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMetricsCollectorTemplates", reflect.TypeOf((*MockClient)(nil).UpdateMetricsCollectorTemplates), varargs...) -} - -// UpdateTrialTemplates mocks base method -func (m *MockClient) UpdateTrialTemplates(arg0 map[string]string, arg1 ...string) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "UpdateTrialTemplates", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateTrialTemplates indicates an expected call of UpdateTrialTemplates -func (mr *MockClientMockRecorder) UpdateTrialTemplates(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTrialTemplates", reflect.TypeOf((*MockClient)(nil).UpdateTrialTemplates), varargs...) -} diff --git a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/AlgorithmSettings.py b/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/AlgorithmSettings.py deleted file mode 100644 index 902d0d88aed..00000000000 --- a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/AlgorithmSettings.py +++ /dev/null @@ -1,70 +0,0 @@ -def parseAlgorithmSettings(params_raw): - param_standard = { - "lstm_num_cells": ['value', int, [1, 'inf']], - "lstm_num_layers": ['value', int, [1, 'inf']], - "lstm_keep_prob": ['value', float, [0.0, 1.0]], - "optimizer": ['categorical', str, ["adam", "momentum", "sgd"]], - "init_learning_rate": ['value', float, [1e-6, 1.0]], - "lr_decay_start": ['value', int, [0, 'inf']], - "lr_decay_every": ['value', int, [1, 'inf']], - "lr_decay_rate": ['value', float, [0.0, 1.0]], - "skip-target": ['value', float, [0.0, 1.0]], - "skip-weight": ['value', float, [0.0, 'inf']], - "l2_reg": ['value', float, [0.0, 'inf']], - "entropy_weight": ['value', float, [0.0, 'inf']], - "baseline_decay": ['value', float, [0.0, 1.0]], - } - - algorithm_settings = { - "lstm_num_cells": 64, - "lstm_num_layers": 1, - "lstm_keep_prob": 1.0, - "optimizer": "adam", - "init_learning_rate": 1e-3, - "lr_decay_start": 0, - "lr_decay_every": 1000, - "lr_decay_rate": 0.9, - "skip-target": 0.4, - "skip-weight": 0.8, - "l2_reg": 0, - "entropy_weight": 1e-4, - "baseline_decay": 0.9999 - } - - def checktype(param_name, param_value, check_mode, supposed_type, supposed_range=None): - correct = True - - try: - converted_value = supposed_type(param_value) - except: - correct = False - print("Parameter {} is of wrong type. Set back to default value {}" - .format(param_name, algorithm_settings[param_name])) - - if correct and check_mode == 'value': - if not ((supposed_range[0] == '-inf' or converted_value >= supposed_range[0]) and - (supposed_range[1] == 'inf' or converted_value <= supposed_range[1])): - correct = False - print("Parameter {} out of range. Set back to default value {}" - .format(param_name, algorithm_settings[param_name])) - elif correct and check_mode == 'categorical': - if converted_value not in supposed_range: - correct = False - print("Parameter {} out of range. Set back to default value {}" - .format(param_name, algorithm_settings[param_name])) - - if correct: - algorithm_settings[param_name] = converted_value - - - for param in params_raw: - if param.name in algorithm_settings.keys(): - checktype(param.name, - param.value, - param_standard[param.name][0], # mode - param_standard[param.name][1], # type - param_standard[param.name][2]) # range - else: - print("Unknown Parameter name: {}".format(param.name)) - - return algorithm_settings diff --git a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Controller.py b/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Controller.py deleted file mode 100755 index eb51c1be1aa..00000000000 --- a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Controller.py +++ /dev/null @@ -1,219 +0,0 @@ -import tensorflow as tf -from pkg.suggestion.v1alpha2.NAS_Reinforcement_Learning.LSTM import stack_lstm -from pkg.suggestion.v1alpha2.NAS_Reinforcement_Learning.Trainer import get_train_ops - - -class Controller(object): - def __init__(self, - num_layers=12, - num_operations=16, - lstm_size=64, - lstm_num_layers=1, - lstm_keep_prob=1.0, - tanh_constant=1.5, - temperature=None, - lr_init=1e-3, - lr_dec_start=0, - lr_dec_every=1000, - lr_dec_rate=0.9, - l2_reg=0, - entropy_weight=1e-4, - clip_mode=None, - grad_bound=None, - bl_dec=0.999, - optim_algo="adam", - sync_replicas=False, - num_aggregate=20, - num_replicas=1, - skip_target=0.4, - skip_weight=0.8, - name="controller", - logger=None): - - self.logger = logger - self.logger.info(">>> Building Controller") - - self.num_layers = num_layers - self.num_operations = num_operations - - self.lstm_size = lstm_size - self.lstm_num_layers = lstm_num_layers - self.lstm_keep_prob = lstm_keep_prob - self.tanh_constant = tanh_constant - self.temperature = temperature - self.lr_init = lr_init - self.lr_dec_start = lr_dec_start - self.lr_dec_every = lr_dec_every - self.lr_dec_rate = lr_dec_rate - self.l2_reg = l2_reg - self.entropy_weight = entropy_weight - self.clip_mode = clip_mode - self.grad_bound = grad_bound - self.bl_dec = bl_dec - - self.skip_target = skip_target - self.skip_weight = skip_weight - - self.optim_algo = optim_algo - self.sync_replicas = sync_replicas - self.num_aggregate = num_aggregate - self.num_replicas = num_replicas - self.name = name - - self._create_params() - self._build_sampler() - - def _create_params(self): - initializer = tf.random_uniform_initializer(minval=-0.1, maxval=0.1) - with tf.variable_scope(self.name, initializer=initializer): - with tf.variable_scope("lstm"): - self.w_lstm = [] - for layer_id in range(self.lstm_num_layers): - with tf.variable_scope("layer_{}".format(layer_id)): - w = tf.get_variable("w", [2 * self.lstm_size, 4 * self.lstm_size]) - self.w_lstm.append(w) - - self.g_emb = tf.get_variable("g_emb", [1, self.lstm_size]) - with tf.variable_scope("emb"): - self.w_emb = tf.get_variable("w", [self.num_operations, self.lstm_size]) - with tf.variable_scope("softmax"): - self.w_soft = tf.get_variable("w", [self.lstm_size, self.num_operations]) - - with tf.variable_scope("attention"): - self.w_attn_1 = tf.get_variable("w_1", [self.lstm_size, self.lstm_size]) - self.w_attn_2 = tf.get_variable("w_2", [self.lstm_size, self.lstm_size]) - self.v_attn = tf.get_variable("v", [self.lstm_size, 1]) - - def _build_sampler(self): - """Build the sampler ops and the log_prob ops.""" - - self.logger.info(">>> Building Controller Sampler") - anchors = [] - anchors_w_1 = [] - - arc_seq = [] - entropys = [] - log_probs = [] - skip_count = [] - skip_penaltys = [] - - prev_c = [tf.zeros([1, self.lstm_size], tf.float32) for _ in range(self.lstm_num_layers)] - prev_h = [tf.zeros([1, self.lstm_size], tf.float32) for _ in range(self.lstm_num_layers)] - inputs = self.g_emb - skip_targets = tf.constant([1.0 - self.skip_target, self.skip_target], dtype=tf.float32) - for layer_id in range(self.num_layers): - next_c, next_h = stack_lstm(inputs, prev_c, prev_h, self.w_lstm) - prev_c, prev_h = next_c, next_h - logit = tf.matmul(next_h[-1], self.w_soft) - if self.temperature is not None: - logit /= self.temperature - if self.tanh_constant is not None: - logit = self.tanh_constant * tf.tanh(logit) - - operation_id = tf.multinomial(logit, 1) - operation_id = tf.to_int32(operation_id) - operation_id = tf.reshape(operation_id, [1]) - - arc_seq.append(operation_id) - log_prob = tf.nn.sparse_softmax_cross_entropy_with_logits( - logits=logit, labels=operation_id) - log_probs.append(log_prob) - entropy = tf.stop_gradient(log_prob * tf.exp(-log_prob)) - entropys.append(entropy) - inputs = tf.nn.embedding_lookup(self.w_emb, operation_id) - - next_c, next_h = stack_lstm(inputs, prev_c, prev_h, self.w_lstm) - prev_c, prev_h = next_c, next_h - - if layer_id > 0: - query = tf.concat(anchors_w_1, axis=0) - query = tf.tanh(query + tf.matmul(next_h[-1], self.w_attn_2)) - query = tf.matmul(query, self.v_attn) - logit = tf.concat([-query, query], axis=1) - if self.temperature is not None: - logit /= self.temperature - if self.tanh_constant is not None: - logit = self.tanh_constant * tf.tanh(logit) - - skip = tf.multinomial(logit, 1) - skip = tf.to_int32(skip) - skip = tf.reshape(skip, [layer_id]) - arc_seq.append(skip) - - skip_prob = tf.sigmoid(logit) - kl = skip_prob * tf.log(skip_prob / skip_targets) - kl = tf.reduce_sum(kl) - skip_penaltys.append(kl) - - log_prob = tf.nn.sparse_softmax_cross_entropy_with_logits( - logits=logit, labels=skip) - log_probs.append(tf.reduce_sum(log_prob, keepdims=True)) - - entropy = tf.stop_gradient( - tf.reduce_sum(log_prob * tf.exp(-log_prob), keepdims=True)) - entropys.append(entropy) - - skip = tf.to_float(skip) - skip = tf.reshape(skip, [1, layer_id]) - skip_count.append(tf.reduce_sum(skip)) - inputs = tf.matmul(skip, tf.concat(anchors, axis=0)) - inputs /= (1.0 + tf.reduce_sum(skip)) - else: - inputs = self.g_emb - - anchors.append(next_h[-1]) - anchors_w_1.append(tf.matmul(next_h[-1], self.w_attn_1)) - - arc_seq = tf.concat(arc_seq, axis=0) - self.sample_arc = tf.reshape(arc_seq, [-1]) - - entropys = tf.stack(entropys) - self.sample_entropy = tf.reduce_sum(entropys) - - log_probs = tf.stack(log_probs) - self.sample_log_prob = tf.reduce_sum(log_probs) - - skip_count = tf.stack(skip_count) - self.skip_count = tf.reduce_sum(skip_count) - - skip_penaltys = tf.stack(skip_penaltys) - self.skip_penaltys = tf.reduce_mean(skip_penaltys) - - def build_trainer(self): - self.reward = tf.placeholder(tf.float32, shape=()) - - normalize = tf.to_float(self.num_layers * (self.num_layers - 1) / 2) - self.skip_rate = tf.to_float(self.skip_count) / normalize - - if self.entropy_weight is not None: - self.reward += self.entropy_weight * self.sample_entropy - - self.sample_log_prob = tf.reduce_sum(self.sample_log_prob) - self.baseline = tf.Variable(0.0, dtype=tf.float32, trainable=False) - baseline_update = tf.assign_sub(self.baseline, (1 - self.bl_dec) * (self.baseline - self.reward)) - - with tf.control_dependencies([baseline_update]): - self.reward = tf.identity(self.reward) - - self.loss = self.sample_log_prob * (self.reward - self.baseline) - if self.skip_weight is not None: - self.loss += self.skip_weight * self.skip_penaltys - - self.train_step = tf.Variable(0, dtype=tf.int32, trainable=False, name=self.name + "_train_step") - tf_variables = [var for var in tf.trainable_variables() if var.name.startswith(self.name)] - - self.train_op, self.lr, self.grad_norm, self.optimizer = get_train_ops( - self.loss, - tf_variables, - self.train_step, - clip_mode=self.clip_mode, - grad_bound=self.grad_bound, - l2_reg=self.l2_reg, - lr_init=self.lr_init, - lr_dec_start=self.lr_dec_start, - lr_dec_every=self.lr_dec_every, - lr_dec_rate=self.lr_dec_rate, - optim_algo=self.optim_algo, - sync_replicas=self.sync_replicas, - num_aggregate=self.num_aggregate, - num_replicas=self.num_replicas) diff --git a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/LSTM.py b/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/LSTM.py deleted file mode 100755 index b3ad6008386..00000000000 --- a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/LSTM.py +++ /dev/null @@ -1,28 +0,0 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -import tensorflow as tf - - -# TODO: will remove this function and use tf.nn.LSTMCell instead - -def lstm(x, prev_c, prev_h, w): - ifog = tf.matmul(tf.concat([x, prev_h], axis=1), w) - i, f, o, g = tf.split(ifog, 4, axis=1) - i = tf.sigmoid(i) - f = tf.sigmoid(f) - o = tf.sigmoid(o) - g = tf.tanh(g) - next_c = i * g + f * prev_c - next_h = o * tf.tanh(next_c) - return next_c, next_h - - -def stack_lstm(x, prev_c, prev_h, w): - next_c, next_h = [], [] - for layer_id, (_c, _h, _w) in enumerate(zip(prev_c, prev_h, w)): - inputs = x if layer_id == 0 else next_h[-1] - curr_c, curr_h = lstm(inputs, _c, _h, _w) - next_c.append(curr_c) - next_h.append(curr_h) - return next_c, next_h diff --git a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Operation.py b/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Operation.py deleted file mode 100644 index 0dd67f12541..00000000000 --- a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Operation.py +++ /dev/null @@ -1,76 +0,0 @@ -import itertools -import numpy as np -from pkg.apis.manager.v1alpha2.python import api_pb2 - - -class Operation(object): - def __init__(self, opt_id, opt_type, opt_params): - self.opt_id = opt_id - self.opt_type = opt_type - self.opt_params = opt_params - - def get_dict(self): - opt_dict = dict() - opt_dict['opt_id'] = self.opt_id - opt_dict['opt_type'] = self.opt_type - opt_dict['opt_params'] = self.opt_params - return opt_dict - - def print_op(self, logger): - logger.info("Operation ID: \n\t{}".format(self.opt_id)) - logger.info("Operation Type: \n\t{}".format(self.opt_type)) - logger.info("Operations Parameters:") - for ikey in self.opt_params: - logger.info("\t{}: {}".format(ikey, self.opt_params[ikey])) - logger.info("") - - -class SearchSpace(object): - def __init__(self, operations): - self.operation_list = list(operations.operation) - self.search_space = list() - self._parse_operations() - print() - self.num_operations = len(self.search_space) - - def _parse_operations(self): - # search_sapce is a list of Operation class - - operation_id = 0 - - for operation_dict in self.operation_list: - opt_type = operation_dict.operation_type - opt_spec = list(operation_dict.parameter_specs.parameters) - # avail_space is dict with the format {"spec_nam": [spec feasible values]} - avail_space = dict() - num_spec = len(opt_spec) - - for ispec in opt_spec: - spec_name = ispec.name - if ispec.parameter_type == api_pb2.CATEGORICAL: - avail_space[spec_name] = list(ispec.feasible_space.list) - elif ispec.parameter_type == api_pb2.INT: - spec_min = int(ispec.feasible_space.min) - spec_max = int(ispec.feasible_space.max) - spec_step = int(ispec.feasible_space.step) - avail_space[spec_name] = range(spec_min, spec_max+1, spec_step) - elif ispec.parameter_type == api_pb2.DOUBLE: - spec_min = float(ispec.feasible_space.min) - spec_max = float(ispec.feasible_space.max) - spec_step = float(ispec.feasible_space.step) - double_list = np.arange(spec_min, spec_max+spec_step, spec_step) - if double_list[-1] > spec_max: - del double_list[-1] - avail_space[spec_name] = double_list - - # generate all the combinations of possible operations - key_avail_space = list(avail_space.keys()) - val_avail_space = list(avail_space.values()) - - for this_opt_vector in itertools.product(*val_avail_space): - opt_params = dict() - for i in range(num_spec): - opt_params[key_avail_space[i]] = this_opt_vector[i] - this_opt_class = Operation(operation_id, opt_type, opt_params) - self.search_space.append(this_opt_class) - operation_id += 1 diff --git a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/README.md b/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/README.md deleted file mode 100644 index c06a4ff592d..00000000000 --- a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/README.md +++ /dev/null @@ -1,129 +0,0 @@ -# About the Nerual Architecture Search with Reinforcement Learning Suggestion - -The algorithm follows the idea proposed in *Neural Architecture Search with Reinforcement Learning* by Zoph & Le (https://arxiv.org/abs/1611.01578), and the implementation is based on the github of *Efficient Neural Architecture Search via Parameter Sharing* (https://github.com/melodyguan/enas). It uses a recurrent neural network with LSTM cells as controller to generate neural architecture candidates. And this controller network is updated by policy gradients. However, it currently does not support parameter sharing. - -## Definition of a Neural Architecture - -Define the number of layers is n, the number of possible operations is m. - -If n = 12, m = 6, the definition of an architecture will be like: - -``` -[2] -[0 0] -[1 1 0] -[5 1 0 1] -[1 1 1 0 1] -[5 0 0 1 0 1] -[1 1 1 0 0 1 0] -[2 0 0 0 1 1 0 1] -[0 0 0 1 1 1 1 1 0] -[2 0 1 0 1 1 1 0 0 0] -[3 1 1 1 1 1 1 0 0 1 1] -[0 1 1 1 1 0 0 1 1 1 1 0] -``` - -There are n rows, the ith row has i elements and describes the ith layer. Please notice that layer 0 is the input and is not included in this definition. - -In each row, the first integer ranges from 0 to m-1 and indicates the operation in this layer. -Starting from the second position, the kth integer is a boolean value that indicates whether (k-2)th layer has a skip connection with this layer. (There will always be a connection from (k-1)th layer to kth layer) - -## Output of `GetSuggestion()` -The output of `GetSuggestion()` consists of two parts: `architecture` and `nn_config`. - -`architecture` is a json string of the definition of a neural architecture. The format is as stated above. One example is: -``` -[[27], [29, 0], [22, 1, 0], [13, 0, 0, 0], [26, 1, 1, 0, 0], [30, 1, 0, 1, 0, 0], [11, 0, 1, 1, 0, 1, 1], [9, 1, 0, 0, 1, 0, 0, 0]] -``` - -`nn_config` is a json string of the detailed description of what is the num of layers, input size, output size and what each operation index stands for. A nn_config corresponding to the architecuture above can be: -``` -{ - "num_layers": 8, - "input_sizes": [32, 32, 3], - "output_sizes": [10], - "embedding": { - "27": { - "opt_id": 27, - "opt_type": "convolution", - "opt_params": { - "filter_size": "7", - "num_filter": "96", - "stride": "2" - } - }, - "29": { - "opt_id": 29, - "opt_type": "convolution", - "opt_params": { - "filter_size": "7", - "num_filter": "128", - "stride": "2" - } - }, - "22": { - "opt_id": 22, - "opt_type": "convolution", - "opt_params": { - "filter_size": "7", - "num_filter": "48", - "stride": "1" - } - }, - "13": { - "opt_id": 13, - "opt_type": "convolution", - "opt_params": { - "filter_size": "5", - "num_filter": "48", - "stride": "2" - } - }, - "26": { - "opt_id": 26, - "opt_type": "convolution", - "opt_params": { - "filter_size": "7", - "num_filter": "96", - "stride": "1" - } - }, - "30": { - "opt_id": 30, - "opt_type": "reduction", - "opt_params": { - "reduction_type": "max_pooling", - "pool_size": 2 - } - }, - "11": { - "opt_id": 11, - "opt_type": "convolution", - "opt_params": { - "filter_size": "5", - "num_filter": "32", - "stride": "2" - } - }, - "9": { - "opt_id": 9, - "opt_type": "convolution", - "opt_params": { - "filter_size": "3", - "num_filter": "128", - "stride": "2" - } - } - } -} -``` -This neural architecture can be visualized as -![a neural netowrk architecure example](example.png) - -## To Do -1. Add 'micro' mode, which means searching for a neural cell instead of the whole neural network. -2. Add supoort for recurrent neural networks and build a training container for the Penn Treebank task. -3. Add parameter sharing, if possible. -4. Change LSTM cell from self defined functions in LSTM.py to `tf.nn.rnn_cell.LSTMCell` -5. Store the suggestion checkpoint to PVC to protect against unexpected nasrl service pod restarts -6. Add `RequestCount` into API so that the suggestion can clean the information of completed studies. diff --git a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Trainer.py b/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Trainer.py deleted file mode 100644 index a8dde5115e5..00000000000 --- a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/Trainer.py +++ /dev/null @@ -1,143 +0,0 @@ -import tensorflow as tf - - -def get_train_ops(loss, - tf_variables, - train_step, - clip_mode=None, - grad_bound=None, - l2_reg=1e-4, - lr_warmup_val=None, - lr_warmup_steps=100, - lr_init=0.1, - lr_dec_start=0, - lr_dec_every=10000, - lr_dec_rate=0.1, - lr_dec_min=None, - lr_cosine=False, - lr_max=None, - lr_min=None, - lr_T_0=None, - lr_T_mul=None, - num_train_batches=None, - optim_algo=None, - sync_replicas=False, - num_aggregate=None, - num_replicas=None, - get_grad_norms=False, - moving_average=None): - """ - Args: - clip_mode: "global", "norm", or None. - moving_average: store the moving average of parameters - """ - - if l2_reg > 0: - l2_losses = [] - for var in tf_variables: - l2_losses.append(tf.reduce_sum(var ** 2)) - l2_loss = tf.add_n(l2_losses) - loss += l2_reg * l2_loss - - grads = tf.gradients(loss, tf_variables) - grad_norm = tf.global_norm(grads) - - grad_norms = {} - for v, g in zip(tf_variables, grads): - if v is None or g is None: - continue - if isinstance(g, tf.IndexedSlices): - grad_norms[v.name] = tf.sqrt(tf.reduce_sum(g.values ** 2)) - else: - grad_norms[v.name] = tf.sqrt(tf.reduce_sum(g ** 2)) - - if clip_mode is not None: - assert grad_bound is not None, "Need grad_bound to clip gradients." - if clip_mode == "global": - grads, _ = tf.clip_by_global_norm(grads, grad_bound) - elif clip_mode == "norm": - clipped = [] - for g in grads: - if isinstance(g, tf.IndexedSlices): - c_g = tf.clip_by_norm(g.values, grad_bound) - c_g = tf.IndexedSlices(g.indices, c_g) - else: - c_g = tf.clip_by_norm(g, grad_bound) - clipped.append(g) - grads = clipped - else: - raise NotImplementedError("Unknown clip_mode {}".format(clip_mode)) - - if lr_cosine: - assert lr_max is not None, "Need lr_max to use lr_cosine" - assert lr_min is not None, "Need lr_min to use lr_cosine" - assert lr_T_0 is not None, "Need lr_T_0 to use lr_cosine" - assert lr_T_mul is not None, "Need lr_T_mul to use lr_cosine" - assert num_train_batches is not None, ("Need num_train_batches to use" - " lr_cosine") - - curr_epoch = train_step // num_train_batches - - last_reset = tf.Variable(0, dtype=tf.int32, trainable=False, - name="last_reset") - T_i = tf.Variable(lr_T_0, dtype=tf.int32, trainable=False, name="T_i") - T_curr = curr_epoch - last_reset - - def _update(): - update_last_reset = tf.assign(last_reset, curr_epoch, use_locking=True) - update_T_i = tf.assign(T_i, T_i * lr_T_mul, use_locking=True) - with tf.control_dependencies([update_last_reset, update_T_i]): - rate = tf.to_float(T_curr) / tf.to_float(T_i) * 3.1415926 - lr = lr_min + 0.5 * (lr_max - lr_min) * (1.0 + tf.cos(rate)) - return lr - - def _no_update(): - rate = tf.to_float(T_curr) / tf.to_float(T_i) * 3.1415926 - lr = lr_min + 0.5 * (lr_max - lr_min) * (1.0 + tf.cos(rate)) - return lr - - learning_rate = tf.cond( - tf.greater_equal(T_curr, T_i), _update, _no_update) - else: - learning_rate = tf.train.exponential_decay( - lr_init, tf.maximum(train_step - lr_dec_start, 0), lr_dec_every, - lr_dec_rate, staircase=True) - if lr_dec_min is not None: - learning_rate = tf.maximum(learning_rate, lr_dec_min) - - if lr_warmup_val is not None: - learning_rate = tf.cond(tf.less(train_step, lr_warmup_steps), - lambda: lr_warmup_val, lambda: learning_rate) - - if optim_algo == "momentum": - opt = tf.train.MomentumOptimizer( - learning_rate, 0.9, use_locking=True, use_nesterov=True) - elif optim_algo == "sgd": - opt = tf.train.GradientDescentOptimizer(learning_rate, use_locking=True) - elif optim_algo == "adam": - opt = tf.train.AdamOptimizer(learning_rate, beta1=0.0, epsilon=1e-3, - use_locking=True) - else: - raise ValueError("Unknown optim_algo {}".format(optim_algo)) - - if sync_replicas: - assert num_aggregate is not None, "Need num_aggregate to sync." - assert num_replicas is not None, "Need num_replicas to sync." - - opt = tf.train.SyncReplicasOptimizer( - opt, - replicas_to_aggregate=num_aggregate, - total_num_replicas=num_replicas, - use_locking=True) - - if moving_average is not None: - opt = tf.contrib.opt.MovingAverageOptimizer( - opt, average_decay=moving_average) - - train_op = opt.apply_gradients( - zip(grads, tf_variables), global_step=train_step) - - if get_grad_norms: - return train_op, learning_rate, grad_norm, opt, grad_norms - else: - return train_op, learning_rate, grad_norm, opt diff --git a/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/example.png b/pkg/suggestion/v1alpha2/NAS_Reinforcement_Learning/example.png deleted file mode 100644 index 90ac2eb6190051e322d45110e9b807473a35632d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137757 zcmZU5WmweP8!Zfj3?0%SjkI)0my~pebhm(Xhje!cNT?{CA`Q|hNH-E99nx|4oOAy7 zez>1_;FBSk|%K){rjlU7GSfcPOGK(Aqsz+c9Gwv~b(h;Hh# zk_Z)}XFXky$BqYp3zy(E9I6!Xh881WyEn+|NX(y%<|}e zpZfR1KVFCvwAmz7o-6MxmP$>on;Tjs3IuLvKV)3wrA)vK|H(rfc;nrm|VnEG~IyWURAt)Ds~@}ze= znO-s5|6)leRR~`gsz}K`czu6!h#5_-u%2NYV9Vz)OO-EJY4f9SD^)|8^J9L%w^D<~ z3cNaO?ei-b6%E^XNC7pNyczx`@J2rb{V6> ztnJ5lR`Fu@Ue$w7+{Y#4Q}b?;p9pzG*1L>k^KOmsui$UGo^Fj;foJEABjx4Ve&?BI z`=c;i@NzZO&A3eVzc=N=L)5zDa-FT843}9wY=7Vz6MJaM;xG-#5({iIML#dA9mSK` zU344cjiB(cG5sR<`?}nqF&i13Fmk=g<_AqT;pMU9V~1=$N4xV`saAeGh^C4* z{B@|zV4u2(su8CSyka`Qg&imYE={@ZelpHkInGwS-&t;Lww?N%raRkGF48tp%^`X^ z%)M3JN5LIK#GbzY%f6zi_iS%&lH8>O@tB~{n(5zolSTuNOv9TyPg03TCY-Gz$$ zm44)Z(JO$X8qQAstGN8-V~F&e=+#Eb)`uJ?E=K`6tASNx*|m2qWnGyWmpctQW>SOYVqNWN-bs=)L{! zJ$4vX#|8*9?q9ue+|bmQdBS>-mmxxE^IZRCORy$Y!CpnFxY|%8IV9z&5*M%iG>>lY za=?uvx5wV>IEya^UQ+W}xabf5YdK@B|MssiE{NIh2Zizes}R`j>6loJr6Sd%03Q~e z3Z8nqDTS)k)qLgr-(>#9l@1z{o&^8h%7&)E;M)&!oqa7l7*6m)#VeuH>)pzjsV|NT z4f3gYZHiW-xwhXt_U%RmeqnH%_hQ6tV6NcU#Sp+Vn-K@RCR&)BN<8(1R6yz z;^-97E-XR#wF!a{7>Q!YV}y<-%76Kud89HfFRQPYz!oh^PEAo^6`qU~138oCV z?9?n(@2Rt$d@)f%uO@B5PK`;1w$d9%rgXgCL%X1|pZQOuWQ7FjUvgO%*XK9k5DT~z zSY%V}h7DH0f(D$L_pLhQWd5yaRJX8C;q15OpG3gL+1oC=G(T&~pA2`&d`u=oJUL8e z_nQ2m^uh1yq)BC*_P^rzUIJ9baf~!Ro-|nEQ%4ZAR=d;XR)?(@%HMvkbw?u36#!0XTQ}LEffCS zob8y$KmWss>Pj_k3WA^i?&gABdI&AB^p`+5`}g!98jKevCI4F+C#dEc`o*Q~Zi+a9 z>n6O$PL~@ny#8B}A+EaE+FMWwb{;2YWd&VF;VV!&)+E6DjRZi z*~xzs{9lY7(NxKLNcIoTW+N%_^SpcaW~-&} z8$j9ZzXk2^gTq|S*3Dsi#&a9)&ZoI5XL}%roZ9ZM?YUpCOS=uRHD)?3eaotN)vRE& z$YnW*|1Ac5pp7x7PVs-ykqeIwfj%XJS1_n*ooZD}D!lzMI8K$f>nbgl1`EGhf2Ymc5eO=%o zdWm3rs-7SY_I{*sB_QWI_07pJ@{t$VHyqOCDwk%;;j)aT_Cl7#cEXa#zCI?;-L9Z zVJ>yd_bVc9Vfaqp>%J$}RCc1r-yhQ-6?1%jIihd*iDY5-->RWnNBy)3`1G9GIjf6Og3?(bMvubTo2zb(cb&pAM9m0w|&@&C#$F3kjN0p0o?h;!yL!aEcBKpBj? zztG6v{TB1F%+E28jWTr0OOU|)jY}RmJ1gyhqm>#bS^Fjvqpeq4IVbwnX5kKM=E%aE zsT$IV#h5J&yOICR2;yr1URAnW?o1)RKp4UcCSml}{jAD0`@w=GgGl1hWecz4yk_dN zG8Gg`zba>uYY-xsm3!(fUdMZs{(;y4YJMwIxxbAR5tmw6JVmj35hcRD$;Z^>fX3A2W6kL5&HPNghyHM zD_qrZXC2`)4H)j_Ze{!TrwK7lpzl)gJOV;`8Gj_RO#rZP+7bfFpc4#3_(4j z2ct=KB5V6`FPY@7I+cxRewFv>7V9Q9eIlnhOK!E(L~&GIKAX?~s^%i75*cKVMercd z)!c5K;2nlC@Dw?Tl?cMr!+F(6jo+|ze!urE@hKgCu-T3Z5IQ0k)*;^#Fhm=Sl1`Q5L z4up(8x0r+npYDV=Ic7_r@j-6Nj_$%gv-5lsm7q6$(q` zyRP_O$S@O!+=FanR7CtviDOAfvvWEsq{7;C>G1iV{7GbjFC7!@lbV2o#imIUf60Mv zu`DQAv)5K~xliI-b zmbhpm=|0x5HUL%ODH;Wdz$_j)zf-Q@{pGK44&s$64m5mTMxR6~W1pQ8v%3&1WMrJd zl$W>-`}w{Hf@%oI4^qcHya+>-KNd+ZlbER^4V4e|PNJc5@(P8#>auJ1aL{cCHuxvpSfz zt&#l)nk}s(vPM-2_8Ibf=d+}?3G3@TTeCEgzDK_Wv=KcVcp6PCYW)R3FKs>rgN_9$ z`Mfc}`;i8(;mNE@w5sb($!0n^pm1bzBH$a73Pt3@s2>qW1Y2^%GMDS!X`tTiOK z8ibU4{Hw1y!t=@*35lGnpITw!eFVjy*_ZgE08x7iGQcQp9y=DrF}l}fHT2!BC|oC7M_1WW@|4I5+VnmB)DEx#p+)`KC0x4>ZP}vCx}cpf$(~lAbQO> zx%T586n$|Rt}104#zL2htmnQzwXiL=$XVji0@#v4L)QWNt@RjoKJbfzY)Z|aTQE_D zr$d>sPkOP4ImBcD1RqdJl2Cc3#AhX3@w*&eQkbs zJPbNCT}lsujv@7;N5CVK4P@$#LB@9|6kY}1Cj$)hmO4h;y>8?^=lhK-gqzb^-#ZXW z(65Pi$*ewWeR+!e-r|ALprOp-jOrC}Qpc@qf2AT7;sf>L7oFlsb#3uhch`U4Moy}T zUVSfcNcNr4Vnux_fg3FFjYCqO7h)N3y~BW75S*&FX$)1pr}BL|9!@@@dWoYNb`nwe z&aTJkwaz~*f)+ffnd$0tS)q}T`h^h5c#I!xgGkYNOL#-i8QwVu-2K&Y+pnL=mZk9i z?!G@i)lnNUkzpr+C@mQJJ?p^*mOO&g6DOyJ-{1ue$Hfx-B(+LKhXfm>^*U*!uM*o5|!+G1qGG=oMo2DRaKy74jAqq$6IlxW+jOd7Fq=OeG*20-Bxq~uZO ziFJ{0T$})rPB6f%QS>@$>i?|G5`1kAaADqexrA_{Rp6*;t`;=}=(hch&myA(anH|P87+p^fAR*QtT?M;B|8!hn2J%lR zgK_qyYgKaMJ)mOHi);D_4@52&&Hv0)I)h>(AkXlE=ZnG`4uVvOYX`nVCvln9iEM%0 z)aMX_pMu3$8_S68*}V3Ht4dK)cZBpojxs2h|xA|SU znsevNVHx`wtvR&-#4wW1W`Oogdh8!Ql?oL;y+G<-eud(hmI-2#^59fd!=e0F?KUc* zJgG!`jWGFQI*CW5CaWV3;b@N>Ix|0Ma-jI8UE)%$lepTK1@JGrghIW^Uw_B_VBQyR z)e}u{OjK=a^NdTR^-IgQf}t=C{k3=*&a5#NP!u zL~xe-QEa%=@l(-n7Wq4iO|`lc-u>&ryMXWF=e7HpI80IeAAd@v2VWn;rbt8C>`#*_ zVy{@eZaWf5F}`#i_fb+tQ`D5m8AMT7DJEf%GVe$r?5zM=f&{%ctXfST3lZ}CEB1=- zp-6RJG9>ZLZ@jg`zx3beFN7x09Mvv^)yu4kk&V)PpeWB$_1xL zxEy{C>m@zTXv;pmQKN003fr z7RxeLp$gX|w&2usm{_P+wd4qv3Ob_~j@oViWXyV>h$uiWr+{E3XoIjx08m8}0UkDq zY$8wyJ~j8RClpB}5GM>>um@;2r*@t|s& z%+P9c3=+i>Qu&cti5)JlBa>4Am;0v$wWq-FpdfH}f6@L>@&S(xPKM9~!*500`$`D0 z1WEd|~#K6Xo*gowiO@}@Qd}>KXLggb2^t*#Cs{;x(cvu?r zw8R9V7#~2S(JNq!iJW97v(c7?tl%1&17?_)=#_htZYUUVh^7y0noq@pID01gh`Fa@ zo33*=5w)qYYFp8>u74$nJzHoNhDv4>1wRQ#&|=quN=AbPr+y;P;5^{D@L7wcI-uOR zeRy!*v{9LHXXLzSQwxMvQH?LN4t3hY`0z6#n4Odan4(%yl~_|3z96r67Lq z0VkD%f5Wwy$X+i%Kc0lnRvL>%bXM`GC97`+o-WhAyg+%M#y)oX%Q2ZMqVh-^lD;ta*OX7t9H0gS!L zBk3<{1q{KkZ?Av#Zsod-;-Z`a3U34ZZ2*}bl=w!6tpvv{Sg>G88m;b-5sX{ksTECY&{YdmekwhL_vkMn#f; zzi|2Uv-JH2D#ncfwEWIRh6_CMFy>a|BR4O8g-f-44nci(j2AiA#r$)Ge;C zHrulPH=0!<@Vr;y?udWI)5P7^BXMbm`;%xbeZzU=)o=rZse(lgzWy2pqor*mzNQ*< zT_UKdE7$aZBO+6gd6{U%_=ImsyD>mEIe5=4`xXI zDXPQLG%lnvFQ#kBbA?SX0Kh@BQy|D?70SeXGu{c5p?U`W=Sgv{3bQo8l~?s|@_ha< z9hZiQZiBDR)T2*+A=lYQb5zO_<9@HExOKOn3LcT_xEgd5u*=dkV84>m94$6$q!kkN#Rg}xo8bAla&)BD_*$CXe9;oD=Y4=#%sn zz)KpyNx-a`_|Zzvs)+6u_E_r*=ulaprMyaOWyEw6zwQ!2lBIWxZR*X{IHm{&Yw;?z zwL~$4)b(`wvzDUA)0Rp-dpN7p1*fS^abK?bG`LjzbXM}4bRft(YBo5`K^0*4rIdb0 z!Hl)iT9O}wi&~>;R*@mYY+J-`aVU&idC_99Rkz`1$fEv$vj3oa=N>adxmQmp1CWSE zEr02AGrAZf$V?JW8;D!0zW66ry|E-_X>zM4s=3$m_LW&cvNPrig#(_gf>10pndZqK za;$U?p4J&m8Xx-mau>sHKLPcH|EBa>lnk<{v1l+(Jd(vNOXFSZU+ygO0zn&*t0)mK zLC_FPC<*pI*WoCO1df6p)k7<(zf}Q^@&nl4~6vC|tPR zsIbjtO_I7{3BYHJ1&iviR5QA|z_oB9cLQNU@j1XJ^ijGd00m_Xu2}xx+bY@vP%(mt zLQbV{0aktgb)0?+*dDrQ@jc^gX~iF><}^Xa?(jLa<#d$WMSpFKP{#5f`BeHi=^C?3 zTkG6RIpP&op8xrr8KTU4+6kWNn8T`M*9wJu7{_*|@36$yx)ioZ>I3q%qXMpp;**#+ z1IhFwprSie9l?b`@hTif*N8L|UMAA=PU8g1JU}{-h46sV^emK@!H&yiReTau>@}HC zGB$*amuD!=p#(m z+!D%G$<+=dY@TAPg&ND4GSr_)Y7G^rM${FX%n($XAnbevJKReEL7(Kr_k+EPH81xm zWfP_Jxur!!*U%I9+cKae89NO4N)#S+$x9Hqb1P2YZj){UJCznp_TCMW*tHeZn?ItL|&MkL4ca5MWK=rHvk3W^cbW%jS1>qKern z88kY143mi$Cu(qVL+iU#PHWBW|NfBGG(f)D86!BfsCA4TTs!()(Uqz@NiNUD>jpl1 z!LQquL9=%}MJq{=ClX*$D5nH4k60#XV5oXLu{TG~rTAEg>bsq^85#n;p3LD=L4rU5 zsT|C;Jm8AZx|J#b^?nQRJjo8^AK!Uo!(A7FY4%E>NLImH#XdyVmC~v8ul7KMFI@ft z2(+hemQKgjrQ-U0!C9uWn>xql7f{nsKE9@Qk_RS;mjE2O{tYts`>5^(&HOT~xAhE- z%1y6F3=ZTR3E7PtR4*e1tQn-?An{ffpdm>UW%o_`3`4Vnrfmwi&?fcW4nLfYq~UXv z@Y8n$ej&`IQUwN$PR-ITk4Hv00cz{`=jpSCvZLAF%=T(b05Xn6Fk$Ua=m)eFV>rWm zM1+VrFNfzWFmY5(^ZI5ui%CsIP7%uB%8@OF>9NH&2F^zMN}_dB@5 zMm-W}*2xGdj8mYcW&weSw8lm{jlps0+nZzv)`{`Nhtisi?-o(N@bH@foREO+@3S&t~W6@&0y^ehKBWmtLtrn@Err}&GC+@ziUFLfl@q;C` zq8F$V=T)ZNx8;WR8c;5L#H9%(lhxw~YCKQC8x-!DMnx5N&_}wx0VoW!Ngg2H2SyKW zRsU;1u+_4DauCv=I1sOAkB$re5Poyjda<0czXUL-X!H_>d%oOIWXa*E&>;`B9Z;Cj zL7p&a_L&S>-TlQTjS0RrXXFtii$b+j&t-4fPdchrb2Yu5D)fO+*zz235lIJ27Pk1` zc+`SPIkOUsWO_Ebi;GR;m0u5!oh9Lu5nU$^a(7=};DyM*&Rl%#-;h1B8mmi6Fzm4q zcHbK0&8?hJ!RevuS$>Dv@s_g*#hQ0{bDu63Zb0)>>`<>XYW-gFKJelGo=+V9@-Wcd zdN^lw&q?{69Qd4o7o?DUEEr!q?1}M4=!v+I9H5Qt zBXEuGRqqFBRDrjB@0r#FBy8Y*kdw}Th3md@n%|U}!8PDnfwQyA9LN~dqDn`Nyd5t2 z>4Y7^_cw!@48`yDS6e{-%f3G*LClFBDL4bo(tqpomx_}nk8)+)ehko2SWI%SaOtUq z)KYZM3qS9{iInRo+8a&ZY~zM|PyT6{p1@e~{?-%Km-?sZNk6Sj zFbx}Nbm~q11*0CL%RqmE*gazgz2baa3C`xEmUN@j67%8G16NPFmY=dIuOz5L|W-wVd>SKTFH##3&it zWKZxbaF#ah7~7pK?e^h!QNl)T&KOZP9;@L2`o#LnxoOX$L)3oBolr*I9%CqgcUasu z<5b*0ZJ&HEh4N4J4vvJ+3=~MQQl7wmFapQ|>A7EhqS0M^(}LT%DJ6T=Bg9&r`Z356 zlAnn@SQG;d{AzwK5$ju-VHHIasUZGwMNfd{}KS34gSxiG8_s5+|M zCy=2Q54BkYOmp^Jt+nh#O{33WyXxu0l}tx_eBs{5$d5L|Dcv_)VnmuzRo8X z_8sxX8-%=xyO<5XXqV3tMO-qbw}FO}0}zzLnUiMGaj3Agi0?TM*vGGWRVKmI1ux)r z6D)kJcAlfe>&Z;g0 z`=!YOkQKkvI7V?OpUE9fB652VV7?T_krdpMXk_r%1%h-|C$}HDR$(z(#+0T@!0_RRqxRD7 z=O^lD*dUCMl=xmtJpuurOE*&Ovp45Q)#5pX*-;r-#EFP`CAyIemDXmU9KQ^~k~iLR(&i=clrL{DyE>e0_| z?S8T`@Q9l-6mA^%arB_TRE*$!&X$yjcto^$7DQ*nQ00s2wnsE&}6zi%= znt9@O-hkL+TXg$JnE0;5*VJ#{E>viIRQ>?ERFc+2sK^)BMywd(dmR;#zo{;d%y=VA z_{(fzO9;;>n00BHbt-b3Cw;ziL%piHol{}1hNy+>0qZ0t`c*WEC=im$qqXm2eE15` zmp5v0gEt@sH{_cD=U4OURh`Wb;SbUr*hQ(emcGDZ5Q!Z1@t&pPtK`?oPI=|oVBfdWm)w+61=9I{`QY90bVvCYL1I%AW*Xn@({EeXr^9fPmy%08N(M_I` zp@oKiP{JUGG^13=i1NWu0?VXy|5ka)Xw8MXhMFL=`UosW$j?dHikq(P+$SqO!)2jB zWYE<=BG9lL>mz&G`I(rkH?rDn80KdJ2%_H9YRnjyF_*(VkY29ruT@GfBM`9Bp=QSu zXZH7N6}&PSh`VG-NkA6+sF?9A{;#Q9nX|G5XB7zzIa%)7ETvvw^6uLY`LSb{$G_eI zII~!7AP}!qbuf#8_ujUhkB1KuOKm=o$<+|cY5s(8jbhzsJ#T$k{g?=Gw^Fgob{hcL zvqrOWCEQ2^h(Nbh?rdV<_JksP8s(FlpA>WV3oohTM+jGE_Zj+JKZk$F_po28#+``Y z^mE&5C^v5`lA82zwDE&+e28T;AJ*mGGQ~ZhKVUjwJK!V;#I5>19B)bJ;t=$%oxt8P zTD%{(UoIRQJ@hZND=WQxe+2vC*1|qlpX-<)pLv+MhRvqGSx{TGZ96%cC5y^Yx^j_#zvg2e=L2FXK07G{3Y5R@p1zic|ga zy97-2i(^Wf5V)?5yHN1ZDCA+34Xj9Lo&l%kEh_nCS9Mb&|gZ( z)Mu@fYO7%q-z@|;>fe$=O^yA_l3@ZDxnQW;1GovVL#t34b#4Ck?~L(Xsjj^mv@2d5 znmYZp+2paCkVkc7%R`@*&Z|w`2=Bf}Mc?C;z9}yP8p-?$+tRS2X^XV)+47EE^mL9D zlo;INg3&Fc3DRNG+!0a9~@rL9V6AdE8T0C)iXh;rKxDWF3XawpEd7sal3BFnX|!6`3JY=0=SgV ze*fr>CE@Np+nHn-I}JHPCLx*ic)PF%jF22hNFOw)rjQ$TA+7zu>1ysza7w(XYQ!2G zCQt_bUVZ&*iu3Zo0l&4F2Z&u5%o6E9yz9_iF@dAi0S>&4h8N|Iz_Q8#5JBy@{S;`J zc1x4@jF3_(sxSpRNu`E1pOZ5Ym(`B23iO2mzTGhM$1_5W%Rct2Iir&T)6@2qt$ZA* z_5Q8F$d*=mhEnOKZlB9`Me{*)bGcLm)*IHjDrw^8%_GY2P2d4^ad4XcIyCY4 z0nk8Qxp2J}2^;l->VoE?7zFEVZgV{5iK_!2R-e`8aiv+gJT43ulB9Kcv>&uM<+SAC2!z;Yb#4K# zk~`jU+%paWBS$QKAa8n@=7f$Oy1Geo)EI?r0}yjX-8R#79yPq1Bbx@6Lvth;ohQ34 zHZe!Xtm6y868D{n^%&Uz<6>Z2^uBh|a}qQU#i2uC^v*ebY)`_)cN129>;BeV-Q$ab zx_8rzZjGLKEk^&vG_!4)YjsTE0-)q*uk5qXhacb~sjjG$Et%-+NX%y(KSL9__TaYW z+(Qa>?Xt{H=VvxtK4&)OjmzQ5wEd#~>9KRV$Sb$N$_{sx^PoI&R~;{ib?_}%_;%EV zJ_1-gHo*zn1vTK2O~imSz3FhF>?GCrtjXj(7|%t`ybxxc`}(be%p;MUTEz7JRE~7fKbNeE zowX&>PUW;V2Z8CbC%ORup9|I1dv3tOo$>Z}iA3dq%5d=+1WRIPk7(Ve@F}tW`VWaz zIHhb$K!-3S)KjN8HYeAj<|Pj>W3_WIhw5EcOC6gia=&cjt!z1oW|S68ql~Yu*DZR1 zIe=%w@EjhHQ5TzMaUd6~#xxSJip_OIVZ= zAY47Pr_nTh4yiucbBt-^_VabN)0}=rWWYW0S1{5!Q)-xgOLLrn=|Jf~?Lg~5k021I zLnZwtB_f}rT=2f2sNRALlB9Ooc6V;jS93lTNAaj@y6ffhLPU8?qDN+yAv{(6e!vAygdPM8C2{%BR^Dnul_{!Z=dM>`6;42Ga`LKVUx7!XF;8W)p)m-w{N;OIeV))uYGy+7#HTJ<`u zWrw2^y_mPQ0hxbC!lcT0dx!Hx3~sm0>WOdJ z?%q}p=Dkn2Lfv$!(E4y9q;v}vr2g2Rv751Ta=m#bTdx+SegIJT32Xkfx%}aBE2e+= zM?gWh^8ls6iE#pxDyZ+`~sV3+? zka+Rm1fshMbfZmtG|H*1z+j0?ezK7xTcH-2Mx6kcG*j67KeFgKl#7+%Ok8VPDtxY9 zcvmO~Wb3C^-hB2k)zf0H2d#xwvrq7LcNwCa{uT}G;tOImaZ6&Y<(e@u41+{ujVKpe zd1jo!ZfqpF@M-*2eBUYJw#PiOUR6Cg8g4@gXY}?&T|QE^fLn}sN&)%>^98G0xUX&x zC6sERk?Hy+(3CNymzkr*KhWaXg^$g@k~yYMcD=v7`k;`;ob*J6l>_bzuD&-xwe*)G zqSAd8byg?%BCe!QUWYsRvnTL9<7p{wI4V;sqz8Z*Z#a?H95`&>{{EqR0`gz(j3=o9 zIqI)qvc}$YCH3HB8qmE*X7|P2z^pYyz2)OUP4k3WUr4Rm?=>89nw8X%d-l5a)9Xvm zk1}w*YwFSEmpURF2vu}Bl>4&8Fo2%_`k$icvfkfq4xJbzkG1+SQgb3@UT~o z2Uckr2ou%3KX8`1<{iwI3lFrI5CGrirm#4aUG1GmxyznM>ZKpt)>Ta?+}Cpi&WWTS zT90I>y=l6mPWj|M<2*G{(=RAc*4(A5>cpz7pg2b(!I<9FBO=1{&>4P{e;+Q9DYn?X zIJ7v)d`~4FgcndJcn46*D-b6kq2e~7d=3W+SMO`Qbwfix$g;uxvKD@`Utbr=@)ozv zf+8+B9mw<-+1IeJz97m~xv) z3B^5W*#qhArYfgFa1~p^T2@D0+-hDCF8?({{;I#Vd>tE-4mJ4XS0IPBYj}aeR8Bt# z3sYVTZ3tnj1E*wo27l4`o9|+c@_Ws8(Wyp_JK?(#$aE+|GtGy2GunEGzNzc+UGVIW zwu$5qp468u!pijP6$}w-PSv(V6%!aCKV+yhCCH@LC7pv$Yw1(!n~i=DY!4ipd7Zz`Xtl@|fN?IF;)m<0 zyq)Bs{ZCT-U=wPbY{PG=8oILX17wQDg+nTYtO6R7r1s^Bi)Ah~xFxnvCN(swR7z&q z)HG_Xl=L(KL8wx1$D0+2;2q*f6;>_5-5ckQg^tCC9wyw9{4r~>7l1Sq-E4|^56NFW zhcLhN4Z+cvBCfh8Ki{%IuBdR(&?)(MkckXURIj&2a)@j#6RJZhhpv-J1QxqK?EMJ% zEt<$NZYd}ASH%X`Wjj-7yXzK%@yOME*ldf#cvocE|#M0|aUuv~cV; zHkdW24rEu3l5+lzJ}khcayEWGMURT*Ll}mz6fvJl_wU7$S)V#)RMU^Nj*5)6R<4Uc zWGVgYn!2s*f_*1mDES({pDutwp}`$2e(3=+>W_~#J-SdCpin;N>`v|a5l`khB-VEk z{Arh}c7SY_(R&4CZ|r&kLuBb*)}wU$(K^S4>BYc@ySMvwE#F_9$?Jar)a1Yw-)F8$ zjZ=|Pk6U1HXE2Dr$|Fu>?;MyQ&pO{<*j6|uOnka!_s9*SBubD-d(DW!9Ci_)Y_?x@ z&h&fV<502Y^(xZmLYM^DHw!8oJ5&57T=WqefN z^DcQ#R!4Q4Mb|>c^7MBdArL}@$ZN~im?mth#}tTOJmuK=!`_GXlVH`)XmMtZY2+-p z!wcY+2KPVH<-3~Y`cu^b(L4DBOg5chgrrB8`L@FaKLes>1WpJhPO%VQsCBtcaO(y# z3u2kp{UsZD-p=7X3fk&8ql%N*s}rjWH`NF3Mu%wLi2r+Q6D9b~?RVT9M0biWxmumy zfgLI)3>J6VS&vj29e~fNv%?5Ujdk<*uYogw*9xct@0YU&MOCN&n6Zv!I^bG~9bEWw zEP-wD9H`yfDtW?dr>X7c@Dy`k$ncxHE#SCPQ)LdrIni+X&N*NUV}O;@#}9L~-D0sv zv=52CfUWkSkV)o?`nOcR1ftqRtT+{cDF6GLTtT-Q8qvwv6zi!4HtAy`-;E^MSf!Lr zJ&^z+hy3g~C2xBFT0NHA3Zp-@+IXkH0vXdzarg?+y70NOrm!vD}67=)!=af!eKs6+>7vV|gS@Z)I_vTzAnJ}gB zr#w$QZuAO&EIoDzFhugqeB+2?S)fyC)cXN{K_;ugTR(1u$$qb);LILq<-H$XruMG{P1X{7Z|`r$K38NLj>OdZ}I@S zd4-HjW=j`Z;8fNNUv0D&>R>~e#I(QK;C$UQ4^>9S=5(3 zI?xzsVVieGzWbXTl&6nx&#*+!R3o7Km(XOP3|9xuCPR<&IqM;7*X4N=Sl`n6$iYf~ z(@zz>z}w>p^EBmSwiu!*=itj3VnpcR^z)6BJ>--)G_( zb8Yi12tw0)tV^a#tJxwO+wFX=<`fnurA+BV zH-+(;_`QO~<8^C*S5~bC9K&lUs}#&|U2^xT=xPK*Q<)Tl12*5kSO&dT?5~sXL))!K0C){eF^g3(t*N=tIENp|uG79m@!S z$AAM&h@CmSQZl%aG>~9GOHiU5u&bl%?S|bcMK|bviN2Ito74iwlH@$ogQ7|`K1Syg z8=428mo6Rkk#U-Z4YNirJu4B)dLDTu$cbQU`TlzZMxXFh`!TCFEFFJq8Th$920A3# zls3R2pNt2=ho7I+q_C2Zd!5*={6}(Ma7O7=t$)>as(5|c{f)50Yl!K$Fj*P3_osoC zXv;BzW+modlG1Lhb9J^U78tLY>zi71j zyy;{1UJvZcZE$CIjUvNr0q*HC8d%#ZDUA!ReR=Yj^tR;vOFcj5CdMaUG^6qv@{h~i z!h^8l_2@f9=-M2~4ZgaVPFKT?j-zfxBB(}da382FPSJ#C*u zn_5J_<*fs5$kWSZ{l$&inZQhzSWLGF!PF?pY3gaLX&eG)+zwd+v6;R5>gDNAB`lD8 zs>JDnIG}SpPdA){Tj0c6mCV_s1M#v*Hv7B0*63X`QGu|)Z2I%w(@ygWc+CI}51%TP%AU>L@S}6H49neyz;=Pa-`_vX zGt7&B06{;GF`bbYXyJIs2?b%`zZJ|-KMu;df(*0jSdCftHrkDoz3ikduLU%YaGLO1Vm+1CwcMKQx$o{Y zP{kpT$Oc*g8A}}~44~LkpgqqGNXCrpJIWs8L(Qy zD|}ci-!{VG=PxmD6Q&O}32?Dd@Jg~B-DyhLUN=YZ+Wv?Rx`27@My3?qUA~x;lXv?S z$DjR)#n=7aM;DmJv6Q+cd!I%BIc`i|TqHN#-LfJ`wn`;-&!@n%pm)s|4ddu#^obR` zkAWLA^}SCi9H;T7@uvx=i3tvIf+_|c36hX4Ijw#MjylP>ATgo7hiNk;qA=GGO?5RQ z8s4aE;5QN~TAoV17`x9D1gEDzU3$+uF3W9`Dhqm1GbNt6#j>4o#PXU~BojlX@tEyn z$q4dhr+hqGVB%8Wg{SI;jlQ1&*W2ns`a!XLN^D6nhhjP_r_QutF za#A@nKfjjNois_e4+bNsOkTPr;bGpoAXTMOA-_o7VtgU?2m|rU?<_FqiAPRHg@wsw zu`)WjyLM!g{oV?qB$18W0LNBl-q_D{{~#6isv>#r{;8TrWeX_4=T%SH^l^`H5XE@Z zyw3NO*2P(KP|Y+v<>>&i(;s%=GcUUp|3*E7!9k$E%sJzz$6LRYFwYeVEEs#lQf2h9 zwoi|oKals6BiHoe)DLABtv`YA?Y=eVJ{91*9Bo#pvyka9hx$<)9n95!#2K209#eQS z-1T%%IK3-PGZE~O>Rcq@vWR5;hJ$bH(us^EJ;2=gB8bzhjF>xsgQWYVF3K%A0W3?; zP1jemMXF8B^BMQK@9TQ6i_pu& z{SWaTQ2uI;#Rme{0oJH@@3rXB4a=0KHui3xy^l%R^9R=x!(^fIW2}|$NOQWNHCYqO zLM(=ozI9Yp#C`V2F{4)ZuU$9C;-6VeX5ZC5 z;{KAL@FKRY4lTIQN|{UcC0C=-NV$_0xdOjgHebrC7W!p&%s)xW{oEN0VWsmXMry{z zM_?JtrTu_{2#HWpqpbzm)L>rl+3_x`DR7^rnHzPAEb=*`cY~pRSMCqfSOujg1&c>o z;)~P@D$@2eo3Ef7T@gN9#GKWBq_w_@D665Whi$mQ|E~@ERttx4G zVwg??_lCuXL1b%7$#0p}lY1v{ZwRDVt`M%{R{Nv8lsv2;wl3uvLz6up7B|+Rr9Vu<$LizlgDntiOPh_l*BJJ{{c5yQ=r^zs^BuMY7 z=@;l1KK$Y#zB4QXeM!%&dMI7%E`2O+XX?CpO+=j7wD`2#FAU4=BBlGB-~U`yOczvG z-_#RSg-sbwEeD*czfzaOvdw^NuaV zJ!Tz2es+!MAsL4jv8E00=|R>ZI_Y^*i`J~@EtR(JT+#3VZ0i}2Wjr!ThF!XZ7+aTI zw)xX`+2a!7%_*|e%x#K~baD|5!XrgT_vi#|L+Xqep9dWNsxQ5Q@6oo4G|Tp3-Z$S1 zOz~Ekqi7ZrW0us63Qj64Tk7lfS#~HH`}U^)thHOd^0bj{r|b!( zntJmXC8zN#psMopns_~F0#$g9_%{KoRwEYm9U-@w`cm=qJLQTsFO6mM(RPYVs|1X4 zMYk%ADL4W(8?SQkl6vyUYAd-W!#-mI3cB|5vjF@nwr@zD%IsQE8rM46ed_A!5qn!n zUT5{BL2Q6QgYip-7=4x`c*j;&+t-6zaVhlLc>C)hlSy+b`0Jj%Cf#kK(!}a%$iQ&q zY8Z0h&2z`KKhQFcwnubRrB#raG@Hh6bz`Pzzg3ZGtj<9dA`UdNdp8@*(M)?SM%9?( zkYbw)q@ig%7~Vfe+F&t|-JeQ&tn#GM1~IL_QzT8KC@I|CKRF^^h$b64$~JJsJ}Z8DfX3;nK%xV30cOeOMD@KkmOkq? ziveA*GOLpL+QrXW{2-fNN;tRA4`WB zU(yl9nNmz9WtMC`uT4V}kGragy)Qd>Rnv9X`AheMO^Zz{O&g5b6gpc4CI38}se32<)u^zP8;47g z={BV-%N}GIap^4TKO~JTz>%#7xUbY>koQw;u-;&p#)T9^gEA6dHCqLv2+IcayDR!+ zm3P(Nb1LvTt~2eL^#q`P{0>h_B6~aXr#My|-T5=-oZrVnnFP&^^QNrG4j_x-(BMnK z%~0R~!q;~9^*q$M6+cStcUKJY_DRRWh%Mz;+|$zEVr-+|o0JsWU*2I~?oICG2avWi zDz$0zmS*1YZ0Qmq4nm~)gUU4gYhNxcoFs+Y=n|zxI=P^>#uZStaAD$bEOB%P5f=aG zJ?G5xSGdaZc*l3&9mk7*CEm3`dZ@Q5g<9Fdr0>TYT@3pt7i;LOKj&_&`VcMl_RjXu zK2LdsGH<-YoThR_3HoUT<-#!n#>@XeE}HRT&b}x1Leo<&7b*>O8X35xO*95RD%!J# zq{@*LY)gy)-4uLq5}=G0E9|W0k$+ChlKN5GoW3$%|Hg+?mfXvhDRv2GS2nY3 zPeU@QKyXqYbfGDKwq^)!h*DPKFl#~I_)iu?qRgKx=4BkE=iKG0A&u6+?@{F8pY?+| z^&lFr<2}DsYZkDL1C`*oNlCnMRDH$klGz*6Ztz9#Y(HS>&5PRxeW0jK|0K0xfc9 zOdcbmegdmnM*SkyWOL+Ot17E1JNMu9&&x{~ut~2V$!3av`F|&xl#~naBH!S!6_3f2 z&Q~?N%l{1&s4dG0Qblvajr;Mu6sO-E{7u2GfpRG+Wj1%2C4Qk_9I1D;g`B0N)^G<8 zdrELhm@sPx&*r;VP1~+UznHQyJ>UasXtwI@#J{!P*?$NbnJQGk6Z;c;B7 zXMRA~%Zwap9CaSd-7Cog4R9p&e`a{h)8Yb77K>*hXa%2}AC=~?kL-H&8D}YOJ->PV zet~GC-_Ft+#8ZfXQBsJIPK=y@YLt6$;qfzPJ8i>=_qpowL0%JVDZN?pB5>WD|6TX{ z0_AMSpZXL5hNi;B>w3!x?Cvb+J8D0v0*r5;|#(A`d{##!bSSDoX1UReN0%l(UyUn>`IOd05Y_Bo$&(A79(#!z?m_lUKXM!KElZbTz2V# zxCDw1Ddac<;8+!fXr9NC+nu;K$6P(^ZxDA10IA1Fx$EI4JEO0sPLEUNQsrTKoOX1> z_qCHi%<1kA+ay(U*okm()VVOy6a`R}CZD}4Kw|s0>TEiK6sXI_USSV1@MB3Ir+g&a z#Gz0wWI`cAlSQ$u*`~^sE&lJAf3iU+(=V?D%(jrnV`QjQ2#H4A2N7;DvGSy7wyJGF z2p*DZ_Zn-a-F_cUVxJ=SXWF57PTS^hq`;*(8;F>DPhku3G>4_u)oiqA+lW>`4A@)m zcZK7Re>cK<^ltV;Gpk!ZY@N2Ntn;%VB3cE5WCcqS77jiSMnZqtp<9vU7Lp{?Lr&z@ z3g*+0N2`!ID2z02rldwQJXZ^{A02dt;tq#k;||@&hc zzxznI-69XY&ze-*bqGG9EMPi&m5!rMK$tAr$mb3q()ff_Eyi zMQZks2y4iMYOMnJz$VKClpR8IFSzC7QI(*_uJ*`FDYqlNg%N9!k8LsIKUF5?h~H3y z2$!_Sde?qHA|0JZ3p{FCH@VMMSrtW*z!4FbiT4W_T@g<(Y_Lp9{nThBX6j)!=3?=4 z9?D9taZ;+Vo@xcH1I?6d`XsCT<~YcxW^H-FYd8@juSoC>E^Ejp_#gXKvkmvgOy5L$ zDdQK4v#-2<-xf{g&*kL>KAzm$B>Fxm6X`e3T-Q&PZKrGPNZ$s4Unh2T`rB-=37s4L zzFJiv?0Q%R$G{!t0?aS?KQ9yq%~rC_XZd<8?`{|VbEt9fjYtX%^^FAI?kPobS+n0m z*=9sNCE>;?x+fZ@vP8W}ae-BSpZ`oBqF<7k>L0%xyS}R!(v%>Y*pw)$2P=O6*SrOW zT@Df@C#h=KxpD5XBqeo4F&cwRcA57ErmRl65!Cbj5!CHd7mIs9C{SHHIGQi@d9upv zI(7VnvC@^$`3GOL@0gn=))s({oWnbCzu_imiqo2OU-iFLcnjVDM77|$x`$`YC#r*5 zGCt}HY(?DVgRu=i#`0CzC@hjoP7Tzrh9Ws>PZ(s(z3&$QClo_fXu^qu&xCa>l|}^# zXGOJmwX)@GQCM8Ui^iYsOss74eCKA+t9iXdfOMMFm_=myFcH7%iV`rcv+qH&cJdM) zJhHxqDuMPtxteg4C(ibQX)q{$G!V^q@mV6t)rF7;F5q7!b@tm8B4gW!ZsuZR={qk< zW7#SBDMjQB7n1M`q+Zk230yQUVj;eWa}PF5Q82uZ{(zXvd*pQOhJN)jOVO<1OcI!C zU9Y$uO(g&9vd%sP^yzvzH2!&VGlV>F<wl;J~LlCc)agVyBs5_~+0k0xmfa1;? zKklQ7EA%&_UpoHsI*4XjkU_r1t8FJTW>btlVIXT(;O)La*oGB*5DMz7i!*p~h%fQ= zz2&72y-_1Dh+uhAn`VE0Y2(#;f1~KwF10fQ-fvQqUYK|amSBQr=OKt94U4uUY9|aK zZq1T_F^*GOQUBHvS};WX7o=Qj$aInLC;!A}VXvzKi{!`Jx6g~vC6};wMY?^#!yw%x za!nFl6nc(? zoRU`aHorRJTVRIcIJMJVO z&B)B?pxRxw72&k6mH>^HHUwRL8lbAXNBHO=fzi?QNW|p+*i9nBM>eFMAcsTIiMUS- zF1lUcc?_HWrzg}xio5~H!dF5YOgT6EAn}MTFJHg%Q}7%a{5KRlGG6_3#qOFnRgnc} z7yuDz7zLUK>~1V>#pcItG=98eue+hP?Lnl#UyX{Ox|bxL9XP`YeW z(w_;eQ{q{mHzPQo0n1)~uh}CBDICNBP5cXliYGHfTPNhqwYLW;4WB7qu#?nd+$9gK z=vj%A52cj#d=T`#n8SU2NiH-v5pq0g+3{$$;DwrR_dikzMHhA^q zC0*hHf80SBhT-plZ7B>{2@8tOUgn*6rkUA$%zZJmAzTg~&~H<{lSNx#!BOH;Y4 z(@#Ux-!N#3BV5DtM!7GrVwEwwvALDPX^f=g3_X>z@sSU}g-Q-Lv@O`X(Z2F{ zS1-#H^yG#mYROlVzW4q>BYA{tu{<@zJ;hLN&vZ;2Mks}xc02O)YaS)|7#W0Noh1Rn zkwir!X|$^v(v&P}K+%4Bk9+9V55XP5$8s&;nH9x3=Ek_M3)4Wf-Ded!l#hwH6s~!s zjz8xxY@{xO17h0__k1^b{mr^hq&}=kFS{=0D}bt8d1Elp#V^rTG0IJ&*k_ONrorZ7 z!$T-jav`F5Ex0}?mmKHVV`lBp${>A1`Ee%{(pmubuxl7F_cLNosZD82X(8C21y$)I z@X7s8J9(Zc-%h|d(#na^C!-Xg6kbgp3~;R5tV{m_?H057$cfg!=Yr@)uoUTDV*G~G z_w{PhNR)7Cru76<3C_apc*km^h?iJ}1UsS`7#s-^zhYvh&C+|!dWBsk03Ez0AQ)5^ z{M9ff4qzd#wvMJ0xTqAEt$JF^0Ks*9Y|HO-$i6BA{>vUZR3BjwBp%UzH-`wzO>K4( zuJo3^obnlsHX6M-@f#0+@#bMJ)Ry>v#NrcmAnr3+47)AkO7IQL=v-}&O>2zoS+_yV zm-WS~W8MWhUc)C)ekJo^a4$~0M8V7 ze-nWHTk<(zsIYPqm45J>)^^RIR4xi z&nrEg+!&y&b_qtuGUJxFk)WT*%QW`UOknHACMWt%14Sv3|4xAee2*S9TS$)6;2(Z+ zCGI*B+hN!q#l*^Q%z{G;qKuzl%5w~EWoD#iqgTqeJ-)V?6*VA<7Br5?;i!%d0&G(C zxo-KdJ|wLrL2`{6tny_>RMo4iVV#KOXkQ#PxNQxHS6>(Q`XW@NrCzy)bMD+>%3Jj&_93 zlKz`A%>zm|4hD?H2o_A6^N8Q=Nf)1b5t5dCk5vv-P|_qZEaU1SBQ`KlUs#%EZ6?Qp~6q}x?=Ku z0k-K`e{-036}($pDf{)iN6nc z9gQOU^i}EExd`a;N7k9R(}J~*I`vN3F`4u6lvc%K#k}Qj;pyx z-zR=)Q9Te=No4TQxv{}^FV8tZ8wfa4DYKi1Wz{GafoG01!6oqiO>E=J6D20yOW&Y` zb7Kmk7rCRy7IF*$X)6~qLr@3F12QE?-)(&rHwM|>)gvi1SwL!=@OIRA_Xd-5p>AJ! zM9V^9Rm!z~4uQbrv|^v93kbwxA#3w@QJ#Io{pw`oXu8YWs=*w~Iq>wPE2X;`l*Z|- zs}m%nSddPr&F~0qJ<*wMMS`TVA|dK?RB(v@uCduHOJl}TWg~fWY7CaRa=6F{qAgUr zrBbc30u)2s7GkHQi8nre4|zxI9t2y$`?iEHJ<5Vpf^tl%M&e zGkpHr6KuL|_$>SazDb&9)nm@)nd&Ue8Ur>@Q6ms{E;S^1Axd1xUBDfOCti`h(TGX!k-6V^DJP^Gp_4kXIS3Zd`RY27F( zJxZS)KitQsL}GPJWjt#k+OY%iK2s%WU(0bLu*#q$ro*n}UL~OX&9ZV$07{p{YR?Kww zssfw#SmZ!3y2`Y!D-W~VpK^oi$9+-L(%QLqRLzirZ&$s(7;(oZjm(;phcn>s%IUYO z(d+aG=Iw?va9zM4KU#;Xj=65M|(-9AbEdE?Xv5j%ZPa3Yln zTcNt}REVgU_=Ws)lr@A9i6{+_X32LwY%V*tfo4YV0pGSqWF?t+2!tytpEb~HgbPwG zLv0{Fc^tB1g6KhpK>qO_=jzeB?efr)Vq^H#iJGdjWydw(S6=MOY?HZF+d!EJIvX@2Z0Ji=K1yp8fK| zB{FyaT?rgcEQ2~xLC{~9{;p+hK6BUS%)}p0zRpjNTIjRIS;cFl zk?5*8jq8LG_cn)afqM;z5adrR7ai0}{E%4_fGcPL05k+d@?|1+7?dDv)p}n@DXkK9 z2^&(!?4D5be0cI-a24W9thZh4KFq9cQi`b$n|s;S7%!UElqPx$q=e|KJiv9}66{7^ zOu!{bJ@^qlnaCMOmhhMRocS(1&p~Q1%O7-vVf(Az=L=FC3nkXu1s;Jw8++W%eK2*M zs`p;{U8YVX;)~t^y^3-em=^x$^4ZMN&m%8eV}$@bQqbwe(^CIDj?Zu7ozsiJ;sfU({&m3&nx`muzrcz z63WEIvLq3pgcTQAZ&S$ea-Xww{-K>DQ(*q|Ap+~0K+yh9ZjqJJ6*8{=<{S+X5?gl~ zhYvYI&Ofqohc2us>8(szc%@7C0bXUJmy01`?sGuwqmQSfPcF(@duIVqqJ=?4##Ba zJ}_E7k?{#>>C6jJjFC+7d>6`K^BLl-Ri{$!zq&SmP`q9D98aA~SDeH8Qz9dyWE-&B*K7moG6fl#}(kH?Do^x@#XJuI(Z@Jtf_(hmgG!!=Cs;Ya*vkIaHUNoCs_vyr?X?p=4)7+CzW+kQOsUyjw(uF zsHy!(0%w@MWAV13nCBelvGKhD#_LW`{DFwl1_A0n_s3Hd_NZth#}UDYSvOaH-PSqg zgI815vQ_gYTsntyS&MSYXv!D}7bay#(4&j`bqBm)wdrQ4dvpYameN31*;#u??4hUp;*W+nj%`W1#in`PDpAMVfGn*e884!-eW6;*E4*?Xd5H(zd{O77=zFOWkXgUPuc`Ya9?K_2@`AqvsOQ(5$pwsOk(me3jL1B| zy}rQNlB_=Z0xrz-=)t$Zhw4phy7A_kXndO_VV&5&M{~p}b6QLPR=P{vuaa~y3)DZud zL%a-t^w+CT+7GE1+mS>vXqT)lX)#_Q#?<&IZ!U}}YZ8-%(Y%aDWW{3eEI2V0qoO>rNzWXa}C%RN-1o=tu0 zK$~U#ntziE@ZO5+g+1a@I!l5SV9~N5>*!MN3{rrazw+b@a{J{Az)xl&HcO4V<2RVd zQa9K7tpkKm_SNrmqHl%N_0Fn&0d$Y0jF3k7y&h2)QGXbbEa#N!p&!%-Y#r5k#M^Sx zdJA8|KgG+guSR8WdWP_|gv3l+)!Hgl#1Ucqf8`9!8ApshU0kw;D%MSGN){*@JCwJl z(Mzj0#;1vhI6TiL;#b4)C$7M{%V*Er0xD?TDJYyl8SlHjxM%)DEZ2dGWj))uV5gOP zbnqN{clydnNwGfmO8(Qms)p7fuFA_drXKwu7qFhAk$KeUK=H0>&%3=&Bl<|!JWg%o z<%44ch>*%y9;)k~pno&`1L4;;>oZg&M?DAQf(x4*B{N97>nweD13`GaazZ3~)LDn| z^&aA`1w$x(<%&8T4OQhzzyJO)_Y3cW`NtU!r*)^fOSw)idi4nrtAsuYvcebtr2s8R z5D5t`dzAy7lifM4!R}Y5Ou=zko4okAC4lk7uyTr&9i=rgVtOf5s{+D}+15>-ot%PD zN8RSgZp27oruNI;uEQ^OJYGc!iZ9pn1S)r`e;}pTnvTwD)Uw2n&oA`5H@>`j`4Pxh zoG(VOH}pPN8#ru(jJq3CimRq^`cwWxHfhvup+4@DFFE5Sx1^SzTrbJ5S^D6AN^HSR z)_Y4(pIlPRd!?_cUY}diiO~zl1LSJ5_+8STzoOGj?GWV?S?e z-#!ymg-oSR4q`RU!jxc{$(%MNrc5gd4U5*5fcKdMYiC*%r+=oM_PxJE6khb+Q_NPF zdcukR(gKTLtQWQ#{`op%@n;u9qX^}cqeJ&nfl;NYw4|Uu+L<)ejnOrNVN(sU-Ksy} zZ$(Tj??njyTrPVsz*XiLI7-*-p9HxhgTZdY>F4f;twFE(*B61wX8pFa4tid3$SuvQ zGp^uOG-*zGCW~JwcxX9GxmLpXSb))S?I^%01v!W6KU6?e!=coM5J2^g#C@gP{{Z$g zxKi%Z#eZal%)qkytupa5c&qvq8~rB$U2^Wz>{#C6Q;ocHM=pPD*~O%OeStL$C*s_a zHx%VLf(^0?kAyF({yy8Q_KU!l%AZN92x9vrOKxNy#Qe3!>?q&t)Z)N* z<8iA(G9BKj)N+F+AciGLbJ3@mc(0y-&0OKeXjDqi{FH{X)P%lxpz|QfCV{{OWo!<= zt@MW^sgsJC7SBtKL7Hd`2R$r0=#OA#C&aIGDpHsMRfMF>+cfrFX>jzRn*v6NpEy?5_d=qD71v(M0(hM z@LK2$?K=MO@gG3LIjb*wU)OJELhj>qv=xmLZz|fuw@16x)9mm3O|x@mJ|`aXN2$ON zOKX2y6G2B8^YGpT{|_wE!Dpvd ze|sMAJC^@?@PprG?Wi;H+7}U13O@Ffce=zjjR4ojc=vClsbXEh7B*c&v=*30rvJ9f z6lv~<@o(=b;5RnX6iIu_P}($mHE2SW5OMb}06n8Y68qp4iGPy5MYrJ_cz4^-~y-LklqqhmFa4+`LQDw^~cae(C8dU21jyLf3EYK{1fHO%t%) z%F28!M>F2>>p^j*@9`}$$6nK!xjy4p)+`U8Enf~wJ9l4xw!g|=(h&Au!nz!Ui4u;% zKsbPa>7zj6&#Tb|JK7DHZ2RO&K;(^gRIlDsqI~8(rEr3$EGYMEDDNH1aXw?@@2u1z z?X?%BFLv7cP1S+nQkkK24#<1Lqfga5Z02z5R5`>qDoU;Dq=qNDgKuoMD^|XMvYqp2 zyN)_y9$zLqMifFGZgQXtP;be}iy_B*ZT9bez0S))l^ul*pK8B|a-s`0;2p-NdS_o? zI5TLCHnymWpGklF+j>fS-7bo1+q7V(tvt)o*$mo>4V z;?3T5xj%L)kXDCGP$@S=J+31Zz?B+MsN?wvY+8Fjl&wPjqD<`~mxGI|TurWg`E zf67~1UXyu3$S;3t{;x{>)4%9f(#R(+Df2X~?+7Ly+z1FUadjJ;D2kRZAh01XIEs-N z5s65wwrsw?v$Jcy{VhhLHuAHn%kdd&=iL66-XGvm%3)Q?HvDdCefU}H4aM`4r} zAOsP98(Ph79Im#8ZU7Vx6^r7g-p_lVoY zQ$0uf2IWx8Jv7I43niHZ!wpID&^8iVk9w75N`v`Av-g?CAloMhh1!X8F^*s^?N4R6 zfHK($*h**`X~9fx#A~vew-mU){4SGZSIT|5w#qbV0Cg=uBURsS3AC;i<5$k9Q#K4d zpOA}}wBoP7s=OyJBNg3F4|>}DhtPg}{y3ZX^4-GA;D41HaJ&_<_?xAo-1P(`JedXT zA!%S3#2|!QdTPIIX zQIlOh{+nX(3@cS8XSuB45x2fLYX+3J_sITJ&1n_z?FBN^{5#(y0-Z^fA{C% zE1W{zAMD(Vnm;CQF-kZ-&egPBvmDVeCl=vk+dok5V^y~@C#7;GD~P;!a`v|?z+z(DSzl(*<5xIS%$HN2YYD)Q=n0OA*m{}VonCc15$e5nMq(K$W3u0o@c{% zOKCEzm=ry>mh!*qZ(GO>tv>MuoD%1*fubOceqrv2Z2ESoqjhvKQFuIq%&dET zKZoc*&8@AWASSCW#Iqa}oTQ6ssm~5o&(rvO^+WhmOH;ruJz)}`Ku{zUcNu-7cSoub z{m163C5LE6qEH-qsRvb4y8IqNxA=odLF)?&9w`lb{#*l*FMj3KV}+Gc(Y&G8?8tYK) zWMb2AP4$+W({&EG7EWBX5zB+#XYSXUn!Ik)AATQa{qp(KAG7N(7aoF>#Q4iMh*H_; zc726YDRlV{NToYff{fi#kKd7&7Q#sy`icL-)Hz=*o7&%L=yprWwKKS%Ryzqz0}xq~ z&zH@y{_4Q1vbBLtaQe|!HLfNDt_6|U(eLxK-<^0keTSH4*{F#`(H6XB;b@GiTt*4r zb?1>ZhfTL-od@97#+zc~v~@>l#Foaj^-fn2tJI3U7W!rtFI%4bDC1m8z+PFtgG9@A zIP=$5{o8sxvp6w6jhPR`vO6BH<|$37!a7}_biXm&X*US62`u0}vE@A96O$iax7(bS zRw%@4Fzj0IA6gN*?Ah4t@*fB5+3QcsE;x z*y)dC7i!!bn#%~K79FPKsm!s!%Yc`%^_mhI*op?%f1CPMjlA%)oy1_&)X-Ja;13n; z%(+i`Rme?#`mBuql=!#*5tlBW_HMU=JC>HMs2kjEn__}lSe5cr2~n5jtao7Or}uva z^HLHN@NLu=d0$_jYWq}6g=u3jl|;W#|NM0(g&#sPJC1&lROwxLCqS6G0vaIO5fG?* zUw*dWL;5;&CW9${Ncf)RM?~O{pfL_j&Ug*i)=bt1GyM%t8tkefwX`bTs_IleeZKBA zB#30dH2rN`eDtr5J_8-@x=Fyyi%5cv15MVN9Q#{Nm>2!QSp6=?z2E_}9YBjQ_ z)m@5XA7K8dEds1uN7DZx?%#^#RyEg0`Pv42r5IV}C_CnbP=d=%F_)r41aB~>$||KT zq~H;lBsqP zZ!mLzI^XI*SWg*9T1hBcMQHE^O8Zh3tgb^~VVn-g_zzkdI~-XH!v$vcuC0VAy_|}w z_+g^>h)gZ^An^K1>z>(|YqB3rk$d2w>*WL3+R27ZASq}?Y9fG`I*gbkUpp@{o$dsr zKE~Dfj?uOWmf>~u;P#6wyn>^mcKPSuk<}y2Y+;O29C~MvoPooY?6GNR^>p=LI1MJFF)dH(i|2@)LD8khv@w7(`Tpd4teoERNKFW3c;fmA` z!Q-gIMFYV~I~?|hxi7^fL|l@jwF*~ed~no#%B8F1p8ik?TYay*N2-vkEr_2=7xx?b zlCKpU36`z0mF+K93CCY1$&()1x`Zzdm$kI`Rvd>@#rQl*gS`&+%v)Z_%cH@G;m$#kX1Ey0(xMASiAcS zi8x-P^HFbdP=rr0GX}y6*a&eQFX5Nz-gE3quCbhz$F$fbY0)-_pOj%9G-#4?rHM?L zDIBYYQEWiAQS}=)ju~;ST;3<8;`^2F77s33XtUI|Ti+TlXeXS)L#e%Y{aj;(tEp&D zSMW(oU4!h+9Q%CCa4+RFsjGL;L_%#x^Kgz>c1iQB zLudT*J7MDNAS%g%Ar!7R7X&bN!QU%U=WM4@!VgRWpO%PQUQ|Rm(MF)vi`YHPiM#|7 znXqy%=@xO6o5gjgr-b)uG)7FO&fCZFJsIA~__)1u@8)vzj8pC^M$4)9XiCz9@!Rd7 z5qFy*=d*7f+;k3mk^{cG=9zkB8S>;J!ADd}s9IjZdIs;@;~Q z4yTmMOaWCiL(5gnQ>1R(>W)N1YR|%E<_<$RK2)T@*sIO;bEX0#gQhb{aiXAqh7N$;fyW!fPDjM^tluJ(itA0;slOSf$`KhQ4 zW+y_od!nuc3)|Z+WzSHV`V_KDCC(stAc zYq{cf{N8+CE}{9URuY`zy8axoG+D5;poNUjt`0-6?H$!Urn2?_*&y|0lT4z7|gnQ(D&UWtnITDUare zY7X7cdc7^j{K`V&cfJYk)H|gFET2(YTfSNj!Nq!&l!fLbB8fX(&ps6gbT_ z%|^%ia_t7pIqgAd+w6CB`g^9{1{@aQ;9y?6>4g*;!4h!8x_G=l#7e~QBe?DjNPFPw&ez9+9X`LmoQj^5b*=`!QFpjb<7 zNgdNzF)}{{^v`LoWCw>ue9t^>9se&20F;BV%tP!x1RKx3OZndAy3{jwjSF2)otFp_ zm;TDW^M+U!J#N(YGOO2}n%h@3eXW09qd{{nYJQNu6;JBJ-_pkU=&2L4!gc(HdkbaH zw}3vrcEBPOVFjg55x&OWLD|Oa*sPHA5Iy@^mgX9{f$pv~=Ads~m8(@_$1QC8!S^wR zMvP02+uMv?7WtT)3^^h)n*QtWJ~!|z?)f^^KiPsdP!K_`Du!Cj_#0+x;>Bjw`mklK zvg)M((GazS0XLrJ&F(IUXg6M?GBS&i5d_$LKHXP^OeW`V|H`_#M%oo6)|Jtk>Pp`o zMMTx1?P+S1gxDYL-jFAqV?@mB?Lo#dAV=)8sd+{q7I~Qz50jZKxJ6-Rjik5FKhUwB z{gD5*8jh8vpw*ew$YM*7jO$R#(M1U??b>6>{!$Jvk89UP+16QJI6%su!SX8@wper^ zwN=$H1cQv-q(t;jgtlZsUy97S)}4IqTMHralTzc~z`%R(FzH5pJyWf>*+|8;VLEIP z`Z;n=(NY5`9CDJf6l^-hv0e~6_QYhX>0$Z>i=SC7Mv(*yX+^t#@qANl=D#{{mbvim zaf%aYPLc_IxNliO=_NHjq5lzNy3NR(iqy~A;`5Dv`Z>qN?=;PT6~u`{C+`l@zU@V~ zP^St|I76q~M4Hd{)sr*P4_YSL$92(a!1Tr{+va*S3&A|Lq;reLWe|SBITlKB82TA1 zZ#|ZE;RjKEw$thDLbpIc`E=1p}GdcEg|0IWV!H4<>xFYyEY>viZ^STl` zVC*bGPP+XUaFJ{T(Zpsw2#6-86uIfHBN%LZ!!hi%R=|U?WM{4DTc%O})90%9P~`9HHrWQIS7jL9xmqQH{{7*G+rwAEhzFI>aU;AUTGq z5uftt#w``x$E@pa55OPjE8|!x8upRVD)xPZIqH@4kGU?KH^Zn_)#mMhB7J6NccT=v zmnUQXqI-Ns{O9ctvd!m*=Vwo|4uy8kzn%ZHX*wj=CA!ppH=$%V_NKUgW5P-@5r4np zYyrX@UWRd9qb8HHCgQK&yq^$PZ<`TTo(C+TSqA(97#QhJz~oEPJOfiyQyNSCrWI_kxc!s zG?*Or;B9J>I^#$ohG!kwW5*e>FYXPkQZdICMZXb9hzLa-2t^4s>PUM@fmrS~JEn&z zyT(D3FK&GgQN(GGYR8WpV2Wa?8FJ(rrG4?&oV@4CR}!#V&Y29dH15T8zK^rvXwN#8 zQ@}&U&aZ#93+E$}-j?5?>Un4chczYksU?>KdJ)DuUxiz_N?OoP+R_^zhpOh@P{JY; zY!C9q4;QGWxVG8)%ODW2=IhsCNTK@2o3aX8D@nY6QWt1ChP(+jJhGNS#rZ$b33G@U zm5l>L3&H{$WnSFiacY12XI2yQN}9gtN~Idgdwe@tH;%T^r9woX&HVy>LNMFfJVNq5 zz89U;(~>Vw$sLh|YO&-hXDWQ{g|vS1SY4_ET$pf3W+#Rnedh*~f}nUI?1!m8%ztwgbNwW~hdWtWR zE$U|MdGQX9a^V$J^yI4eO+H-T5F}$eKi!;f_4}Tl7M=iOm?E&NPVfCOhM!Gv7V<;^FMsy1}8|bW_;bTj0Tu zX?*_YcEw}SRsCBe! zcyZ91teDHnxZ?I%Npd=MpgGM2Z=(*&O8@OCm_>#3?CSROZytJ;k6!J$gC0?ANSreH zZv|+u)(8FXlij$%F4ct(ZT@=|>@NK8h#TV`5l_36 zhPFXiWj>(oZ2o?5W@ zsn6=PG(<5Pu)#Qt$KS%Yxj#)gcl|6N&3vg}i+vsz*(=DuTX%2m?TE82@V*tMcIckA zwmD_>&zrbmF_hGyKV!y_Hb=erS4l@R3x<#4^Cj>72SmJ3nM(7 z2x8gzN$tLgCtu4-l-LT#y+*NPltWB5Z|;2St_o8(DHSH>RO&{?DuxMU z<@kPlqoP(HAIyk-0~{tI*YfT@Zu!~#WeBv9h+oSSnS)*4l536HAJB-w@_ouR7=03= zvC0BRLvc%Qp5{->pp{$PxS@(@Mi4PR$GZTV%*gR zediF&BVb>hpNJ2)wyHzBHw=sICcO~#jZ+q$>4iSW@r<+V4=k$+$pWhB@W3gd%3Wekia`nCK9k%&cxANHd(JXn<;_~LsvLT_(qbUUslZjSe zH=%jwzt$d2pNyT3winkxS9Tqlh<*&EKf9UK$xE1-um_%`&r_wpUh1LL)=R=)DqcHJ z95e>x{B&qyz8x{nxg3Cg>UuaJfqh%z z01!`(Gw?VY`*goAiF=VT%A7J{;yIDE3=s}yzb{Pud7kT;BJ7Ef1e~5JlFJ>UU?v#H znfekVrpAYZRQaUslOvvPPjL(gBNQW! zuT|OnD_T~{Kser-6ksXqO~HNtDqx3e(9ooMn@g)*VURYR(nM%HXexYuYJ4e0V>6&@ zIWcF)>s+neZ__Zy{zGI=(v&ac5E(x7@cS5Z(e*p8WLY{B1q`Ai6PHEq;*w7YWcltf zW9*drI>ex#i&>!uY17eN{jy9E`eK#%|HspJ2U6LG{TnBataFTn%9fG6C0iVl>>ZW8 zGAng#naPe2Wo1)FQAxIpkWo@bMn*XZ$B6g3pWplb{(Am;bk2Rg_xHN4&-EFS5M~wh zy0O_n0xE@Of0JPD++9(9D!U6L9qTefjR^fB*g%?pG(J+y$RSsm8 z5=Sg|Mf+M2eYJSc9O|R%1o%@lH74~TE;}Si`dnECv za18{yykF1LV}P3fdCP<$?cXX&B+rd_kdrNcu_#iEE^S4g(&|iZ6I6dvBi;8x_oEWu zy2HBevMzSGmy9&UqxwZB8~l-zuh&AMI`}M<=>v37-pMT|?kx|{h zUk_Sn_4{YLY|?Hp=@LJN-Tjq=)S5J%{MIO4M=p{Xp2vUO$}7zV?;G0%Ae&frKeb;kzm@B80Zcm-?V&V$77~ew+TC# zU+I`@w>2faiAr1l>q0!9Fc{DlMKCndgR+S6M7Gl%catIaOv;0I2Z_E-BI6E%2V@|z ztB%oOFPIf08?ilvIh$rH^XnaXUQ4<5M7MJ=zLe|(4Qp#h-QR&vO%?V+_U9^6A(SZI zj!xmFi4c955k|Ss3$gkx+?t8D;d_F9I`zVhxVRnMGNeQ2NBJd4VZrA({k5D zbpLpNFfV4*wF6wiq`83?bh-wQ7|AfVGKML4u#u5#F1tD6iJ5<(=!Rzb_sVw>dpHk3 zp?HR@2<8o9NiAD+WA%npcb;$*fvbpavU~A37X`0RFc6md;m~rI7V6CEagr!#o(1MS zVuprq8fn1tV9fYc|9+8lgftAZ)(k3LT@~RO;h*hDv>}BtZLpM3dbFw_p4b31fzMCX z$hUs#?QVSNV(HHnYY#3+kY%W~2e7<9)j(OWiV7)cUm;}}F%M{ekhvj+$CW^a^ccf^Lfc=0|q=nXO)1lM*ZrKgYrJ2;HTM;Hm zf)p8v&ZaMHu5@a&!ArXzCgyW&E_t0ct~VM%QBsEAa(i>jM#BW22}84FzXV?bViK?o zorh$Cs)4l^N>`2enxd~M~$pgKfIX{|9W$J*dLAMoIXF}mqGJF9?De5h@QhQWK{-hTiM#(h3ssEVG680 zoAEMo;o@;H_i^kvMNO)366zk*6~`>+gB|gqBzdT;Sb?Ibo8Vb%B`G-Hiw@Dx_qUY8 zC4-^#<7XPtakmnmJ`6eB%u}b}3Ng10NKd=1_pzQgFz4Ry`V7<<<|+0>cjLuhQCQs0 zJ><{Yq4W0E(y8zUm#u|bwV9(#%`CP45tSZ~mqdj{(OZJ=rpfb|3Ol3lQ@6fcTWDO& zWvu-R`#)D?Re@U>F3_g$;fw9i;8R3ZHSaC69j39>U{C*0-mZwOrm0nbaqnPfB*&V9 za6yqT@+N2{Mek}(UK%=4&S5un zB$Y`*&Olb42D!1fzV%~tQcLGQhb9c)`0btuH9HimA`RDtJ>~z_ zwP$H?zpI`sdG+Obd^@AEoQ6wLqT;fE;LOFp62T!DwQ%%Z@S?wZcZqM@#7-|#wfGTz z>b=t72wiE--~8$TaciNyJZ%|k!UFmKJlL&I(BA1v4Bc!K8ch^2SVFGS1D1T}2h5}g z#1xm|N_t-1pzm#-j>0QfUy5W5n;65|-oCh=ESoK9U){s$HkM)pW zE@^D8Bo9M0hjoP`gY$Bfc{m5SV3V!hU{--PY8f z^7mXw+fv;EzolW#mHl=AH$7?PUYR~F zp)3QPKwih{KUl5w2=jY~|A!~mLd-6kbpuIvL%AKX?erti+aJK3C( zHs+UIe5#lED{(?_CZ671fpK9HJe(|Ys&6RQ=MM0oboGg^rD-P#F5x_E$4!NG>>ybq z?_}SbbpAK1FXKOStwC^_IKrlaLM)}32PwryF&tZXKQ3S53xo!X1c%lp}LjtCH4*GW6^dv$pcd0a3Kd^g(T1| zo0Lczw`a^_KKIJf3$Z)tg{yl<3uM>}-Twl)sT7}+mHMjD?XG~ZVj0H4&BZNCI>s27 zw$yBj{F_F0w`Kcz=+A0iJNkVyL<)G@sV`)K7+yt5)-69cxUqj<)*P+~c(tNE6LNRE z`1z=xtqY|mz?^8L^-Ga=h!6xBzMqmuLO0ESPf;Xro*^;a1+rpWJ*ss>6;hylWfU>1;%sF_2iy zz|jHfHd8FOPH<@~E6Yi(yn%XDc$R*5<1cjOJw9go;BZaaRL$Iv99}SxYVrQ;lWoxb z0!>M$WiEL2rfIo>knVx=sPS%$s!3#`JD;}(RbFE4)hr1$lEJJJ6K#^uj?j!a+=FVV zxe`r*>9>Q9wPQ|i*m-$RF;DhPYw2%2h698TmSU8V)^-n$EMGNe?Yf{%; z*NB`}_2SHTJ#oh3^^xNb@}W9KvIlwRQ8}uN;kty|YY<(67+|`Pe|}&vG7hb^TcpOn zg70nbBSSpWKVBqB^(uvdJ7tm(Gt28u{y9-s5!;ezAcGJ1B!YVA37XCYqzl{7E);X} zu5-Qi;dVkauTh$6pN^O916A&I*9aYDpuD7Tq`n1wpF#iC&8e#gbQ11muo(+}_2nVR z!oRA0JjuihuOH**^Q8`)e~9mmMIxu zv=f@bA1ANxLHg1+zRbcuXSS^2ie>q!$T^NxLBVux5=pP3Tv?j^XY2kWBui(hxtqc6 zG;iWB(*x_F7Dq-M_M?nU49C6I7asaRUr@U;_U=2-@21zNX8|OeJW|$@Ddngq(~vM!ZOx z)k%B!%{i+&9Wrsz#yJM6x81iY{s_~OA?WrTM)RKTA?)+|PB&)}#eTjirEivbVb*HS zn5wgFKcJ=ma+npgm=x=z(FK3{H-s%+^JUYQ75O}Zy^u`KzT2#ytdxNU^u^#Zf?LDkB$53 zV``&6Nwrw@U}(nXq}Q;tpUS<`2_4d>G0NdGzPRITpOgMdJ8E(Y(Q-JDY(^=6f8^uK zqb$Rw+&=FbPxLSSbqKrdjFL};4g$%;&QE;Y3m5iV!}$}Z>GO5h-}C34n*X5;gF;}( zq5)(p5vMp=cs4aPr2~(HfbI^`H|f3f5~?tH>5}GkskZv?o&@QWq|cgK#Mk)B*U3p* zSEj{J&$LzaCR{2CMtT3yUg@XJYe^tH^5kGMvGI?t!i!sGfkZEevVjuV+ zq)sGU8G5NKkjL7Es|gwI=0}P})xUwHyx5$-jSmcH#D58@qct6e=b19W2!1Yk@atdC zER1SId|I~)Ana3dlR$8i@ZnPZp1q5p&90yq@C(gb+vbxSs zPkj#RiABl*15@ZlXyiFeUYc8F_KvaRa)vgrBe$SbWg{hXW5tH&Wv?uOA=iS+j_N~2 zrErS(hCl8)7}k?G-#bI1Yirfd6(5y2!U)SapErMH9MSe;rX0<~mxPYu)7}&ovL-hm zE(IpvpLUk(?qNcSwvY*t@+r|o3>=l8A_?cb(>y`u*8k$t2&P>;DF$Foou#$h1cG5eha4i7bUDEuSmfpO)Qyqi07P40bJU*!|r@b56e-dMa$>fe` zB1+fvPTO%eemxOgb<0rxOA;oJ<|wu7W{C<(aT6JS^(T$MEc<-! z(+YS4C`I1*$kTPT(Gj5U+4Gs6r-&I~zbE+3TxNSFM91!Hq$)?gvFY-~(5=vhHLw9m zn~a~k$y;P#rAcMiE){!phALy+;zmNur^4@NkC8fy#(a#XKQ%}&~MY{t$TE^s8TLl z=L49XIAU>h*&J6j{{G+Zn+ss{BZI&%rYeZ;_gW>=7%FTPBpgPNm?^l4rIsf$i9%DL zcMKG{@!o8KZf!ofSr3riE=enkX-m|3O1^v@;SYP~XCfIVp>v=jn{3|=nu$W31&Zg& z@*8QE%hhv`bx-M|8OE!aPoO{VA-5+kb9rSl1d8`*A>3euMpX-58)oiwjsJi?2&Y+t zZ-*WcP+0=ALLUNk`XJv~xH+$pm^2MeKw{z~4u_bPR&0N^HLG;81zl8&vxItWHh6EYHDLd~2iKUD6*z!mzo?X%V^b$Tv2G=VeJp?54Y1K&Q9Ex z?M{NriL)luc~yU*3)!XH3uk~w-uasNLYwE~n|I?v-%%Zt-7%gkxCgVvT*y~tHSJ*0 z3uWU@#nm?qbQ{t!n%8aHJ5LHi~ig~A#WD6y`C^y zN6}zq=KbYb^sfBdoX$eFW;DmyK|-m5oO&qZM1T#OvNWkYcw8(*il!+>{pNma+kX4B zzVL>yw*qXy_#S&zh0!aMXaza+m3<9A2lTj`gBGB-AGeSc=Ks>v`9LA#Ae{GFwf;Fh zaR7D25i8mkMb`yc za7pgp{v8ykr9opxf8lRZW_b{+x$@8daM{4Rj^|<0B)Y^6l1lZg&iS_JS_zfcy2RmE zHQozdtI%WbPlD~-R!T%lRw<65n~~I<@|3sg*fn}qNzLYH%~4Z5RYtgEQt-}qT*1O$7RkAZylK0&UDp-}{D(rNan(yH-AOFm}iV?fcVCz`+ z$({jY(0vk?c%G}Xu!onl^P!UxrR5ke3}g2h@OZnZ-V5*z|H45CHnc@wA+>wNY0cS}RP|yS#IuXV@f}LioJeptW{z;X@Ge(o#9Kgj-d}Sa zE{w%{zzu)r_PaH%Fc%@J60WY(*q&=4AMTzP@FUleo^aOJ_w$_*Ym=@G1)C z8@s%s(&B_qL{KG~v}Fw5H~LhA`%T_xSo)A8xe&wUR=|(bX{9kN7wHZcuw3DA)>$w( zM%PzW&u7)Ss>7)nbb_Dz9&T2jSDcjnGMX3~Y52GhF8!DL>E>5`?0SWDX&r#wku;7! zO!`LmG7wBEvw+8-nOiKB_hNMX(O+d3L8_;?|M#&*Ld3Z3jR!q**p!95l8i#L285Q> z0h-(1<+Y{Cs)XdWuZcoOR~M-f!Q=Qz8v5A6W2}%QRG9g!jDmk$Pqa}Jzt>8sdMozt z1?UcFmJF6tVclkvh1B4DnaIeQeQnJ@fOv}Tl1MnteqQYCCe@@ho=x0FvuW{G1avw) zAh0u?$j5sQCa&tnDaa`W*OhB>k2{*tzuK99$Iu+()Ot~8Y~P=GsI=bt6E-H5FjLc? z*zC5eWXE)j<|eW~LlAUQ?cyCwH$_&>1b!Od?0YE^&@c0Js?mfkxDe9P1l}sDG*vh6 z>DFD()S}A014zA%-_U`Y=Cagc6ZwGrPZ}xk&BKXbVoM(?&}Q$R0>9kVteD*t>2tCS zLIgiuFkSZCt)t}NUa;uyuK}=q(+}v5>8d=Ja*(5dX%ql zzYg{l1`|*J`H}VbWhuX+_j?)N9NCfU{gNc9Rhb`4+&2DF(cW?{rXX?ubZ`Cf{yv@MwjVFnU#P?l%!*p z^3VJOFD6e}8tW4Y8bsj1Y-kjsDj{AJz7R^j_(i-gR=LJR#IDJVDUzOrG+hNdsQO6d z#o+BB?v|ShD+xZ*6rvzhpP4vwP>`MJ{eJRd{q=eBL>XgOT2jhWKg z`Ht&1Bx}GcZ+@DU+oY6EjSzKH{WzmhiGx`e=P-bO)w00E$nclsHNQn4b>D{kIA#8g zr9=il97deDVs|9u*n6BxUa(6BjKROv{7B&~<;Twt64ZzSXA&BtdlF`l#w^nmHT7Z*H zt?l->$Vqc2e@ZVleJ+^c@hRtD4v67BN~fe8C79-EFW2R36%0ojsQzXQK_z|_irD?_*W%@9|zuIGQ-17&7 zS#R&5N4l8JhQsntMIYYglfoqJavVZd^n14D@G7ayK_JW6w^-?~iAUa`|a z^c-R!`m-xhE={?hoppYob=11X!tgrnxj>6mF#K5pu%SNK*Y)Rsg5yUfR_dQcbl#%P zaW0=90?gfbvD5sIuhWA?Xcy&>uKrEM+}nxghi=zR`*^F$8^lUER>O}2>vr)=)Dest zDA^r5`1Bk7~0i}jI&JdjmC`g&b(UBcElmd?GJ_)(`f6-ajh zNeUp%PQ2d#Y{S~az3GwX9a($vn)$YHu>aNRBr%(`t{g3$$b>+tv-_3d+%@xq;jk5z zt67+G^ORJv$Y=U;2@_UnF1*987hXtz*p&<}M!nAaPgy)5A!2yIj1zn52TXKjf6h_S zcqE6mq;%QCm=jj7i~@f6qqW^WB5N&3*v3?hnhQAejL2*HixSR%1x_xT1!KtrPq4iX z3uruEv8zzSraxY|jQ5I`xlK8CR?4Em!_xkr>HI4{pg;au`C|9GE&ajQG3JN=CX3{+ zmBBl*IHPe-{eD8>`~q&^CvHRA3d(Z#v%oQ(?{n2$w~x6HF)}NPnuqw`Lj}<;`2_0t zZy+Jmk&toYZjZ>?yrh=m;>K}!g zQXg0QjC+H`TGFt~UYb;N>dWM^Wh86@N7Q_DplI6*`tAfNvCXfpsMwq!5F64gxYh-^ zJQ69DZmgSeaG_LC`DeJ88K`EgGaYeWyJ2M>@1iPUnELDF(M9R(`4m{RW`b|jqzw$~ z^K9ydi~8`g`1zC^T{U!n!A&Q6c8140f;}#aN=7M zd)=vWZ4#3UW=S7xfQMp4dGh~cX>UjWo-F5LY}G7mV2nA%?|@EW%zyOVIYT|N>^z#D z2Gfp9W zf6B0F8dlI^MPdW1&Hehroj=ie#ZEoSeo0gZpS!iRr9E*8B@o6YO-eh`p}OQi@A6fTEJ&S z`jo4YC7*5b9sH=!JsuJKiS{zXj~WwfVv&_SVCc8oO4lcVC$he4{l6+TUa~i*R)PR$ z?97_$u#-$~z8Auo?bg~w7B5VD?Al+4JL91VY)7?CJdq>@wevB{XJXJ>ZPXT5kyoR9PLwLlK zQ28d%TZeP$!F1*6YVSeqN1^g=QQtAgta2`mMyvY4*Z*I@RuNL|6Xcv*`{k1hci@-% zM8}V?d(3GpUzVaTLGl**vZP(FS4@>*s>>)O-g1d?mIja6g#@wc(L8^!$^@0hg?J^t zwx;03ZAPtlu<{>?QdQ7z%Dm-)N!?o?l~thnwua8j@?Xi7m&OD8y2d4ja6Vom#-_uc z?Z-*-@P?1B`vgkA{kepH5yK?DYA8=xF6SrvKd{;pK6yM7V_T1Ze<3L6>vP?c)zM5b z-8`MuRzo2^*_^opjL5XM*go2wM1DqE7tiqB6OPBTl*J435UyH^UKiKH)%D{aL^A@4 zO~$j_S{J1SCmjk-k5}Qx}G`u?q;#5MGUE#J1$utRm0!Hde2? zuHbhj%ipNv`?Raj*=Y|XL=8ISV8-dYPcUrPwiP~*A5Pa}&wipBuBXGVA4;Xh%Nu=> z{2sj8x*-Q2{Nt`5vbEt6PLnI}EfNYRd!(K9A{dT7O#T47)EAS6jgck_u`Im}<+!Zj zmzZF$vjQ~+CZkmnarBXs)*KN6O=HT&k)d0jR28hxJb}I*(9>`1 zJJm}&He!M|zoc+i1g?m&Bpo_H;@k`RZwo1@yB{z0Ua$90*=`r2A`Bclkzzrm_)}B*9NIx|gEyJf5$Lube zeoHnZ5B~$mpJaP48g~mh+)tw`s%`DbS;+JR965g04V7&*Gy+OLuc-4v{VvO&9uHXp zS52|Q?m)_5%K~G?-oPFc1-Pr!L|!rK_#&{-!eIR&T0&FAEL-4bt#U$`jDmJh)0aK% zcUJntnnVxH{BxWug;#&G6%g&)zLK*$GHZ=bIO}3+sPr8#AQ5?vZ@9D1sCC*K%cObI z+?^ffRJ|;(=5&h`E?G)+OMbS?bMmoxhzSphtboD377*m?9EZ)-IJ5Ktlc|Z+pXUWSu z9{jcOxn0F?yB}{^F@0924tr<_?X@Rbew@r%x3tnWZ68+}dZS@eAz{O2;&vSx7#zZ* zh1nbfvZOVc;#6^*zbQ*`A4Q1cRHt6G!>#G4cB=1Dj--#>y5q63GCRa(%z3Fp~n@jJWD&JfR5F5xLNYTPk+yJdLa!0anJgvf zT_T|FmJO7>Z&%ja=5@~P5c8EomZ|K3L`JjgpU;#_HyR?Q8~J%ijyL{p+GEG)*=EHt zp&M6fy(YUe4)K^~8)4zJ!_}pgq2i;YyPt`F4Ud>>#o7~vbcK4fLXWW7DY`LdNLhKa zuY$@Xt=3N_JoR2cW1`YlBt3Jb@J7!0bB(Wf-4*40fj|1tvZz6`&D_gR^o#KV+L)rJ z)ifm`l)^JD_z>-(zPSm=DizmLB`Ya*HNEf~Xa1O`M3D46^Q=;R{9ZX|FB3|K^~X1c zHy#^#rt_Dc#T&X4#TRGaXwMbE&&Wd7j8X24u>?Fhpx;cg**Mk9f72nAH5)b}Q-mua zy&|t-O2OAo|Mavy*1 z1$`#Wd@F0lHTFNLu7o*rs?WX$_yIw@S*Ze7@%!k%$j%WJ_(fOmDzDE&`s9tg*sL~$ z&=~k^OhoV&;=?!8ng2im;LVPkO$R(%H&F0|T!=Bld=kD)`Pe4Ir&$BaLELz#ModYg z71^ux#r)ql`Zy-?A>bN>VutU4>CEgm14K80!xu>(fZt`Bs-P`?!K7Z@&si^zl}V9k zT?Ko^>rUFea$b}2Lj*1F<@Vc;@3wY@*907=H6SZ`1k{TjJmk-?J+pSRH=f8d;J4MK zkg0w6%WX`5`#St2yNmRjT&TIv1}ZY2pBrSfzcX=f8K>V|1F|l^mB1fnp2sd8Gn4~33?`mOXN!p0XO*sHlIbGVaQp3V^VrLEZzM`==9WU%{a|vubK}OeD4If z8+5Lg^M6li&6*e(BqUGuvJAD*+BxMDd`fVyyjOLDcyT!hA?_=Ibsy3)``|N(Si=sy zFOFH5#z|Y+xb7Qxadb>oWGcQcYNp`W)KJhO zYi)AyArVu2r`?Tt3dU+(gk$)k%H-f8iT=5{`?MdPAHc(ANr{kkhxXSA>gxiu{EQ4b zxtGe+kjciBeV;Q1$5<5rSf=kglX`FV@im*uD_N>{*W>5Xr}#JSI~~{bhE=`q6!=hA zqk1M`YGTVwrZN%9gIDN|(FD+p96yYPt9^JQV_#tZOK3wi4^PY_0XRMw53p_8&fZx| zG`vxkoAVdJd>=L~8NWe2l=1!j!A3mqtzejZ%XP5IZoHuvYda*^J?oMuKZ(=&+1>D4 z+od~3+4KFUk@^8ZSsN`eW`E$8V^q0_XO)^Veski(EJbXG(mhb(f4t|*zOdpI087UB z?Y|H_sMY*~ZE&ft=~vdM(^4Zg&aaxibu zCC|Nc8@#x&03P54?_fQ9;zai_Y)U&Kaf&C=%m_Wj>&%^L(sfsA=VzfO8S3N4l;2_p zL+hzMd8`-i>F^ah%StEA>^umYrm7&FNszrZgMS!#eSklKHc!G>wd#EX`l)BuIz;8D>`x@g?PW)eej@cd)LYgRS*nk15bN(^4F6s)Rn;5W}#xS|B90r@tXQ}S1gicKZ?zgE3NxaHEP^z`^# zh(O>IlKwoESRF}E%Teq^mIQwx)Qy-T=d3vU3-cO+@%n6Uf9I3=Peiz`_27?3&q^cw z|Hc|FcS=#Td0BpX_nr3k*GCKAbeyn`iFjo;sk6Y=J~XAJ%D;Ksez1g9?3M(G;V69{PtL1WjZvnZ&>4(ex^hD+R9ezR;+Z<-Ry@l&3(U%H(0NPv zz4@C>QWK7T0B6jlTdxpoxxzzln##7`Sioi4*!)rBKX}r-!%ljs3H3cm0Q6Q@P;T5c zkcN|u_*Dw|)VYseKI7%yQ1;*gvj(wyPk%4gDCXj?M`Rrzm)o3aIb_cFv{pNPpR2@4 z<73=*Q{-+d&Jr=4xWE6&!(+d}#s}D;%u_uV6v1sk8Bf$*Z!5tzovECTr0H;Ojc$y% z`v|6?qz)!Fe$CT@9cxx4)Fsrn}aZ)lX3h4{Q5w7i7)VUZA`O(aL zMt{%0R#8HSmtB&?64y(k!~*qhZYnon%X{NyUiMkfhZ3R6y@PR&@qxUS_(QORS9`WQoE zdHxKfa3CvMB)iy-JFr(i$HKr?B9eY_0r_gbyB1G<1Kvr~WyX+~ydc6#6Sa9QzHVVY zd<^PUij#G9y$SkCoG0*!qVPdr|6O`=*jyqq@xD=93vFK`!lv;kvcgXo?7_*X1R>&& zt1i$R(`bDeP5kst@S~!*HgX7=&wMXMkHnD_uEFNDnmY(_zpM28ym6nQS;^Um$A1%b zDVv&%NZ8GaP9)7I)poB8#`jp&fC5X#PSNT;##=>!XW{?601B%ib0U99Z+{IOV3fw; zd@WFA%CeyFa!Zmrw39kNuA8=IyjA#&-M>##NT1gX4A1z6PmP|tG9QN@6wjhLvL1=O zKX_^XS6clQ)Pn66PIMp0h^FhK5_^Ui+;44k zh5A70|Es54_xyu6Zai^5(oO>#aem}M)H|`;L{<5 zaiiqTwDx%ZO%gd_K0Gex!s%KAbOlHX7GlrlitA@dWA*JM;<)mvgq0q_-vvY9NA}di z229*l((E5NUBSj%CriKs!ll)}UY6M#|Dy>W`1^gl~*wLF4JC=G&7l_N~ z(-(y>oYY-VzT6S!HFfC#y9LtOE=7UwavwCBW#5~$#vz*oN*yq;%MQp0;CnQ=t)+yC|nxhm3lw}F24 zhBy^YK{&t1Rh0WXGAj6}XP`NIxo}B)MTIQQAP9g4sY;_)p=o!T zZI5*V{L<;~uc4tF-p;GS4++>(J&|{Ka=F8;>X64^3$H_E_aI(MCAV;-SV%Ac{3S1yVc%N_tW&Z7LrG`En&f{u61Ai;oAvun0m!TO5Ru<9` zKnA$!Q#^mkg@{ia46uMG+Cju|jjeQr1lJ-Q<^T&-aYM!Sc5ZR+Y1Q@l^Bdhfw4&E= z>2W;xOH9d4yA)op)6TKgC65$cZT2}EO9)E=AB~%pOukMq7CtTR5+K{<5)VGOqtWlf zeY?jzOS9CXHKRI;z7^bgdDc=F`F*g(L47zLJlsze%&~7sdftHwRf|&*<$dfP^v1M* zY~dWg-i2GC;Jl^g1#?~iH_4y>6>BDPJ6qs-@)ss^W`?7|lYkG4=?hT9?SV(!ywWwcXW3FF6XN7yylzB+ zV;R-oG&&tux-t=VA>-g(Hmw%!P`#52w%oTtL6IYHNhpO-31$u{s;rN4%LQh7nFT#F zVpWIHQy`miL;oOlsT?K;3hsT?K%vn_o)yuI1sb{{WQaxr+1B^t&OUJfUUgpPN`+2q z*J>U37>&Ga>|?TA?a_xB!)9<;_A#2bzp$4GqO#Tuh1B5SPTLk!zjePzMIkNDAhZo^ z(~Uw-g)|qMG?luv$^qz^qg#B==Jk~c*WvlU|2}v6XyHB+!eT-3_CiwEj}FbzGlvKs zhW$(436LR9c1g3p;eL~Y48(c`usmM&T+@h%c&hXmatq%fn^5eazg-~BG^6EnrpH|8hVaj?P49X)f zCP#d!CP8X+cu!gEMo8E8TF8-g8RzTlm+yHhl_eP-qz;<@BbNP~{dx9PgGt-s&sCxv zzwZ6fvkou7?=BT}b9CJ7z1#w9ss2)#^BYTR;>n*8 zMS#0TldxUuOR9K0fg1Qj6jmbWj# zY5TUW`IV#0oX7o-zaMa{=kWk(m_u2Ys+1T{GVujwZfzO-;pODpJR0|+-{54`_O;(x z*eC*1bsCIqq+vXfLqwbzq+-kf+xS5JRC^MP2ZOrgzSj)R2Pc{v4(Z8oun0?U{h6C_hn39&h=nAe-*J5R`={5Hp-B3g z9T>x_I>;AnlrkQh_g1V%@4=3DUo?|xXll!dX^>jUHi?*oT&B7ghl zv!rLUFqiZ%_r3xW7(#Zq6MXEDuKIERF9}%dORVjg<-VMyvI7IlK8Th#awl^_a}*Vu zSvoR@m}frhvqo{^mBe|6l)^ba!2n+p#{Q$KN`4iq{2Rn+a(KnCk9( z>IkEjdkhlLn*3RSP{qPEsKzXh0 zbI;@-jtRL>S(Om#z8d{WM8v?HG9czt3Y|hgpV?ND3Vy0@|s@^#BLW zrIb|q%3Q`VtQw_I2T!P8AF@|K7{!~T=61|e*QoB6+-dE~pMs9DqavFY+)=+?847BI znxuCS9&(8!5NHlpAOFlQw7AsaQENZ)cX)u z#d9xNo>)>p-Tc|xp5o7>`K<&e$H@9GN0=|!pAkzn08eYL#`o`Tf!dJddk>;N&s$!AGTp?`kc%7f8gWMBlGR>v2N7f=88C4l(C^BM}p*0JaeDY+S zP?1)s%P)Wo;{spRU09s5{>RC&izwcdetHkM-wbS5^( z#3B%+Jl`9ajp#k4ky#4`bj}`!k zshj}IRH;A%`_OWl`Kv3!>}*lX2rbZKiz;2dWR+}}=QO68nB)a@JfBa~xVzIih)AT* zLUb)eZMswPgI9V_4j9rIw(d|aX9lc+V}qODQ&RTP=|TEqoJl8WIpk77i)yyJ&qQ+n z3MhItuI`yQm*4ZoT0K_AHt6r%}43Vc|dwz7%?rH(c{KrUri+EyZEvG z9yMuigP|o)MLo6qS}uMAS6aPN7xIT$pL1=9DHw8LWY9%CkHBCf;V}g6U<~T|F6$8b zhzN;OV`LdrGs4v)Pwt;HOR)iRW-*LmPT;v8#o#fI;lqbKy*%9szlPTdv8(5fq*o6S z-Q{|Fci-+or+c*s*J|MgyM_gxhf zDxh%d5clIcfk+bEPmgjQtFZL73xs1&JGTH|qC0dGP~EpM{-G?`&ob zjzC8mg<+f&hcdLwMr#jJ{Ywz}I+t$s9>*-bJ~!8Pwh64KUUX3k%urY609a=*QmOgo z+2ao?YCQfLBun4kVmK3d7UFpqXZ%<$O?O68F-~d+ZDBxr2NLR#>#uK5GwuNTL_O5@ z-V@QCz6^JwEXQV@2R2X3cw!4q_AEqSJV6<$r-ALB7DDciZSX@NK*WL>iWC5JCWdK%A44BM{7DMg8weD`=pp>j2^M;`rqq-+6_FsOlYaRuH1_F|| zfk|UQPsk&dfE^S835-5d(_t>~^jUs?2ZHAfM7`km;TTKILYz`HV%CMIThdoYRmJw{ zE;S;nQOpIm;qVz~=Q?&0Nze!Xtm<62ns4%POnJDRHjmEvUtN;ip{|s;h^RykYuU=zhMmVuKb3Ofq3LtH zQ2BS|IyUqC?W)32PTG$E1&9pQ75)wPNbP!fx6bvrw7`jKfrn?gPvxYnt_7~DW-T#%K=N_nL zp*dI*9)Z$H!60OnHc+)=wP=1+m;OTg3esVm%h4O9{wgbAyA9n_Cb$r00S(cHjOTU6&dRvKL6TlT)%AU@sTrWKxcvcH-j`00 z^4}QK@eCCsQO3h(XcSY%j%K=D{@EqdC4F+0Kp-Ztpc8z`dY~K5<2mj`Uzt zoQ0uId-|B5CTAd$S@hxe*~*@XP}?@YKp?{K?VNzFXG zaV3^l)J~ZXZ|Ou{D{5#C-9%`?8((nJ&ES`!=eO;<4UJYuP6I9 zv^07s0se0gLKLe42P0qIG$mR!f`V4_O?37NrztSZxg0YEU55E~1v!x$gdH9E^YLvN z22^&Bw)Ap2ygcO1fGc+&=`b`}qTU1xkzNVV=x?IKzQ0<^)PBIrr8^`xcPPb%e`Q_o z=18c_&!;iV1v1753{61_9>r-6NzEx1g568EL85|=J$pe{;osF*C4LgLU0aD3mEDQR zCr*iH$pGcNf*Lk*5^5J<96|yF=QWholK5!RC99maN8&igtut(;R)qs?nAYDGkJdSQLGlp?QHj|#?GV>Ruy-*ovVTK=?p}s z9j(()6&Ntm*V|)s4B#cFe#>;5f5I8`y~|H?k8ylYXD4&z!*4Er%BZ7keD<_*7P>ry zSfQQc;uJ1H821AAoNM|!t6ysm$?LV2F`?6`yzDQvW}R$+9^-Qy!sFDXd)w(X;UvH0 zjNjySvi04ao-WNtGli?N={KRg4xoMTjW~y5yufdTlKt*)e3Khf@NT&EURSur1#7P= zl*`kvn-YeSq`V$QNxpj}>DLbochp9x;F{}RTm6gd%^T=>b7Slv?!zJ*GT zu0M*-sV-G1Vs#2|8E?Z)*aR{n{GNoaWKgv3fL<@ovRk{-RN;Ayz$6S1IvtsaTEz*> z#zhvr%bx7R;mL@ZCS1N0zngMFI*|7yznzl>!PKOOHVhi-?*{w59UEfn0FnF zQckvjh}ofrOJ>N)(HzO1%PeVYaWT!nxXwDsnDn9TJhNm;^c&z4jd+-JULeLjOKyvc z{B*{zJ1SPpjuqIA7R8)*=jaPL%)|Jmn(N*rzYQwXV^#DovDlw&iJVRVVDbugmtGKD zGpsR)&BOv|B$Gp!niZ!*$@}1W=ML$r2$5~^B$)x0K=H8uu~WewcIbp5Pv}jyd9I(` z6C7LhY57NpGr)BG{r5|VTCDrSLiW?|1x{l1cY)r+Up+ITh!7_;_qtDaMFpZEj! zhD%M{@;xZ%5iMykRDJaWeh4=IJkJnwUod(9w9`$S$FEtU=0RMYw&`#*WNPSDP4PRX^)_f_&esNAFXKJ=*D7AK zMbWOe=|!`;*7n@g%yyVS&5%RbyRbbu`O}7jO#v${KXSOWTYtPIm$mC~drEFiE?2`V zRMY-x{2B$MT|ukgvJggXX64Ga`@M$Qm`rb?ywk%reopbVoVAFfJ;!UZ2@A@j777QQ z^X1IPE26||3WaM5?e?Ap1-XA{%0)G_>e##YQEYR`c<(6bt(FbkjL;@4XQc)1=RzGpeSuMnx+&)!b zHhGG!e7;oHLx*ICf5naIi_1WZ+o!T1jza=`B1+jNlf4<>q?|fzn%D=6)U!2N*SM1Z zPHODK3+2kI_p%n(+}``D8xqR|<~*>22YHs8n<;277QpoXUdxq*w78a~SBb zp+PHsr>>}aw-vt zEBywKCc`unjP_`2MYinS8M*bl64;$9_%9!jxyKLJd#IB!D&AVP5TQk@iDueYb`D(v zXWYpgz&bC#W86D)Ud!m1+{-^J1Q8U0g3XFXEI+v#YdNIPU2 zmHA2H`4p_{lN0;gf@p`n{by}B04)f)E;`Q-f6MOcStlvT5=8k+5C3LpI)cbve6IhwzDX?5ZG{IfjUWRbb*RB-*GmqS4!cqx7G8)8P!OUK&DE|`iViRGxot$ z=Xg2un{{>(&*O(vz@qpcs?Itp>MnZsfOJSpcY|~b4&5Q$N_T^R=+KRHmm(z%(xG&h zgmg%Q^dJgD2=~nUyLa7t|8wbbhVO9ZoU`|Sp3hV9cN@|gZA&B^l?u6d9>R?3oy3V+ zFzaAs_J`McLWv%De5#j>_hR$}l5&eNWdw_znGDU-dY4(mBAd+CCHJ2_2HTx7AN%XyU2993Q2|4 zCo_7TR6TCZ=#-{=PonrSzpR(#qgt7*LPGLC?NY&xwTOTf|Mrk3X&@d%!rBg8{H#H> z6we{}RF6}}#Y6FppXS+gii`-qxL`ALTc>ny^@CHo%Ck}&o-c$sFVeI&M>)`ZS)w>L z$D|W`x9^B;u^k9KrLcNgqVK$x|W)|Gf4|>dBU@F$C@Byenou?rnw{VK-3U ztCkQ!l)n=yQ72=b(B8YZDkbF%7^Bg9-nk_~7qHf4ER^EN8FIS#tp}q=NK=I&0r0J4 z9yG=+A$zv| zM|14`1ZieF98Jo9FqU~BkBasI%!zqRu3h@w-uR8IUr?#ld+eVX{lOBDljeM`x&ZM( zZT{rT`ZVNae~8aAu9>_}JbJqvAtnPKU}tvc*vP({xoQRtJQ=ZF*_#@^HbWct*&c9o z(;T3|$xECk+K5I}ZxWfKSu{d~*HmUJ0-~{>j$pggbad}ERZ>E<>*WVh>mzOjWoN6^ zI;==ZLMHIp95tRYBz3x|GPnx$~{9+lxlI`_$yA7ZgAI&U_)tw@TOc1kM zvv~a}D@wqw$`*SAE{Y{1V7Z$5(8Q%lf6|)x4zmB-CyDly&;zKzdj})xW>ho9WRr%YNcP3Xscz1HgL4|Cqwx!R&T_O zF_Zdd@5!^u@{z`3uot35LT5BM0~w_Cv4jGECdJg|k=*;pMJgSe{oxktLhUx+6m*I8 z2Iy_{*XQ#{g%$kH0```IZV>CupZ#ZeO=;6pmh<10K##_6dU&(X?ZUWSFA?q<8 ze3w-!Tu4+ee??hm``wIY9(zjiuoDa{57WBBu9$q(IfiNfv7{gK`|5n3B`r|T)xo?7 zkz%>e9f$=beCS_72(_($?96gI!_*&F160lknCCedFZp1l`LKzesxm|6S>;s0PgO?f z(Zi#iA9WuyzxyCA=)t<~&9#Zc5ZN3WI@jcA=VDCC{}%!jFa)O1eSVahO#s64K^T&rq{q;z5 zP%oYPp+}EW)v%lHCX3H#0El!R@$^vEB@nV32bk^veHvLq-sNf$h!USa`y``k0 zPU;_g(c=lAEz$R0$xy zt5x2}Hx>>lGs%@5S|m}5R42$fiJjKbaSZ?F`bR0Siy4z#s|`gb>`0Gj2f$4E0TDIY zwM4uANJ8gDjeZ^;VD zLN>KljNl#eTxtqfUw*&zNSE%zKz^@V7LNebKe>|zR2?Bx8*INO47sn)-&jmCduJfK z`4#-iYuf*<8Os^^H*$|eN84BHKYk;^qAORKa!GzM&sO03l%-xE;$5_cv=mjb&nBU2nAbg(2W~hjYzrPT0^%x&mF9bql$O}459B}q})y> z*N~ozi}fDZaHlA@ufd?j#{5kcPkqj}HxbzPxhiQ^HR3f#1GY%1;xZ(jiJ9+IK|4;p zAX_#K_ODJA9>v`MjI4JEz=He*)Vx_DTJJ+-ai+#UW2d>F;3hGcp;*aJt4x1e?x$Ami-H24%oPx=Q>#$< zS3|hZY|DJZ*3A*LQV`D8kP}kwuXbXn4$yTG5#J*8VmAWk0VdOXkiuSXOqw47fdba4 z_lXS5%NYTwvo@RmS)WwCFd>4vkU>ya@=Zr`S}t`TeAKnZp65FM8JO9x*$&){=5UDV zM$ftE6CXA&O&hKlV$oHl)|!ddwncZ8V~FIw1AWOUvmEDKY}w$P8(VT#ogz?w6T;;nvXBV%*SJF6g{@wtZ+apkg z5f};38W9H^@B6Y9zY=Ql*>t*A#j`Uk51*X3NQ;>09o4VO4<||b-qg`tiHmxy+fh{l z>Xu4Ip2Zxz-M4MXW$=jLzk=8<9ox$2yMmkBp%mtTxQarBOgRDwkmYm7Xo&8ye#0^* z9iB@&?=@Yh84VQHgWO-p0|M~8QI3>o5pxRt313i4e**IWpy$UfFXW{neVXrR!vliD35SULUMnHk(WBuPOqx%B?xE!o7) zOPVxICM&f(va$^be^eQh_7W7-P977&3$3-*LAxI(-_XC@P4hijMiaqgKVz7k2m?mFN#7Ee&acV8R{-0MWOQ~9M24R&Nbed!y;`*NmuWub=RKP3sgY$kz6L`EV z`52-!hKkEQ^ZgUGLePu>=GfL%9rRMwAFK!C_~r8>!_*wY2=aChFLdOdcxv|pvllhI zGkIt}MRh6TsWD^IyS1~D*E#1HKfdYrD&Ld>&A=>zl4Rxk-QmgD5J0O_s^tvqXnryg zkLYG*%;_UsZ;MmHTBl=|frB5K8LiA4IYH#oQ6BphSt=RZg16(>9s1yP5+eI2mtKW( zHa1|e*R-W5&Q_4&Z78t0eRT(#;>jD&?pC(IU{id+$ThbO7$e6Kkf0Ti9c6{&US3V~{+&573Y3FlwQVo)_`VB6uldyb51lUSx<7K|J|Jp$x!?Dt^?*37mF z-Z3c?EcDC`cn2Zy=TK0dR5pX=_@vRvrvpH4rqYZz{QZ0LqUFuG6;>K^BE$W(Cyq5> z=UGpbmwx1IL)nG|?OnrGm`~}ck5iXeSL_jkpI#|iDS~TE(PzK6Rsm3hi1Wi_-Lgmr zrXJ;{HEYc5TsPjs{A(6sh+W@JpNd5v=uMJ2Q*uX>Eel|lu2hNZKEce9DrMgI8M0Ri zl%v0CM(Q0CXERI&=dcy~-z9K%>s)(2et z8IG`_%+a=>Pguz93RnPjknF*n!3%MpY1irKLeJd-kyDJQWpsT0(wxU_Pc8@%KXXJR z?*ir;UpMm)d9?3RK#GNga`$DEc0-*eJs3OO{dBdB$kqsJAveuA97Y&p?3moXc`g2M zcM*>lm()KLvDb`ql{xl~(U1XqbK+)iq`;vvuQ~Bh6Z1BY;IC$a=pJ`&Qp5LvvuLIh zdXH9$Hb?^v)la2ATsHVR$7b16)RDr$o0kLMqMkCy??v7!rN*E)iZF0yz7zcaELE#3 z628am%X;eV^ZWb>KlWZfR%S<||NY+s=(BG&5NbsVA*Jj^t($zi^SFY>cuQiXn|_NK9})=>T%itttqqDN*S zN?#!eVj7t?>mB&!G`;z|-(*MoI=fK9|C5afP8H>0vl%oyt$ z*xrr)4h?k6E4-n=VuiryRh8@A?A%-bL)s-b{j9<0%8iBT0z6hnf6#%-&#Ngw-tEW# zwOGyDZ~zp|Oya}@+rQMvfg7-`@yQ3S{L1zGZE9$q3wSOs`B(<94_=C8R0GvSNK@R1 zUq(3kJa6@(M4?u7m$?O2L2)cYY<9Fg%o0}{$5=vH3K784opM(8!cgm>8TIAQ17jiX zF*+^c@2`F(GIkR)x)U2c5%PSi)lRU{)00CxTKrz?947>XUtl!5=#OBe z%lBen8sxI#vn54&l`eRsqFmQ^x`fOnscA~KbafgIGdXGx7a5k>aB>PrkuAG7Z__W$ zw`dRM;cWW0J+IDwmeFRVo@C_3C@WGu$GBqqreRW%UoBz445JwMsmekKZZ!IJ7-Vno zoK`o@Dhe?z?mhNWRAuG3+~DFX2Bt;jMY6hb9-$id&e7lcuSmRKwxKoD%)uxsiZ&i{ zD+&DHUj#yiY%V`so2FljHw5tKW4&gMC$`=T2-qr2I5&-ZMvA?+15zU>D_;tWu6l%_ zPQrH@GVv-OCVyrJzZ5?G_W*ey6OX)lKAglJK``P&L0m2$sTor?9*%opgFPZ?xL3!R zJ(|X#@)?_ByG>RblR{vuEp7Ap&xVJq{h^K%d#QJTbJex(b7Fr66gpP{wPyiR&H)SV zjWJaNrFB#85zQQ%4P{1nALJ#Be<(4;aV{(V5@VP-?9(GOi}@Mz2~UbQM;k3Mmu)xm z_=lZdRMx2H<}WucOxu8d9W2?ODycY+AJ~4kZ{jF;1Z()_wPXfr;GpctGQVK($Mq*C zmwe;#RP)2@XC9CDFO1x#RN+r$c|vTShbM*(GMDyW8vp{bG<+uIwYcBsX_)7!nUH>A zm^5&;vG`?IM-zRJQLtbJk(80exAZgVB<#iQUm(YX`r=0-5zik+n6 zkV1fW+s?OBq;K$N3X7kA(D3Zvy2jZ_s9=Q?7S5IEQSQ(Z2bo1QVOv(qr@@TV=%IYO zZyVyaqg8*>;{7bMIbiY2ZzO`)={*uHY^&iv+A=TKp+wHL>R)`#99i6-bvyM@`tA?I zXCXJ>@rwV6MrKAI!ViKUs}ZiE5+ZDW+`8`r#`I7l{W4V@&8>jXyWeYi*BPLHv%I~( z7Vt2tJXOgnPtinu6RTc?PuHNa5&4t4sO1!ERSVC2_d-@57gInbh9h|}3^#B&t-iio zg41333YQdF`4%W~9S}ogtUT9ccIzMOS(|-PY9||782j4$1Q6B3wnOfc9Q|JVX$FTr zuHFT}9OdYeokb8MmA^(NK9s7CNtAd;pa#u5z}ai}Rt-bxWbWQFyJGs7PJh(uBb8E) zowt7c4fHb_dIHZS8f+4?R2dN5AA;AMmi&H9igA3i0-t47W@raJ7rtOMbN&8c&}+ZY znMv6>XJ9&^#WToisd*Wc{_&*@YU?6m{8X+!hC=U8}}reeqSSX(8Wp-=+eakU=j7IU&(g^5Xcd&t)LL z3YBH)w{;yzcNhOXv={VwesS>2I9m#idgA)DsY%JW9Hm9La{!oBO~0T9BrQ{wKZy~L=XMlD3t zY_mw^)gxt(_XOk>{i|=bQL0v`7WBH*7o8a`Z@SD;hIEyhM3n^LNnPQW=3tiYiS z7E}nVF6kQy(VH!~PwArH7UUhegebBzZoX}( z!;tW$9d65h1&=+7`4ELiWk(BAZt>hkb7O7CGE_|R!1#p%g`Qy?Kt_nGX*!(%+bm5L z;-Gt8v za1g~#BmfDIDeI}|o!NP(+C5*4&2_d-%46;m zi9_U8>64+6NxMWcI+J2L(eJUXgQfSJ2x$s-?nmx9H$e`AToJZ7@19N?Fpo-M;mp+z zs1~1sraVIr72v3H9s7 z=F6Vjv2KD^{8a;$s{{(Lt=$F?wZdURC0JQZU)a4PgB|hB=`izE#eipG>%ARNW2G-3 z;D4e^l~+&s=IVL$w&IZ%%ytmd>$i-+KA5#}_v+Zp;%eEMH>Q{K8S#xABZ0;9a{To( zU6o6}>T;?MTMd$8qE3&!T_Bf9aiU(u2P19^10x0~Q!e=H`Ot-qUhC*LgH@*LU@?W7 z9P?1H5gGx1wX`ra=sR}^6WeEOS9gi637+TtzG`gX*rc=%>Vh z+=hodLrl8qpd?88FZ$r}4-V?e(XkJh77(^+AJCv12b3jpj{2b`3?KYIbdDz>72F_t z(qEfiua7J#GLeG5@0ovw@^oQ}Ix1Ls``_GvUohoX4fsL&nX&Wf-z7mnz-Ew0Suyg` z(PCW@B5aAk_2FIhwkSw(pw#UInl)~J~_uH*gns-frY*?e{GrsY16moS7|{G066A|g~aOc5P={7gD;OFw$1*F=)go?l+%25#D_4f z;SSutd*E2U^)3p;ra{J@_x9FmsA?p;X$R=ugt3t8W2Djw}w{ z&&sdcMY(TRu)|+WwB1`#+Z-jp+TLjgu9tuQn*gf@d-ioJ{5}BS=C+340sBAvXQnR! zE=t8FS6lBIk46=Ab?tXP#}@CtKg(8 z+ZISz*`X^ApJd#U9>o}%JToIfe@yM*2JCe4X&1!5kX9mL2*9aVTQf@dCksPVH;0&} z(5dit!c?Al^uODc0hE9)#6BnJF&#s-v|R-la*!)+Ng`2{8B1U*tJ;8p8@o|2J#-x1 zZVi|Xf35;^3L2Y|=pYVqb-nhR&M8>k_i5I0c?@JTd_I{9JnJO4R8bjd;slT=bvvt`=b2GtY9!5W~_$@AeCK&cg72_BLMn{n2jd_S2V5< z64HHSjZ$R~_WD8i@=v!&0MF;I^??sgme2lp_O?$$jQbh*E)xj4fsW=lSb(y+l(RTO zd(f1>70ejOjZi%;4rZ_iTIOybq7K6Pc**e6-+(CCTG-vWbi|0-M0>=pL0RNBr%2xa~s2H|!;oRn54| z{1BU~ZVIG}aJx&P)+|gxe)D59q0Qk>aV+ zk)D`$!MAWIJ~_b)pTC$(c-$Lx*_>4T5f(xEC0U9B{(B8*A`p37V-G4_L#QBCWq=JE zkFL<9bBjFUFHRs3TE-SV0MRS<5>v%B@JMQ?QwU@RX$wOK_8|#fRjpgG;2DKH0jOBl zCdG!R`YUMMXC2jit(nsDF~ud&qU+pBZ3O1UY&_9bt+gkyawN;V1du|_k&(|c1jw}A z)5itm!N+w8sf-SA`Z`Z`h}TLV3%) zXOUZojaf|Ot}ukEVu_NDusou44NtaK)`% zEA1;)IHN4w$N`|8zL~v2u%Vc%zRrFK10S6(SegI5)ZH{Yj>x;q<1di}ZGjAO4wtYf z#!m^-@x@r55Aj46=^abcZ!Q2r#s*7XrEiEpyEfmW7YiYh=B6}wxuf^m8x?f-_@g)@ z2&Mb3fXko){VShjft$Wmr_|<93ts(DJaK(gr3MjNZ&YrCYCQox!I9L%^^2ZV9X#`J zA?WxN2r$9zw*&%yG&XfnMPg)uTw;onbdlIed`ifSGy>X(_@%RB9s^zM9wo2WfFy;T^1NPiE_$aK&gTMGfIdEZ|h@^PjeFBtdehTqj&?gNNzHd(&zgv zQ->Z!A1Y=V@Ho&&J~~UvAF)&e{Mbiim~>APf!$KDiXr?bFGpCr?+NGq3x~@T+74Ce zSSPrwx$j4OKtTmkLAx2BK4wC}hd6|~bEWu^2j?lX_4Ym3^pm~Z^)dg-~(J`>p#yMCb3W-W`CHjHCIvXT$QeAEg)QjAzIr&bdUf3VnW%x5_-D9Hzxa8h!;1g}$s%>D&Ii z_dq>Qaw+|c%kF#0#cb|tupiAyvlc9Cg7x`SFz6mCXgiwbgg^IBPP*F>A)H4C5PZ-f zHw;Tr?IRhj&GPy2d9x_P1>u?lQH$f_*@C*nO%>t1X+d?}&vub(l8SR+n+|ky#i?N9 zOJ4&2bplu{UOD`HZQ73rvRMiTdx+93K-%dqA-5Y^U=oz8br>0XaeYaUJNyOM)uL%l z@)C)5yc)|jV0)EUhijLy(9Qf|Yc>@E-#TpdGjP;dDOXVFQ;4`^NqTNeR}s0QwmQOK z(kQO!TbKyTX=H9(j?a5*l6hW<)7Bz}k}$y|onV@HI^oWx$b8e&qXqLI;cs3o=M=8S zv$lY{CVL53n3o``oZ>ITyJwxi6+67~tT;syRh6)lG{vty{R80v#<2d6VwKd<$C#G9 zA6w74+rSl-i#^6YB67KeFjd%mK>U2)~ZUHtFf0)XI2O5QtwG^+CTG9c5 zqYIZ%*`1^hBH|P{GRz8IGS$TgMv&O9$+dAulpS~6nBlT+t>olfJ!4*{IIMj{7;gA zJrLxjuqEd~6OQ>KpE(p?8jRUNZ2Rx2FZ% zox#r(`=UN~CXxI!ahMEueUGyVhURPIz(>Ss0&*o~3N32>4p1dS=o zI!_|RQ@s)p(S!ug7qoe%t*Jy45tb)I&mBRsnM2Kl3k z@F=9ue|29xZz{VUigy7JU!s$rKz?P=XhVE!rD~PWw_88PBM8!VoPfgnbnxJs%w^CuisycjR!b-XbwaP`0wZwh}@#EfHar08c^~b%jz|oGU9Y zt+@G4OB? zER!rC4=HPZmPR8yF$a}Bm3*GUf3>N_}XxSMQ2#U={*q|St`3NvO`u_L&fL*E0G+}dZBvy*x{VB=ODqgEWI6o1}<%c&=2QU@3e>oNIW>bW*6-Oyo( z5K^D4>kd(7YT~l5mIM=RAi6>LSBC4(N?+R85jdTAbAC1Tgg~GS-pGM(BgWfmBnDR+ z9d*mG;!M?Zc0tjT`opj{b5;KnWhaU^m3{9OXrQbi&_;UzSitLH*UsU93R92+%a7(a zWw|NME18q$0FC1^`nb`L;4{?I?&WwJxG+yXh<`bAxS|%HI7{=~&V2)v02HIc$u>Dc zLXJ3t4G;W}0)H|EKhPFZ zb{>9-fCV5#rk44|+jvU#t%`j%SE1d2rvnt#mnhlkicnxe^{omdj%dtqJ=0yU#i;p+b=JsHi zu_5^5qJD#@Jf4n*#iN{>)de8y9|s+>U4=Go#yhWFz%UR6c4tCv;H1r*5*IuKu2)I| z8D+~ri5iVY&!F3tb-*^Uifrb%Qqbc&Dp=GQYf{){$otXOBaR{`u!&POHpUP|tuyPn zMw35yb$zk#9GesV;+qpVV847-CJ`_sS$v+7JM~*zAiC6f7}1jv>n&wnJA`4>A`mYd ziixz(D0)qRIR5q$%wgubpBZ1;Xn~`hY@o_{7$OLd0XVN@w z@@%68Bg2+YSkJy%k4pW==>mdtHF4|_NB}J?R^eb!w_~>lnr_uYD@3PEY%`3gX$MAb zKvoG>@r#pUew6RUrtA!^+Z{e?JSafE_g--~pA2|D@!$Rzh%G$5+S=b&B^Sy|uL^iC z{7DR@GE7KCIZ>;CbW}vYWL+E){ZZnPklU=@W{%| zX6?V{IRfep^+iL>K5QDciTmofob#hS>3A9cQ3CDrXIbB^mT|NkYRHb5*&U(OFI@#c8i&ZX=8QB0 z^svitB~BJT^~~aDUt^h7{{!B{8aRDfge@4}WGNvssTqU-7$n`Vu?SV6Sb@I&+pyM# zQ!Fna!;F8m=*Q8Z@1cZK%HAXH$t>&iNdtxcKSI}m2-K!yL$M&m40NFkZQN3&;bOu( zfo4;Hua6b8%I($OzQl&wII4KkEo(w>*Xj#;fy-2}*U6~r1keaxs#6N6JBR~60F4^B z*||k&xlmxfO(-N!`VH9d4gK3(QA<9d?Fj#zUu5yY8G>1?f(B|>mxCMCX=`!Uc2~=8 zhAFG;bn>6JiobVL8$^8i>Vo+usXX1x5wLS+HQ8w}1*0nTOZ9ry#B=j05$uI0(Wz|J zfbmgSqC&MPSE({etQsbx3GZ41m!p2kC2*1ApPo-}d7Btco=ToW7D_?x%7Ndnx3aN} z9|8d(Amhjw)Jc>R0+bNpeb(Ct6cAEB9(DG>a{K3fKFz})6(SvyZ(v}s2gIxDGmZmW zW@)fFQ4L4z)o!7&2X+%y6n1oc+NY;Th$|L+w_uG*z$QAS<0eBdtmxboRrkxl6=9WU z57N86;5G}*tXyWCt0*8~V!0;K4RYfdeTiirQj)~1LH@!G09=S4(yhe5U`v0>m6S$8 zT;`lGh@>DhF3iU44}TMb?&MI2;8MH2>T4#Lm?n@4{o?6y@;`ZD{6=Boi-H*AXx_44 zFunWDSTy*&b(Jz7gwuBzH-w-A>h0z8FqRltUHFJxlfyKlf2hW3O2W_V&Aw6@s-{UC zQ3j&Bt>Ap-o>&-g;l4j3H(`b319Lx7v4HEckjmq#a%gX^=NC2^L2sE20`ER*ena@} zxj07#J#AU*I>#oCdk5NdgA+XV)3}ru09;%*!?YQG+#%>VJL5hL3yA9*M4tbENLUKU zPj4t=ho>cNi^O|nIzj%z){C$Qa{pa+<2~EuwCFsqPPz}V~S~Ta1O&Kga*H6HSC2F(Ub?`ZNE0D8}0;Clj<#Nu%Yi))o zuZiK*kR*ix@3uM-@>$~#&B)VpW8~RR72p`Pj_Zw$W`H-!sH_b%iNPln7{>th#9cK)+}}dFKnUk&;4s^QomEKBCdM`sprMxi>d7M- zuLFybYL60Scy&kyQ?o!7cxuJQ4Fat7@XQJChTCZk|3Z^>N8MP7@Pg8uYdhwFWs_{_ zgH4^Zv9D#laVf`eH2{BP_{s}J-ieXu#5_xIHXbY|3#xUP=pYkNAO#UP>S>P=M(MfstK0Ou<$bN*e`UUkF-WU6KoE z7Dut(-$34SiG`TcKN`Q)>HXb|&b@S)zv#X;-s&e=naPjO2OJUoDiQ6nYqic+1gV@J z&Q;x*LLu&D)3c84T1>Od#hm9y^1Wqhv9Lb==op-#_P{gb@K_Qi{iDg*P!M4e2Ytw? zC}oQga1{Yz@DSo2-0rq=U<&D@!ZX(?dhPupJ-Qx*8)Spg^crG_(2j)U^9Y|~tWXnhUvaya;fJ~xIp0Ts^4Y-bR6418H$_aW#nhK0ILQ*H{>sra;o?u&NqI75@#h`9QQK% zIMg!6IQ}nGwi_8kPm+R}*e-~#6z@t_t`$H-vq7oeu+{upiOD&Aq)rJu*_213)Nx`Yy3}`74c}t}V(9%ewf&X) zhT`iMrHu3jDWW`+W;3XCN$%kEzro^biL>7u&$a{j)%UpJS-%i*VT>B1j`M-_i3?KaE39Rks=T}r$7 z_wNwVN=e-FM1TFmYSzB@u^(8$c=c2;z$1%C7!)-$leM7#2J{r0V@ z75x5+=aRJUT6hvS2N@Ajvk=VSvwJ#{%D+ryFqk5_l<3`ns(;zQ>aa9Ocl#y1j+xV% zj-Y;}@G?ZW-^5A-jk_5&&%*AXP}r%-Ee=))5cQ4ZU36(HQ}TapB!ED!DKfs2nh zoPcL~a4&w0I^fT=ZEj1aeKyeBq_3VKdgVskrh`t2^|vy7^iBqkGV8RvWGOFh8<1`A zqN#2REWYHdJ?#l+ub*HQ{@#pNZj%c*MJ))WZZ^17{)7^h}&=si403=rWb5X0u{UuCMvT!4&6CVjckb+6xPeG1y9`n!U5 zj^UVAZ1No`rG$dzUwtiA_f`ves#w&2$t3;-Uf87W`2K7y_pZZc^4JD5aXJq}O>NAJvE`ASm~2zd`QdLhPI z4i9BWmKs$oYN~}C%vZGY!8%(t`3}E-qj9ezW&pX>Qs!a#xuWho>i{pdhQ7je4G3pZ z!>!Srw4jwGz7@?BhtpZP1LwQ4)TnDVvX&VJ8hbqC7*%+vw8XOjF_4KUtt<=$R`ngKvw%vqDB^0-m`rD=ukL&txRR%)_e#E=w?9z zra_~c-UR(kvr(^|dRfwtRZj0}bM=c)P{e25-*^=G4x}x|<57Xh&1V<KIh3dwyqMEia6u~gr1y@9eb%|-#-NG zN^qUrjDaWenK0XTA@$@Xy4}GfWAnk*sKoIQ0lxH$rjZ zCWu*HtT+x7%wIG==86N=G}*gVT#`zI7pKCToi8*s7V5-9xTrl_kJfm1qA zXKN(u~r^y68=LPtP-{#y|m79c!fpenPVVz zGbOSeBMlS^Wbs18kc_8}Cg9%f>VmTQre=dcX(ED(j+483?;kTNMeF9>&>!@Jf09n` z@d!Pf$E({SyWU>lrJe&j$AO0RvT7B9G?uoijv5GD5aTQT085?^MtVHMwGmXLBaQ+; z1Kn-Tp{kkZVYsX8ra|>HGDm^2(iEt9tQi;zQm9?Zui)Z<+;WXsoB=~dwY+y^gKl*H zpeOW|i^LsyVru_Y)e+!(f2dNGcvkEh3PD#}?`FeWJ=?DPmR>3l!ibSu2JhY~%YRkk z88eyr3HSfG>?;I@NSRi2ovSR$UIz8+pbhoRuOW~pB$$aQ@Z~qP*B{{dQ!vYq2%6B@ z{&JPEpj-~CAx-bqbkwVBv7H{AavVA#{jB*4YoSnUN+~@Lv&`V=7Fh_ z499!f>9cr34@!Wbh_5U6!?_;CM8{egmUAD|zK(^-J3o7`IjkW@MuN9zyw ze$#U0pF&IrLojIBZx;@8Wa?i*{XuK&qA)<=0K=ml++a1C=P`r(y`k&Z_8>3th`{RkHD@GfAmSG&J}2FN;12+T-X=~vxNnfH zs|1x(gwX$kv$NU#=$@4{sD0eO(*lTCRGd1XdxYlFl+b&lPBb2PrW1rzi{+1g>&_VZVlHkt+Neixp22s z-hb2qeSL7l=Lrzf2lo1G;Hfgj9nsTQWeQdy3!>PMe)-n@Uy}(cY#T?mZ>aU{-$NE2 zJQ+jy@X*fIdtMO{x{t-Gg&$7!MxG59@y`-cw!l}}S&v3k$#6;yL0 z*yIT4)8>CYEor`hLO{*Gsnvnm*tB)x%lusu_^z1Ezc=5rk{YaXMSqW2+e=%Syymn| zw+PQpfIC_M3>2GCJ>;Qf1^D=QVL9Iaa?vsAb})3)*JtXim4IQvRPMTtFQVSmEYqXT zL-s%*9Ga~OL!$z?CxEB%83!HfqwJU|eBC0d2JX-T2LC5(uu4`b3ygy`59=H zQ=*7YCO=hBV6E zNuEV$2bl1W13ek$;ns}%n|xjxhT8ZRu#jv(SEm#;PetfO$Zy@tf~VFmaZxBXz_lTxE}cLi zBOG#I4qxnY-JskBXK?~Ni)XKmUMoB=9Gv#yQ46B#W?cmjn+F} z5O6o?@}&no8!!j>t+A{=1JIt=ag}j{&4Sxn`-q>KfS}nU5Rb>W?uw++%yHR-A4##i zbz`AoKj;K5=2yI6w0)-zN}?TdXRisPhu(3}de5laa}*!^umH4yInNE9QzjNox+!v1 zdW9!WyKMb6Sj_s7`G56rak$OtnM{zK z27go)zf}K?xjh0BER{1aVjV6mexI>y(mq}=AyF!N%=q3P%w#Dl^@kS=e<@r}P0Sa6 z#>a*5K5|<%pxX834H9|b>KaWV%+W`Xi?4grLRs%}Wk8itM@kvaw=_H(2h6h>+=2#7 z?6)$-F0dqOXN`AD*4|PGm#J*M3v-~a;H~V>sy6Lr@m`EJFRQW7wq+D2s9wm529?aY z4q;~o)@cj0#_hKC;*R5Inq9J7=V0f*nW{Rf7_Og&cAw_-iiYA`~U zC*CZgZ^GCuE(_d*LjC`Ofv@2B1dvBqRb6T{TPrG`vLuZNAzqnVz(OwKcO3LdjpYgmgAUf`k9@ zdn+z}bj#v$q~tfUAcu2e|6gDUu`p5w2gzD$oK>DxFeCvN3; z|0!v$VcB_^x*{fi5)ExyE_pgK@^5W&a{kyJHbe#dp~bf$xZ)3j&acvIVty*Xj>brx zm(ywoXs77Whbf(_7|u@dcgoXRKVeqxB&}5)7|nc=7H|iKl=D!&%nDAi#5w}C~)Xt|KOjUZK*$h@AM0f(R ztFBhS4}3>q5CN$dL#`+x1jvIi=v|A|fTr9K@F2+g)pZO8i?b475j|#X*xn!CE7YOjBI+INka&43BUVeYnK(FF8&7Le;J%edf%l{=rW)R&;xu1iQ3zbOykeP3! zy1OTE7*J^$&#r@(o1EElqo3@y?}uYkWl3?77Wy&h>$OUoIdRq27JYyH9{s()hgFzq z|Eh+(H$zWctWR%ARUI;Iq%}6-n(WZR*Z8L19Lw=4hWQlp!acLDBn`W-K&oekxr)Y> zt!wsRtZknugguYdem_Vw8w%j!Y{cG-5Sunp=)=2z9T>`_CJgE^4vnxP994R}Vi5)( zte7c=Kuxnl=9-rxoC~f`WUU`Pr9964Hyud7ixuco+{VyC_gROE+3Km+ASI*vR^HZj%GitC;rOn;J+QM~(1I2GMD3qM!O`w?^Cm&#>KRpn;*teZgxz=40#Pp)`2Y zOu8)mbpjn~1N_|>ZKq2s#)D2cf-Z6h5L3*et;FrOhx=O!9Yex_qh@2T^g8h?0r^vt z%*1ipcgGCV?Hkr%d;$gy8FljNm-}M5l`m$>Js^!Tjl3NCVoI0xxp)L4iyQbcgL@LZ zGXn^tF-2~oR^jV4@~S1B%ZB+#TLVpx9y`p|hp=B`7lUv|n4k z)Y*-86$;1D1+?VfFqxWvotBx;a4O?dNHllQ8kdW7zRv%p5fS)n82zwzMNR z7qVj8r09_9k1hGLuco&X$pp$Q~hk9V_4a z`TSnL|N1BAoaed6bzSdOXjdW4+VnayqaoH-%=m{F7Rg5XPc(RorfJoyS>DP=+DDjz zbV#nn8;WU|OK5A()OV#S8$ZCeUH@nIn%2clK0%EN9M~4+8lOd*($@W0we{kjQFY5G zj#`;yfk`5nPr@?C%Lleh2Y(yn)hc|WotJwLj4_{9+;FxkpqUD!wSldUwHfF?123^u zH^;MA&bc|1snD-{q@vrR|5@e=%Ed6CPnnZOf5KZDvYX-iBr9$Hru9-CA+Y7deaJV5 zV0}8=8QaI2aNaO2;u6%*k!9)j>Cs~@Ie1$JsyX@NBPC#J5)25?6Qo45sXIoxIF3%g zvD@hfxtEFJZcVbjU9dTsP}~}!cVa#CfZcCS3baq8-TB4P=7lO3_y}4|) zbqI?%3UWLo%R^E&>IKslz3RCS z49YbVY4$;(|1@zA0a5w_VMx1fTA`UWEZe;(EPEap&x-}$5Bhtbe3GD{UW@=ByQUr( zeD#Oe?<%gUnatNeC)k}Q@SjgJ`s<7ztmj<-Aj8d7v4kiX8YB7lmX;G4F0{?pY&kq7 zvgFOwyGGBnK|<(A1f%FH<9^oSbKqj*{9ofyops7|wQ`QULvWO$W5N*^@`jLhFs)dX zSu`L=D41r=*t=!v`cL7sXg0|GbiE|T;q3H$cl~VAONn%k?yj?&X#yT0`bNBjE%=y? zw;hZCf88gS>4Qh2rN4OOSZf`-`)OMB;kY8YSHSK4vUuftlF)D5y2#yfpsoOEY)SYB$D9ShRIiF;~w zx()&4b=Y`vErzd+KZQ-paMyg2mG#jo$jwveR&M_KXlkm>8E0w9`WY~zn_55)$Ln`d zUWdJ3u4}Lx0rP%J|4pAW$Dzc5+dcrZ*h7?VA?HcGr*D#t;}@;DyjLwAlhL<~sf7K?vP-=Gd_Iv|+um ztHh7k8utehEqvF>h5XK3Id0(6iFR<|PAb&aHv?A99QIknm@b&ZG%$hmyiMFEK-*cR z_UC++{c*enNftagWd)vV3*xcF>xM3)b-%^QvuoR&0<;1^Vq2kIeArO9SH?+~%gCZuZ*h)%hNeSka|v zoIM^m)EvwY+6#(|$?nu~v(7?#^4mKo0xe2oEqSn zqCe1*j)7HlOQH;%fsa#h={a#j`zElCZpqJ~U8j+wkjj6L8OyV5Q z2e6c&8kif(ewtr0dTezk3LcKC0-A<5w=U*;b$$+k7`SlFf!CWte3!SNYa0f={YKXJ zwjZK|bMgKK#ol45FNT+N7*A*Au&>d*rHOk%niNj6!!B22wSwgH8cxhT@M8BE}95rvM7 z>ZsZ@)k(a2-oKh4el?OnN z2j+LdD=dC7X+a*0OEh*Xjz1 zF9LXziRx4Q`wxUYiz3TO*TnT}jRNjpe#IuFfX&lB80$1Vbk6gmZ0@Vre%m5`TYbtVB>++|B%w_) zN)V=k@r$oeip7@S=c6F_ZamU5#k6_z57xSDulU=7T&Y719Ph@$Ey0QBDmd@b)het^ z!B3@7ei7Z@_k_V8=IXd+_EKoeU9$Ykam3c?iNorLGWUO4%_^!S^gu?TBn_(?? zWTcb%NaajpmMR|cN?jixj4(5K0r~a@C|0zJQyy;2Q}CE%0H)*&#s|7pVhl5SfwGht z9WY0y2CF5I0qnY+;;H7ZDVh%kw1ZcHH4z-qReK0;om~<3U#KssnhZgsZUafODo7KN zz7!h*9y;o;ki!m1SRjbcf)Z;4fS-R^Ntxm48WtQr2_`hog^Wnbq*r3e)CrjSd7hY{hnna(H(jy8Pyn~@2> zAyUOiuQp85Cv`vM#DJvv5X_vZ2X9XIew)G-_yZ}>)=fDAhNu_ z2*h10CizJ%%foWiuMEIf=2k!<*P>TzL3Bo9WDEE%D<6(PwCLqrCSg^@n^A0S7e|sh zcMg1d-%EbI=i8G5m9>MM$rO>|Ao+ERfy|vKv|xpz9!8c#@Czva z`vnvuq#^X-;BQ<0f`*7ng{o2$&45znI7}5xlfiVn4tyh$B5*K>kWELEdRi)XqIMhS zcmro911%a|Ga+h6mbZc#&eAQA(PcyO{T?0187EmFwWY6v)>RBe(1Z%-Kjtw|S3$Lw z%HTB^8lx89M@RuoRDplT5f^_EP4gKuPcIvJa{wbAZoyFZz2ss0rfJ)dgG5ITQNhDeW)On4xkXx?z@fN`gdS8NQ;k$b{oY6sx;KUh{qjGQu z3D{^P9m=rL1Ve|m|Kon%Tfha!p7F$& zI@E9Tzc`xQbgw{vphb`g9Qd7j) z-N90)Aa>{3$FIfYV8==bC8$t#9RhLTy6aSe90PEpeLOA-3MB5xJ?A}4AYv|_a(?rv z1oQB)rv_r_P{z?M;tc))q}U=|P-s;Ds&eJ34Ecpq52QLQpQ&kICO!!e=h5xmw_tedy%#m3D-Qb%L>pp&Xv6eEMRsH?E zOkcXqQkgbkp(718Ddl$-+ZRMCJa`9>A_GtbRFb(XT#zBGqF5ga!uTALA#zY%FSSd5 zIKM+(z+E`H^Is?~Sl1--L75JjZY{&B_h&DjxBa_x@dgk{Hh2qWOjL)n%&!S?zIfXK z@rE!Y=O|rywCCw`8!K`CH1H~W7O41s5GXBeYW>~-%<93rRQwDFZ4KSefc%y3=|7Gc zVKD7)t-2Iphk4jS*6SkxjHc61H#h~!t>sJQuQmbGX54bGtLZPOUPPggrE3{Fj}COD zIZh+b!au%Q%ydYQ5CYPqOLQE2dNi4y7A>t_;*)_qFnB@P!A=M41Y$Qlv$DFDQvS$~!S9HwDtY+l9*OeI{){PhN+-Y<8vjbzSoNwAJw9WdP40|m#6 zEGzi+{J0^XdF#(uS_wh$tQ3^cz-6{x1swbl3WfiUf^bk=nj=INpeB}H%2Rt0@kWdJ znVOCMR`q0acqPbdvMM-~EmTgsdwo<+OxgV2q-{{UJLk&~@0ZASFFWNw=BG@uZT-+~ zksSK8e*Dp?=!ZTo3=u}~LI_3S^aTO_z8$b@@`xi~VxhLx0K~$QOA9eCK7;|SYT7?} zjxqqpMibtPY63tIk2j#QQ%TP-DZV82C=RQB_zJXZ*@_Ys5={>c&G&-OUI7-QnBzwS zvfxh;8XR#AvJzaNX##j5&0&XWIW7oR7L#Les^Zwd<1WJvoWk6hA9MaX0M%C}CgDSE z64uo^F<=%N+BhI(YcPpS${jm$a(>ISwC4IBbr77DBKOq@SOWt6m%}NCf#)noF!eU> zirBAT0UY4Dk;_IT`qmS0f&fWK0S1Phi`wDLxa8Ugq#(}IX9wIuZA3pF_UwUrTm*3H zGZMeX-&c|}+D9Yv}ciJ<${q>P4F$Rd4 z%!L1;D#a2o^26$#Kn~#BXk5q8(iWOVNTzl#h*po5&P(nAuI}Ce!@6>!RI9p)fy44~f72!=%BP{CDtnziue_1sHlGBca(88*IQo!~+}zQTvozCcuY3eGDsn zTJ<#wxBK?p?X@z7Td9haKgz@VZ%v=-XR>6+!m?96ZIPfr;h_*)x;rxtG_kioA#9E?44}Gj{i6*G| z5UdvJQRV}rS`Qfs_EP2K{U$+Ct{{UVEkI|L<42Iuch_IU>%`fET_mLV>nP|1s8_N9 z-x!H}XM{4EBRD<)1$@Q68~PGFORf%#_|Gxgw^{j!m#7sFh|p<35^pNlW=6K6&Ay2< zcnT_lpk^5f zLdP5ixr9995kygt3LAjj0w+ISv^AMf*Bt6weqZklUu)<5$H))TEz5B5XI((TOW=K{ zp=eor=)q%9i$O7KIy>7GoovG+;+w0Z*s~qzK+&r;xwd86=HEj0=G@vJM5(&WT4L6- zA|lSXE+=D-4+`Rdql39W8%}@FQWEklS`_<~&A0QnOGNndj^e8i(R6w>M_TYb4=-tg z114|xz|HxXq1D}DP7k&X5HSm4*f>=cDD*Z!JP1c^ggXH#`t=|FGTjm`BacK@>Tx_{ zr{XkdWTcZkOw8S(BwdD)#Cjp3^C__v3X44YEmtdX&K`CAbt;+$-@y*>df!+wkF?Ja zQC7F>aGgU6Gzba%?Bu2eg)X!BD_O2>)PUNLbD1kdDqub-n@jL zP}$|EP&C4OkR29w0a!1nA5o3v@X08!s7TQEfM#JO*4&!%hC>$C2K4eOT%G{KkF*Jp zp7mB>^ocPFFw5YMx$u|C2HR3;Px5k$!ffYBaN+_nqF&_V+n4#P3?p3Ymm z#W_$wKPtFup^}JsP2BZi!|WDq^MS0cCq@Q)VMzg85h`w2?6G8|BQdScz!@rw;AWlo z`sd~7@Ktcf9iaTWe!{nZ1sq69iNh_!uWQIJ2_*LBnyQO3I^SOdwx(*}nzu zPC30tE1tSbmEh&aoyBbf(uaxq5n4G_lu1dw5r;;@iatHYTDI-i-#{gh#r(F6^wLo0lVCV+AecX~w$#OWR>&pTnkDXH=l6Q%LWQyv~2VZjm zA&y#D3hr`=k!{k8qnH)B22pq$aHp>TO8o8V=q_pc3-xrOfYa5h*S#6u@GFo*LX^%C zJ0;H188y_+l5R#abesM-xGJ=Y26_Svt_!U#v!GCrin-(-Py46Oh>`l{6-an5LsUzM>b0R{nV|P4GC(q z!I?Mx5E4%t@e^zsIL0b&0dDaIb=eiRIOu&*I(VNrgkN~h^@fs`nAHy=Obm5k1@T}R z2ns2dJmcgkRm2O1l;Y~~s1dTynKf}a{^tGPCHLp^KVx-LPe!psOK!^t4S_+^bpHqZ zI&qdUWJatgq29&bmwmd^A7zgI^FbmaF#?Gw5CmrcYVxYA?H65?Zxt6Gs;7Aim9_au z$rB&Yfgf+j&tl9mAUqxoJ`%mY+OZ5uppBv(nL3k0L9T9ESn6LAnTVT?x zp}^i@T4ydR%4^=TE+tdCNQR_G;ifZyzTz&3}6=bGr(NfB&v8O8n0E zyfhsVTuDDPB}a(L@KjVov|m*NOm?L&efruP*tt*+!Lppl_leMquB`zlzdEY&Yp8)K zE*!jIay0y9<_TiKrR!!+arGBvr08(Gq(%^|7%rZ_8utCgLfNiraU9TGydRfT92o$s z&i17Q;}TQ)%fovzY|8VrPTq^ZCFej>;wG@8D_uq67)Fl~IX{LBx~ntDrsgOJzfmFp+dURfe6m z>Vd!!r=lF^yNE>{(zj0DcFGMCv)(;^Z6oE8hb1kq50Ote2u&qm>{)^(J)@RBz+g7d zX!BimB=A%(x19b8xOT~}UfGS}btxlSqF=y02s@}(N_oov-wS{r@GkbLr{0nUqY;`^W;bnk&=`EBNv9T2{EG%K48%k%?W8k$x>5>`++3skl~2xXMuHsBc(3>L7p2Ri8V z7t+U)MI|Qh?jhriY5@;mYLaXXPlKu2Bz&7VQ6|!3FQy|5^ma%S@&b2a;g=^k_LE(9 zH}0ReN{-|U`y7s@Sd7OG4$%%lsr#*bx`xs_WS@!f?m9`T-?)*8fN}QCdOs(HwQ#~?+90XY~7@2PRUq1i?%2J^T zJh^|g_cn9UQlZ*eeKYaV23|qXEoC(zGnMd;*cQsc>Vr?;ya7=*P6+?<-^cdvJ--%G zv zQC$jF6((jtVq)}h8TA`PioPvJCqmR)LygA6`K9CjR$U`%k`|~pd(MB3Dh<%IS;8tY zqwD4U{HLH)Q?0Vs2h`x%pluyEO}M28X>Q*^l~v(!#vq9DNE#L!2qP2(S@7zZH7v?B zza;a#1p2&we9#sT|H+82B5-Ta3?uns3TkA8Zo1<#Osu$HfH1loe(JgK>*E+MZqq)5UHb}`+3VsKO& z2oOX1C$e0&OX3eG1bj2Z5Zl4FTu57w{6nDd^Z79qS=m-+HK3(vd7|PYPZ8k%_n@WQ$mQ?P znw3@=&lN?LUAYG-P&gwkm=~y?F^PpP--RhfgK#VvXYIF zyMKlwHUTX=ES`bPJuDRm$R_f@_(coRuK!N@weYU2a0&NOVMkGd6J?-)aG)X_;!mzD zs(cr$?@BHD0!Fe$+X`cBlVBjIvL1>hiQlC_Tjo1fUp^U+c0mLBH64|1`8F-^>N%iS z@5MTPv^+*f$ykhL&!ejGK9|vL5a=G*(#YXm;=tb#fnws_EL@G{#n5MZkI@N~b*@mU zsIVtEaYzdYtMdQir7s=3v+#6ZBGvGgyK`a!t3F#ywspbH9suB3DdsmQ34hT{Fp~$v zp%!#dWeYf5B(ffTS26}wu??g#97iVK%bUc2@*5oM0Y?Xipbff%`wnmRbj4_~w%WN10KwF6Bwji97hx=rmdJ#b=qlh=pnk8JzEu!290i zDKbGH#uN=|98NYYo_j1`3d+~Jo614ieZ*8e2%!oFJp5nYuj}c+LLLPL;ne%V{D$Aj zSa6nE9!H_)&CHX*9_>k_V>&VAT_!I>r3~d40p!Bd9-pK<&Ax0!>KT{tX%>WWjmOs^EF6V z=3yj}u;L|sHCQUAT8DZXwV)%q&C7}6oMH~@&8$~|(daCIIX;pJoKemh29y5~%q8(o zKjjgiSft~SI4b20!V1qyFrQAuzoKopU1OAO$bu@5!FFPv_(if`;&f)MWX{+r>AYJ3 z{;=e-=hcmA-Q5C&^bR?mZ#wNj4jPj4zdvovWCq-+Q|U^U>Oyy7%xNs3;Ior`TdIZS(~A@RY~1n~0@+VEMsc2P|$fLA<$qxm6+^m`;MD zcoK~j8zKE6V>&VsF%mochXX(v*nxl@VtbzsTRqo;PDtm8G{ zfTS?grlq_5!t|-_5ZM8r^76k z?Iv=!T{_F=1u{4UV&omYTs~MYbic!+|K5ya!Z~;W89tD_1omL`Q?GF|q6Ox3iHKo; z^F)>z`^0^)0op2`CgF*OF0Zjtk;byZL z!08cY0Q;@i_+RzyCEpLguP3$Lx?fJE-C(&rS@y=vUTy#cy;wrS!g(2OJaZL$WDO{S7#kgGyZ|a@X*DDH#19()Jh_8rzYVIVyDADW3Df zackJD2jvR&JbyA(b0;S0ZG_@x1(FtefoRp3%_~?9Duy1{E>a#2`)d?U$BLhlx>3X^YR#%2M|~14-*J zO4;;GVU~K3jL-qIe7=b+i%#g@- zp#7xm+fxnmUdK|m08LawaFO;R87a$aS0D(UwLj45CQQ+_k-5FDyM7MFcxAo}uOaK2>myLIAj!lwV@2T;aZxGWg}5=K{v4fH>F67A$7~_Q$y$DLGZeqU z(}(6Vw(6;F6$a2d%Tk&P1l*`;T(#}^?$=?Qimgceq5^mkE_#KJ6NBg!{JSiE<5v0# z{Ac#_-sHU4(_)Uc6zulLUYRwvqoHqGow~Aoh2Co0x#mu~h5~E%#0HxNj@pr|r$VB{ zuDw~obysAU9*{hsl7iJn#q|9H zb8lHHGd0A13)`sq+PUU+#l|@fKTb}$`JMGrP_$nzzRs4X4xlWtU+>wvN_>j_T4sOF zb>3;eJqqDb6Pgu;Oyn$fARz^))NL0BnM`qJe7|N6v4#EP+wGG(?m+6&^>VvT-nI+8NK2JyNrA{<_4fiM2Yg?>udo!Lc5 zl+p?^D;lM<59Jk1q=I*WAS@w6n{3@ z&VhB1V?{@_W5GUGxuM!->TshDsy0DG7q-O<%=bXFp;5bd!4GnR8O4b7E1ZTNd%q4{ z9VgOH>%70fGp*?(%cg4WIAZz@G~+d$Oh&e89UZz=oNHCY0)_BT9rb0PmaUUv3gzMP(Kn37hb ziGMaTuN_9P7Wn40K$k8U)Ccy>Z%l5dk0f{KqGi>I+4~l$FAl7F<%F$uE!nReKzEwR zbO>-bjxSH8B!8Z!i|9=Mh^Oo$X|}@2MdbCGZNW&(S=y{OzTLY7BS*e$IJF*M$#*Xm zEhv;;;&x*sI~&kQ^gh=sjxKe-X-V>xtt`>J#>6p^J(zlb31@Xs|CrHx_ytOwT7Plg zM~4BhlStydrQQF_SZKO#p<1szy0JF_(QuXYJ<-A zfg4K;#ujW88Z7aT!v6&&{^93pZnmWRhwV&`Ya|&M+vJXvRPOK=VMv2$gfNX z(=ytcQLPq<8V-9bB%(%@gt-~{QPDh230G3*FZrbPB;M2pC;F(5XLR3eS0o?un$#ni zqQOCBGO)*T&RF}9gIapH1z}E@5}6K@#E?m*rJK2{dK%vHh8ZoKfRP36A;asd@ky)= zOCFK;jn!sADRlP|0P~^^k9wu$?0HelCbcIE4L8nw<|GW(dajexviFr|ANtqwx*9jd z`WcU8D)yOJNI7LPpoP#yzER>&B z<2K$#iXr&80_G;(*||uf5v6FC&Ei*^FcoPBX6H4r8e}|+65o^MqLNuws5V~|pon%B z*~C}ZG|1dUtW|RBWdQIk5qtP^k~Jiy`x}WA&aY2ByxpJWBDGnWrZK|w{n>QB95gPxjS!q$|>YX$V6Mn4c-RqpfBA+RX;ICn|e}T;3ALc_B zot`uUJ^?jyCVCAy)gm*Lb1W2dING(8r+;6?eapwBL%6(+yzuI@L?=}Hq6hO=3i9L6 zqEG#eTK)KW_9};si=cg_$`~b8rLnf|YoaOD^0<815r#4QS?$HV z;PkDAyZm%(Zm=vP?}N0}%4uYO+$lEKFM=%t+$fPKdm!Xy?UO??u;;X^P03$@e&;)& znn}vj{uX!Rm5oA%hk53RWZJuWApZ-7-xqz1u<<^&t5j(BXY0aYG?}`*Q3)&(0N9i2 zdn@w!4LH4e(&d5zPZC1l75vAFfg{>l>Fv(Ad*WzS3xT~;z@7JckibU5X^G&1( z&XDND=;M*cz0L!IiE3w<*zO^URV0VQq6Jk|6bOZ$ddX?4KMR@d4B@wo*@>nTQ;(0E z*q)I79=Ra;M(e>&jkNg~HzoO7)1u92hj@R6T zTl`hx=Q=ClFy0baZ)R`%3z8WS7~+?t^+ET7Bei6DoTGXo+(Aod{jdIF{Q3{8ryEJ6 z6^`~<>ruNyVCk^}(EIl2kC@~KRIup9B^!R>J>V;%;AMTvl=kGL@+$XS^=#mGd){bl zI43Nl3)wN;jKp=*`%R@@ZbtfeF#zu)Ug{omGBv#xALb*tZ0ATvN#)^{u)oVYiLR#P zauH5^V$0uN8Zi2hcV;I6-Cs|#nG)4uuBtp7FPAWWAC1=P6yr}=Fw7Gflq&=YQ|t47 z!imIhb7gVcni9$VO+(Lry~^(MD3v?Fu=R+Uw+{Ocwj4wH-x|hSKaLFEHk7sJC2s@a zu7riuSzVSeP8++=U2ppohV)-b8x8Z)EHtGD%KkEswNUrurM<%)}8vB4yDOS54gCGUS6AD-@#@ykoPgVp0PvW zRRBwc*+i+s2@bmtMtcTHYtEyT z^Qc8ej}4$=O%{F-uDho{=l<`X;x^pLlw%h+Pou4dlAh^{O|Ns(QQ*Wr@Y1bo6^U>-XgM}LFsc!=IUHd^b!IJI@9EC* z1);UcqwcP#kKQIsA?&z)IX*c&6C-A~*4wkap**yycX}y^I=y6pRcR+D$kMrdCV!{e zep&E@<~QfDjSKtLY}`{fJ@X`&7*z!rdlYg^&t2u)8^1qdN(>ipXqwZ79i8h`n2-Ow z2YsHxi0^rgnx^A5xp26# zO!yzW>~nqv?YrZ%iuqsI?Pact$r!@svlegu_BJ&}A)B0%{9RlyFyvMjKFh`5+8DH3Sx zE%TI+{kkXABy}VWkgfO&)PV*w-}@}@+Z-J;w*G7t^852JMbfPPd=^d|PbY7bD>I+qT(>J6lxNtBg;7^f({r8`pd zz}iv6oFS232D5HrhHmuhsthtPCSB&jGFqSG7+123hKMD)ruqRzVt&6`eUjfr46!vHk)#L`zre z9Sr5m_Nb0Hac30ZY!VUIr#-I`<+6GGmc@s#Iq@G73`2x4*k3kRg8*kI@*EKBLZb5m z=%~YlLl$>xtsfLV=PDjXzK~O;M7{=IIK}={_M+rU`R1_5zif7i_$DM8WX0|La>*tA zSd{ln8@dlVf>|G^2OrGZF28>mIrVA*j614QZ}hzP_Tj&xCA_2xpD{Ij09=-O<{&>z zLiu7{V{(7}HMHcs^2rFaB3v(MSgXb~c4<KzF(JQ!Sy}pQ*Pt1NJ)8E{TU&Y3f z8I7el*r&9*T1e^vIsE4m!6D_hC;5QIsGE~l)X_|^G|{1e<)k?FOqqj?n)Qjli`#7L z&tXzR7nFE1m%y$yChiD?aKFVhea^S*@#lgIBcub6!PkEq{$h_t7OK+x9Y_)1_VRyv zjifVsCX91!1%fT!Fc1jS=nUU}i%Wnt&1)n73~CU0ISz#kXyo9PSGAY3rocXqIBVeu z?E=@|5g^r$;9>o$ zheCGTQyc%eypFr@7uI~Icy=T&X|wY)dQ=-?odVKr#%nq2sr3HM0eFk=V7DjFOTZ;s z&mB!9FwL1eU4}UnipJ4GF+6hc?#mY0AE4<6dT(gwocYbTQv<5)2KZ5$G77D zV%jn@V1`uP(B=kjA<2T_46+Qgsw~%MF)DIh%3-|m)2Y!bU8TA*7>=?GdPSO1dcyZy zmcLP2kliv4k}v=LP73p}0FDPw`4g5&l_YrGuLFvYO9Qd$!>!?#S>I;jFJn^g+r;}u z92^$G1(*cMH1;8Rsz_sulpMtlv-6x5$P_c4xt4kK1Rl_NKeW_-Vzx+!->3$w<$M0R z-jE)(QE;9&2MnIrosiJcY^|GkP$NYAOw^@Cah6>2ag$Lzn&ygG<)e67C*Un{Zh#&6UDD37!O+;e?K>^12~e>;O+N{ffmSFr->+Vsx&16l*^frwdk}+&`zdU z_ORI?Qdc=AVl=t9aC-}xU;wj@MVnUmI9nW|NHaCzvpJ+EC5A=*lql#V$9E(1%^yKs zF4@=>cC%-U=&dYVT9!ERjo{Ozx|h9VBb@AvF57l?}jT%@$}Hj4=Lcfq+!>v<2fn2 z&bF}=jyKgD2F(JKA%!???z^gI{-Gu`@e&yGAd~~Ol1II_a@oV9jVgVy57QCv+{e@1jTE)brpz)5p_t%a!treegSBBW>b+;o4xFbo zAnUtGdX|}ZVVq8p#C4JHU~z3Afe-U-3sf&p-3O;=j!? zF^UYDK}8vUqJtHg%A-P2AB;LB_u7uQUP%d~h<<^L@w4J&ZNM(cG3$JqsH9;%0Qip4 zWl7KI6DiO0Zto@kF}J$Z^g6C>@WC(9TNv;03?LFd&%4TWBa&2IzuvL9O@8gzjnkH# zXcZ}d$joNk2fR(9Dh@@h21bIa-u(>E@xRLzRCZl`m}18{6*^D-MF-~P$tf@vBGnCR z(}yLd>yEI{&7KjxH09t>Mg3}Y<6>oS*W8Y@!0p-&U>*xj#egij83o*0aLPZPqW=K73CQa|dq+{2SkyviMQ zLRM&D>avOBOUOZv>s9)p>;*#xfwxzSg`&b1y`gW@Cj5ax+0)QFg^t$e z>pcxRO8J^FZL~z|@?`dZwP6Xs23x5NaHcl!k_BwKs3f0P%H%p$M9BvA+ji}7RDb(? z4+suXl&mXj@(-d)vD__xg`E(8N_xh~9;2#=+J;bw73S;{@9ASbSgX9{+22``Pr)?i z5**v$%#i&1DKt@v3h@qL$V;FMO7XHoIT0f~fLGnskEBLwKN$QM74U_~c#eISieckP z&V0&J9aZm|EDDg2sUOX-Kq(#}@Uz^*loC_Qr-Om!i5cgF zYdkuA@}QGS<<4Oj9^a%8om3+R4Ee)r%D^b<>tco!TnC_3OYZs1Ae&Ykfb2y80L zDJou~B4=D=3gg?_Fq_~#{X467@WGs)+Lc^MmbjDv9Zvs|C=IF7rHo0Y#x?|*%4(0j zKKV1g5rW4{#6$l}`oA}UAn5ITUQyL32v}JaEkN=Rvs*qF!w^&`q}8i)wAyV%D&&xi zLqF5_@8(KPq8B(6X1?VyrO0IbT?uE$_(t>?Fj>fW{{Zv4nkUq*d}^o%KHIkTBUvmh z<fd4J8Pt~_@gxgZcZl16f)P1D8d4vfzer5)eS zN)qyOMDISOd^C(+N2M)$=ME;uqq`Yj3#eoPiGuW%Qndv3aK5<`F(x~lGg`vha5%Cc zB$|pypWjmRCindM>1fjz*Noq}V^YTzo0++pd3)RCO)d_a?@C!QM2I{1c0uWXOkD{G zI`vm-Nf~-ouQ1^L^$5oc{>_z%q^hWr%X=(OcR<1t5y)Rn<@Z?X82j>Ke+^%onIt%s zcxfY%n{yUn7XRUGT1Ouxk&0|u9!sww%3%)$4CL=?bp~6kLlN?u*IgEGCUXSZbQsXk zEI0~wQ&L|cR2T-VkY(N0>5mosWZdVQlZ7@{j0WTSKz8pE&PK|!T@eamBo}&R;M%92 z2+6s(Q+bN94NgB;A0G8H&z@D>9Lb_ts202cDW)6t#7EU%0X*a@p7NQS90N)--~6-s zChj!k?PE8049AP;s%5{GC^ifq0S*B}&RwuPUc}MqtfBVHqJrSUd1$kerJp*_{a%|G zV$k1zzB4^CqIkMxcC`_Kc2NOH(PZrZG*jmU`e;c5z!`I$qyDudPZoe9*S-0GHfHr@ zw^7gP()pt!2{54Be7-k7J0d)FSHLIRLjkhF%xAj$&(E2O0i%Uc)`y`|{1o4R&}3;2 zh~~OJybCZn`LZ;>q#DTgb8o-(Sd+3#VD5b|%1@y2 z3AYHiVByM|soq02Ym9C$nMJ32XNDfaf?dApKTc}lcw841H3 z%1&xE?i$6fB^eDJ%1`>hHjEIk>7Cqx{gP;hp@Lrmf|FFpIk0)Xt7y;p)FL4BL(2== z%`(@HP}^MKq@{8E%uDn+Oqv8k3&deKyq^A02t)`Gkk1U_`rJdPlRIwz94Igh`REHT z`G2%AX~)A3PS>yefLBfV`AHoGN}K*abPly0Cw_~~-FncqToA*HOUkBs!nC%g`4Bjm zk|xpHi|k$rOJ@hU!-WU(yyR4cle=$K7-vB}43a z>`&suK$+{57vIZ^5yc#&v=1C7aUVa~nX9Eh{h^8?*(LsG<2=ADn{0o?vcevBs}B61 ze!qCbwC>ELog@pG67yT>?0j?}YorwAY23zZzl3G6;v}}2%uiiK7d|f_F#?c6yOwxi zC*poKbTjWyYa%Ywl?xxr(!q0lGW;1-4b|sS&t#Y3L@f%ql=T5X^W^&&2(2*F9vqPB zk_KmV$m8*>-3}RYMP=V#HGl5 zkl-Dh%78FpQ%zk8_i}YaeKIF|pdzwimQy`Yo!NT^Z1I~hedik8FumVre93}G%I@I+ zAFO7w-KONf?vSJW1bY6mGO#k`C{@#X?JK3O0 zidI{f5`}S5elU&9^+Bi+ziOdGdNwjlY8qeVLgfbhAErcl4B)VE=3j2R>gZU})X^6O zSsiHeysc~3QV6EJ5^u}FCZzjYvH;X0Sl5kXu9n+r2^KZgnunta`%`1@6}o{EYE$AW za+oi@Xd#u|83@eeyyKG1(cfovWD1K^K7{+F7Bg$#RSSV0+CTU_$j%M$o&xs;*1IA( z40@6cz^h-jYoqqJzyDYt10HZ)3Vg5n%pJ(}qz1AtYBqnBr-=mvn#{z|Ct&H~@)3u1 z#zvxE9@{VwI5T{WIG>Q=-O+b*t6?|Djc0(4MZFb9FDRnr1Bfz-*^qxA;Y#17>) z&KxY@@!oqqqAf)khNiTNjZeK6kO|V9yJV&LnZ$;a>hy@lI3D6eWghOB+GpCy12cv} zrlp7u{A50`zZZSmt#dH-9J2rogpB#`A&u-dTi%qSEbK@vNLU%@IlrcJxDIDhBMv;f zfIY)-N)yGGrI$9W)i$>>=>FH=!9F+uMc^IWTtZs$v8le+UjIVFJeZ-G=Qn=$d2zmP zy&4NZBW6BP5-98s&`TE-5Y-+BbmI7DOZh!_KH6Wdi}=)s-vQPWhZWyGmm(Wc@GUdo zZi}JLdsMlqCfO1A6sZ1zCJ>_*1`yds9n7)L0j8kUQ!sQ|DlvDqlm>(Y?azKM{n=X^Aytg}nO5OC&Y0KaQQt%27m%(TQ4%{SsZ2I1>l0FI|BL@CO79A0I z_=Lq~qKp3CT3hn3hvhdp)u{4nX$d+_6c3Xd!zQH>=e!NQpOyb`g{@-*^Wkrp=~gE; zV!QEmnP*+&tGT^)mR?t00%Fp;;7oUSRR8oyy-EjzzLUl=Ok1oxjTfDyYXLBg=w^o~ zWvFFCq#<)cvH#KZ-QiUK@Bf@mIY?G030Wa~lf8F#Rz@TvGLn&X%-8M>{kR_kH+j8Bu&M~H{42ebHkD>sttRzv z5u-4NVKlDK9b|YmutZgQ~w@Bpmn8K;@kK5(0kHr8sVlhC9B zKJuSP)Ahpau`a2^u_t(q7{#-?w!2^S^Fc6ICv69uFSo3y;B#XT~( zKW--^ujd33F8-{pg@6yQvSOHSkLp&(oe}sy@G<=Jr*P)i8Kif0OUw;ziFr?%Ma7x>HII3D#g^ljY`}lvXiIXWO`w^z;8VsUoo)q>l^it2a3!Xz$V)!|U^btjawhgScv!})hE=0& z-m>X2TX^IQLb%TA_@t=>L-B-;d$N3!aPvr4FdtoQY7rxC$#@a*mZihM{wpCz<3eu! zc|{g!MRAj&7hUS}@xSUEw5IFDyQ*VI-KJbRuQQSdxP7ZRB*P^wz{Bkhx|aG!PXK&Q zylM3J%0^szRH_=S&d9C-7N~isdoxcVU}v!0ytymky&^!<&QBmMKt5^i1|N~CorYdj zI3!U}a8`CP#HUI#ZY`;clRBxBJSigZ)SotCPrK0jSs+kw_d20pdiT(E!GbeWnr$E* z90~H@jp{;exDMtWlHiis;@}RiD^OCm51Ouw1nb~r?_TAo zG0#*NcwI2%GY!U?HrAeRW{fy06tqXjh$@dz&F%;Xl=Qq4de5B=kEK-#h+{_ z8vHEf@JgJ_9ZWaUkLhB+E5A6L`g=LcPH0+8xN5R?)s$Lv(HRt$LbjJEt9kGGZ;B3V zq_$i&YAU_3^SW2Y_9BO!s{r`x)IV*8R_o+2r97^B&24b-0x2s8?$qmwz**`Su}SJ&`0JYQr$Kaa}CK3BiJ>JUaJb9}O@c@xR!T@g39&6JE2I0DH~%j>jB zwdIO#H_GUN49dA8UlL^z9e5Q*oxc()(EaDGLvvDl<&7UUzC9p!Sv*c{j~4!!A{uke z?Uh397d<+ zI9!~pui zltK2`*$dE!y!hs?}C#nWFP9@u6TT`XtvAKM`YK;SDy)xoFFd`DKWO_SFU<=o&n{UI{ z)$X+D^JV*~^>b};e{t}ui}iD2NCohVX88q4NwC%=BGByo*kQ*8-0xlc_GG(5nW+*!p zUX$8T1ZNwH%zFW&)NvyPCIc^d3p;!hiXg6(jcA?!)wu)OvNW>Lt@bOK@@grsHH0UX zpoHs3!(p^A9R!_l@1N9v3>&=nj}^NZ`N3!4gQoQBWI8OI^!H>ec$=R3QzFaA(h zpnq;$i62+I1&GFTj^z#0K$5^Dg?7qOJQ2;v0E^3nwz(;Gw(TD8ijsQShXkq{OJe0r zjCVe4`tU3nll^}FLcGfMBFDw=J#WoQgT}WNL>qkaEoQ|jmucsQ)IXF@797gB z$0L@i-E;aUrhgUS`jeXh8Y>ZH9Yq;9`tf7}*+a8Q?W2m8Ota$-V%FOkawA&j=swpk_NT;ni(rVTt;X(? z1YV|HZ`G<%Beb*&5djAq-b9D6i1{Buds@HpzQgYy%Z7{M*63zK)MC_cg#ZVd5J?g& z4T6BjCIwdh0tO=8AsJGYX|3 zp8NR&5w8eNC%>W^w5-|k1Ah%UY#fm8_u!4jzEynO^k>-EIm)5=s)sufZqi{BQ~LXs z=nYV1p{vu7Hygri@!b+6tU)*Y`Z<~ z9JRFw!3PrU5=QIuVWQe$fU!uXd(MTos^-?ugl>fLP!PJR8Hot2ZDUZKcaIcrAS_O)v0RL({T2FezZ1Zs^3;XuJ#Jw-{L!EV< zXBBnL9?G_Rz;T85^^e5q{(RZ5`HZTDBTWHq+bqQHjp{wMEJ5oX}N>!wEkf09Ye|6sF ztVNfITV3J3AAEFpV_`tKG3d()yylI+#KCUIJXTo`L7V1*OUy}`R;u%;=jxUair%l_ zU4_~c?~-1*y621RZ8iAWIvd6+)PQ*e`IxC=C^@fSedC8uKNqT~hAYvQ$ z;UjpAgt*5QTFo!G!|~easTtLM#WBaytlAFZxVLC%k<>xqnyt?wz=i$$1R!!EaCM9& z{DJvtTR#%$ApGu)VZGR$2SN18mjym-j8_?tG)V&Qo5d8Kg91~)cM^hgrbfyqdcO^{ zu(4k@t-`Iu2NMbeM&;?F(F2tm{gG#MQq}u~*#J9H;5xt15OS%qrd~3L;&rR-_CQhM zs8{cA#mmK8q#*3fQtX%c%fUgqK+m|$62G3w88j`EB}kKBl2e# z@E50kQCHhC%r>#?yhhJ^+wUVF5KoEN;vJ?)5`ss*E>b+=$n(htW#$dUGjcsc`pF@H zRP$cv2a}*LsM6M#S51Aj$bzb8k`B3EA`hpQ)1XglBy7A%W->CnWNvyvQdVXZnuH|v zOAwv$`YMkU!#?RgmPfa&m2UqP(KVr-ldZa0#yXtVAoVRrSx}JZ}@DlK)Ro@3RU+^ej2O-AsUxYq@UB8 z`);AUm;-VoSX6_hj)(4VQ7@XKrPPza-oc1|$)r#y`ynr<&i9wUA10XU8b?35h1dhC zS1UAZm{K)`k+y`#u^b3sc@ea{TrIUP@`>e>$pnTL4GID-pWT8(y&eMrY^;hd_lpFE zTth>L(wc}bGE0=$KoWXV?nU!psbKo!p{_ked=dC(3%FGz%IC77J^_<}3=)*6h26+Y z+(9jWL}kuKSa;q?SyU3=2_H(@$5&ujaF=rSXdea|MDmx52sC0WiyJF%1Sr1#>;BIn z!SYT1acT%kM-Lk-KxHf3#Tl|Fw?jkd{>?ojmt-aqr}Zzu7EiahRXjKEF)q=NChgi2t=^-4Hwco%6CR zU(AqgLeaSsL9g0wr$vAevz1PDAw4ki?G4J;II0{a)BtL37*8qCk({fzeVQ%oW*c=S zB7~jFmxDS0IoMCS6b;-N8UQwDj5Lc@-m2|?Pj){@SHAcUtgVh;5t8ux4YNW9e_ zq3%YW8eVVKdAGL8ZiVr%ridxt4x0^Nom6Glz{=Cn_m|0Lj9oSA-)8Bj`{Dh1$>9N!x}-h6Y)A&F%Q zV5ucHmZq(-!x_v4jnfZoQ^Ba}a@`HNP*3*6(0~rQO;8;_(U742h~zEIe4D?<=X71y zACpjkBz_*9Q(`4V93)Eya0h`fZ(}77L#Wem^%aiTFcr8N{-T2c6@D{dM#!=aO?66w11Tn6d$_q~jLUbrYM(+J zJh#o{MYjUWxZ*VwJm4p62iXYNDjEH03=czg;JVBl|6$Zw4_ zFt*FXOiLV*742B2wc0{I;P!ej`&o{zrs(IRijvJiIJK50m9Bk_#Bpc|4DivY5He&0 z1U&|=zI8qIVCI zzKm$7K1*c4b&W|-d$|i;IJ1z)1BUaGZ{kDf=tz$bU_!@W&oCf@Ld&Hta{bXHNgD(A zsen5Xc8}X&61kp7!b@~BPrEUtValbQ>dJJ-p-uHo;aPt$_f&1;VS7|?Nymgl-N#G< zuRL0l)0!+C0OxiDZM;lL%1VgRyVRC`gw#=xk}2`dO|zs$Y2$)uXV-Z_zvF#*g$AZw zdwUB8t#i169F?OD92G67pM-6?QydiP(v7uW*^58Dia3p8A-0T~3Zb|bUQ%eNlPLs# zJ?#_BY zTG;AfBx4CuN&-P1!%d2fH^SrSJTT3*b^u7 zU|!Zz<74|>Wi}yK2oGmhmo~VR4ZXY2*Pp~C(|+<7 zB;tI>@*`qnWB41KhV54$rjvrfM|uR^at*A%7<`MbpVPzRp4;$*3+j8Mt&h_pX~p80oYlzE%sgWm!y{Ev@xsp6hO zdV&m7oTtFZpF4?mFNBzH@xEjyO$?6wnG56K2YqS+j0zYhy1~WdjDX<2kM?Lr++nsff37bz^b9sG4Veh^3yeqcG3py#mgV(pE8sU4qux%H8bFcCldQsT_2mu! z%{1`-x4txTnwn~s4abUTWqNQtb9jt8NzbaV{YXKVtBnE+T9L9~?x-r$xA5U^;d%(Z zQG9AMW4FhZ6IkZ)sXQl!Y5{AFCM`Bo#X>Wi$RN6_Iz?NUbwkV)o#x^*+6XCzTRQ|`~Kx0xO(+F9E>}ysBc=rrt$)6jPl-Z=>W<#W*NaeqnmjYOdSpKbdd%$O$ z>+iX^&drJWBvrf3v#E6YsK(Z}@x0*v5ezwore75bSJBDdYW?F{PITYiaY<69F{YDLsu?+_*N-ZJBz zB;-VP!XRkvx>V?yG4(5bpAE}b^|eDA;Q}3<9l;-^c~tL3+gdkS^`L2NdQ!C4)@@>T z*7Q%VZIvjpUSx?XC}esy}kSxWHW-0T%ic51iB_;4}p@p{gz1s+LE1SRje`vlBLqK(iI3IPRoZ>3Ty z52SY}mPx1CC9o6GSq3q+EbQi9;E~n6=Lr1Wy=o3Yh2#!gjL*ScM`RlKw%)SwU`zi{ zMDwcL*^Z;>wG{^4+N4iI@)#WoW};}p&-+GJ_6%`Cs71}iRvokjqA_%A?~f982TU*4 zZM*bc2Q@9}U0&k5Ha6Zj0QnQdO?dSxwXNIgfv;BEQ>L4gfhh;|4-`R+Kw2WdlXfRV z>AJ~);^NkdS;{gCeb>9@gADyzwdcjrQ(%nL>hqWH2(hxy&PO%BD!E(jcL!Kt??1xKaN8JHJbKD`D4CxX$?-YjX!sKr$7U{yqxG=> za5H-Lo1h#hfOxxjBec&o%`vpjOyQ^(T&Iz+FzDZM5fNVEEV^5o^b z<0ij$Ia=C~AlXy5D8tA~-4b>_72o!0?=kfn5S(f2 zcp#K$I%I_J+T#!JGG7UBoE+`#SqKDc99A8B4}z~8jYqPV&{^Av4LefHGmNDH*73Rp zzR;SHjOOjN>Re*MKbv_Bo0Yx?qmw)?S{-<2l4|WF)N^#YfAF`nFo`_4K9d{_f~Ni_ zJ5GG+?Rsn1xWFZPw6}17iT5;AC{UE+-zYg+_dyN|zmvv^?%!*ng1&!KI=DZ8w}vJ3 z$2(u?1$SPoJsrN}&9{0O!~gwstDbIgCnrYiYq`m2K$1_!UEfG)UyRn+=)VV{pzUWE z`GwNS^o#uXSOw!F&1CQRr?fU{;O;6#-qzcgfV>NvVh!jkT32N>(Ek(yzH-X5o6xqG zu%|9K(5&1=+cRuHLe+WpMUt7%8qRDrdKVn^JaBvD=O-m1+8Fm!3u_yGR3mpb0dBUc zoqRx1xU?kxCkGBQw*&FyLrUx+nI||4wn3!fRaOUOf;t@sX2uN{OOitlyTbAQ>PHi; z>D6j$-gc4I;o&}XHcJg$Qxow$RGB;pBnUF@wx*j&v@meA*L-%JKguWk>oQ5nhL=8p@kr$~v>$d}TN2iu>>@8mwAq<)WCNN$0cJ_@7BxZ@0_ z$e(M3A`K8h!$|OQSQ3t{uCHNUr{ZK>!(ERb8XtEFxSnSC&VBG%Xme1n3gGU?j;BZx z_&!SSE+1HO>^eYV{Q#p7!YxiGjXxWzKKx9p+S+GcN!?@^^_GTo_W&a0Lhe2N_W937 zN9M8-T7KpX0}F_@75z4#qa>v_fv!kYld!SOhFhQHdDIf3NWh77mvuW$5MV*g@#I#Qk&e)DZT zPo<|?atwV)2wcSIL%u)QGf#xV{ZG=Fu9f@wngNRQBCYsD?&ZL+2?YEw z|KH=L#J#mfRibBXAz}P0`94vO$P#A?7w?Umd|!S#%)j>e_eJ{=gKF1+z(rD4c3f5b zRAM#jKn3m2)-MOspFTLWB_-1x!3Q~9C(j$Was+0|27mk(bEpI%V2#gF*BVP7um9VH zyo~wv?)=b6jDF(D*>%FkZ=>Pk+cq*YF!SpSxu0BlW&W`L{ARS?eW#AVki} z*u6|)q*p{|g-Xf9s}gi#Sydvk=suxv1dppzKQQX(?Lmk{o79~tnH+X5HXkU|%04f3 z(^zwZNGr0dnyM-MpNkr2jo#;2!qYUt&pVb#{lJScjQLprH|9FS{Z`G-S7ZnKQxAa{FF4cy5qvw(Jp3e@sg|@9w!~ zR7|Zi%oVTi;e4YwoA~O^6VjjXR>h>aDECRq=0cn4-5uv`7Om)B*!}Y%_vPuBZ4Wzo zwzB_^HfxZ<&i56w%Z?-9h!3VTs^NM)5<+*@Y5zesZ|t<9&1n=QhQ;+fBfP(9#Zf6% zRa(^Yu=QqBtQ|A|QOcsgR>J_dp;`&sn8CYo{j8<3E#@GcrsFB))X2NmY1`Hpi!eE? zYFOev1Gn+N-UpQeFH}ee{vf3oBPF9sR^s+3GIIv{p_td>pr<-K7BlxEZxOR#%V2Oj7hY${zGU!E=GtzE zkz*D2SODE6N!f)XRn<$C_ISn73|jQ4{kHgXu|7`#Y&XF68E@G^P+W51Ls6HxPxVi$ zZ|_w=_3ky91jG=(vi@66JZ{C!f?GD9d)FQA+R42XcF_tx(b~UhbKRLv+=q7a#do{6 zuZw7S_r5<0l3`z`^1n$MC;OF#)|7mh{%}tp9@dg%yyK0UPXLbmASOAJA-{C)^GxL6 z6_72%D}ieGasq;{2i2?Y{}pfEJ044RyJdonjnoX(clG3~>fvi5$$)+3YDSpWh!MeM z7~fCG4G9YxI)=KsKmy!^`m&($o(d1z z^$cyZLQE^zp6Zx0Xbc)>eTlp_DHQxc$Z-;#y*{@KbFd2u1qS2F`)Z6T{QB&3iXqYb zeIks0CQJNm*GY;BoMq&?l_LcMPFe8$ValR0E*V2B(U9%dutT>m-yD5?q4WZ^ zanpAsj;frtg?ALcVf1=tq+`j|raMM*C3zyfnp}qlbPQTlxK3X=X1?aM6?Wx(4zs1j~;l5f!fbJT* z^Wf4^qH4>vFMKrhu>T*8w~n3K zb=~hgJE@q3D4etY{m8jmZ(z*BR__zz&Wf=fDqXyv;G6keB!g`_*y=ri4YzRp>NbPE zfm2VAT}B(lUDJ3s|C)$L8n=H18cK#-4*n8K@GR=(ip0B$&SyOz4#;+Y(^XxjU|%8I zouG0`3A%a*_`+K(0&ZN?V&{+`K*2WS_=-LMN87?@Xp(==Q#xy~GZ&pSM~iOKW6Qm{ zup>m^8=}SYBI-8Qq>p1#3%;8x8WtAQ^O zN&(=H%srkV*kWvC5F}tH*bc^>eK6Fm<5z>np+f9C8sf zV)U3cfC&{0{UI84OXY|B3PsH-zVb|W#>=HY^D*})DlBI~!nGX`BhqXj(J)xXpv8yg z$Wx{ld(l<*kOM0!tax&`Lnyyn^zs638S{9eL$~0fv0HEbE<7_b57s#dhr zS2IsNN7C;>GoIu?bN7nM&Vs=H2nqdxn9A@V7XV9xSh51Wc4(g{5>nl2W7hn?!A-XMVeAEX@|wP8QcAWsGKop)X;`t`s<^z8J@3Hj98le_cJYk$^KHuX$`pT zQmi+-D5V}aQp5BBC9Gf|lbycF=1j6&+SNZ$%<+BD$Tjp!9_`CL7$9(=coNfq zi947JCf9TxkBw(k@~+Uj*ZF(vkTkC4u9TV4-)Q4Qkf#ws=!Cv>5Z2o`UcqR7IOc(( zMMuuf7sm>pogsuM5zvk#DvNeT&95_Ud}jK$-IL5kEvbGp=mHS| zAP$c+`f{BV-UwivtG1`y`s)n{W{IOk^FDyk^7TNW?#=$@QOGnLfbUSbw|3*;_7~ei zMpZ%jg!X1Ac(YVquw?KN+#q&bPBL-23hjF9kRg4V!WWX6P_#!N@O8(1RqEgAcGKbF z`y5!kTK4Ko7xi0m1!}ivE@?ksj`hax5X^|`4CLT?;BG+M_7oeMTMSH_973LjR{8z; zt5}lK8DPTeJNVn3#3kt1{vr8I5=i>bQ&HN?XY;d!8V-tg(HQ*!DgnMy-O)O=bespO zg&}GyEJI}$eWTvJX9~$J$^IRw{BPEBcA3~$!Le|NT*XFmgb+G#0HtU`W`bJC9o{2U zHX92uLzpDo+mAdi%`T6m5M@D@L-?7tOx@?bJ&2vyNMwB%5Eh5{w=T)05e&W6YNoVI z#tST~L|NDPRO`m$Z!|~5-e&VhTC>^!3NPgcZr=Dl=bJ|MSzI0lc~RlHuRk(?pb=E8 z>|1i|5JSM1!AAWaEg~xY2E_Rp zVppubZ|`Z!+l{>W`V|Mig(9JZD~yH=1Emm%SLP+ZUvg*&&|4905ny+!h|=Pz2JQM4 zFh_Oz4bFf^Yk97GY_!$rCI&NcpU245Mf(01@S7V^tJaQ|MgXM^G|7IE{oFvE{^dD# zf~PRBFDI@9Uu-x0z<18i72g$&Y3bi0@OO0Ym?M$i(mYSaXYeMAMR*Ogd?x9wze{9L z<|xWm7=&Mq5t+kywB!r@1?p)bx*ETZi#iZ9q8K3lRKOL#2xwV)EE~XOuFDh~D}kc6 zJp_E)UzPvU^uDWwD#|m_ni|b~1WWQFQwHeK!McoR$cY5uKR%x**@9Rye|P#VD`TO_sBC@{bSmJ;}aM>;a@8ZWkkW4 z1Afk^>g0JY9Pn&vC=E2u1QJfw>iZD3gK;~5{=v{lf(m>(U%6VIc8${yF+_1U z3p1~6WwXka7kwd2eF%#W`O#8FL3&{G-Dg)JGqMh>yFae)zy#Q=>&9;ams?`IAin}+8FhJ6@o(l zd!A@=dc0K_J5xM`35)ayr|7Pxiy(A}m2BgD00(o6k-j z+k(9^f=qoZc$W8iNAdryDtr2XgWUu*E*H8@aLEk@iKf65JORs>`UZuw7)MP)IBo6f zb&R6i0F1hL^Ys%Qq*Q6g;?e#t|6Xl3e^z2dQ+DrvEA(qhOA4=*_#vhLM`WfSg!Tab z9UqI1v2Jq9UE}fLhgBmwY9XL|m=g2@KJ~vT-&c<+RXl-LuIl_gE#ZI9$O;qp#~s)} z_=#H!wJ3){*oRlO7z$oqf-jQi#<`UC1xB}&VDY#9z=_hxnzY{K`{8!#Z6hmI|Hou@~x){mT zV7s!Ek8iC68|Z1esuTD6B8Wk*vU>UsYY2zH2L9@{e;q8_W&vMhuRpMt{cjt^pfN4K ze|~&60gZ|rz!oPgXHW}YEH2)4{Kkog@AJUp%dI<}K%F20TeGJ%r;z=3&hh}Xkc!Co zB6qVmO7$=Drs)OIHht;KEZ<=eF07u)$1D!tc^2U}(XEfD%bx3HgLftRIrV2>SBBpw zQYFtz%}5xY_(sdQj1O0JxzAT2iZJ9zyE6mr0|6pO_V*``i}4U%G1FD_mRiUdJcsEOLagpk^=|{CA@|l zVGg^9MsG1yNowao1$ret+d$^^^RI4r0)B{e=#@7D4(%P$R~9S9(ptjV_X}U4iV{v} zY%nSPX98pKuXYI>S8*T1cBc(#9FQesepF4Z$qT*0EtZqZ>DTC*k->h@Z2-ne2mWa* zzfzt?h|K5t2S||j_GTLc0ECn!G!$lAyLIz1gz!4T8W)fVG>(tkLwUlMy#<5t7Yb5a zdOZnHu>b}JKE$)W$9o#rl1g$02YuVgNj57xF-ck;vNJBn<4o5q3^B&8z!^!?@MM{c zZ>g_hK2d)p5}Ih~eUE;iMeGX{b<5J4v9D$1Ys@G` zX;fyCOb-61NeP;eXFDsuzI{hR(wxB?H;lV!KYQ?`_`hGnDvZK-BbE7)dd^_ZIwzMP zl3)DzmN0GF<9Yb=9K_{zHl$EcdAZiDR(6Y9^1D-q!C64vj2znC3|joKLItY^ZxS&Dm`}64O-JbPx_jI=x{p|1JtBi( zX`1KT%+Ue=y8&CyZf?K@^vu^Skhe}HU-kl91z1&b`JbHajoc!&y#l|BXg)uuk{$>- zgu&-7iO?fqkFy6$nZ(5<5LNj$bRJOn%izTRox^*O>%YC&fL2aXPk5&O9{43%Eq7xr zE;_})d8*q$KHfv13ER3gK6weBZ7NzNkk1i0$?HJtaSvw|;&sSGla~?(N)+Cd;2*>5 z#HM>q;ba2u9I*DM8(*)~wUt1Z_n=qtML#i?W${W8+Wx?@*v#R^2BJ7aZkCHc^?D)t z81Cv>;JIzH3KaQ3&z*pIlSM1#=aY9Memg0YvhhCS{ny8d(AHkZLa{N~yoZb^TKc)C zLEp2Zd+Fnfg`J5e(mJzgx*M3Id}bxU`xMLlp9+BkCS|y#)9{TJsap z;KO}WK+kPoq83qg0xC!fT98CmfCYkeSCTYa-c zU|RsWWAlsk=d4a(Um+r&D=;@9L#i)CfpYkRTdJDL#{fn*q%B!~5Wr4Y^{~Ip9g|os z8ziS9D@YoElQs*dP+PGT+ymn2Pli;?-kQ2Q)kqR(NK5*Ju#|0$DhIrYfjv7t+%N@a z&@40(#JAV$a&Gg#SbqS3p&)HBu{?bynq+1}qO|u%K!3q)PD}30yA0QTbJjirzjmtn z&QnzNv;9SA)0Ji+I{=?-cgW?snqwl|7i$qoEk66RxlVt9*F=uU{hz|9@Xn%ohLoSy zH?Hwvvbq7bS16Uw4r*+l9_9{f-7-h*vyi)}4Jhob|7eH4<=6CG*rvw6zg4|$L??1z z@BJ`=wjSc#r5HG{)j*C9^#K{x%}H6$DBoCsx!DDJ#PzVKicXJF;-NOFId+`4NU$wn5uze zEwwqR;x4Q|qN8 z`Z@Q!QPo#C`Ooa9E>R0~sVO27+*x4Y?ugB4yb|JE`{MAl5H3>g(d0WpvG_BWH5!6U z9)A>6&yTdL;i}E8Lb+d3-Z~aXhN-MO{EkYjf=q(eQEqe&MuY;<&4QSnM2oLSxSlPA#PF~M9 zc=dzN(_v`XK_(rkF4)bO0}6^d&p9OlXq)u0yGgw$XH zwoF>PzYMzYzTWq_i`uF$hw3_hi4fxZ{PG;_cJ71T=~80b9G22KCtB#Ave=NV)(<%i z^oraYpg7|85|_dO4>_)x^EHq8@GXiut-CcC2H)ozwCd1nnDLb-E9y(3_?E|FlXo@Q zu%J$Trt?sMcfKQ<5O@G)A|M$$S13^MTjpyr#1FIORSj1VYT$5gif{GI6DurHrujMb zD~XEtRKa|ubg7@w()H~0BL-xXtN*F3hN&fBvL#6cp9cOB)YI@+!TPJ)~* zh4g0;!ISMfjNVmZ*f__92zlqI5apgQ{cAEf=*zQaBvN;MG|om+oxrecRBlI74Yj|K z{iR*_FH-j+hb$r+oB*qg<3pQo(ND>-dgO3=u5`a`U3!Hhbvea{^wd*B(bx58Q+j_m z*14%%y7$B%O#b~e!0ThK-;|E_azSiJJ))83Xg>aTRfe6iz|-bg$%Dv{4~MqjNfvA| zq2Jyc78`2kJQwAqRJ|oxbpktjw~UlPg(ZgD{@8Z3=w-9PfcDO|(YgJ_8^1vz=Ejwh z(|a3{C%f+`*%f0FxsZbXnWJD84Y?<*uBp}TSd8oiW2&Aeu&?l#0M~P-<6kKrQ`Zm3 zRqT%elnsUk#hMo5BM_Vg?C;@_Ohb$;tFcwIplN~JZ#65q3Ax{h%@rTYkz)#RP`R2# ziA4qysd%KnnZj5Ka%rv&4%be(Mot&pu*mr=_bSYw+%z?DUTh$J2@a9RPAroQD0edH z4e5>czp;9kQfBVYK87jTi;cTCThlyRGXFvQyNy@#f^-|~Q07lvfZ4j4Zi^9-H`bla zrs;kC?ps=oFvz#50>PK&H9`*BEk! z1M|Ul>-if4X^pSkWuck;&{(*J>Rf*b0|jTR*}qU>dTh;t_cE#H%z*hjcDZ`KBFCQ? z&)lzGFx6>;i{u5HNhnV((jH_q!ksvAUP3{0T#>J?B5X#f(n8=K2+?(zGtl($e%A1e zHKTBzZ%mSmV~!aS^K99l2;#_m`PuI3vi_X~2a_YQ!MDGVrrgWSqgU(>dVq`m_y@cV zEZxt%Bx80cxVX$bUg&Y}Y?5{llSKaH%>Rlww7`CvphIfcvzf%c4XcbXLc%fLGTgY1kJ8~)pGMF_bFez919@$gV&GWv4B@f; zX3i8aa!tFy8QjEnvf6I!#8!zEszb8V<;^9TdE1%4u+7_a@Af$0 zakU^5=Y=@#y(;pTYL}Zs(_{!R zBo@-A+`&=_;xGD%n%RS;1jy0X6O9=;@$-eU(|JE`GERd6Gm}4Nd*7&#A`=I7c|5G< z0Ce8LK+l{wcO9g$6o^1A{VnH>jo@pvs5^54f>R`xP304FQz`q4Sy`swuYp>Qza%n) zv!_u~S8f&=fEm$%*YhK)It;Urh!Y=Vdv_n}`#USF4Y^CG2~|IA&V+II`uV5WLYZYl zwViTpE6avghSSA8A|0jwP?QnYHf+ZEMV(*{Q! zetHAKWC;*M{(Tsdo9;twAykTW6<>%*)5Ha0?M|C*Ic{I)hLQq~yLV{!4;XAaIlw+waA(9u@*0bYUoKo?-g~5s5(F%_{ialCN|Gc| zOi7Dr33KRD8p$MR*>lZ@57T^9O5GsgA{6@EE{)oK5`#zYR8n=qrbyh^CP({&!o3C+ zs7mXKk>?>07l3ZM5IAhf5J!wUuIOl^3#6AyT-cAS@ds{6>A0Oqwe9SpRnL8So5hBB zR?nFhY{pa)-3svCZ_>cyr}d2g<5t)_M@m0q1+m^4q0d_w|4m+pvef9HU;A62J9e7> zPksJa*}dC$@?>*4Ro)@JtE(Ek1t+f}VbZRvxC|utPo!~}vMHomU>NzM#@`kv+_qH1 zP05S5+Cii}M_UxS=QfD&m{KZ!7bMSg7#*C<$$IH#c%8PF%(HX9*C?;&m%Wa!~r?!cr6sDBzN(pGFTv z#l@g9rH;=EHr1$!P*Tn%N;phcT|O%-sk_+Tzh6pldWY$GhkBp8Is@Las?v7V6PjhK#rM<*31q2BA>=Na&pzK&IrWvtf&9YLUNu2e^)tvx&F_dh;C1hkUg5lKBWgM^F$^}EQhuO$jm(d7(U zz1ABMyX!+F^0Ug%%cgYhEW8{lQpCdux*Q4J9afYAbHHCZ*-7w<(fT7oa=8CaVy$|3 ziY6?;@ZId&PGX)`M#K_Cdcp+e3Afg>#~HN3LA1m3E5U)RSu(p?g(pTO`Bhv)hDwt! z7=;r>+&BlHRr1WwUkv{y5CAJzAp*IJU9lmTGoe~?MJ7!`Jo&y3pYT!eQh8@$2iKnQqLnG+=udyT;-zg!@l&Z;P^xf^}k&ItuKPQuz|pu z0^cX(S7}wa^iO>HeG;~C>EvkqULDIip;$gAy#?gj`Pn%!L5@VR13%{`twfY)8q=`+ z^%vblSwuuOLPUFwF%{q~ zk1#zidNu#^JCHz=c(WEJMOTD9ja0=Tvq!L!)MF2pC_}roPm@^2z6UvvCy-uB$yDCA z(ROBewe@pQ?oNzB9hs4y)jW`yPBNny2y8{G-gmqIbIXyYZfbismMTxLjaF_Pf>IM{ ztj{w%v6^Mm4(f5`vE6yj(*&7EQ&0ARJ5=u_T((hxNN*Iwy@te|u3otWe!2F~l;U!8 zufNn-x!)!!7kUvN8MqokJle_By~d}#+mT*ZO4%|Q6X)oz5GJl}BUKrE`A&_ll*BJG zVc%Z7n^jV7gnQhV<3q=%s72BjZXd2s*FjJAGFEpG!!!xkl!SXXm~A+4bSFi8v5jMh zV?p67pO)M}Ag+`a=msyRZuwM0MKe}Br-%(RT3S~3-1y31(-#e)l2+wBWOUY(ja>qM zW}B^nTK~yT`20ISHYqb|fd4Ka`ZolJZ9;x(WMkpxx8Ra4fuQ(bY*8H2EHLpdJvJOR zJ>We%`3vNd;9v4lhzCNKec#~{Wy?$^;#@Ka=+E4DM5xwfMwsr*#rgJ#!VLUf=?4W-J50WuJQ!V0x7aGaY_WAK|vU+KML= z??}-ftMx@_t19Xa)erx(llW2Xz7Kc46OPe3#MS(FRQp2_^{?OXAqiHVR2n1eSz$XR zA6?8Fl*(f%8=MsDW%RRF_1<-_h4`i)Jq=|P#oLxIg_H7GD*0TSn)5uuJLyFQ!iIO7S zNJ-tfeLwH}e(xRk54b2RU#voKB3VNzO*s zl!>~@8QYZwJvP5Tre@}X29@WD8*QOZP%@x@7(6o|;!LOaFt>$e zn5Fmu`-2~M6gL@kk`mLy22@}D9)qT1G-}yIM7A-apGS3(^ZZ|h?ZS+!7$+1$)G+hD z)9BeoCH}6BEHu$QtxsJ9LWZ`CSDz)9xa6kEBvGvm6kR zF#wFvi=uIWvSSr|%}(ZjpF ztg0fAKWW^#b%(<6fsNjelTNkLtDG}e?}JJ>;0(0m?RZ@MoASji%{%Ce+ekt(1x)=yTr*OZ91%bjusvc4g4nfnelR+@GV@JOVPAd;s`N!)E7n@va zERwHsxh~<_fK5HzoIijqopg^*2RE-QqW=l%`9OY-ie-;s=+9vwUz9>%`Q%reLb~Q0 zg`YFqr8~9P4Yoi6!Ex!);y^FRq+?TLaY<^eQL+QKo6e%iA$1R*hcjlm0$b26Cx3fcTIsl zr3wSCh+(3NgwxM{UnLy8qAnd3;g^LM@l+vk5O|}1?I)EV12vWg$ueeZ^dE77dntC5 z_m;~ed-R(#l-3MzLPz|}e|Z&3PL5$*?wDs?3g4u&0=dr&if(?3aZgsGrQ4uKYH+n~ zY|I%6{9B9EdTyOtYocvRDwo48kN(=@#>)1&4$g)?0WnzXe zk==S9ARB>y?gk47+Oq1?D^Pk>is?-H$xf}gt&A|e!|ZLr*A1w@Wn_uTHNxtHYnVnX95lY0?`i7_2#Uo z?@O>IF~bHcN8@5dZyQ_wxJVljaU3F5VCIs=TPP}JtaE4WkX2{0;IngS9M{R>FTNaq z_=q&S)p-@4+rSgvZKl>*pxlH2b>@5Zr%whYAJ!3>z{%mn*%&UOHZwb8k* zwQg|f36x@pz%@blL*&Js?!-I2JdT+8S8vKV2}jK$5MIMf2qaR6jjMoZvHv{){_ zB;%nkV;9++gAn&dW5F$5sdRt>#1V%ZbC`(VJ;m>@VlpwsIZr$Q4*3{C^}wlO@%(YQ zpdZe_*Xx$Ho$16fcZOJPW2;hLIh{$3>*j)VF-zJrg5&kitC*`O5Zg-Zsw=+ihxooF zib0s~$uhTCq4m^vsOrXa&LXBlh&}Wa90OaIp@2Sc|KWK3lgWzFQG```-%O*8-TWQZ z!^Q#&R3TP-p%f`y8>EPd%dEnjO!=N7YxlIjCE5h?8dGY?Cz~_9z&*MI9%UMQw|TN> zQ`?{dNSfTVC|!k68BYU(L!T92rYMUW#*+m&{u`Vqp7qc$Ol1uWk9cm=H^4w_pl( z`rcr{P%5%iK9GNjT^P-;2H30ZBK7PpaoZwX!AqIzSzPNe*Qmx$tFS zcPmVSy^jH3v3f7o_<3n3b^RQB?iu;*`t}8IJXuKlBgBJI7+KVm&@gLg__x)b0DjmrzI(I9Y}kX}1$wF{uO<^|e{9WXe5_rMb0l3!wPjb!owiONo35 z?#sPFuWP6SRkk?7C$0_b+|&501c@E0J^_VP@qnh-K|L@qVp3ArwyZjTN0h2g&}pZC z)4Me(H66;91N1e{oR0!sl_`C|){6bsU?5-+P}KS!wPg{ZIY;ZK!-`>+J$MCmOlMZ# zlsFYVjYxk$>@&4HVmK^5JXJ9xs(He2qVJJ`JSBWZZ&DwBpH z-Mer1(@H_PWF_kj5{y&YFKL&yQuX+^GKMRmUfGoSrqR}@{*ve3x?KD+;*PPb9O(Cw5fEcN59`sxu>}yR z6-(|R=D+b-d+OgvKmfMA{a=OSS1~atq=*f*{e?GL>zQhbY@%NfgR1tyYFKFc^gEUXDEn4ljVbu=?zf-Ta3s)&7=m_XAm)b~uuAsC%2{yiV zaH@%=`9>EUOzv9ET4>(cf`@ak1r;x54XLxxaGROjs>BM9)nj*+5ebrei;cy1Z;E_f zH94StaLP7PM0!u{-$5^I^~dLyNLZs)@Q_d|%S=YQ{65q5nX^CTvjgcJ()S6kDB zd!W;(W7jaSbf&)>Ra#Rb%zmHiSqhILTrY_@58dLE47sFqNm(qSYz1(5zbvv!J@(+p zgYMbAKg$7}RD7)dcLv4axGG2!S|hy1lF8Dv23Xp%Bnf3rSf7Dyk>t>LG>c-GAnL_U z)R$P;%gXDQQ!CM^VG9|^%F`xw4QO*97{KQ?gFE z3R8ZQ{eVY_J2>OKy6w4Y4@8FH-({o~{6}RD*H@M+dUm4z;(C0s<0u~qD)E;b;YaJ! zR&J4AyVF)0MIz8};S*F)Y`pD70&^KsB%E@HjhAnh4V>q^XT^Jtv=1m1R^MJES5^$=xK0{jI}VAa87{j^N`+U5^bv~#t1Suh zwW0LI*;&HM_q2Yg=n>PuK|=~PM&_B#ZRr=G_);|S!8Wg?^PYJrKY1Sq#k5Q1R1aiN z_eYj~comW&CTuCn_aa}$5S$#?gwJ`fzvZxrEJ{_rpIIQFK@k@EM>HZXvl)+zb?ek` z%OZ_5RjS<%@cqCW{BqAftC8O^d!SDuHC{Shd;W zqgxDquo9=%A2HU*XUWC3%)*Ta>#Ai69!bf6sYNLlzg-b#5h=gil+x3ge@O`3Ls1G1 z@00}7deXPdNrD~}UDO#Y{VS^mlR2*5z?-9ILXZ<6g&M2$z(&nKk8wlkBQT7;lYuaH z^J#04-$*Uw|u+N#_qA z&w&SWrl;7s=SJnZm&*d16J&?aQ?>`=^ff0>5ME-r6=7pvA*pcydG^dRU(dZwl-^jF zoDt!AGr|?Gd-c5jVeaM6ViuysE<-gg%Dz=ispczLU6y>RBOQ!)w%PGWIWVMm6hALW zP+oAtOICgh%oDS`dg%lLd0ePgQ^S*vo(@iJQ(T zHngJj8=%B24laK6pnbNp@;wB$u5Z*#FUvsn5r#6LRwAvqX27G%WWJ(Xq^INL^8xrc z7o-uC#;Qa(Os)V;(e4PmKK#OlML+aR^>=V{kQq}c;LK^9O~<)th3FFebqzpBG8B$H zkaFO#s1I%TS}S47P~fe+WwxNx1T~d4${cHFUi{FLb}qMGdV||&%!t#9;VC8J3QmLb zMU;O%F%c$R=TeULGdT;wb;T3tyBCDG?0Ev0|Mr!40PFb8-|o+Toxq7(!Z)03d%er7 zM8?*)3Y!Y9f|M#^xcCp*5B^xYvPQe(AqQqDs^#`kV=Ve9-#1_`jqpgad#}@*y+Eyh zdP%khg}T{Wa+ju3b{0@ zmDRSnL1|~Bfa%1?;R6`(s+@;MV^e2A{}!Daiqpj8eOt+17O)Ba!$+$>B#~Bl8DGis zeX6D@lL1=5JRXNWAu{uLEDivYl0YQx*dPrCRlex>({P6`zy|1!&HDpB zn*S~mMB6j{03Hb*Jv$S^`k9`KnZ=EzIJd$>UV?vr4;n6Y2dzQwBjd=&K9jdkWV`%d zau2*6Pgs4w?LuJ;4c*fn-C=ue2JGpBr!hEPHqjZ|QHp)H6ZX;S(J!7ty|zTmJpKge za)bPdkeIhrZXW8j^P^RTTx#RiFC*@jJe06tyomP($rnVE)K1a*^>ZMc8h6Nj2GE(Y2}vk=2CPgURt>71QDVCfA~_Mwm`yltrLJUH^<*%nialIB zY>yevQ$KU&HF!BqT}xLD3G+qg#=sdSa$6LfE7a1lNXSbs$EpN{+hYKK@KWV<8Y;m* ztf+e21DDhcs$@rg7=)gmD3Su z)jOFz_!k3pKq_hne{6SHqv`SDR~1TGdVLA@rzkuDNHESkrO-uhTSR$@m<_e*k(Z$7 z+#r|njO@mHxllRf%4P5wJaz0Q?E}*)tJztmTeSxnj@QQy-iq*^3W(=!Z}{V!MIo)! zq(z5yPtn55j3jhHmc_zI!r}Lq0P)eLY>3DE7*4GwkQxYCr2|?d&5ZG5LHo{}HUZo1 zBfp{2MO#!p#Eh3Z!O%8=Nt7@GZHu;~W!BA?)5_y+g=ah2bL&pr7C+s(`w`Us@3#FY zG8BHRe%@A)M^^YYywCuzB*J{!soGqDL~DRjZZb^t9&P56i2D>%Jl>e-*3pVl&alZ) z3JKUI_U(abn8d8FtyQ?-9$9$7gtZcp{wIjUl*xS&#>IG-6;s=LvOa{eBz^qsS`%`rANq7aCQ>SC4NI>SI^JB*5vP zw^?q}3zul+EJYL_6hK->Z#pU;8@rR-meA<7$a#P`Bb??ZM-u{Qc3&7(d z!X>r8HmdmF|I$Iqgarbbrv?7<;r{Ys9{~wKUz}|PTuA=@8~*$cc?LG=f3edkz}5@s z6lpO#|NI*v3jT*a00p;yMj|%`gCFctdHSD`g~}DcZ>n$q0)vmg>`oY&Qr5pTF}X6x zKmPTF8ANXT&!)}#e}=)TB@XN2k#IlLfB!4`0jx|NuYD2se~%0tztiC6-=DJ~|L=dP zh{A8a`RGYs|L>9g&l>4}2KWD`?f;xMKhBsc-5$9Bo&n|1aD?+Z1)(uf z4|ppeR;kl-xwx>K#h-!4^y|?FQDgWtu!W;22kKNH{NVecmr2kk3A)>d_d@qEqus9| z$QsbH#v7a{p!1-)oQXVF_GBEqAGibz6th6erdR%KwajMz_L|ZkWK5yRm?%Hq;Dah8 z6W#}pZ6XM}tRha$3h!vcSxn)_P8F>x{!IU>C30l3`-u)2uz`t6)o2;w2_fpOw}LzR zm-CI!4gn6X`I0USV1d)ISDxU>TEmnJtD2X71#5bBWSoP30!AEpLdg7(JJ4E&G{ zyCb+m+z&S0cy#~eZR9NhZ9;o)S}AeP6f)hJSn%RIb#K5r-Wbsa#a*$E(1NKhf)|`; zspIYE=W+|wdoUzCJflPCGoZHz=1Wbm@k$Q|c>P>K4!}LgC7S_e_!YJH=rCM>`S>YM zab+xlQzv+qC1eoJni&I9(9HUrcRC7jtJ=Ce-nIoCM_ORX%=)u6v61iG`up%q5Z)(G z>>`+iXPKc8>qJEH8?^8>U;iK({Ku|g6&(vl=}cYwO2OmdUf|nBlpsnp@STBU;U8(J zc&;VJ^OjK(b5`3b;}`b@)y6*PW1)N;=eL#<%(arb6ss8c02M2X&mMscac?4b2^ zoAirjCB49u4XbXS z9U`Yp*THIZydZ982}06yhX}SA;<{-Creizn<=#sVfk2cEb)wq^B=VMkya-qt1*QFg z8=3bPlMRJ-ifBMNUfCM-p{J`u*N1Ce=1Mtwg)&?#R1`-$9I+-+3yIwXg8OXBN3qLe6c(0pS$xi{0cOeedjn zIcg4i_iY027z7|*V1ui94QsH`K`C7BtousUa1#XaXPKVNP!7|uOlGr;!mDj6RSA$$ z5F#F={5gnOR7Qk|zj!Jvc@*;r6jiy95SWQi9S0u|ix?9kl>bB^HO6<}XfBDsLeN8z0W6kv2nXN$ zYWkx48lhtFbOdrD)App3I}cGHV5dof19N(F_}f(sE$TMB$p~U~38+q*%>MU7m_3-3 zdq5{ znc%a^5SEX?5Rq2zP27b=I+acfEuY!ek-Z6+;ymHdn(q36k^v%ro5~6xBZ9b4WAk(o zQh(KnZO{St(zi0H5sId~GQyE*ZmvBZH(13ua39-DiZ#Z&0^M^=OEJySc z(6{%$^)6~<6e0x&$kfP*`6{)L-BAKW)iOZ@2P~+T8^_0M8z8kgMy{31QxAB(12IdQG-c|J8j0u>@9gf*v|*^wzC0P<*Gyw zE`BT@(p+dbnxCh@Ov4hl%&4c|s1&)xn=rcwW>heX@Ju?p>NO!&46nRA z>aMnb=FRLWO+)Ib~(GeGmVxIn&ezO`H2~XLbH!`c{X)xohN&)%QB+o&eSM)}_09Z8WsPTZf<;GQ{Up z7!Ksozr=7J5LZ4Be3XTP&SX?kXPC0kl&|4+?y!oTx zQv~DW;Rn!9fk@|hzKSoZ{3`ai>@Eu~Rj4H%*NyZ`LsWNz$r$PTwCzVq8)telCkzTB z%2@daD~g*#FWxGMUjTg!Ry6Hh*T|IzxN}0AFTqi(?Q~eT%Ao6#$-+JmLj@&WW(Q=C zR~&rQtBbWvz#pbcw!`SYSC?V_dCQ8y7q+`R!>yWjpXXdlw4fw$2OvdAbh+Hn2}DAtl&g^5{L0Icl&bJo%W|6oGvFo=K869(|UWo3CwanKypl_8*syzc4xLS+kHBHOp~n?cnk zy1h6k3}RjJrQx^Y&(8>m(emgGa9sC%97e0=!JLTFu2xIn{!^!ur#1^6QH{D*Lxcwl z^~L9UGR55l(#!liM@$-TPV~EvOa98sk3O~T8#!f7*WX5*7w>-j zc{NH{FZbM%Zq8iqW8TN#quJYtw7(YI;`#6?m|O4^0U6lg|BMh{d~(8Jx-@SQ8yow( zo;KYGfn_cc5)!t}mWk@g(brkseEa=_&&PK{Is^${EhlYxHSVmJjGnZdtFPmQyUk{c z-j5KMEjCIzA)o50q@zk^xLR zo3`2k65ht)$Ov4kqM*Lr^LKP)Cr)y%lio)tWHR>{)palVzpWbB*B1uKVgH;$k>oFU z1eYk%Z!8QIr>)`#$|*HIs=Q}8AbIQeJX*F+#J(+((bgN98!wG3FS8*f+^TMfMKmld za&RA?^uM}({vmafFx#W_r*QWJgu|3;+!A}w_Z?-Puf+N$p&iLHk2;zZ@HW(N%r&)& zMxM=6F!l__A8e)HK%D$G;RJoKZW_o8-Jo21^Gpvu8E|SOXH6*=-Rh||1>KBC85s+G zKmM*%p8LkM2Wdl02kki}twdhK92T?5sW1*r_m>uLXj#m6R>uk-mHh63+^se229O)_ zF~&+CJ@-Yt8CC;^OMJ>A>E4S-fos7Bg5gq{@T2e>lAe2|t0&(-devo=PwPejv)rWs z#ZXKg&QJTZ)?iiX4n_BAr2Efe)l%iukI-Je3y{P;30{=gy}C7DU)WuDzU$-qH+Bk5 z)P=oi8!<^bDiwLG5mrR^^WtFPO%uYk9soraPGQuRH*I=DOrb2`!F2G0fh#ngmYnf& zE{jq0i^c}*n=J5G@F1!+{K}2C^v81w^8esD^!~!oX5PU}sRRE@{HN%Z&2kzZJ&mkGu@~4LRXWF?G}eXfx7Kwi;IUI&#`E*JsyNJ#tWrl@ zTzB`Tw6FY%*DA%`RJC3ZPBs!P-7K9BrT(;!F<`9IyngaCD!qXs>bR9sTCDQ<$%5}1 zMcf4n@_FKP9#AH;IC9rQyx+R|g!pylP!zmMuM=ng8?3U;~`Sp7=1_$ZCR1VwvdFrEC=rW(KN=|GFm1LXMo~KjftseDy;=jyTI-W;^ zEv3rI9oGCbdM=!DwTg^I_PMpkBQ5b%e5Mw6eM+rVWFKrn)mNIwSaRULr9vDu-xyZB z>M<6jVkpuQ6k`vy$5yMqd&6+v&YkAN{UnuB?@zroI<`DG$Q&P5_&i8)(JtLi~^ z`?Z8sQ2g3$iH8O;_bASu!+!)?ZQEtEFDxfKl0u=)0KLVhT^NB)s5m32@xEp13H{2PbKHviRGbl@#{pXKs=0S!VS zhaaHrmZdyRe$%$~tNjh|iXGul-CjlniGvk%Oa*Q!L*gWX;%`jr-VrglPmdlwNi}UT z8mlB*WGy84W1e)m3jiDk@N%a;BGtZEto{bniHGi|O{i+;Wd zk=7r5L6Gt5_?>g?KQ4{r{#bT-_h%>xz1WQ``Bzlo&9$cmiKjv-_#273zl*rF8OcPL z%8Eg1C%PVcO^+v9Kyg1IWiHOldMwsdy6Eld#=Tm z%&MGrIG^xwec22tq|bGqk}xuV6-l1*M0RJgu?)AP8LdVlFlL57T%4f6tzVM<;0ew4 zRQA&H3h|DVLE1M-g15%YS2b#NZG#Fus4TyoxxryTCi`eH{xoBow-k?9#cu;%>SmX7 zx4XpX%zMRzbhzdt%q46r*%xnLn=#F};v@S)va72y)R)Q0nhxMs}>BMO^?#gXxCKDSzagn+aKB z0IS~x>a4HV;<MkMn%QK4r-sfFe*>A?}9PdVa zB_N0bp^Zd2W7zuF^==mF$g!k1Ypmm{VIR<%c+7K>c$Mo`dkmLPf_7ud>jf?gv*3HdV<5evf~^jrY~4BvNCo>3}9JNNEeRHd3Zo6sInC zX>naPr8v&Fnow)~$Getu@a?qyum?A1k~7T@OCCoPo~ z8RdVzFWIq*dZ(QdFKJ~O=c~WzUcDYUB|a|6b-^`PVoQ>J@(~`5=WU-;65dp$sOWRe z!FYWnG^G+O9Qq(i#6S3Q7(hr(M|d|7XZ&2flzYfJ|I`bAVWM%tdRruBh~dI=jI|5T zQLAFNQIj$t064yB_d{~*&izvtY`KN*+J)}sDGzH#s!N5U@2Ds8_BjfbPO^-pM-ach z_!ADFx&GS~#_W@fFoy9I+sJs7&~+Sj$M%O|o~2Mg>L0PE@ImMGL8&3EL4!Kt?Rm^* zqQD(~vAPicucN$N4+a%w&1R?~U5h^L<#hB#%UQ#e1|@PCv-#C*KgC7yYCB zUWXb;d_^^jyU;QBF*7yz(|vv{C+k0IU0PrHeXXxP*j*bo8+UB+ZLc_YLs~7knG^Rh zb=IWI?qTU;_DMB7;0AucI0{Si>lYcYh$R)R4*IV*69^tV&vq_+`B-r?h0Qnl37YX# zOi0gk>+@etLB#Zm?*6-7Tb@VtXE7N#oXiBx~g3fg-{r9dmW&8Gd zP#}c>;><QqM`q&E0^?7aK%D&CxId`7- zA;gxq{CY%dii&<^RL9SqD3A#0mX!ok0D*v+SW4NveY;!UPU zOjD$_jvjyisL%F~gy6!i}Ta>>?!>xPa)i|+RA{?6{5M(Jd#}p%5?K2#U5AyTN zqg5TdjY4H??v8;!L)qMVNzorITEkR9@Vx!=WK5FaQ|#gXR-r^w-^r;)nu4RC5iWwp zFh|Z~=D8nG+Gd4#k9dzk#$#aj`~=HhI$j@f2%%5*^IyYX5_pyf615}@F3G)93|FSY z;8J8w{(LG2bGn7X?2s`@&r|#Dt%hFk*$8ym^E%vfdSp=3k7X%Y|D3>+(sYl^&M)+*gMInmd=m6hA4LYLVtv~%Oi&xgvNtVtv#CntaLm^Yv{SDhKJ zt??O@kfUEM$cy2O>$|G5nNq&(aZQ@Sfz%0HJ;!5YKks~4SM;QQw?(Y^%8KK=g(^#Ae< zIX|(j`PUP>n}G#L=pL8?;)*j}c2)7|NfQ^C^b8`R%>_9q?%ZAgavwR@ef>>%JW4 z)gQI4b+EoK!0QmLW%^t8rKvD}$!s{dU}P=;@7u~%N)tuKun);; zx80Ia(()oAzX?wR<_6)y?K_r7@Yzgh9`3PxMWI+{nCcqJwPfyZ4 zW#pm$@s0g7A@W9rVsME*qMK%4!c17C$wBkL891@toc436X@jU3a1RbFhiP>;$-z}T z_Q}h5=m%P_G|owacaYo!;29hQWDL;^lFq2~IdbH3j>Nb|dq0GzmyzjOB9!X|Lf9oU z!!sSV63S(Be-Tz(^ABLpUVpzK2Q5h zmYpb+3ic5SITAXOz{p4sIX;&Dw3EfaboyR__uq&9@CMu!AzqTe9X(BBl$xy5bRfeO zZ|QkTN!OmtD{r$6O7(m8BYy^yo{zr;CpbF`i#(%bIva!JI-|`{7|lgiRaI5_DD(^o z`9xvKw8e9-+tOsQs2mkoQeo@+)-cv}3JHjQ0WBqeU%d)7tXOywgpu7=@RZ;5=W=jz z{s~NB>)-sktpf3ND~KfW?YWLf_E@cvb@Z?1AjB zF9~1QMtBS=?q9#Cl_iIjIfN}#4ljj6t})5bqDT{Niyn`{9?t$)=m3rK#H?$XN%DZg zfScu4Xkjde`X62gplN>|sG)dFj_`Gpu_|o{V!p(Jf6y-tnqM|z2P9qLDLD& zp@|KPUP&pg-gZA}(jk;z@{xvyxRK{A-a+jOifYsoWlGPeJR(kz<^4aO2N7PowV#YL zF&%F-L@i(7e(&{U$c$FQ5m$)yYj4b#4>;}r!SOct$kQ6IvZMV-(YOcasyd}^k%2bM zA16p%V&Jh8?VJ_5P?&XVf5c(t4+2s0Kc$1W2MM!mz(qlG zrZM$XY${HXcjTUN`Q2xpfZaQ9&Zv$hjePWax&T(x-k4-0h^SYFSN5q(H)WhJ58C9t zt7;;@DL1t6N`PBiDCbCLH%nL?DSHW|p&P}If17oUx|*Lb7x`|@^(4WbQCLNDgWX^i zvD3)|-^Bj%d+MK4gsp~{uyx357zP1~#`QB&>Ud?>aahUKE2+6|#Dmm@aOW3GFe6H( z+I}n-e7Wem+21KIbdR&ecOro%aHDknA`JW;jTQzAlYlLxoaB4)_=n`{Of4Jm@ z3+1G+AYBQ~t^n!a0~d%5{jhy_2djXB7c(2A8?b8PL}CyN8E-Sfz*Fs@p}q?O?)Pf~ zn=;eXFmX+)u&mQvzljmLCu0G7{RM5R62WVu14KxRZ@wEkm zzvo={i~brX%UW>k$%T4L>=hsH-ABnX0NAvPz}BO|_LCIW?E%bZJBZbNap!WIW3{$K&hma5d+DoQK!!)yJ zp^~vN0(h_ky+aq7*6Dfto@Y@J49;tWx}TQY@(7F1UNf@@#`zunT$eT*PIjbZi;2Yz z!RlnoPSM$P1R!|_>1ykcXIVA!-U0BL2wp~tper-#y7hdWyItTZlsH@M+=z#p%DfHdlIftb8>bM8 z-=rq%-~g;)vekDTfA4iUcvGi@Y+XdQ3{KcgU&U;krdnsh4K$EXCcBH3YmWqxwmeb> z$sXAnubT`%3&X@&!y6~8Kku%*UV;DyHBqq7uBK7%gd(2|wZhbAxOyL;b%yo*)B2C1 zUpV3WLDAU+jH6gvpPxwrKM@u9A=5qqH-D7MI8Wn1me)fz_1{2Gzzv z)h1t)pmk>E>k*v2B_no&1-C?*ek5>bTz;em43MIWEg)6q_!PyQWHzVsuEOc(wG=_i z;MvS0s2Aj#)H>_Ho@g^#`35On4axTBq{JFcIs`iS34elZZw9naiBQ1*S$&&LUA^ZpstKlhG;IR#ZTCl-dsi{ndDb+D*p2j#G?cc@{hvBp(lq*8xjP;7{N$WSt z;4_qx)5O&Av62zou2BJpUNVL0>)ToYy`=jmYLUxf|}rPo2d0 zx!LX)g+tAdotgUc>b};(^1VKZ@;Ov=l+}AdNx?&|URZkfTKVKyqg3Ey!ZjK=q2*i& zbB~{&9XnoMfN9reU(dgCq>A4gfAQuF)Yif*G>;Fgmp6<{&HVVO$_Qx27nsBcq~N??6%MR8QFzCeVre&;Hh2RTNTyxaasgA2zf1xnAHtJ6|rb`iV)3*U<8g1v}C7 z4!D7;R=AjXm%4T%xFQE$pXjAcyK#&Jen`tqO?fxl88%9s%US*Fz#@(?mxncBsssXL9_vcl}1& z`8Fd|M3=Cw+sf#@qP>1G?}P6Xiw_Z$VolObGwqFWbxBzyNgI*!NWv#>Vhv@-Od{6NaE>|rPJg?B_G*;6cS3Eo9{G1Ih4?DXm3eZ* z!c9ZljaGg(AWq!>$$WCQ%3ji6z~}g|&7*yhV1k8)p)sVp%DPXXXa8~K-OsTpbe<4Z z_PX_ctn%I$Pnz8Yaw{kTmBxnW?z{mbve6-6&ixiy%pSY^Xz}b4OVJ#L#%UEgHEoVv zHpAk`SS87L&0V6a3oL4Qcv(0O_(xFQWt!OTej&9aGxXr~96}{oi8FQH8MGNHO1XIR zRd`vV<`xjF9(XOqPuDR;2>b=cOf8Ypt~BoIRE3Y9p$fJGRmu>Scdg}mgmy%G4=9ESzk@B7A#NDO#ts>f( zD~*|$_%ib<*n(kTXz;;kRay!P(!-RQ@zQ~sd#H*+25yJo;@aAV;GmAgI&5ElK$rmwzAJq zCdxP&CCZTuG0@IO`GbQ&hLTgH&7<}*6M3}ccA1j3<%hgS>Zx;6qD1PMk18qZKJj;X zOrm&2BC>bQz$tw-QZ!QusS?DS57mjxB)%yk8Mv%H|4_v# z@wWUmvUs2qDFgaka-{r6B#Q;X<@Cp3NZT)+w1_FEhj6 zR?daGsE}s%V<^B7fx;sScj4r*l|s(_?NAzbF_p?4+^2{1;`Y3^3UoK}nh&62sat83 zPdTymasywl7x*1ZiI>+n3cqeZHpSsdW!B<;Gw zY_UC4`DQTOG?L_xN}%~0{kIt&8LTuNATSW+C6vB5g=-s>(0F7`%$#0r!8Ispo3K?y z{&p1dXX_f;x?zpx46Nc=rV4cC^u(FK=e3}vtIBNeH&03%JU_f4I|ijpCm|1vNhkC1 zIzfP-(MH};*~V5lZOSYd8x+3tlNGb>#qt`z>ooA2TdFp-7aO9wUnJUtsedk<0a0fP zfSLP$?2DhY8F5FL9uHn#53DL9^!mnEbgyT`%f+J@GLrkCM*jHpqGNkmO z6f8$3-FD1k4lnuoSw9dg>h89g+YC%J3+r7P(c)Ni_4{D6UQXJ2)@-oZThhIsbzRVT zX|(3Cd<+(kz&4jw`++L4(M2V$4XaTiRnrVelL{PCh8mvCFb3079;tq_;(h!xmG(Jq zM&0qQ@}|@*arXs-p`f4?R91xe$KA!lT>&=n&)DlnTaE40>xYjFgRkoc{7#q)Nt0A#^wLM9{}||C$W+ZLf#Mc zS_3^x7C&nWY~7r@k@C-dPfkMj2*AIF@2CId@H?SskK>A};m{@EYJG}YU!7w7%U~ga zSiIeF_9l`sQ#5p4x%+JCaywb8C~o~zcLF5iVO8{fGsxPUqRE0gOj$FVYKy8h`k9S! z+=QO`j#Q)YgEjODX&M9Xv6;^mGX)g$j+sUAtwk3a4Kp?Uy!x$O40mK5Gv&igBP* z(QxGB!IzJqY&nOUQ0Kb93RQ`lf}bzw8D^*aVG68htP6P@jZCi)Oz*#kiio^MuuX`Y zTuq5X$^u3IOYddR>ZF#_;0L7tQ~-kC4Mc-#G<OKQL(vvxz0upq)F9hnDf?G z3~>p%FrVy&U@wRMsH%D}7z=`w2azVBR}84MPm?jcK0ql)&~u2bq#&F?i?8|5 zu19bJP55TVpdz_U?l*CWwR!g@kC8kJNo4Nai9R{=;|#9>2I=x(MDy^yC?mm+-l(gc z(V3dR1y;>Mn^otT6cQK81igkx)7{voSYq%+yhZqt+;Dc2rI1Y zVhi48Ya3Mr;2|kFSD!y9F*wj4F;K>Fft*uUvGh%^2!R8%#_a<99*Idvojd3*>L@k* zJk8_V1?Gg6#W0_#5D%w8DtwNILbQQ@v|3O0=-~?`lFjL96L{mV!_nFWf=9FHE5nx~ zlc8gm>elY4jIYrrB9Val>Kh9`YAd4Z9+_Pd<9|^Lodwf7W*vME(#G}kZ!pS)q{(|GM8v^-#WSiZCS z1`*5iJ4K>;6QcDlf9r4@kP+^@h2zRS1xLrkyp~Gxx;~uhaTf}7-{h!gAv%D|M%YsW zM)R&dtf%ju6opm&ct(5OqS)i3phfMOY~y$KW8CWuA9NZw3w+AxWRGn496o;S7UD>J z{=)y4IStR=?__a@+uMTQtxyK4yeO^-DRNsRwz zSU`9%9QULrtck_hDT6*(+RNp+4ASns310O&`K8q>#|LZrQ^6mc-S%}660u(#7P71v zVC?lBIUKK;IhevJzD={!XZj`=N)L-%oSd&NMW3=eU9J-uY(!qP z%V*Hv0Oiovyr&fXXJYBqntT4b{S;$!9Rh1oJOQjf#;Thu)^`al*A7m>A$T3sO(}8= ztqSsHGvJKJo>d6N$#^0)XXo-FqbfDvQ4Kgv1Aez@_$@sRkf{7S!qcc2%Er0Mv~fy{ zO7Q=spX=f0DZF`2K|!IwxYtL*%}m2lB?VaX1()rw_#w#;)LbpIE#`NeDty={#b5~b zX_Px5s2nBi>eHL@xY~gya+$JTm(^rG?^*KbzQ#DzZv^v){Fw;)rOTzs(}pj2kCCVH z3xqL8g^NOBEuk)q9Ss+{``(ab<7K;TOkbVT?X~=J;D5{i6QBR(=IMKkH!6wT^XrFK zrQ%^GiSSg}q)Cdr%2?Y3FN71WQH@^=z14~THzPx$nh>c>HM|mbUyc@FA)=eAFzxFg znm75TnSXO$K*<15Cp@9xa7HP;072t?f-n!zy?R~+Np(EAP#Ui%A!v#$r z9Ue@#qCp1F(mOX&BQ`9iHJoqg^i=CJqGHfreU*fIIP(^m5m z12~>?RItZa)R66k3XL&iM2C+VyvMw@cbfC;hBC$v&F)wR>0xW^ z-izGKQ6enf1x9y)eo@5K9C4CGYnJ@e9nJDGJ$V<{Ol@D&iC84D4XO_t{UND$dDtm? z$AB(SJw?{*eHj_yN0*^L)4_TH*(2x_e?63BhD}R=2$`-`Orn%C|YOfeECCc)9J$7MjaugXx4dw#A{{0 zi3P^O=?oSp8K!xg@BjW-x!9;UT(*;acR0MN`7JI#v$pwo+Y@SA%fIX#=AgWA}j_-D1SMU!ru6b5Dy3 zeFLCCi8C2Uk&eyxtlM6c#PoV>WS|Z76C6Xvw;l|a@Sz3#!|8Z8 zuH(3b*S4iwu5OTFmWjp*kwx{tF#zz1=>{sz_M*Ii{F&!-a;#HrZz^wZ;NDo?at62a z;w;@izdzLy@YoN|4D1oaBR{SvFS8KVB+BKfCCmUH`s*bw019FN%6=9Rz=d{RW)2^z zI%W2$pTqY*;9_89BMbwHzAQp;KDb(1m5kh^a+JYsX;hRTbKlH?_6Bm^yLA()FRw+I zOgwg5Z$QC$%hs-kSI9&p?HE%ra{A}c#9;`8L^}w&IG$eiiG9)ouax8ixY-DK{IK`u4u z>U;@#iU890{-^-_t9G_}1% zhL_(ZWnaLca$#N+!r~&JAd`D_5`Go0kASBi#89oXxd{`8v*O%`V3*Vu&1B<8ys-~~ z!e=-P-Y7T#%9$El0<4DzUO^)r8U?i!k0ZL^B7rdgbDy0mw}G5-5*5jOh5wG{Mo^n$ zz#dR2!&kSUqe7gVXQlmEs!gr`%Z}fMxzfhib1_@QV%%`UYy%`j*?b0gEWvE zhs6Nu5*H948QQ>p0SD%n=JJy`{+dwhk`^$+Bn}rF=ii{?0rNAqrdJqyrlwbNyp{q? zC?**@nLk%9kfouH6@C4q-U6oWTSy2~s*I3jc=U?2nGNEtAh)z|BR%5D(35|u23Us@aS>FLWI+fTvxPZfX$U7TryTouYkM(bBD zPfY!YmU?Vob#{9GWUP#}>5tn~6TVaA@kCiB85uW__j{wZ#w3}f-L>$UB5&|p{C*2K z9k&i_X9d&UWw)FBpB+UYu@!r?A$)!cN82CxhoCYJT_r*j-3!?6+y_#IE`ACdHvK2) zofIy&;o%eIQYEg3U!_t3PE@;cM^I z{+9h%as1r!XdDg5uK98C!U+QC{0r@& zMkHf{XfUM=6-u4H*TXvJvp(zl7ktIoe|1{;1>mmwAz-OCpb3;)=0< zsTVZXF2bk!C0G*u@3o}=|EK*QdTL-nxZdRK-9gsE#11;@5EYDbiqH!~yY$B_Op_O@ zhl7N<9a=TErxTz80B%Xgn!4o?(ISh*t`&)n@pjajGJx`aaCSQV4EG4J0i6yfBBxF4 z;M_*{CcEQ!CNI{_2^lufvCe88o63Fp0gYzn=ht_i-*^~LmJc5{@R4QQBS1Nlbes4g zJxh9z7~LH9Zu!W3*F==F^}%4hol_PrYrl<-L;C<+By(ThY);>30@$YQKUcanZV;`J zg^0`-NTI#QFrsAl`vHGCEAH4_O}@$v+s87KMLQFlH;77qvH@k)HI37O_D^@j#>$e* zZ;ddyqi}&Mh@ASbDPZ@@`!`W-`dTe7>BrL3f)nNlCuR{sHTmYOn&gu56xz`43SSYv z3+$J6`zJUn+PI(jCC$1YB)cyI)q(A}MLTIF|2~Fw6z||%1Y|T*Dsw*$^f-|?V85*o zEd;9qYq_d}!)K?~c|6THFy5ypXH$6o;}7OM(_u@5kaip;kvyy$M7Izdt+f+E zt1W2h>n4NdQf@`SN8^)jAMqv1x(s0{um?(A9`p17+asNMK!MVPC;(JzXt3_&l1X^d zj|_t72GXR6xE%x!gjoSP!sV=$kX%o^ee{ha=O8rZS{K>d71jLkz6N|PMZrOXF)X!k zyqLWD0Fv49tU9v=A*w;0)piiJ;n%akU!-aqr3Zn{=tp^Q19F=+O|)0E7ycl#S?LX) zxXUfN!SfgRKi{{~DE&~P?xblr^Xne~Cv-Q*#`n$XyHpRX_ii^D_v$Xb6y_;ooiUd` znc@*Wprkey^qb3f^Fg>eBNj}zC{XeRuQXrLM=;-n=?3-CDj$_r!*NOKtx(dMdnDP@H?(T zN6E!-ysAYC}G1PLuQL-Vj11PW55NlUD~?nsaJ7!NRTjFg({#^VO#zLclyPGU7V5>4KUGnO;S9CycGF#D%M+C)?7wa)YBUGm-M# zs0xK#Sr)|p?PEfYcuSx>j{SV&%xk6)XUbM$#v)OG;nPV-Mhr;9u;-Rn@++VknWaMx zUObW^wG>|lwUEIzIv*J%br)xCi6Y$3UHrP+%i#22Q1komV~4COKUKW6@6fp&v~YH| zk6{IT>pR?c)|;HzGs_G^;=DBh(fPgY7h`NI5$SO>Tbb}QkZ!P0hJg;`3qcFVT-Ep@ z%E!>?>pU%q`4Q(ZTsNAI2(;M@_bU<3svaWXFN)E>D@7L`=vLTMaoSmN@e)cTR}h_= z`t@xy+tyxvwg5v!KJ|19o;Zs0U%Eh6ZlUY<0fd;Q)q ztTx#zCTR&rv$~OoL=F*@o9D3hxw*B0baXp}i4@l3!~mh(>`MNFEIXS2%(zn(9{Bo% zH;67W*o1bTvA4;}(qL5>uK&SR`dgY$mXZlclpQ){?oSz3(k7nNhz~#{&aD$J!~YCU z2Cbnt<8Z4*gX~B zgk*3cbP(Aacaf5#fC9rVS;G54*C@_@RPvkf+h_M+_1%Uk7vBL{tY1ArST_Oh>MvYm z>(MN=;!|0bA=CcJWlTaiTJ8MYjl=`=zdewCSq6yx47e1zV3oIFUnWg)o1{@+aW!@V z$NB)Zdu#APam}C(4D&#lIT{lTeO1g$dckBaxOX530Y$QQbTkI)1+)%uiuSHDRImZ19H9zTTBA|B@ zQhwjuuhCH&BA4;WrJCx=JwP(--j$&9-uOP?X^c(;J=6zviP3DV>5}mo1ChGC7+@sG+>qpReG2ym2lt7O=_=#TK@>Ix~RimM`m`5gnnd=gR{AJO8~ zIXs2o)L1t8l~Xb~TwoWxtnJkkq-+VwoCc)o*m9+##*yop4*h@qn4J`}40Xwwm=`{R z$G%#SaF0@Edteh$dHSF}vVPVBN}Ha-?w^LF$(>)D6~M!@0?hp+KyM@EaDOOR%I~)s zI`9K9M2C*qR?pp^J}%humDg7D z)s}YYbkdP##iLhNG9F#YStrjL+?tas%Pduy!UVz*KVS>nr>8&^82N_e=A*LP(_WA> zjS%ZX{j#-!@8p2SZLq-L-78S7azym~!@dqZ8xbp|*RqwfWI`q!D^8&Ul(KxZi=R0&F!$x3o&9Cgj6}+g;_^*r}3DpAw^_rQqMonp1I?u!{Bbi7l%jO2dJHNo~gODDT%dtv1-7` zm~oD>58fHDwu~%0p1g5NG5otpYk<^CN`@S=IXUolTQ#~p;s|$8>+OmYhJuf+hN#LO zUe=0v6D^R;U*2^m=u^SAtD(W)a%hz*F;|~&cmx)7U6Z5cSnH?In*-=G$JupH7G&Q&8ac?wnbg> zc*W6w_{vmye0x;f#7AgdcB4G|NireLI{RCRAX6k(jS3WkbGXa)hY~;|m+3Z< zj}1;R&~PThv|S!%orjkn!`8&Hz+-n~_LDTltddT3mvw;yAo;Z&8-p_4%IOl1haPk&>m1zqcwmX)2&beeAY3#przmMBMSx7hvq<54)E zZYkTSFZbDDS{Axjs%M6+p59CXlos12rT0dQOts@l&TS=deuLkIgJZo8fK~D%|NO&| z_tAdaHohbr%xzZX-aFs4c@urlGsB@t^olZuVw*)X5u~6z?>-dZj ztt4Un^G#Z+OI@bcF-l}sNl5%18~TqI^=b4^9M%mF5)I;oPA*Ml>l~6t86I&P#qSZH znoYX}{MWJO{?yMqiTpHIK)2}At-X)MY7diK9ZBw+b3@^=`M&M>XBJl0Td9!0MAprl zH9e3awF*7r;>Pp?UxzH4ZTp!#j+g!z(qz_z&K6myPNtn&90#6H#SJc&Mx?JBd3{39MNvD9i`4({de8_gHTaoyeDs`fg3wB&J$Tz8Z*`MQl@ zmv^Oqd1{#);lp`abfek5-Dj@6MQbb2Pv@6rs!H(zD5v|De46}+BS(02#CYVz>;5mu z19QOWi#9VTSrD?GlzTHvB9tN@)t@`=P`e$z-2xbs5cN?^vZ(#Hr-Kf-$p^|L zT~kCeoaPdqh+{J|Joq*=lwz33$knEOkV(1X7$_ROny$faNRJJvqJwyz*W^1SL%a$3^01thHkST9R|jJ2f8Mxx1l z2~{LbFLS2qSJ28utfD*eEw>O#C2PDxPd_zi(Zn}okc@?=8Ee39;vZ#S0nR+%VnWan zaz7a=%_?BQw&BKK)tD{n{5*>@rtfm1_8RyloPm_-$f;J4B@3Sl(*s7@!ACosXTAU112a# zlEvf=WLQNuC8%G9hS8-aiCr#OUr}SgRu2{2eH)Bwj)17y_i^fXjSUI^SbXy(3}mjk zwJg2pMk;UTv&djg%|tZ;N+j{K6{lbth{Hg0`c-{z)LCbfl4z*=Qi!yj{|)>buba_C zyj1TV>T@jtf0TP;bdoBZf1i!PjUf$rRe_Soc#4bKLB)=RO$hsJ{qh`Yz4B4C_DB_y6enej$ePR_WG{bLAC%#zmLr!^Wv;Ap@d z6QT5gm{uaikm&c1Vry}(V@8i}-N0}AWsOZ?e%A~y**-BBa5woUOSK5fDam5K>qH5N zZ}{or0mlX1h{y!A1vjtFXw;>kcV578Lu#c{?Zc}mB#$YV9jD>4*rmH=D;H&rvW(-j^R<2K2AJLWMcClT= 0 and current_slope < prev_slope: - temp = opt_list[prev].prev - opt_list[prev].prev = -1 - prev = temp - prev_slope = opt_list[prev].slope - diff1 = b[i].d - diff2 = opt_list[prev].point.d - current_slope = ( - b[i].fc - opt_list[prev].point.fc) / (diff1 - diff2) - - opt_list.append(OptimalPoint(b[i], prev, current_slope)) - - opt_list2 = [] - for i in range(len(opt_list)): - if opt_list[i].prev != -1: - opt_list2.append(opt_list[i]) - - for i in range(len(opt_list2) - 1): - c1 = opt_list2[i].point.d - c2 = opt_list2[i + 1].point.d - fc1 = opt_list2[i].point.fc - fc2 = opt_list2[i + 1].point.fc - if fc1 - c1 * (fc1 - fc2) / (c1 - c2) > (1 - 0.001) * f_min: - # if abs(fc1-fc2)<0.0001: - opt_list2[i] = None - while None in opt_list2: - index = opt_list2.index(None) - del opt_list2[index] - # for opt in opt_list2: - # print(opt.point.fc) - return opt_list2 - - def direct(self, request_num): - """ main algorithm """ - self.dim = self.l.shape[1] - division_num = 0 - - # create the first rectangle and put it in the first bucket - first_rect = RectPack(self.l, self.u, division_num, self.dim, - self.scaler, self.aq_func) - self.buckets.append(RectBucket(first_rect.d, first_rect)) - - ei_min = [] - f_min = first_rect.fc - x_next = first_rect.center - ei_min.append(f_min) - - for _ in range(self.N): - opt_set = self.potential_opt(f_min) - - # for bucket in self.buckets: - # for i in range(len(bucket.array)): - # print(bucket.array[i].fc) - # plt.plot(bucket.diff, bucket.array[i].fc, 'b.') - # - # for opt in opt_set: - # plt.plot(opt.point.d, opt.point.fc, 'r.') - # plt.show() - - for opt in opt_set: - f_min, x_next = self.divide_rect( - opt.point, - f_min, - x_next, - self.aq_func, - self.scaler - ) - for bucket in self.buckets: - if bucket.diff_exist(opt.point.d): - bucket.delete() - if not bucket.array: - index = self.buckets.index(bucket) - del self.buckets[index] - ei_min.append(f_min) - x_next_candidate = self.sample_buckets(request_num) - return f_min, x_next_candidate - - def sample_buckets(self, request_num): - self.logger.debug("In lne self.buckets: %r", len(self.buckets)) - bucket_index = [] - fc_sum = 0.0 - x_next_candidate = [] - for bucket in self.buckets: - for a in bucket.array: - self.logger.debug("fc: %r, %r", a.fc, a.center) - fc_sum -= a.fc - bucket_index.append([-a.fc, a.center]) - bucket_index = sorted(bucket_index, key=lambda x: x[0]) - for _ in range(request_num): - sample = np.random.rand() - stick = 0.0 - for b in bucket_index: - stick += b[0]/fc_sum - if stick > sample: - x_next_candidate.append(b[1]) - break - return x_next_candidate - - def divide_rect(self, opt_rect, f_min, x_next, aq_func, scaler): - """ divide the rectangular into smaller ones """ - rect = copy.deepcopy(opt_rect) - division_num = rect.division_num - j = np.mod(division_num, self.dim) - k = (division_num - j) / self.dim - max_side_len = np.power(3, float(-k)) - delta = max_side_len / 3 - dim_set = [] - for i in range(self.dim): - if abs(max_side_len - (rect.u[0, i] - rect.l[0, i])) < 0.0000001: - dim_set.append(i) - - dim_list = [] - for i in dim_set: - e = np.zeros((1, self.dim)) - e[0, i] = 1 - function_value = min( - aq_func.compute(scaler.inverse_transform( - rect.center + delta * e)), - aq_func.compute(scaler.inverse_transform( - rect.center - delta * e)) - ) - dim_list.append(DimPack(i, function_value)) - dim_list.sort(key=lambda x: x.fc) - - for i in range(len(dim_list)): - division_num = division_num + 1 - temp = np.zeros((1, self.dim)) - temp[0, dim_list[i].dim] = delta - left_rect = RectPack( - rect.l, - rect.u - 2 * temp, - division_num, - self.dim, - self.scaler, - aq_func - ) - middle_rect = RectPack( - rect.l + temp, - rect.u - temp, - division_num, - self.dim, - self.scaler, - aq_func - ) - right_rect = RectPack( - rect.l + 2 * temp, - rect.u, - division_num, - self.dim, - self.scaler, - aq_func - ) - if left_rect.fc < f_min: - f_min = left_rect.fc - x_next = left_rect.center - if right_rect.fc < f_min: - f_min = right_rect.fc - x_next = right_rect.center - - insert = 0 - for bucket in self.buckets: - if bucket.diff_exist(left_rect.d): - bucket.insert(left_rect) - bucket.insert(right_rect) - if i == len(dim_list) - 1: - bucket.insert(middle_rect) - insert = 1 - break - if insert == 0: - new_bucket = RectBucket(left_rect.d, left_rect) - new_bucket.insert(right_rect) - if i == len(dim_list) - 1: - new_bucket.insert(middle_rect) - self.buckets.append(new_bucket) - rect = middle_rect - return f_min, x_next diff --git a/pkg/suggestion/v1alpha2/bayesianoptimization/src/model/__init__.py b/pkg/suggestion/v1alpha2/bayesianoptimization/src/model/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/pkg/suggestion/v1alpha2/bayesianoptimization/src/model/gp.py b/pkg/suggestion/v1alpha2/bayesianoptimization/src/model/gp.py deleted file mode 100644 index 446238c0669..00000000000 --- a/pkg/suggestion/v1alpha2/bayesianoptimization/src/model/gp.py +++ /dev/null @@ -1,38 +0,0 @@ -""" module for gaussian process prior """ -from sklearn.gaussian_process.kernels import RBF, Matern -from sklearn.gaussian_process import GaussianProcessRegressor - - -class GaussianProcessModel: - """ use the gaussian process as a prior """ - def __init__(self, length_scale=0.5, noise=0.00005, - nu=1.5, kernel_type="matern"): - """ - :param length_scale: the larger the length_scale is, the smoother the gaussian prior is. If a float, - an isotropic kernel is used. If an array, an anisotropic kernel is used where each dimension of it defines - the length-scale of the respective feature dimension. - :param noise: - :param nu: control the smoothness of the prior using Matern kernel. The larger nu is, the smoother the - approximate function is. - :param kernel_type: "rbf": squared exponential kernel, "matern": Matern kernel. - """ - if kernel_type == "rbf": - kernel = RBF(length_scale=length_scale) - elif kernel_type == "matern": - kernel = Matern(length_scale=length_scale, nu=nu) - else: - raise Exception("kernel_type must be 'rbf' or 'matern'") - self.gp = GaussianProcessRegressor( - kernel=kernel, - alpha=noise, - random_state=0, - optimizer=None, - ) - - def fit(self, X_train, y_train): - self.gp.fit(X_train, y_train) - - def predict(self, X_test): - y_mean, y_std = self.gp.predict(X_test, return_std=True) - y_variance = y_std ** 2 - return y_mean, y_std, y_variance diff --git a/pkg/suggestion/v1alpha2/bayesianoptimization/src/model/rf.py b/pkg/suggestion/v1alpha2/bayesianoptimization/src/model/rf.py deleted file mode 100644 index 8778b921e78..00000000000 --- a/pkg/suggestion/v1alpha2/bayesianoptimization/src/model/rf.py +++ /dev/null @@ -1,24 +0,0 @@ -import numpy as np -import forestci as fci -from sklearn.ensemble import RandomForestRegressor - - -class RandomForestModel: - - def __init__(self, n_estimators=50, max_features="auto"): - self.rf = RandomForestRegressor( - n_estimators=n_estimators, - max_features=max_features, - ) - self.X_train = None - - def fit(self, X_train, y_train): - print(X_train.shape, y_train.shape) - self.X_train = X_train - self.rf.fit(X_train, y_train) - - def predict(self, X_test): - y_mean = self.rf.predict(X_test) - y_variance = fci.random_forest_error(self.rf, self.X_train, X_test) - y_std = np.sqrt(y_variance) - return y_mean, y_std, y_variance diff --git a/pkg/suggestion/v1alpha2/bayesianoptimization/src/utils.py b/pkg/suggestion/v1alpha2/bayesianoptimization/src/utils.py deleted file mode 100644 index a63bfb3b169..00000000000 --- a/pkg/suggestion/v1alpha2/bayesianoptimization/src/utils.py +++ /dev/null @@ -1,17 +0,0 @@ -import os -import logging -from logging import getLogger, StreamHandler - - -FORMAT = '%(asctime)-15s Experiment %(experiment_name)s %(message)s' -LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO") - - -def get_logger(name=__name__): - logger = getLogger(name) - logging.basicConfig(format=FORMAT) - handler = StreamHandler() - logger.setLevel(LOG_LEVEL) - logger.addHandler(handler) - logger.propagate = False - return logger diff --git a/pkg/suggestion/v1alpha2/grid_service.py b/pkg/suggestion/v1alpha2/grid_service.py deleted file mode 100644 index 0884b2db8b1..00000000000 --- a/pkg/suggestion/v1alpha2/grid_service.py +++ /dev/null @@ -1,110 +0,0 @@ -from logging import getLogger, StreamHandler, INFO, DEBUG -import itertools -import grpc -import numpy as np -from pkg.apis.manager.v1alpha2.python import api_pb2 -from pkg.apis.manager.v1alpha2.python import api_pb2_grpc -from . import parsing_util - -class GridService(api_pb2_grpc.SuggestionServicer): - def __init__(self): - self.manager_addr = "katib-manager" - self.manager_port = 6789 - self.default_grid = 10 - - def _get_experiment(self, name): - channel = grpc.beta.implementations.insecure_channel(self.manager_addr, self.manager_port) - with api_pb2.beta_create_Manager_stub(channel) as client: - exp = client.GetExperiment(api_pb2.GetExperimentRequest(experiment_name=name), 10) - return exp.experiment - - def _get_algorithm_settings(self, experiment_name): - channel = grpc.beta.implementations.insecure_channel(self.manager_addr, self.manager_port) - with api_pb2.beta_create_Manager_stub(channel) as client: - alg = client.GetAlgorithmExtraSettings(api_pb2.GetAlgorithmExtraSettingsRequest( - experiment_name=experiment_name), 10) - params = alg.extra_algorithm_settings - alg_settings = {} - for param in params: - alg_settings[param.name] = param.value - return alg_settings - - def _get_trials(self, experiment_name): - channel = grpc.beta.implementations.insecure_channel(self.manager_addr, self.manager_port) - with api_pb2.beta_create_Manager_stub(channel) as client: - trials = client.GetTrialList(api_pb2.GetTrialListRequest( - experiment_name=experiment_name), 10) - return trials.trials - - def _create_all_combinations(self, parameters, alg_settings): - param_ranges = [] - cur_index = 0 - parameter_config = parsing_util.parse_parameter_configs(parameters) - default_grid_size = alg_settings.get("DefaultGrid", self.default_grid) - for idx, param_type in enumerate(parameter_config.parameter_types): - param_name = parameter_config.names[idx] - if param_type in [api_pb2.DOUBLE, api_pb2.INT]: - num = alg_settings.get(param_name, default_grid_size) - param_values = \ - np.linspace(parameter_config.lower_bounds[0, cur_index], - parameter_config.upper_bounds[0, cur_index], - num=num) - cur_index += 1 - if param_type == api_pb2.INT: - param_values = param_values.astype(np.int64) - elif param_type == api_pb2.DISCRETE: - for discrete_param in parameter_config.discrete_info: - if param_name == discrete_param["name"]: - param_values = discrete_param["values"] - break - cur_index += 1 - elif param_type == api_pb2.CATEGORICAL: - for categ_param in parameter_config.categorical_info: - if param_name == categ_param["name"]: - param_values = categ_param["values"] - break - cur_index += categ_param["number"] - param_ranges.append(param_values) - all_combinations = [comb for comb in itertools.product(*param_ranges)] - return all_combinations, parameter_config - - def GetSuggestions(self, request, context): - """ - Main function to provide suggestion. - """ - experiment_name = request.experiment_name - request_number = request.request_number - experiment = self._get_experiment(experiment_name) - parameters = experiment.spec.parameter_specs.parameters - alg_settings = self._get_algorithm_settings(experiment_name) - combinations, parameter_config = self._create_all_combinations(parameters, alg_settings) - total_combinations = len(combinations) - - allocated_trials = self._get_trials(experiment_name) - total_allocated_trials = len(allocated_trials) - return_start_index = total_allocated_trials - return_end_index = return_start_index + request_number - - if return_start_index > total_combinations: - return_start_index = 0 - return_end_index = return_start_index + request_number - elif return_start_index + request_number > total_combinations: - return_start_index = total_combinations - request_number - return_end_index = total_combinations - if return_start_index < 0: - return_start_index = 0 - - trial_specs = [] - for elem in combinations[return_start_index:return_end_index]: - suggestion = parsing_util.parse_x_next_tuple(elem, parameter_config.parameter_types, - parameter_config.names) - trial_spec = api_pb2.TrialSpec() - trial_spec.experiment_name = experiment_name - for param in suggestion: - trial_spec.parameter_assignments.assignments.add(name=param['name'], - value=str(param['value'])) - trial_specs.append(trial_spec) - reply = api_pb2.GetSuggestionsReply() - for trial_spec in trial_specs: - reply.trials.add(spec=trial_spec) - return reply diff --git a/pkg/suggestion/v1alpha2/hyperband_service.py b/pkg/suggestion/v1alpha2/hyperband_service.py deleted file mode 100644 index 45ed03077bc..00000000000 --- a/pkg/suggestion/v1alpha2/hyperband_service.py +++ /dev/null @@ -1,302 +0,0 @@ -import math -import traceback - -import logging -from logging import getLogger, StreamHandler, DEBUG -from pkg.apis.manager.v1alpha2.python import api_pb2 -from pkg.apis.manager.v1alpha2.python import api_pb2_grpc -import grpc -from . import parsing_util - -class HyperbandService(api_pb2_grpc.SuggestionServicer): - def __init__(self): - self.manager_addr = "katib-manager" - self.manager_port = 6789 - FORMAT = '%(asctime)-15s Experiment %(experiment_name)s %(message)s' - self.logger = getLogger(__name__) - logging.basicConfig(format=FORMAT) - handler = StreamHandler() - handler.setLevel(DEBUG) - self.logger.setLevel(DEBUG) - self.logger.addHandler(handler) - - def _get_experiment(self, name): - channel = grpc.beta.implementations.insecure_channel(self.manager_addr, self.manager_port) - with api_pb2.beta_create_Manager_stub(channel) as client: - exp = client.GetExperiment(api_pb2.GetExperimentRequest(experiment_name=name), 10) - return exp.experiment - - def _get_algorithm_settings(self, experiment_name): - channel = grpc.beta.implementations.insecure_channel(self.manager_addr, self.manager_port) - with api_pb2.beta_create_Manager_stub(channel) as client: - alg = client.GetAlgorithmExtraSettings(api_pb2.GetAlgorithmExtraSettingsRequest( - experiment_name=experiment_name), 10) - params = alg.extra_algorithm_settings - alg_settings = {} - for param in params: - alg_settings[param.name] = param.value - return alg_settings - - def _get_trials(self, experiment_name): - channel = grpc.beta.implementations.insecure_channel(self.manager_addr, self.manager_port) - with api_pb2.beta_create_Manager_stub(channel) as client: - reply = client.GetTrialList(api_pb2.GetTrialListRequest(experiment_name=experiment_name), 10) - return reply.trials - - def GetSuggestions(self, request, context): - """ - Main function to provide suggestion. - """ - try: - reply = api_pb2.GetSuggestionsReply() - experiment_name = request.experiment_name - experiment = self._get_experiment(experiment_name) - alg_settings = self._get_algorithm_settings(experiment_name) - - sParams = self._parse_suggestionParameters(experiment, alg_settings) - if sParams["current_s"] < 0: - return reply - - trials = self._make_bracket(experiment, sParams) - self._update_algorithm_extrasettings(experiment_name, sParams) - for trial in trials: - reply.trials.add(spec=trial) - return reply - except Exception as e: - self.logger.error("Fail to generate trials: \n%s", - traceback.format_exc(), extra={"experiment_name": experiment_name}) - raise e - - def _update_hbParameters(self, sParams): - sParams["current_i"] += 1 - if sParams["current_i"] > sParams["current_s"]: - self._new_hbParameters(sParams) - - def _new_hbParameters(self, sParams): - sParams["current_s"] -= 1 - sParams["current_i"] = 0 - if sParams["current_s"] >= 0: - # when sParams["current_s"] < 0, hyperband algorithm reaches the end - sParams["n"] = int(math.ceil(float(sParams["sMax"] + 1) * ( - float(sParams["eta"]**sParams["current_s"]) / float(sParams["current_s"]+1)))) - sParams["r"] = sParams["r_l"]*sParams["eta"]**(-sParams["current_s"]) - - def _parse_suggestionParameters(self, experiment, alg_settings): - sParams = { - "eta": 3, - "sMax": -1, - "r_l": -1, - "b_l": -1, - "r": -1, - "n": -1, - "current_s": -2, - "current_i": -1, - "resourceName": "", - "evaluatingTrials": 0, - } - - for k, v in alg_settings.items(): - if k in ["eta", "r_l", "b_l"]: - sParams[k] = float(v) - elif k in ["n", "r", "current_s", "current_i", "sMax", "evaluatingTrials"]: - sParams[k] = int(float(v)) - elif k == "resourceName": - sParams[k] = v - else: - self.logger.info("Unknown HyperBand Param %s, ignore it", - k, extra={"experiment_name": experiment.name}) - if sParams["current_s"] == -1: - # Hyperband outlerloop has finished - self.logger.info("HyperBand outlerloop has finished.", - extra={"experiment_name": experiment.name}) - return sParams - - if sParams["eta"] <= 0: - sParams["eta"] = 3 - if sParams["sMax"] < 0: - sParams["sMax"] = int(math.log(sParams["r_l"]) / math.log(sParams["eta"])) - if sParams["b_l"] < 0: - sParams["b_l"] = (sParams["sMax"] + 1) * sParams["r_l"] - if sParams["current_s"] < 0: - sParams["current_s"] = sParams["sMax"] - if sParams["current_i"] < 0: - sParams["current_i"] = 0 - if sParams["n"] < 0: - sParams["n"] = int(math.ceil(float(sParams["sMax"] + 1) * ( - float(sParams["eta"]**sParams["current_s"]) / float(sParams["current_s"]+1)))) - if sParams["r"] < 0: - sParams["r"] = sParams["r_l"]*sParams["eta"]**(-sParams["current_s"]) - - return sParams - - def _make_bracket(self, experiment, sParams): - if sParams["evaluatingTrials"] == 0: - trialSpecs = self._make_master_bracket(experiment, sParams) - else: - trialSpecs = self._make_child_bracket(experiment, sParams) - if sParams["current_i"] < sParams["current_s"]: - sParams["evaluatingTrials"] = len(trialSpecs) - else: - sParams["evaluatingTrials"] = 0 - - self.logger.info("HyperBand Param eta %d.", - sParams["eta"], extra={"experiment_name": experiment.name}) - self.logger.info("HyperBand Param R %d.", - sParams["r_l"], extra={"experiment_name": experiment.name}) - self.logger.info("HyperBand Param sMax %d.", - sParams["sMax"], extra={"experiment_name": experiment.name}) - self.logger.info("HyperBand Param B %d.", - sParams["b_l"], extra={"experiment_name": experiment.name}) - self.logger.info("HyperBand Param n %d.", - sParams["n"], extra={"experiment_name": experiment.name}) - self.logger.info("HyperBand Param r %d.", - sParams["r"], extra={"experiment_name": experiment.name}) - self.logger.info("HyperBand Param s %d.", - sParams["current_s"], extra={"experiment_name": experiment.name}) - self.logger.info("HyperBand Param i %d.", - sParams["current_i"], extra={"experiment_name": experiment.name}) - self.logger.info("HyperBand evaluating trials count %d.", - sParams["evaluatingTrials"], extra={"experiment_name": experiment.name}) - - if sParams["evaluatingTrials"] == 0: - self._new_hbParameters(sParams) - - return trialSpecs - - def _make_child_bracket(self, experiment, sParams): - n_i = math.ceil(sParams["n"] * sParams["eta"]**(-sParams["current_i"])) - top_trials_num = int(math.ceil(n_i / sParams["eta"])) - self._update_hbParameters(sParams) - r_i = int(sParams["r"] * sParams["eta"]**sParams["current_i"]) - last_trials = self._get_top_trial(sParams["evaluatingTrials"], top_trials_num, experiment) - trialSpecs = self._copy_trials(last_trials, r_i, sParams["resourceName"]) - - self.logger.info("Generate %d trials by child bracket.", - top_trials_num, extra={"experiment_name": experiment.name}) - return trialSpecs - - def _get_last_trials(self, all_trials, latest_trials_num): - sorted_trials = sorted(all_trials, key=lambda trial: trial.status.start_time) - if len(sorted_trials) > latest_trials_num: - return sorted_trials[-latest_trials_num:] - else: - return sorted_trials - - def _get_top_trial(self, latest_trials_num, top_trials_num, experiment): - objective_metric = experiment.spec.objective.objective_metric_name - objective_type = experiment.spec.objective.type - - def get_objective_value(t): - for m in t.status.observation.metrics: - if m.name == objective_metric: - return float(m.value) - - top_trials = [] - all_trials = self._get_trials(experiment.name) - latest_trials = self._get_last_trials(all_trials, latest_trials_num) - - for t in latest_trials: - if t.status.condition != api_pb2.TrialStatus.TrialConditionType.SUCCEEDED: - raise Exception( - "There are some trials which are not completed yet for experiment %s." % experiment.name) - - if objective_type == api_pb2.MAXIMIZE: - top_trials.extend(sorted(latest_trials, key=get_objective_value, reverse=True)) - else: - top_trials.extend(sorted(latest_trials, key=get_objective_value)) - return top_trials[:top_trials_num] - - def _copy_trials(self, trials, r_i, resourceName): - trialSpecs = [] - for t in trials: - trial_spec = api_pb2.TrialSpec() - for assignment in t.spec.parameter_assignments.assignments: - if assignment.name == resourceName: - value = str(r_i) - else: - value = assignment.value - trial_spec.parameter_assignments.assignments.add(name=assignment.name, - value=value) - trialSpecs.append(trial_spec) - return trialSpecs - - def _make_master_bracket(self, experiment, sParams): - n = sParams["n"] - r = int(sParams["r"]) - parameter_config = parsing_util.parse_parameter_configs( - experiment.spec.parameter_specs.parameters) - trial_specs = [] - for _ in range(n): - sample = parameter_config.random_sample() - suggestion = parsing_util.parse_x_next_vector( - sample, - parameter_config.parameter_types, - parameter_config.names, - parameter_config.discrete_info, - parameter_config.categorical_info) - trial_spec = api_pb2.TrialSpec() - trial_spec.experiment_name = experiment.name - for param in suggestion: - if param['name'] == sParams["resourceName"]: - param['value'] = str(r) - trial_spec.parameter_assignments.assignments.add(name=param['name'], - value=str(param['value'])) - trial_specs.append(trial_spec) - self.logger.info("Generate %d trials by master bracket.", - n, extra={"experiment_name": experiment.name}) - return trial_specs - - def _update_algorithm_extrasettings(self, experiment_name, sParams): - as_list = [] - for k, v in sParams.items(): - as_list.append(api_pb2.AlgorithmSetting(name=k, value=str(v))) - channel = grpc.beta.implementations.insecure_channel(self.manager_addr, self.manager_port) - with api_pb2.beta_create_Manager_stub(channel) as client: - client.UpdateAlgorithmExtraSettings(api_pb2.UpdateAlgorithmExtraSettingsRequest( - experiment_name=experiment_name, extra_algorithm_settings=as_list), 10) - - def _set_validate_context_error(self, context, error_message): - context.set_code(grpc.StatusCode.INVALID_ARGUMENT) - context.set_details(error_message) - self.logger.info(error_message) - return api_pb2.ValidateAlgorithmSettingsReply() - - def ValidateAlgorithmSettings(self, request, context): - params = request.experiment_spec.parameter_specs.parameters - settings = request.experiment_spec.algorithm.algorithm_setting - setting_dict = {} - for setting in settings: - setting_dict[setting.name] = setting.value - if "r_l" not in setting_dict or "resourceName" not in setting_dict: - return self._set_validate_context_error(context, "r_l and resourceName must be set.") - try: - rl = float(setting_dict["r_l"]) - except: - return self._set_validate_context_error(context, "r_l must be a positive float number.") - else: - if rl < 0: - return self._set_validate_context_error(context, "r_l must be a positive float number.") - - if "eta" in setting_dict: - eta = int(float(setting_dict["eta"])) - if eta <= 0: - eta = 3 - else: - eta = 3 - - smax = int(math.log(rl)/math.log(eta)) - max_parallel = int(math.ceil(eta**smax)) - if request.experiment_spec.parallel_trial_count < max_parallel: - return self._set_validate_context_error(context, - "parallelTrialCount must be not less than %d." % max_parallel) - - valid_resourceName = False - for param in params: - if param.name == setting_dict["resourceName"]: - valid_resourceName = True - break - if not valid_resourceName: - return self._set_validate_context_error(context, - "value of resourceName setting must be in parameters.") - - return api_pb2.ValidateAlgorithmSettingsReply() diff --git a/pkg/suggestion/v1alpha2/nasrl_service.py b/pkg/suggestion/v1alpha2/nasrl_service.py deleted file mode 100644 index f4f52459d18..00000000000 --- a/pkg/suggestion/v1alpha2/nasrl_service.py +++ /dev/null @@ -1,397 +0,0 @@ -from pkg.suggestion.v1alpha2.NAS_Reinforcement_Learning.Controller import Controller -from pkg.suggestion.v1alpha2.NAS_Reinforcement_Learning.Operation import SearchSpace -from pkg.suggestion.v1alpha2.NAS_Reinforcement_Learning.AlgorithmSettings import parseAlgorithmSettings -import tensorflow as tf -import grpc -from pkg.apis.manager.v1alpha2.python import api_pb2 -from pkg.apis.manager.v1alpha2.python import api_pb2_grpc - -import logging -from logging import getLogger, StreamHandler, INFO, DEBUG -import json -import os -import time - -MANAGER_ADDRESS = "katib-manager" -MANAGER_PORT = 6789 -RESPAWN_SLEEP = 20 -RESPAWN_LIMIT = 10 - - -class NAS_RL_Experiment(object): - def __init__(self, request, logger): - self.logger = logger - self.experiment_name = request.experiment_name - self.num_trials = 1 - if request.request_number > 0: - self.num_trials = request.request_number - self.tf_graph = tf.Graph() - # self.prev_trial_ids = list() - # self.prev_trials = None - self.ctrl_cache_file = "ctrl_cache/{}.ckpt".format(request.experiment_name) - self.ctrl_step = 0 - self.is_first_run = True - self.algorithm_settings = None - self.controller = None - self.num_layers = None - self.input_sizes = None - self.output_sizes = None - self.num_operations = None - self.search_space = None - self.opt_direction = None - self.objective_name = None - # self.respawn_count = 0 - - self.logger.info("-" * 100 + "\nSetting Up Suggestion for Experiment {}\n".format(request.experiment_name) + "-" * 100) - self._get_experiment_param() - self._setup_controller() - self.logger.info(">>> Suggestion for Experiment {} has been initialized.\n".format(self.experiment_name)) - - def _get_experiment_param(self): - # this function need to - # 1) get the number of layers - # 2) get the I/O size - # 3) get the available operations - # 4) get the optimization direction (i.e. minimize or maximize) - # 5) get the objective name - # 6) get the algorithm settings - - channel = grpc.beta.implementations.insecure_channel(MANAGER_ADDRESS, MANAGER_PORT) - with api_pb2.beta_create_Manager_stub(channel) as client: - api_experiment_param = client.GetExperiment(api_pb2.GetExperimentRequest(experiment_name=self.experiment_name), 10) - - # Get Search Space - self.experiment_name = api_experiment_param.experiment.name - self.opt_direction = api_experiment_param.experiment.spec.objective.type - self.objective_name = api_experiment_param.experiment.spec.objective.objective_metric_name - - nas_config = api_experiment_param.experiment.spec.nas_config - - graph_config = nas_config.graph_config - self.num_layers = int(graph_config.num_layers) - self.input_sizes = list(map(int, graph_config.input_sizes)) - self.output_sizes = list(map(int, graph_config.output_sizes)) - - search_space_raw = nas_config.operations - search_space_object = SearchSpace(search_space_raw) - self.search_space = search_space_object.search_space - self.num_operations = search_space_object.num_operations - - self.print_search_space() - - # Get Experiment Parameters - params_raw = api_experiment_param.experiment.spec.algorithm.algorithm_setting - self.algorithm_settings = parseAlgorithmSettings(params_raw) - - self.print_algorithm_settings() - - def _setup_controller(self): - - with self.tf_graph.as_default(): - - self.controller = Controller( - num_layers=self.num_layers, - num_operations=self.num_operations, - lstm_size=self.algorithm_settings['lstm_num_cells'], - lstm_num_layers=self.algorithm_settings['lstm_num_layers'], - lstm_keep_prob=self.algorithm_settings['lstm_keep_prob'], - lr_init=self.algorithm_settings['init_learning_rate'], - lr_dec_start=self.algorithm_settings['lr_decay_start'], - lr_dec_every=self.algorithm_settings['lr_decay_every'], - lr_dec_rate=self.algorithm_settings['lr_decay_rate'], - l2_reg=self.algorithm_settings['l2_reg'], - entropy_weight=self.algorithm_settings['entropy_weight'], - bl_dec=self.algorithm_settings['baseline_decay'], - optim_algo=self.algorithm_settings['optimizer'], - skip_target=self.algorithm_settings['skip-target'], - skip_weight=self.algorithm_settings['skip-weight'], - name="Ctrl_" + self.experiment_name, - logger=self.logger) - - self.controller.build_trainer() - - def print_search_space(self): - if self.search_space is None: - self.logger.warning("Error! The Suggestion has not yet been initialized!") - return - - self.logger.info(">>> Search Space for Experiment {}".format(self.experiment_name)) - for opt in self.search_space: - opt.print_op(self.logger) - self.logger.info("There are {} operations in total.\n".format(self.num_operations)) - - def print_algorithm_settings(self): - if self.algorithm_settings is None: - self.logger.warning("Error! The Suggestion has not yet been initialized!") - return - - self.logger.info(">>> Parameters of LSTM Controller for Experiment {}".format(self.experiment_name)) - for spec in self.algorithm_settings: - if len(spec) > 13: - self.logger.info("{}: \t{}".format(spec, self.algorithm_settings[spec])) - else: - self.logger.info("{}: \t\t{}".format(spec, self.algorithm_settings[spec])) - self.logger.info("RequestNumber:\t\t{}".format(self.num_trials)) - self.logger.info("") - - -class NasrlService(api_pb2_grpc.SuggestionServicer): - def __init__(self, logger=None): - - self.registered_experiments = dict() - - if logger == None: - self.logger = getLogger(__name__) - FORMAT = '%(asctime)-15s Experiment %(experiment_name)s %(message)s' - logging.basicConfig(format=FORMAT) - handler = StreamHandler() - handler.setLevel(INFO) - self.logger.setLevel(INFO) - self.logger.addHandler(handler) - self.logger.propagate = False - else: - self.logger = logger - - if not os.path.exists("ctrl_cache/"): - os.makedirs("ctrl_cache/") - - def ValidateAlgorithmSettings(self, request, context): - self.logger.info("Validate Algorithm Settings start") - graph_config = request.experiment_spec.nas_config.graph_config - - # Validate GraphConfig - # Check InputSize - if not graph_config.input_sizes: - return self.SetValidateContextError(context, "Missing InputSizes in GraphConfig:\n{}".format(graph_config)) - - # Check OutputSize - if not graph_config.output_sizes: - return self.SetValidateContextError(context, "Missing OutputSizes in GraphConfig:\n{}".format(graph_config)) - - # Check NumLayers - if not graph_config.num_layers: - return self.SetValidateContextError(context, "Missing NumLayers in GraphConfig:\n{}".format(graph_config)) - - # Validate each operation - operations_list = list(request.experiment_spec.nas_config.operations.operation) - for operation in operations_list: - - # Check OperationType - if not operation.operation_type: - return self.SetValidateContextError(context, "Missing operationType in Operation:\n{}".format(operation)) - - # Check ParameterConfigs - if not operation.parameter_specs.parameters: - return self.SetValidateContextError(context, "Missing ParameterConfigs in Operation:\n{}".format(operation)) - - # Validate each ParameterConfig in Operation - parameters_list = list(operation.parameter_specs.parameters) - for parameter in parameters_list: - - # Check Name - if not parameter.name: - return self.SetValidateContextError(context, "Missing Name in ParameterConfig:\n{}".format(parameter)) - - # Check ParameterType - if not parameter.parameter_type: - return self.SetValidateContextError(context, "Missing ParameterType in ParameterConfig:\n{}".format(parameter)) - - # Check List in Categorical or Discrete Type - if parameter.parameter_type == api_pb2.CATEGORICAL or parameter.parameter_type == api_pb2.DISCRETE: - if not parameter.feasible_space.list: - return self.SetValidateContextError(context, "Missing List in ParameterConfig.feasibleSpace:\n{}".format(parameter) ) - - # Check Max, Min, Step in Int or Double Type - elif parameter.parameter_type == api_pb2.INT or parameter.parameter_type == api_pb2.DOUBLE: - if not parameter.feasible_space.min and not parameter.feasible_space.max: - return self.SetValidateContextError(context, "Missing Max and Min in ParameterConfig.feasibleSpace:\n{}".format(parameter)) - - if parameter.parameter_type == api_pb2.DOUBLE and (not parameter.feasible_space.step or float(parameter.feasible_space.step) <= 0): - return self.SetValidateContextError(context, "Step parameter should be > 0 in ParameterConfig.feasibleSpace:\n{}".format(parameter)) - - self.logger.info("All Experiment Settings are Valid") - return api_pb2.ValidateAlgorithmSettingsReply() - - def SetValidateContextError(self, context, error_message): - context.set_code(grpc.StatusCode.INVALID_ARGUMENT) - context.set_details(error_message) - self.logger.info(error_message) - return api_pb2.ValidateAlgorithmSettingsReply() - - def GetSuggestions(self, request, context): - - if request.experiment_name not in self.registered_experiments: - self.registered_experiments[request.experiment_name] = NAS_RL_Experiment(request, self.logger) - - experiment = self.registered_experiments[request.experiment_name] - - self.logger.info("-" * 100 + "\nSuggestion Step {} for Experiment {}\n".format(experiment.ctrl_step, experiment.experiment_name) + "-" * 100) - - with experiment.tf_graph.as_default(): - saver = tf.train.Saver() - ctrl = experiment.controller - - controller_ops = { - "train_step": ctrl.train_step, - "loss": ctrl.loss, - "train_op": ctrl.train_op, - "lr": ctrl.lr, - "grad_norm": ctrl.grad_norm, - "optimizer": ctrl.optimizer, - "baseline": ctrl.baseline, - "entropy": ctrl.sample_entropy, - "sample_arc": ctrl.sample_arc, - "skip_rate": ctrl.skip_rate} - - run_ops = [ - controller_ops["loss"], - controller_ops["entropy"], - controller_ops["lr"], - controller_ops["grad_norm"], - controller_ops["baseline"], - controller_ops["skip_rate"], - controller_ops["train_op"]] - - if experiment.is_first_run: - self.logger.info(">>> First time running suggestion for {}. Random architecture will be given.".format(experiment.experiment_name)) - with tf.Session() as sess: - sess.run(tf.global_variables_initializer()) - candidates = list() - for _ in range(experiment.num_trials): - candidates.append(sess.run(controller_ops["sample_arc"])) - - # TODO: will use PVC to store the checkpoint to protect against unexpected suggestion pod restart - saver.save(sess, experiment.ctrl_cache_file) - - experiment.is_first_run = False - - else: - with tf.Session() as sess: - saver.restore(sess, experiment.ctrl_cache_file) - - valid_acc = ctrl.reward - result = self.GetEvaluationResult(experiment) - - # TODO: (andreyvelich) I deleted this part, should it be handle by controller? - # Sometimes training container may fail and GetEvaluationResult() will return None - # In this case, the Suggestion will: - # 1. Firstly try to respawn the previous trials after waiting for RESPAWN_SLEEP seconds - # 2. If respawning the trials for RESPAWN_LIMIT times still cannot collect valid results, - # then fail the task because it may indicate that the training container has errors. - if result is None: - self.logger.warning(">>> Suggestion has spawned trials, but they all failed.") - self.logger.warning(">>> Please check whether the training container is correctly implemented") - self.logger.info(">>> Experiment {} failed".format(experiment.experiment_name)) - return [] - - # This LSTM network is designed to maximize the metrics - # However, if the user wants to minimize the metrics, we can take the negative of the result - - if experiment.opt_direction == api_pb2.MINIMIZE: - result = -result - - loss, entropy, lr, gn, bl, skip, _ = sess.run( - fetches=run_ops, - feed_dict={valid_acc: result}) - - self.logger.info(">>> Suggestion updated. LSTM Controller Reward: {}".format(loss)) - - candidates = list() - for _ in range(experiment.num_trials): - candidates.append(sess.run(controller_ops["sample_arc"])) - - saver.save(sess, experiment.ctrl_cache_file) - - organized_candidates = list() - trials = list() - - for i in range(experiment.num_trials): - arc = candidates[i].tolist() - organized_arc = [0 for _ in range(experiment.num_layers)] - record = 0 - for l in range(experiment.num_layers): - organized_arc[l] = arc[record: record + l + 1] - record += l + 1 - organized_candidates.append(organized_arc) - - nn_config = dict() - nn_config['num_layers'] = experiment.num_layers - nn_config['input_sizes'] = experiment.input_sizes - nn_config['output_sizes'] = experiment.output_sizes - nn_config['embedding'] = dict() - for l in range(experiment.num_layers): - opt = organized_arc[l][0] - nn_config['embedding'][opt] = experiment.search_space[opt].get_dict() - - organized_arc_json = json.dumps(organized_arc) - nn_config_json = json.dumps(nn_config) - - organized_arc_str = str(organized_arc_json).replace('\"', '\'') - nn_config_str = str(nn_config_json).replace('\"', '\'') - - self.logger.info("\n>>> New Neural Network Architecture Candidate #{} (internal representation):".format(i)) - self.logger.info(organized_arc_json) - self.logger.info("\n>>> Corresponding Seach Space Description:") - self.logger.info(nn_config_str) - - trials.append(api_pb2.Trial( - spec=api_pb2.TrialSpec( - experiment_name=request.experiment_name, - parameter_assignments=api_pb2.TrialSpec.ParameterAssignments( - assignments=[ - api_pb2.ParameterAssignment( - name="architecture", - value=organized_arc_str - ), - api_pb2.ParameterAssignment( - name="nn_config", - value=nn_config_str - ) - ] - ) - ) - )) - - self.logger.info("") - self.logger.info(">>> {} Trials were created for Experiment {}".format(experiment.num_trials, experiment.experiment_name)) - self.logger.info("") - - experiment.ctrl_step += 1 - - return api_pb2.GetSuggestionsReply(trials=trials) - - def GetEvaluationResult(self, experiment): - channel = grpc.beta.implementations.insecure_channel(MANAGER_ADDRESS, MANAGER_PORT) - with api_pb2.beta_create_Manager_stub(channel) as client: - trials_resp = client.GetTrialList(api_pb2.GetTrialListRequest(experiment_name=experiment.experiment_name), 10) - trials_list = trials_resp.trials - - completed_trials = dict() - failed_trials = [] - for t in trials_list: - if t.status.condition == api_pb2.TrialStatus.TrialConditionType.SUCCEEDED: - obslog_resp = client.GetObservationLog( - api_pb2.GetObservationLogRequest( - trial_name=t.name, - metric_name=t.spec.objective.objective_metric_name - ), 10 - ) - - # Take only the latest metric value - completed_trials[t.name] = float(obslog_resp.observation_log.metric_logs[-1].metric.value) - - if t.status.condition == api_pb2.TrialStatus.TrialConditionType.FAILED: - failed_trials.append(t.name) - - n_completed = len(completed_trials) - self.logger.info(">>> By now: {} Trials succeeded, {} Trials failed".format(n_completed, len(failed_trials))) - for tname in completed_trials: - self.logger.info("Trial: {}, Value: {}".format(tname, completed_trials[tname])) - for tname in failed_trials: - self.logger.info("Trial: {} was failed".format(tname)) - - if n_completed > 0: - avg_metrics = sum(completed_trials.values()) / n_completed - self.logger.info("The average is {}\n".format(avg_metrics)) - - return avg_metrics diff --git a/pkg/suggestion/v1alpha2/parameter.py b/pkg/suggestion/v1alpha2/parameter.py deleted file mode 100644 index 8918fd877de..00000000000 --- a/pkg/suggestion/v1alpha2/parameter.py +++ /dev/null @@ -1,52 +0,0 @@ -import numpy as np -from sklearn.preprocessing import MinMaxScaler - -class ParameterConfig: - """ - Class to hold the parameter configuration for an experiment. - - Attributes: - name_ids (dict): Mapping from a parameter name to the index of that - parameter in the other fields. - dim (int): Dimension of the vectors created when parameter assignments - are mapped to a vector. Each int, double, or discrete parameter - adds one to the dimension, and each categorical parameter adds - the number of feasible values for that parameter due to one-hot - encoding. - lower_bounds (ndarray): The lower bounds for each parameter in the - search space. - upper_bounds (ndarray): The lower bounds for each parameter in the - search space. - parameter_types (list): The type of each parameter. - names (list): The name of each parameter. - discrete_info (list): A list of dicts where each dict contains the - information for a single discrete parameter. An example of a dict - is {"name": "discrete_parameter, "values": [2, 3, 5]}] - categorical_info (list): A list of dicts where each dict contains the - information for a single categorical parameter. An example dict is - {"name": "cat_param", "values": ["true", "false"], "number": 2}. - """ - - def __init__(self, name_ids, dim, lower_bounds, upper_bounds, - parameter_types, names, discrete_info, categorical_info): - self.name_ids = name_ids - self.dim = dim - self.lower_bounds = np.array(lower_bounds).reshape((1, dim)) - self.upper_bounds = np.array(upper_bounds).reshape((1, dim)) - self.parameter_types = parameter_types - self.names = names - self.discrete_info = discrete_info - self.categorical_info = categorical_info - if len(self.names) != len(set(self.names)): - raise Exception("Parameter names are not unique.") - - def create_scaler(self): - search_space = np.append(self.lower_bounds, self.upper_bounds, axis=0) - scaler = MinMaxScaler() - scaler.fit(search_space) - return scaler - - def random_sample(self): - new_sample = np.random.uniform(self.lower_bounds, self.upper_bounds, - size=(1, self.dim)) - return new_sample diff --git a/pkg/suggestion/v1alpha2/parsing_util.py b/pkg/suggestion/v1alpha2/parsing_util.py deleted file mode 100644 index 22358a0d9e2..00000000000 --- a/pkg/suggestion/v1alpha2/parsing_util.py +++ /dev/null @@ -1,144 +0,0 @@ -""" -Module containing helper functions to translate objects that come -to/from the grpc API into the format accepted/returned by the different -suggestion generation algorithms. -""" -from collections.abc import Iterable -from pkg.apis.manager.v1alpha2.python import api_pb2 -import numpy as np -from .parameter import ParameterConfig - - -def _deal_with_discrete(feasible_values, current_value): - """ function to embed the current values to the feasible discrete space""" - diff = np.subtract(feasible_values, current_value) - diff = np.absolute(diff) - return feasible_values[np.argmin(diff)] - - -def _deal_with_categorical(feasible_values, one_hot_values): - """ function to do the one hot encoding of the categorical values """ - index = np.argmax(one_hot_values) - return feasible_values[int(index)] - - -def parse_parameter_configs(parameter_configs): - name_ids = {} - dim = 0 - lower_bounds = [] - upper_bounds = [] - parameter_types = [] - names = [] - discrete_info = [] - categorical_info = [] - for param_idx, param in enumerate(parameter_configs): - name_ids[param.name] = param_idx - parameter_types.append(param.parameter_type) - names.append(param.name) - if param.parameter_type == api_pb2.DOUBLE: - new_lower = float(param.feasible_space.min) - new_upper = float(param.feasible_space.max) - elif param.parameter_type == api_pb2.INT: - new_lower = int(param.feasible_space.min) - new_upper = int(param.feasible_space.max) - elif param.parameter_type == api_pb2.DISCRETE: - discrete_values = [int(x) for x in param.feasible_space.list] - new_lower = min(discrete_values) - new_upper = max(discrete_values) - discrete_info.append( - {"name": param.name, "values": discrete_values}) - elif param.parameter_type == api_pb2.CATEGORICAL: - num_feasible = len(param.feasible_space.list) - new_lower = [0 for _ in range(num_feasible)] - new_upper = [1 for _ in range(num_feasible)] - categorical_info.append({ - "name": param.name, - "values": param.feasible_space.list, - "number": num_feasible, - }) - if isinstance(new_lower, Iterable): # handles categorical parameters - lower_bounds.extend(new_lower) - upper_bounds.extend(new_upper) - dim += len(new_lower) - else: # handles ints, doubles, and discrete parameters - lower_bounds.append(new_lower) - upper_bounds.append(new_upper) - dim += 1 - parsed_config = ParameterConfig(name_ids, - dim, - lower_bounds, - upper_bounds, - parameter_types, - names, - discrete_info, - categorical_info) - return parsed_config - - -def parse_previous_observations(parameters_list, dim, name_id, types, categorical_info): - parsed_X = np.zeros(shape=(len(parameters_list), dim)) - for row_idx, parameters in enumerate(parameters_list): - offset = 0 - for p in parameters: - map_id = name_id[p.name] - if types[map_id] in [api_pb2.DOUBLE, api_pb2.INT, - api_pb2.DISCRETE]: - parsed_X[row_idx, offset] = float(p.value) - offset += 1 - elif types[map_id] == api_pb2.CATEGORICAL: - for ci in categorical_info: - if ci["name"] == p.name: - value_num = ci["values"].index(p.value) - parsed_X[row_idx, offset + value_num] = 1 - offset += ci["number"] - return parsed_X - - -def parse_metric(y_train, goal): - """ - Parse the metric to the dictionary - """ - y_array = np.array(y_train, dtype=np.float64) - if goal == api_pb2.MINIMIZE: - y_array *= -1 - return y_array - - -def parse_x_next_vector(x_next, param_types, param_names, discrete_info, categorical_info): - """ parse the next suggestion to the proper format """ - counter = 0 - result = [] - if isinstance(x_next, np.ndarray): - x_next = x_next.squeeze(axis=0) - for par_type, par_name in zip(param_types, param_names): - if par_type == api_pb2.INT: - value = int(round(x_next[counter], 0)) - counter = counter + 1 - elif par_type == api_pb2.DOUBLE: - value = float(x_next[counter]) - counter = counter + 1 - elif par_type == api_pb2.DISCRETE: - for param in discrete_info: - if param["name"] == par_name: - value = _deal_with_discrete(param["values"], - x_next[counter]) - counter = counter + 1 - break - elif par_type == api_pb2.CATEGORICAL: - for param in categorical_info: - if param["name"] == par_name: - value = _deal_with_categorical( - feasible_values=param["values"], - one_hot_values=x_next[counter:counter + param["number"]], - ) - counter = counter + param["number"] - break - result.append({"name": par_name, "value": value, "type": par_type}) - return result - - -def parse_x_next_tuple(x_next, param_types, param_names): - result = [] - for value, param_type, param_name in zip(x_next, param_types, param_names): - result.append({"name": param_name, "type": param_type, "value": str(value)}) - return result diff --git a/pkg/suggestion/v1alpha2/random_service.py b/pkg/suggestion/v1alpha2/random_service.py deleted file mode 100644 index 5c16d59e224..00000000000 --- a/pkg/suggestion/v1alpha2/random_service.py +++ /dev/null @@ -1,44 +0,0 @@ -from logging import getLogger, StreamHandler, INFO, DEBUG -from pkg.apis.manager.v1alpha2.python import api_pb2 -from pkg.apis.manager.v1alpha2.python import api_pb2_grpc -import grpc -from . import parsing_util - -class RandomService(api_pb2_grpc.SuggestionServicer): - def __init__(self): - self.manager_addr = "katib-manager" - self.manager_port = 6789 - - def _get_experiment(self, name): - channel = grpc.beta.implementations.insecure_channel(self.manager_addr, self.manager_port) - with api_pb2.beta_create_Manager_stub(channel) as client: - exp = client.GetExperiment(api_pb2.GetExperimentRequest(experiment_name=name), 10) - return exp.experiment - - def GetSuggestions(self, request, context): - """ - Main function to provide suggestion. - """ - experiment = self._get_experiment(request.experiment_name) - parameter_config = parsing_util.parse_parameter_configs( - experiment.spec.parameter_specs.parameters) - trial_specs = [] - for _ in range(request.request_number): - sample = parameter_config.random_sample() - suggestion = parsing_util.parse_x_next_vector(sample, - parameter_config.parameter_types, - parameter_config.names, - parameter_config.discrete_info, - parameter_config.categorical_info) - trial_spec = api_pb2.TrialSpec() - trial_spec.experiment_name = request.experiment_name - for param in suggestion: - trial_spec.parameter_assignments.assignments.add(name=param['name'], - value=str(param['value'])) - trial_specs.append(trial_spec) - - reply = api_pb2.GetSuggestionsReply() - for trial_spec in trial_specs: - reply.trials.add(spec=trial_spec) - - return reply diff --git a/pkg/ui/v1alpha2/backend.go b/pkg/ui/v1alpha2/backend.go deleted file mode 100644 index dbe011e9d15..00000000000 --- a/pkg/ui/v1alpha2/backend.go +++ /dev/null @@ -1,463 +0,0 @@ -package ui - -import ( - "context" - "encoding/json" - "log" - "net/http" - "strconv" - "strings" - "time" - - experimentv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - api_pb_v1alpha2 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - common_v1alpha2 "github.com/kubeflow/katib/pkg/common/v1alpha2" - - "github.com/kubeflow/katib/pkg/util/v1alpha2/katibclient" - "google.golang.org/grpc" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/ghodss/yaml" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func NewKatibUIHandler() *KatibUIHandler { - kclient, err := katibclient.NewClient(client.Options{}) - if err != nil { - log.Printf("NewClient for Katib failed: %v", err) - panic(err) - } - return &KatibUIHandler{ - katibClient: kclient, - } -} - -func (k *KatibUIHandler) connectManager() (*grpc.ClientConn, api_pb_v1alpha2.ManagerClient) { - conn, err := grpc.Dial(common_v1alpha2.ManagerAddr, grpc.WithInsecure()) - if err != nil { - log.Printf("Dial to GRPC failed: %v", err) - return nil, nil - } - c := api_pb_v1alpha2.NewManagerClient(conn) - return conn, c -} - -func (k *KatibUIHandler) FetchHPJobs(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - - jobs := make([]JobView, 0) - - el, err := k.katibClient.GetExperimentList() - if err != nil { - log.Printf("GetExperimentList for HP failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - for _, experiment := range el.Items { - if experiment.Spec.Parameters != nil { - experimentLastCondition, err := experiment.GetLastConditionType() - if err != nil { - log.Printf("GetLastConditionType for HP failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - jobs = append(jobs, JobView{ - Name: experiment.Name, - Status: string(experimentLastCondition), - }) - } - } - - response, err := json.Marshal(jobs) - if err != nil { - log.Printf("Marshal HP jobs failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write(response) - -} - -func (k *KatibUIHandler) FetchNASJobs(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - - jobs := make([]JobView, 0) - - el, err := k.katibClient.GetExperimentList() - if err != nil { - log.Printf("GetExperimentList for NAS failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - for _, experiment := range el.Items { - if experiment.Spec.NasConfig != nil { - experimentLastCondition, err := experiment.GetLastConditionType() - if err != nil { - log.Printf("GetLastConditionType for HP failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - jobs = append(jobs, JobView{ - Name: experiment.Name, - Status: string(experimentLastCondition), - }) - } - } - - response, err := json.Marshal(jobs) - if err != nil { - log.Printf("Marshal NAS jobs failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write(response) - -} - -func (k *KatibUIHandler) SubmitYamlJob(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - var data map[string]interface{} - - json.NewDecoder(r.Body).Decode(&data) - - job := experimentv1alpha2.Experiment{} - if yamlContent, ok := data["yaml"].(string); ok { - err := yaml.Unmarshal([]byte(yamlContent), &job) - if err != nil { - log.Printf("Unmarshal YAML content failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - err = k.katibClient.CreateExperiment(&job) - if err != nil { - log.Printf("CreateExperiment from YAML failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } - -} - -func (k *KatibUIHandler) SubmitParamsJob(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - var data map[string]interface{} - - json.NewDecoder(r.Body).Decode(&data) - if data, ok := data["postData"]; ok { - jsonbody, err := json.Marshal(data) - if err != nil { - log.Printf("Marshal data for HP job failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - job := experimentv1alpha2.Experiment{} - if err := json.Unmarshal(jsonbody, &job); err != nil { - log.Printf("Unmarshal HP job failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - dataMap := data.(map[string]interface{}) - job.TypeMeta = metav1.TypeMeta{ - APIVersion: "kubeflow.org/v1alpha2", - Kind: "Experiment", - } - job.ObjectMeta = metav1.ObjectMeta{ - Name: dataMap["metadata"].(map[string]interface{})["name"].(string), - Namespace: dataMap["metadata"].(map[string]interface{})["namespace"].(string), - } - err = k.katibClient.CreateExperiment(&job) - if err != nil { - log.Printf("CreateExperiment for HP failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } -} - -func (k *KatibUIHandler) DeleteExperiment(w http.ResponseWriter, r *http.Request) { - experimentName := r.URL.Query()["experimentName"][0] - experiment, err := k.katibClient.GetExperiment(experimentName) - if err != nil { - log.Printf("GetExperiment failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - err = k.katibClient.DeleteExperiment(experiment) - if err != nil { - log.Printf("DeleteExperiment failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } -} - -func (k *KatibUIHandler) FetchHPJobInfo(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - experimentName := r.URL.Query()["experimentName"][0] - - conn, c := k.connectManager() - defer conn.Close() - - resultText := "trialName" - expResp, err := c.GetExperiment( - context.Background(), - &api_pb_v1alpha2.GetExperimentRequest{ - ExperimentName: experimentName, - }, - ) - if err != nil { - log.Printf("GetExperiment from HP job failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - log.Printf("Got Experiment") - metricsList := map[string]int{} - metricsName := expResp.Experiment.Spec.Objective.ObjectiveMetricName - resultText += "," + metricsName - metricsList[metricsName] = 0 - for i, m := range expResp.Experiment.Spec.Objective.AdditionalMetricNames { - resultText += "," + m - metricsList[m] = i + 1 - } - log.Printf("Got metrics names") - paramList := map[string]int{} - for i, p := range expResp.Experiment.Spec.ParameterSpecs.Parameters { - resultText += "," + p.Name - paramList[p.Name] = i + len(metricsList) - } - log.Printf("Got Parameters names") - - trialListResp, err := c.GetTrialList( - context.Background(), - &api_pb_v1alpha2.GetTrialListRequest{ - ExperimentName: experimentName, - Filter: "", - }, - ) - if err != nil { - log.Printf("GetTrialList from HP job failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - log.Printf("Got Trial List") - - for _, t := range trialListResp.Trials { - - if t.Status.Condition == api_pb_v1alpha2.TrialStatus_SUCCEEDED { - obsLogResp, err := c.GetObservationLog( - context.Background(), - &api_pb_v1alpha2.GetObservationLogRequest{ - TrialName: t.Name, - StartTime: "", - EndTime: "", - }, - ) - if err != nil { - log.Printf("GetObservationLog from HP job failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - trialResText := make([]string, len(metricsList)+len(paramList)) - for _, m := range obsLogResp.ObservationLog.MetricLogs { - trialResText[metricsList[m.Metric.Name]] = m.Metric.Value - - } - for _, trialParam := range t.Spec.ParameterAssignments.Assignments { - trialResText[paramList[trialParam.Name]] = trialParam.Value - } - resultText += "\n" + t.Name + "," + strings.Join(trialResText, ",") - } - } - log.Printf("Logs parsed, results:\n %v", resultText) - response, err := json.Marshal(resultText) - if err != nil { - log.Printf("Marshal result text for HP job failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write(response) - -} - -func (k *KatibUIHandler) FetchHPJobTrialInfo(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - trialName := r.URL.Query()["trialName"][0] - conn, c := k.connectManager() - defer conn.Close() - - resultText := "metricName,time,value\n" - obsLogResp, err := c.GetObservationLog( - context.Background(), - &api_pb_v1alpha2.GetObservationLogRequest{ - TrialName: trialName, - StartTime: "", - EndTime: "", - }, - ) - if err != nil { - log.Printf("GetObservationLog failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - prevTime := "" - for _, m := range obsLogResp.ObservationLog.MetricLogs { - parsedTime, _ := time.Parse(time.RFC3339Nano, m.TimeStamp) - formatTime := parsedTime.Format("2006-01-02T15:4:5") - if formatTime != prevTime { - resultText += m.Metric.Name + "," + formatTime + "," + m.Metric.Value + "\n" - prevTime = formatTime - } - } - - response, err := json.Marshal(resultText) - if err != nil { - log.Printf("Marshal result text in Trial info failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write(response) -} - -func (k *KatibUIHandler) FetchNASJobInfo(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - experimentName := r.URL.Query()["experimentName"][0] - - responseRaw := make([]NNView, 0) - var architecture string - var decoder string - - conn, c := k.connectManager() - - defer conn.Close() - - trialListResp, err := c.GetTrialList( - context.Background(), - &api_pb_v1alpha2.GetTrialListRequest{ - ExperimentName: experimentName, - Filter: "", - }, - ) - if err != nil { - log.Printf("GetTrialList from NAS job failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - log.Printf("Got Trial List") - - for i, t := range trialListResp.Trials { - - if t.Status.Condition == api_pb_v1alpha2.TrialStatus_SUCCEEDED { - obsLogResp, err := c.GetObservationLog( - context.Background(), - &api_pb_v1alpha2.GetObservationLogRequest{ - TrialName: t.Name, - StartTime: "", - EndTime: "", - }, - ) - if err != nil { - log.Printf("GetObservationLog from NAS job failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - metricsName := make([]string, 0) - metricsValue := make([]string, 0) - for _, m := range obsLogResp.ObservationLog.MetricLogs { - metricsName = append(metricsName, m.Metric.Name) - metricsValue = append(metricsValue, m.Metric.Value) - - } - for _, trialParam := range t.Spec.ParameterAssignments.Assignments { - if trialParam.Name == "architecture" { - architecture = trialParam.Value - } - if trialParam.Name == "nn_config" { - decoder = trialParam.Value - } - } - responseRaw = append(responseRaw, NNView{ - Name: "Generation " + strconv.Itoa(i), - TrialName: t.Name, - Architecture: generateNNImage(architecture, decoder), - MetricsName: metricsName, - MetricsValue: metricsValue, - }) - } - } - log.Printf("Logs parsed, result: %v", responseRaw) - - response, err := json.Marshal(responseRaw) - if err != nil { - log.Printf("Marshal result in NAS job failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write(response) -} - -func (k *KatibUIHandler) FetchTrialTemplates(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - trialTemplates, err := k.katibClient.GetTrialTemplates() - if err != nil { - log.Printf("GetTrialTemplate failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - response, err := json.Marshal(getTemplatesView(trialTemplates)) - if err != nil { - log.Printf("Marshal templates failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write(response) -} - -func (k *KatibUIHandler) FetchMetricsCollectorTemplates(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - metricsCollectorTemplates, err := k.katibClient.GetMetricsCollectorTemplates() - if err != nil { - log.Printf("GetMetricsCollectorTemplates failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - response, err := json.Marshal(getTemplatesView(metricsCollectorTemplates)) - if err != nil { - log.Printf("Marshal templates failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write(response) -} - -func (k *KatibUIHandler) AddEditDeleteTemplate(w http.ResponseWriter, r *http.Request) { - //enableCors(&w) - //TODO: need to delete? - if r.Method == "OPTIONS" { - return - } - var data map[string]interface{} - var err error - var templateResponse TemplateResponse - - json.NewDecoder(r.Body).Decode(&data) - if data["action"].(string) == "delete" { - templateResponse, err = k.updateTemplates(data, true) - } else { - templateResponse, err = k.updateTemplates(data, false) - } - if err != nil { - log.Printf("updateTemplates failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - response, err := json.Marshal(templateResponse) - if err != nil { - log.Printf("Marhal failed: %v", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write(response) -} diff --git a/pkg/ui/v1alpha2/frontend/.gitignore b/pkg/ui/v1alpha2/frontend/.gitignore deleted file mode 100755 index 495881eb157..00000000000 --- a/pkg/ui/v1alpha2/frontend/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# package-lock -package-lock.json - -# build -/build diff --git a/pkg/ui/v1alpha2/frontend/README.md b/pkg/ui/v1alpha2/frontend/README.md deleted file mode 100755 index d0373f0ab80..00000000000 --- a/pkg/ui/v1alpha2/frontend/README.md +++ /dev/null @@ -1,5 +0,0 @@ -TODO: Add docs for Devevelopment and Production testing. - -### Development - -### Production diff --git a/pkg/ui/v1alpha2/frontend/config/env.js b/pkg/ui/v1alpha2/frontend/config/env.js deleted file mode 100644 index b0344c5a83e..00000000000 --- a/pkg/ui/v1alpha2/frontend/config/env.js +++ /dev/null @@ -1,93 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const paths = require('./paths'); - -// Make sure that including paths.js after env.js will read .env variables. -delete require.cache[require.resolve('./paths')]; - -const NODE_ENV = process.env.NODE_ENV; -if (!NODE_ENV) { - throw new Error( - 'The NODE_ENV environment variable is required but was not specified.' - ); -} - -// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use -var dotenvFiles = [ - `${paths.dotenv}.${NODE_ENV}.local`, - `${paths.dotenv}.${NODE_ENV}`, - // Don't include `.env.local` for `test` environment - // since normally you expect tests to produce the same - // results for everyone - NODE_ENV !== 'test' && `${paths.dotenv}.local`, - paths.dotenv, -].filter(Boolean); - -// Load environment variables from .env* files. Suppress warnings using silent -// if this file is missing. dotenv will never modify any environment variables -// that have already been set. Variable expansion is supported in .env files. -// https://github.com/motdotla/dotenv -// https://github.com/motdotla/dotenv-expand -dotenvFiles.forEach(dotenvFile => { - if (fs.existsSync(dotenvFile)) { - require('dotenv-expand')( - require('dotenv').config({ - path: dotenvFile, - }) - ); - } -}); - -// We support resolving modules according to `NODE_PATH`. -// This lets you use absolute paths in imports inside large monorepos: -// https://github.com/facebook/create-react-app/issues/253. -// It works similar to `NODE_PATH` in Node itself: -// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders -// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. -// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. -// https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421 -// We also resolve them to make sure all tools using them work consistently. -const appDirectory = fs.realpathSync(process.cwd()); -process.env.NODE_PATH = (process.env.NODE_PATH || '') - .split(path.delimiter) - .filter(folder => folder && !path.isAbsolute(folder)) - .map(folder => path.resolve(appDirectory, folder)) - .join(path.delimiter); - -// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be -// injected into the application via DefinePlugin in Webpack configuration. -const REACT_APP = /^REACT_APP_/i; - -function getClientEnvironment(publicUrl) { - const raw = Object.keys(process.env) - .filter(key => REACT_APP.test(key)) - .reduce( - (env, key) => { - env[key] = process.env[key]; - return env; - }, - { - // Useful for determining whether we’re running in production mode. - // Most importantly, it switches React into the correct mode. - NODE_ENV: process.env.NODE_ENV || 'development', - // Useful for resolving the correct path to static assets in `public`. - // For example, . - // This should only be used as an escape hatch. Normally you would put - // images into the `src` and `import` them in code to get their paths. - PUBLIC_URL: publicUrl, - } - ); - // Stringify all values so we can feed into Webpack DefinePlugin - const stringified = { - 'process.env': Object.keys(raw).reduce((env, key) => { - env[key] = JSON.stringify(raw[key]); - return env; - }, {}), - }; - - return { raw, stringified }; -} - -module.exports = getClientEnvironment; diff --git a/pkg/ui/v1alpha2/frontend/config/jest/cssTransform.js b/pkg/ui/v1alpha2/frontend/config/jest/cssTransform.js deleted file mode 100644 index 8f65114812a..00000000000 --- a/pkg/ui/v1alpha2/frontend/config/jest/cssTransform.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -// This is a custom Jest transformer turning style imports into empty objects. -// http://facebook.github.io/jest/docs/en/webpack.html - -module.exports = { - process() { - return 'module.exports = {};'; - }, - getCacheKey() { - // The output is always the same. - return 'cssTransform'; - }, -}; diff --git a/pkg/ui/v1alpha2/frontend/config/jest/fileTransform.js b/pkg/ui/v1alpha2/frontend/config/jest/fileTransform.js deleted file mode 100644 index 4ed6bdb005d..00000000000 --- a/pkg/ui/v1alpha2/frontend/config/jest/fileTransform.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -const path = require('path'); - -// This is a custom Jest transformer turning file imports into filenames. -// http://facebook.github.io/jest/docs/en/webpack.html - -module.exports = { - process(src, filename) { - const assetFilename = JSON.stringify(path.basename(filename)); - - if (filename.match(/\.svg$/)) { - return `const React = require('react'); - module.exports = { - __esModule: true, - default: ${assetFilename}, - ReactComponent: React.forwardRef((props, ref) => ({ - $$typeof: Symbol.for('react.element'), - type: 'svg', - ref: ref, - key: null, - props: Object.assign({}, props, { - children: ${assetFilename} - }) - })), - };`; - } - - return `module.exports = ${assetFilename};`; - }, -}; diff --git a/pkg/ui/v1alpha2/frontend/config/paths.js b/pkg/ui/v1alpha2/frontend/config/paths.js deleted file mode 100644 index c24b4dd1f84..00000000000 --- a/pkg/ui/v1alpha2/frontend/config/paths.js +++ /dev/null @@ -1,89 +0,0 @@ -'use strict'; - -const path = require('path'); -const fs = require('fs'); -const url = require('url'); - -// Make sure any symlinks in the project folder are resolved: -// https://github.com/facebook/create-react-app/issues/637 -const appDirectory = fs.realpathSync(process.cwd()); -const resolveApp = relativePath => path.resolve(appDirectory, relativePath); - -const envPublicUrl = process.env.PUBLIC_URL; - -function ensureSlash(inputPath, needsSlash) { - const hasSlash = inputPath.endsWith('/'); - if (hasSlash && !needsSlash) { - return inputPath.substr(0, inputPath.length - 1); - } else if (!hasSlash && needsSlash) { - return `${inputPath}/`; - } else { - return inputPath; - } -} - -const getPublicUrl = appPackageJson => - envPublicUrl || require(appPackageJson).homepage; - -// We use `PUBLIC_URL` environment variable or "homepage" field to infer -// "public path" at which the app is served. -// Webpack needs to know it to put the right - - - - - - - - - - - - - - - - - Katib UI - - - -
- - - diff --git a/pkg/ui/v1alpha2/frontend/public/logo.png b/pkg/ui/v1alpha2/frontend/public/logo.png deleted file mode 100644 index a0120a540892c8d63fb07ce6a1bd8cc80e29b67e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81189 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¬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 { - throw err; -}); - -// Ensure environment variables are read. -require('../config/env'); - - -const path = require('path'); -const chalk = require('react-dev-utils/chalk'); -const fs = require('fs-extra'); -const webpack = require('webpack'); -const bfj = require('bfj'); -const configFactory = require('../config/webpack.config'); -const paths = require('../config/paths'); -const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); -const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); -const printHostingInstructions = require('react-dev-utils/printHostingInstructions'); -const FileSizeReporter = require('react-dev-utils/FileSizeReporter'); -const printBuildError = require('react-dev-utils/printBuildError'); - -const measureFileSizesBeforeBuild = - FileSizeReporter.measureFileSizesBeforeBuild; -const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild; -const useYarn = fs.existsSync(paths.yarnLockFile); - -// These sizes are pretty large. We'll warn for bundles exceeding them. -const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024; -const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024; - -const isInteractive = process.stdout.isTTY; - -// Warn and crash if required files are missing -if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { - process.exit(1); -} - -// Process CLI arguments -const argv = process.argv.slice(2); -const writeStatsJson = argv.indexOf('--stats') !== -1; - -// Generate configuration -const config = configFactory('production'); - -// We require that you explicitly set browsers and do not fall back to -// browserslist defaults. -const { checkBrowsers } = require('react-dev-utils/browsersHelper'); -checkBrowsers(paths.appPath, isInteractive) - .then(() => { - // First, read the current file sizes in build directory. - // This lets us display how much they changed later. - return measureFileSizesBeforeBuild(paths.appBuild); - }) - .then(previousFileSizes => { - // Remove all content but keep the directory so that - // if you're in it, you don't end up in Trash - fs.emptyDirSync(paths.appBuild); - // Merge with the public folder - copyPublicFolder(); - // Start the webpack build - return build(previousFileSizes); - }) - .then( - ({ stats, previousFileSizes, warnings }) => { - if (warnings.length) { - console.log(chalk.yellow('Compiled with warnings.\n')); - console.log(warnings.join('\n\n')); - console.log( - '\nSearch for the ' + - chalk.underline(chalk.yellow('keywords')) + - ' to learn more about each warning.' - ); - console.log( - 'To ignore, add ' + - chalk.cyan('// eslint-disable-next-line') + - ' to the line before.\n' - ); - } else { - console.log(chalk.green('Compiled successfully.\n')); - } - - console.log('File sizes after gzip:\n'); - printFileSizesAfterBuild( - stats, - previousFileSizes, - paths.appBuild, - WARN_AFTER_BUNDLE_GZIP_SIZE, - WARN_AFTER_CHUNK_GZIP_SIZE - ); - console.log(); - - const appPackage = require(paths.appPackageJson); - const publicUrl = paths.publicUrl; - const publicPath = config.output.publicPath; - const buildFolder = path.relative(process.cwd(), paths.appBuild); - printHostingInstructions( - appPackage, - publicUrl, - publicPath, - buildFolder, - useYarn - ); - }, - err => { - console.log(chalk.red('Failed to compile.\n')); - printBuildError(err); - process.exit(1); - } - ) - .catch(err => { - if (err && err.message) { - console.log(err.message); - } - process.exit(1); - }); - -// Create the production build and print the deployment instructions. -function build(previousFileSizes) { - console.log('Creating an optimized production build...'); - - let compiler = webpack(config); - return new Promise((resolve, reject) => { - compiler.run((err, stats) => { - let messages; - if (err) { - if (!err.message) { - return reject(err); - } - messages = formatWebpackMessages({ - errors: [err.message], - warnings: [], - }); - } else { - messages = formatWebpackMessages( - stats.toJson({ all: false, warnings: true, errors: true }) - ); - } - if (messages.errors.length) { - // Only keep the first error. Others are often indicative - // of the same problem, but confuse the reader with noise. - if (messages.errors.length > 1) { - messages.errors.length = 1; - } - return reject(new Error(messages.errors.join('\n\n'))); - } - if ( - process.env.CI && - (typeof process.env.CI !== 'string' || - process.env.CI.toLowerCase() !== 'false') && - messages.warnings.length - ) { - console.log( - chalk.yellow( - '\nTreating warnings as errors because process.env.CI = true.\n' + - 'Most CI servers set it automatically.\n' - ) - ); - return reject(new Error(messages.warnings.join('\n\n'))); - } - - const resolveArgs = { - stats, - previousFileSizes, - warnings: messages.warnings, - }; - if (writeStatsJson) { - return bfj - .write(paths.appBuild + '/bundle-stats.json', stats.toJson()) - .then(() => resolve(resolveArgs)) - .catch(error => reject(new Error(error))); - } - - return resolve(resolveArgs); - }); - }); -} - -function copyPublicFolder() { - fs.copySync(paths.appPublic, paths.appBuild, { - dereference: true, - filter: file => file !== paths.appHtml, - }); -} diff --git a/pkg/ui/v1alpha2/frontend/scripts/start.js b/pkg/ui/v1alpha2/frontend/scripts/start.js deleted file mode 100644 index 99bb4ab3869..00000000000 --- a/pkg/ui/v1alpha2/frontend/scripts/start.js +++ /dev/null @@ -1,132 +0,0 @@ -'use strict'; - -// Do this as the first thing so that any code reading it knows the right env. -process.env.BABEL_ENV = 'development'; -process.env.NODE_ENV = 'development'; - -// Makes the script crash on unhandled rejections instead of silently -// ignoring them. In the future, promise rejections that are not handled will -// terminate the Node.js process with a non-zero exit code. -process.on('unhandledRejection', err => { - throw err; -}); - -// Ensure environment variables are read. -require('../config/env'); - - -const fs = require('fs'); -const chalk = require('react-dev-utils/chalk'); -const webpack = require('webpack'); -const WebpackDevServer = require('webpack-dev-server'); -const clearConsole = require('react-dev-utils/clearConsole'); -const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); -const { - choosePort, - createCompiler, - prepareProxy, - prepareUrls, -} = require('react-dev-utils/WebpackDevServerUtils'); -const openBrowser = require('react-dev-utils/openBrowser'); -const paths = require('../config/paths'); -const configFactory = require('../config/webpack.config'); -const createDevServerConfig = require('../config/webpackDevServer.config'); - -const useYarn = fs.existsSync(paths.yarnLockFile); -const isInteractive = process.stdout.isTTY; - -// Warn and crash if required files are missing -if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { - process.exit(1); -} - -// Tools like Cloud9 rely on this. -const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; -const HOST = process.env.HOST || '0.0.0.0'; - -if (process.env.HOST) { - console.log( - chalk.cyan( - `Attempting to bind to HOST environment variable: ${chalk.yellow( - chalk.bold(process.env.HOST) - )}` - ) - ); - console.log( - `If this was unintentional, check that you haven't mistakenly set it in your shell.` - ); - console.log( - `Learn more here: ${chalk.yellow('https://bit.ly/CRA-advanced-config')}` - ); - console.log(); -} - -// We require that you explictly set browsers and do not fall back to -// browserslist defaults. -const { checkBrowsers } = require('react-dev-utils/browsersHelper'); -checkBrowsers(paths.appPath, isInteractive) - .then(() => { - // We attempt to use the default port but if it is busy, we offer the user to - // run on a different port. `choosePort()` Promise resolves to the next free port. - return choosePort(HOST, DEFAULT_PORT); - }) - .then(port => { - if (port == null) { - // We have not found a port. - return; - } - const config = configFactory('development'); - const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; - const appName = require(paths.appPackageJson).name; - const useTypeScript = fs.existsSync(paths.appTsConfig); - const urls = prepareUrls(protocol, HOST, port); - const devSocket = { - warnings: warnings => - devServer.sockWrite(devServer.sockets, 'warnings', warnings), - errors: errors => - devServer.sockWrite(devServer.sockets, 'errors', errors), - }; - // Create a webpack compiler that is configured with custom messages. - const compiler = createCompiler({ - appName, - config, - devSocket, - urls, - useYarn, - useTypeScript, - webpack, - }); - // Load proxy config - const proxySetting = require(paths.appPackageJson).proxy; - const proxyConfig = prepareProxy(proxySetting, paths.appPublic); - // Serve webpack assets generated by the compiler over a web server. - const serverConfig = createDevServerConfig( - proxyConfig, - urls.lanUrlForConfig - ); - const devServer = new WebpackDevServer(compiler, serverConfig); - // Launch WebpackDevServer. - devServer.listen(port, HOST, err => { - if (err) { - return console.log(err); - } - if (isInteractive) { - clearConsole(); - } - console.log(chalk.cyan('Starting the development server...\n')); - openBrowser(urls.localUrlForBrowser); - }); - - ['SIGINT', 'SIGTERM'].forEach(function(sig) { - process.on(sig, function() { - devServer.close(); - process.exit(); - }); - }); - }) - .catch(err => { - if (err && err.message) { - console.log(err.message); - } - process.exit(1); - }); diff --git a/pkg/ui/v1alpha2/frontend/scripts/test.js b/pkg/ui/v1alpha2/frontend/scripts/test.js deleted file mode 100644 index 4172e422c75..00000000000 --- a/pkg/ui/v1alpha2/frontend/scripts/test.js +++ /dev/null @@ -1,60 +0,0 @@ -'use strict'; - -// Do this as the first thing so that any code reading it knows the right env. -process.env.BABEL_ENV = 'test'; -process.env.NODE_ENV = 'test'; -process.env.PUBLIC_URL = ''; - -// Makes the script crash on unhandled rejections instead of silently -// ignoring them. In the future, promise rejections that are not handled will -// terminate the Node.js process with a non-zero exit code. -process.on('unhandledRejection', err => { - throw err; -}); - -// Ensure environment variables are read. -require('../config/env'); - - -const jest = require('jest'); -const execSync = require('child_process').execSync; -let argv = process.argv.slice(2); - -function isInGitRepository() { - try { - execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }); - return true; - } catch (e) { - return false; - } -} - -function isInMercurialRepository() { - try { - execSync('hg --cwd . root', { stdio: 'ignore' }); - return true; - } catch (e) { - return false; - } -} - -// Watch unless on CI, in coverage mode, explicitly adding `--no-watch`, -// or explicitly running all tests -if ( - !process.env.CI && - argv.indexOf('--coverage') === -1 && - argv.indexOf('--no-watch') === -1 && - argv.indexOf('--watchAll') === -1 -) { - // https://github.com/facebook/create-react-app/issues/5210 - const hasSourceControl = isInGitRepository() || isInMercurialRepository(); - argv.push(hasSourceControl ? '--watch' : '--watchAll'); -} - -// Jest doesn't have this option so we'll remove it -if (argv.indexOf('--no-watch') !== -1) { - argv = argv.filter(arg => arg !== '--no-watch'); -} - - -jest.run(argv); diff --git a/pkg/ui/v1alpha2/frontend/src/actions/generalActions.js b/pkg/ui/v1alpha2/frontend/src/actions/generalActions.js deleted file mode 100644 index 024f30fb59d..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/actions/generalActions.js +++ /dev/null @@ -1,47 +0,0 @@ -export const TOGGLE_MENU = "TOGGLE_MENU"; - -export const toggleMenu = (state) => { - return { - type: TOGGLE_MENU, - state, - }; -}; - -export const CLOSE_SNACKBAR = "CLOSE_SNACKBAR"; - -export const closeSnackbar = () => { - return { - type: CLOSE_SNACKBAR, - }; -}; - -export const SUBMIT_YAML_REQUEST = "SUBMIT_YAML_REQUEST"; -export const SUBMIT_YAML_FAILURE = "SUBMIT_YAML_FAILURE"; -export const SUBMIT_YAML_SUCCESS = "SUBMIT_YAML_SUCCESS"; - -export const submitYaml = (yaml) => ({ - type: SUBMIT_YAML_REQUEST, - yaml, -}) - -export const DELETE_EXPERIMENT_REQUEST = "DELETE_EXPERIMENT_REQUEST"; -export const DELETE_EXPERIMENT_FAILURE = "DELETE_EXPERIMENT_FAILURE"; -export const DELETE_EXPERIMENT_SUCCESS = "DELETE_EXPERIMENT_SUCCESS"; - -export const deleteExperiment = (experimentName) => ({ - type: DELETE_EXPERIMENT_REQUEST, - experimentName, -}) - -export const OPEN_DELETE_EXPERIMENT_DIALOG = "OPEN_DELETE_EXPERIMENT_DIALOG"; - -export const openDeleteExperimentDialog = (experimentName) => ({ - type: OPEN_DELETE_EXPERIMENT_DIALOG, - experimentName, -}) - -export const CLOSE_DELETE_EXPERIMENT_DIALOG = "CLOSE_DELETE_EXPERIMENT_DIALOG"; - -export const closeDeleteExperimentDialog = () => ({ - type: CLOSE_DELETE_EXPERIMENT_DIALOG, -}) diff --git a/pkg/ui/v1alpha2/frontend/src/actions/hpCreateActions.js b/pkg/ui/v1alpha2/frontend/src/actions/hpCreateActions.js deleted file mode 100644 index 0aef7c5fecf..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/actions/hpCreateActions.js +++ /dev/null @@ -1,131 +0,0 @@ -export const CHANGE_YAML_HP = "CHANGE_YAML_HP"; - -export const changeYaml = (yaml) => ({ - type: CHANGE_YAML_HP, - payload: yaml -}) - -export const CHANGE_META_HP = "CHANGE_META_HP"; - -export const changeMeta = (name, value) => ({ - type: CHANGE_META_HP, - name, value, -}) - -export const CHANGE_SPEC_HP = "CHANGE_SPEC_HP"; - -export const changeSpec = (name, value) => ({ - type: CHANGE_SPEC_HP, - name, value -}) - -export const CHANGE_OBJECTIVE_HP = "CHANGE_OBJECTIVE_HP"; - -export const changeObjective = (name, value) => ({ - type: CHANGE_OBJECTIVE_HP, - name, value -}) -export const ADD_METRICS_HP = "ADD_METRICS_HP"; - -export const addMetrics = () => ({ - type: ADD_METRICS_HP, -}) - -export const DELETE_METRICS_HP = "DELETE_METRICS_HP"; - -export const deleteMetrics = (index) => ({ - type: DELETE_METRICS_HP, - index, -}) - -export const EDIT_METRICS_HP = "EDIT_METRICS_HP"; - -export const editMetrics = (index, value) => ({ - type: EDIT_METRICS_HP, - index, value, -}) - -export const CHANGE_ALGORITHM_NAME_HP = "CHANGE_ALGORITHM_NAME_HP"; - -export const changeAlgorithmName = (algorithmName) => ({ - type: CHANGE_ALGORITHM_NAME_HP, - algorithmName, -}) - -export const ADD_ALGORITHM_SETTING_HP = "ADD_ALGORITHM_SETTING_HP"; - -export const addAlgorithmSetting = () => ({ - type: ADD_ALGORITHM_SETTING_HP, -}) - -export const CHANGE_ALGORITHM_SETTING_HP = "CHANGE_ALGORITHM_SETTING_HP"; - -export const changeAlgorithmSetting = (index, field, value) => ({ - type: CHANGE_ALGORITHM_SETTING_HP, - field, value, index -}) - -export const DELETE_ALGORITHM_SETTING_HP = "DELETE_ALGORITHM_SETTING_HP"; - -export const deleteAlgorithmSetting = (index) => ({ - type: DELETE_ALGORITHM_SETTING_HP, - index -}) - -export const ADD_PARAMETER_HP = "CHANGE_PARAMETER_HP"; - -export const addParameter = () => ({ - type: ADD_PARAMETER_HP, -}) - -export const EDIT_PARAMETER_HP = "EDIT_PARAMTER_HP"; - -export const editParameter = (index, field, value) => ({ - type: EDIT_PARAMETER_HP, - index, field, value, -}) - -export const DELETE_PARAMETER_HP = "DELETE_PARAMETER_HP"; - -export const deleteParameter = (index) => ({ - type: DELETE_PARAMETER_HP, - index, -}) - -export const ADD_LIST_PARAMETER_HP = "ADD_LIST_PARAMETER_HP"; - - -export const addListParameter = (paramIndex) => ({ - type: ADD_LIST_PARAMETER_HP, - paramIndex, -}) - -export const EDIT_LIST_PARAMETER_HP = "EDIT_LIST_PARAMETER_HP"; - -export const editListParameter = (paramIndex, index, value) => ({ - type: EDIT_LIST_PARAMETER_HP, - paramIndex, index, value -}) - -export const DELETE_LIST_PARAMETER_HP = "DELETE_LIST_PARAMETER_HP"; - -export const deleteListParameter = (paramIndex, index) => ({ - type: DELETE_LIST_PARAMETER_HP, - paramIndex, index -}) - -export const CHANGE_TRIAL_HP = "CHANGE_TRIAL_HP"; - -export const changeTrial = (trial) => ({ - type: CHANGE_TRIAL_HP, - trial, -}) - -export const SUBMIT_HP_JOB_REQUEST = "SUBMIT_HP_JOB_REQUEST"; -export const SUBMIT_HP_JOB_SUCCESS = "SUBMIT_HP_JOB_SUCCESS"; -export const SUBMIT_HP_JOB_FAILURE = "SUBMIT_HP_JOB_FAILURE"; - -export const submitHPJob = (data) => ({ - type: SUBMIT_HP_JOB_REQUEST, - data, -}) diff --git a/pkg/ui/v1alpha2/frontend/src/actions/hpMonitorActions.js b/pkg/ui/v1alpha2/frontend/src/actions/hpMonitorActions.js deleted file mode 100644 index 1439e1634c1..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/actions/hpMonitorActions.js +++ /dev/null @@ -1,45 +0,0 @@ -export const FILTER_JOBS = "FILTER_JOBS"; - -export const filterJobs = (filter) => ({ - type: FILTER_JOBS, - filter, -}) - -export const CHANGE_TYPE = "CHANGE_TYPE"; - -export const changeType = (filter, checked) => ({ - type: CHANGE_TYPE, - filter, checked -}) - -export const FETCH_HP_JOBS_REQUEST = "FETCH_HP_JOBS_REQUEST"; -export const FETCH_HP_JOBS_SUCCESS = "FETCH_HP_JOBS_SUCCESS"; -export const FETCH_HP_JOBS_FAILURE = "FETCH_HP_JOBS_FAILURE"; - -export const fetchHPJobs = () => ({ - type: FETCH_HP_JOBS_REQUEST, -}) - -export const FETCH_HP_JOB_INFO_REQUEST = "FETCH_HP_JOB_INFO_REQUEST"; -export const FETCH_HP_JOB_INFO_SUCCESS = "FETCH_HP_JOB_INFO_SUCCESS"; -export const FETCH_HP_JOB_INFO_FAILURE = "FETCH_HP_JOB_INFO_FAILURE"; - -export const fetchHPJobInfo = (experimentName) => ({ - type: FETCH_HP_JOB_INFO_REQUEST, - experimentName -}) - -export const FETCH_HP_JOB_TRIAL_INFO_REQUEST = "FETCH_HP_JOB_TRIAL_INFO_REQUEST"; -export const FETCH_HP_JOB_TRIAL_INFO_SUCCESS = "FETCH_HP_JOB_TRIAL_INFO_SUCCESS"; -export const FETCH_HP_JOB_TRIAL_INFO_FAILURE = "FETCH_HP_JOB_TRIAL_INFO_FAILURE"; - -export const fetchHPJobTrialInfo = (trialName) => ({ - type: FETCH_HP_JOB_TRIAL_INFO_REQUEST, - trialName -}) - -export const CLOSE_DIALOG = "CLOSE_DIALOG"; - -export const closeDialog = () => ({ - type: CLOSE_DIALOG, -}) diff --git a/pkg/ui/v1alpha2/frontend/src/actions/nasCreateActions.js b/pkg/ui/v1alpha2/frontend/src/actions/nasCreateActions.js deleted file mode 100644 index 7542ed36466..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/actions/nasCreateActions.js +++ /dev/null @@ -1,187 +0,0 @@ -export const CHANGE_YAML_NAS = "CHANGE_YAML_NAS"; - -export const changeYaml = (yaml) => ({ - type: CHANGE_YAML_NAS, - payload: yaml -}) - -export const CHANGE_META_NAS = "CHANGE_META_NAS"; - -export const changeMeta = (name, value) => ({ - type: CHANGE_META_NAS, - name, value, -}) - -export const CHANGE_SPEC_NAS = "CHANGE_SPEC_NAS"; - -export const changeSpec = (name, value) => ({ - type: CHANGE_SPEC_NAS, - name, value -}) - -export const CHANGE_OBJECTIVE_NAS = "CHANGE_OBJECTIVE_NAS"; - -export const changeObjective = (name, value) => ({ - type: CHANGE_OBJECTIVE_NAS, - name, value -}) - -export const ADD_METRICS_NAS = "ADD_METRICS_NAS"; - -export const addMetrics = () => ({ - type: ADD_METRICS_NAS, -}) - -export const DELETE_METRICS_NAS = "DELETE_METRICS_NAS"; - -export const deleteMetrics = (index) => ({ - type: DELETE_METRICS_NAS, - index, -}) - -export const EDIT_METRICS_NAS = "EDIT_METRICS_NAS"; - -export const editMetrics = (index, value) => ({ - type: EDIT_METRICS_NAS, - index, value, -}) - -export const CHANGE_ALGORITHM_NAME_NAS = "CHANGE_ALGORITHM_NAME_NAS"; - -export const changeAlgorithmName = (algorithmName) => ({ - type: CHANGE_ALGORITHM_NAME_NAS, - algorithmName, -}) - -export const ADD_ALGORITHM_SETTING_NAS = "ADD_ALGORITHM_SETTING_NAS"; - -export const addAlgorithmSetting = () => ({ - type: ADD_ALGORITHM_SETTING_NAS, -}) - -export const CHANGE_ALGORITHM_SETTING_NAS = "CHANGE_ALGORITHM_SETTING_NAS"; - -export const changeAlgorithmSetting = (index, field, value) => ({ - type: CHANGE_ALGORITHM_SETTING_NAS, - field, value, index -}) - -export const DELETE_ALGORITHM_SETTING_NAS = "DELETE_ALGORITHM_SETTING_NAS"; - -export const deleteAlgorithmSetting = (index) => ({ - type: DELETE_ALGORITHM_SETTING_NAS, - index -}) - -export const EDIT_NUM_LAYERS = "EDIT_NUM_LAYERS" - -export const editNumLayers = (value) => ({ - type: EDIT_NUM_LAYERS, - value -}) - -export const ADD_SIZE = "ADD_SIZE"; - -export const addSize = (sizeType) => ({ - type: ADD_SIZE, - sizeType, -}) - -export const EDIT_SIZE = "EDIT_SIZE"; - -export const editSize = (sizeType, index, value) => ({ - type: EDIT_SIZE, - sizeType, index, value, -}) - -export const DELETE_SIZE = "DELETE_SIZE"; - -export const deleteSize = (sizeType, index) => ({ - type: DELETE_SIZE, - sizeType, index, -}) - -export const ADD_OPERATION = "ADD_OPERATION"; - -export const addOperation = () => ({ - type: ADD_OPERATION, -}) - -export const DELETE_OPERATION = "DELETE_OPERATION"; - -export const deleteOperation = (index) => ({ - type: DELETE_OPERATION, - index, -}) - -export const CHANGE_OPERATION = "CHANGE_OPERATION"; - -export const changeOperation = (index, value) => ({ - type: CHANGE_OPERATION, - index, value, -}) - -export const ADD_PARAMETER_NAS = "ADD_PARAMETER_NAS"; - -export const addParameter = (opIndex) => ({ - type: ADD_PARAMETER_NAS, - opIndex, -}) - -export const CHANGE_PARAMETER_NAS = "CHANGE_PARAMETER_NAS"; - -export const changeParameter = (opIndex, paramIndex, field, value) => ({ - type: CHANGE_PARAMETER_NAS, - opIndex, paramIndex, field, value, -}) - -export const DELETE_PARAMETER_NAS = "DELETE_PARAMETER_NAS"; - -export const deleteParameter = (opIndex, paramIndex) => ({ - type: DELETE_PARAMETER_NAS, - opIndex, paramIndex, -}) - - -export const ADD_LIST_PARAMETER_NAS = "ADD_LIST_PARAMETER_NAS"; - -export const addListParameter = (opIndex, paramIndex) => ({ - type: ADD_LIST_PARAMETER_NAS, - opIndex, paramIndex, -}) - -export const EDIT_LIST_PARAMETER_NAS = "EDIT_LIST_PARAMETER_NAS"; - -export const editListParameter = (opIndex, paramIndex, listIndex, value) => ({ - type: EDIT_LIST_PARAMETER_NAS, - opIndex, paramIndex, listIndex, value, -}) - -export const DELETE_LIST_PARAMETER_NAS = "DELETE_LIST_PARAMETER_NAS"; - -export const deleteListParameter = (opIndex, paramIndex, listIndex) => ({ - type: DELETE_LIST_PARAMETER_NAS, - opIndex, paramIndex, listIndex, -}) - -export const CHANGE_TRIAL_NAS = "CHANGE_TRIAL_NAS"; - -export const changeTrial = (trial) => ({ - type: CHANGE_TRIAL_NAS, - trial, -}) - -export const SUBMIT_NAS_JOB_REQUEST = "SUBMIT_NAS_JOB_REQUEST"; -export const SUBMIT_NAS_JOB_SUCCESS = "SUBMIT_NAS_JOB_SUCCESS"; -export const SUBMIT_NAS_JOB_FAILURE = "SUBMIT_NAS_JOB_FAILURE"; - -export const submitNASJob = (data) => ({ - type: SUBMIT_NAS_JOB_REQUEST, - data, -}) - -export const CLOSE_SNACKBAR = "CLOSE_SNACKBAR"; - -export const closeSnackbar = () => ({ - type: CLOSE_SNACKBAR, -}) diff --git a/pkg/ui/v1alpha2/frontend/src/actions/nasMonitorActions.js b/pkg/ui/v1alpha2/frontend/src/actions/nasMonitorActions.js deleted file mode 100644 index 4796d91ec5e..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/actions/nasMonitorActions.js +++ /dev/null @@ -1,30 +0,0 @@ -export const FILTER_JOBS = "FILTER_JOBS"; - -export const filterJobs = (filter) => ({ - type: FILTER_JOBS, - filter, -}) - -export const CHANGE_TYPE = "CHANGE_TYPE"; - -export const changeType = (filter, checked) => ({ - type: CHANGE_TYPE, - filter, checked -}) - -export const FETCH_NAS_JOBS_REQUEST = "FETCH_NAS_JOBS_REQUEST"; -export const FETCH_NAS_JOBS_SUCCESS = "FETCH_NAS_JOBS_SUCCESS"; -export const FETCH_NAS_JOBS_FAILURE = "FETCH_NAS_JOBS_FAILURE"; - -export const fetchNASJobs = () => ({ - type: FETCH_NAS_JOBS_REQUEST, -}) - -export const FETCH_NAS_JOB_INFO_REQUEST = "FETCH_NAS_JOB_INFO_REQUEST"; -export const FETCH_NAS_JOB_INFO_SUCCESS = "FETCH_NAS_JOB_INFO_SUCCESS"; -export const FETCH_NAS_JOB_INFO_FAILURE = "FETCH_NAS_JOB_INFO_FAILURE"; - -export const fetchNASJobInfo = (experimentName) => ({ - type: FETCH_NAS_JOB_INFO_REQUEST, - experimentName -}) diff --git a/pkg/ui/v1alpha2/frontend/src/actions/templateActions.js b/pkg/ui/v1alpha2/frontend/src/actions/templateActions.js deleted file mode 100644 index 613cfebac9a..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/actions/templateActions.js +++ /dev/null @@ -1,63 +0,0 @@ -export const CLOSE_DIALOG = "CLOSE_DIALOG"; - -export const closeDialog = (dialogType) => ({ - type: CLOSE_DIALOG, - dialogType, -}) - -export const OPEN_DIALOG = "OPEN_DIALOG"; - -export const openDialog = (dialogType, index = -1, templateType = -1) => ({ - type: OPEN_DIALOG, - dialogType, index, templateType -}) - -export const CHANGE_TEMPLATE = "CHANGE_TEMPLATE"; - -export const changeTemplate = (field, value) => ({ - type: CHANGE_TEMPLATE, - field, value -}) - -export const FETCH_TRIAL_TEMPLATES_REQUEST = "FETCH_TRIAL_TEMPLATES_REQUEST" -export const FETCH_TRIAL_TEMPLATES_SUCCESS = "FETCH_TRIAL_TEMPLATES_SUCCESS" -export const FETCH_TRIAL_TEMPLATES_FAILURE = "FETCH_TRIAL_TEMPLATES_FAILURE" - -export const fetchTrialTemplates = () => ({ - type: FETCH_TRIAL_TEMPLATES_REQUEST, -}) - -export const FETCH_COLLECTOR_TEMPLATES_REQUEST = "FETCH_COLLECTOR_TEMPLATES_REQUEST" -export const FETCH_COLLECTOR_TEMPLATES_SUCCESS = "FETCH_COLLECTOR_TEMPLATES_SUCCESS" -export const FETCH_COLLECTOR_TEMPLATES_FAILURE = "FETCH_COLLECTOR_TEMPLATES_FAILURE" - -export const fetchCollectorTemplates = () => ({ - type: FETCH_COLLECTOR_TEMPLATES_REQUEST, -}) - -export const ADD_TEMPLATE_REQUEST = "ADD_TEMPLATE_REQUEST" -export const ADD_TEMPLATE_SUCCESS = "ADD_TEMPLATE_SUCCESS" -export const ADD_TEMPLATE_FAILURE = "ADD_TEMPLATE_FAILURE" - -export const addTemplate = (name, yaml, kind, action) => ({ - type: ADD_TEMPLATE_REQUEST, - name, yaml, kind, action -}) - -export const EDIT_TEMPLATE_REQUEST = "EDIT_TEMPLATE_REQUEST" -export const EDIT_TEMPLATE_SUCCESS = "EDIT_TEMPLATE_SUCCESS" -export const EDIT_TEMPLATE_FAILURE = "EDIT_TEMPLATE_FAILURE" - -export const editTemplate = (name, yaml, kind, action) => ({ - type: EDIT_TEMPLATE_REQUEST, - name, yaml, kind, action -}) - -export const DELETE_TEMPLATE_REQUEST = "DELETE_TEMPLATE_REQUEST" -export const DELETE_TEMPLATE_SUCCESS = "DELETE_TEMPLATE_SUCCESS" -export const DELETE_TEMPLATE_FAILURE = "DELETE_TEMPLATE_FAILURE" - -export const deleteTemplate = (name, kind, action) => ({ - type: DELETE_TEMPLATE_REQUEST, - name, kind, action -}) diff --git a/pkg/ui/v1alpha2/frontend/src/components/App.jsx b/pkg/ui/v1alpha2/frontend/src/components/App.jsx deleted file mode 100644 index c36ab51d14d..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/App.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react'; - -import Header from './Menu/Header'; -import Snack from './Menu/Snack'; - -import { makeStyles } from '@material-ui/styles'; - -import { Route } from 'react-router-dom'; -import Main from './Menu/Main'; -import HP from './HP/Create/HP'; -import HPJobMonitor from './HP/Monitor/HPJobMonitor'; -import HPJobInfo from './HP/Monitor/HPJobInfo'; -import NAS from './NAS/Create/NAS'; -import NASJobMonitor from './NAS/Monitor/NASJobMonitor'; -import NASJobInfo from './NAS/Monitor/NASJobInfo'; -import Trial from './Templates/Trial'; -import Collector from './Templates/Collector'; - - -const useStyles = makeStyles({ - root: { - width: '90%', - margin: '0 auto', - paddingTop: 20, - } -}); - -const App = (props) => { - const classes = useStyles(); - return ( -

- ) -}; - -export default App; diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/HP.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Create/HP.jsx deleted file mode 100644 index 4325fed0fe4..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/HP.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; -import { Tabs } from 'antd'; -import "antd/dist/antd.css"; - -import YAML from './YAML'; -import HPParameters from './HPParameters'; - - -const TabPane = Tabs.TabPane; - - -const useStyles = makeStyles({ - root: { - flexGrow: 1, - marginTop: 40, - }, -}); - - -const HP = (props) => { - const classes = useStyles(); - - return ( -
- - - - - - - - -
- ); -}; - -export default HP; diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/HPParameters.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Create/HPParameters.jsx deleted file mode 100644 index 43d658359b8..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/HPParameters.jsx +++ /dev/null @@ -1,186 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import withStyles from '@material-ui/styles/withStyles'; -import Button from '@material-ui/core/Button'; -import Grid from '@material-ui/core/Grid'; -import Typography from '@material-ui/core/Typography'; - -import CommonParametersMeta from './Params/CommonMeta'; -import CommonParametersSpec from './Params/CommonSpec'; -import Objective from './Params/Objective' -import TrialSpecParam from './Params/Trial'; -import Parameters from './Params/Parameters'; - -import { submitHPJob } from '../../../actions/hpCreateActions'; - -import { connect } from 'react-redux'; -import Algorithm from './Params/Algorithm'; - -const module = "hpCreate"; - -const styles = theme => ({ - root: { - width: '90%', - margin: '0 auto', - }, - submit: { - textAlign: 'center', - marginTop: 10, - }, - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - }, - section: { - padding: 4, - }, - parameter: { - padding: 2, - }, - formControl: { - margin: 4, - width: '100%', - }, - selectEmpty: { - marginTop: 10, - }, - button: { - margin: 10, - } -}) - -const SectionInTypography = (name, classes) => { - return ( -
- - - - {name} - -
-
-
-
- ) -} - -// probably get render into a function -const deCapitalizeFirstLetterAndAppend = (source, destination) => { - source.map((parameter, i) => { - let value = Number(parameter.value) - let name = parameter.name.charAt(0).toLowerCase() + parameter.name.slice(1) - destination[name] = (isNaN(value) ? parameter.value : value) - }) -} - -const addAlgorithmSettings = (spec, destination) => { - spec.map((parameter, i) => { - destination.push(parameter) - }) -} - -const addParameter = (source, destination) => { - source.map((param, i) => { - let tempParam = {} - tempParam.name = param.name - tempParam.parameterType = param.parameterType - tempParam.feasibleSpace = {} - if (param.feasibleSpace === "list") { - tempParam.feasibleSpace.list = param.list.map((param, i) => param.value) - } else { - tempParam.feasibleSpace.min = param.min - tempParam.feasibleSpace.max = param.max - } - destination.push(tempParam) - }) -} - - -const HPParameters = (props) => { - const submitJob = () => { - let data = {} - data.metadata = {} - deCapitalizeFirstLetterAndAppend(props.commonParametersMetadata, data.metadata) - data.spec = {} - deCapitalizeFirstLetterAndAppend(props.commonParametersSpec, data.spec) - data.spec.objective = {} - deCapitalizeFirstLetterAndAppend(props.objective, data.spec.objective) - data.spec.objective.additionalMetricNames = props.additionalMetricNames.map((metrics, i) => metrics.value) - - data.spec.algorithm = {} - data.spec.algorithm.algorithmName = props.algorithmName - data.spec.algorithm.algorithmSettings = [] - addAlgorithmSettings(props.algorithmSettings, data.spec.algorithm.algorithmSettings) - - data.spec.parameters = [] - addParameter(props.parameters, data.spec.parameters) - - //TODO: Add support not only for default ConfigMap for Trial-Templates - data.spec.trialTemplate = { - goTemplate: { - templateSpec: { - configMapName: "trial-template", - configMapNamespace: data.metadata.namespace, - templatePath: props.trial, - } - } - } - - props.submitHPJob(data) - } - - const { classes } = props; - - return ( -
- {/* Common Metadata */} - {SectionInTypography("Metadata", classes)} -
- - {SectionInTypography("Common Parameters", classes)} - - {SectionInTypography("Objective", classes)} - - {SectionInTypography("Algorithm", classes)} - - - {SectionInTypography("Parameters", classes)} - - {SectionInTypography("Trial Spec", classes)} - - -
- -
-
- ) -} - -// TODO: think of a better way of passing those -const mapStateToProps = (state) => ({ - commonParametersMetadata: state[module].commonParametersMetadata, - commonParametersSpec: state[module].commonParametersSpec, - objective: state[module].objective, - additionalMetricNames: state[module].additionalMetricNames, - algorithmName: state[module].algorithmName, - algorithmSettings: state[module].algorithmSettings, - parameters: state[module].parameters, - trial: state[module].trial -}) - -//TODO: Added validation and remove it -// HPParameters.propTypes = { -// trial: PropTypes.string, -// requestNumber: PropTypes.number, -// suggestionAlgorithm: PropTypes.string, -// metricsName: PropTypes.arrayOf(PropTypes.string), -// } - -export default connect(mapStateToProps, { submitHPJob })(withStyles(styles)(HPParameters)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Algorithm.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Algorithm.jsx deleted file mode 100644 index 39c52c90245..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Algorithm.jsx +++ /dev/null @@ -1,160 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Button from '@material-ui/core/Button'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import OutlinedInput from '@material-ui/core/OutlinedInput'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import Select from '@material-ui/core/Select'; -import InputLabel from '@material-ui/core/InputLabel'; -import TextField from '@material-ui/core/TextField'; -import IconButton from '@material-ui/core/IconButton'; - -import DeleteIcon from '@material-ui/icons/Delete'; - -import { connect } from 'react-redux'; -import { changeAlgorithmName, addAlgorithmSetting, changeAlgorithmSetting, deleteAlgorithmSetting } from '../../../../actions/hpCreateActions'; - -const module = "hpCreate"; - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '80%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, - icon: { - padding: 4, - margin: '0 auto', - verticalAlign: "middle !important", - }, - formControl: { - margin: 4, - width: '100%', - }, - addButton: { - margin: 10, - } -}) - -const Algorithm = (props) => { - - const classes = useStyles(); - - const onAlgorithmNameChange = (event) => { - props.changeAlgorithmName(event.target.value); - } - - const onAddAlgorithmSetting = () => { - props.addAlgorithmSetting(); - } - - const onChangeAlgorithmSetting = (name, index) => (event) => { - props.changeAlgorithmSetting(index, name, event.target.value); - } - - const onDeleteAlgorithmSetting= (index) => (event) => { - props.deleteAlgorithmSetting(index); - } - return ( -
- -
- - - - - - - {"Algorithm Name"} - - - - - - Algorithm Name - - - - - -
-
- {props.algorithmSettings.map((param, i) => { - return ( -
- - - - - - - - - - - - - - -
- ) - })} -
- ) -} - - -const mapStateToProps = state => { - return { - algorithmName: state[module].algorithmName, - allAlgorithms: state[module].allAlgorithms, - algorithmSettings: state[module].algorithmSettings - } -} - -export default connect(mapStateToProps, { changeAlgorithmName, addAlgorithmSetting, changeAlgorithmSetting, deleteAlgorithmSetting })(Algorithm); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/CommonMeta.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/CommonMeta.jsx deleted file mode 100644 index ca21672f3f6..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/CommonMeta.jsx +++ /dev/null @@ -1,75 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import TextField from '@material-ui/core/TextField'; - -import { changeMeta } from '../../../../actions/hpCreateActions'; - - -const module = "hpCreate"; - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, -}) - -const CommonParametersMeta = (props) => { - const classes = useStyles(); - - const onMetaChange = (param) => (event) => { - props.changeMeta(param, event.target.value); - } - - return ( -
- {props.commonParametersMetadata.map((param, i) => { - return ( -
- - - - - - - {param.name} - - - - - - -
- ) - })} -
- ) -} - - -const mapStateToProps = state => { - return { - commonParametersMetadata: state[module].commonParametersMetadata, - } -} - -export default connect(mapStateToProps, { changeMeta })(CommonParametersMeta); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/CommonSpec.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/CommonSpec.jsx deleted file mode 100644 index 3039a318a22..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/CommonSpec.jsx +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import TextField from '@material-ui/core/TextField'; - -import { changeSpec } from '../../../../actions/hpCreateActions'; - - -const module = "hpCreate"; - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, -}) - -const CommonParametersSpec = (props) => { - - const classes = useStyles(); - - const onSpecChange = (name) => (event) => { - props.changeSpec(name, event.target.value); - } - - return ( -
- {props.commonParametersSpec.map((param, i) => { - return ( -
- - - - - - - {param.name} - - - - - - -
- ) - })} -
- ) -} - - -const mapStateToProps = state => { - return { - commonParametersSpec: state[module].commonParametersSpec, - } -} - -export default connect(mapStateToProps, { changeSpec })(CommonParametersSpec); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Objective.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Objective.jsx deleted file mode 100644 index f555310111c..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Objective.jsx +++ /dev/null @@ -1,178 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import TextField from '@material-ui/core/TextField'; -import IconButton from '@material-ui/core/IconButton'; -import DeleteIcon from '@material-ui/icons/Delete'; -import Fab from '@material-ui/core/Fab'; -import AddIcon from '@material-ui/icons/Add'; -import FormControl from '@material-ui/core/FormControl'; -import Select from '@material-ui/core/Select'; -import InputLabel from '@material-ui/core/InputLabel'; -import OutlinedInput from '@material-ui/core/OutlinedInput'; -import MenuItem from '@material-ui/core/MenuItem'; - -import { changeObjective, addMetrics, editMetrics, deleteMetrics } from '../../../../actions/hpCreateActions'; - - -const module = "hpCreate"; - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, - selectBox: { - width: 150 - } -}) - -const Objective = (props) => { - - const classes = useStyles(); - - const onObjectiveChange = (name) => (event) => { - props.changeObjective(name, event.target.value); - } - - const onMetricsEdit = (index) => (event) => { - props.editMetrics(index, event.target.value); - } - - const onMetricsDelete = (index) => (event) => { - props.deleteMetrics(index); - } - - return ( -
- {props.objective.map((param, i) => { - return ( - param.name === "Type" ? -
- - - - - - - {param.name} - - - - - - Objective Type - - - - - -
- : -
- - - - - - - {param.name} - - - - - - -
- ) - })} -
- - - - - - - AdditionalMetricNames - - - - { - props.additionalMetricNames.map((metrics, mIndex) => { - return ( - - - - - - - - - - - ) - }) - } - - - - - - - -
-
- ) -} - - -const mapStateToProps = state => { - return { - allObjectiveTypes: state[module].allObjectiveTypes, - objective: state[module].objective, - additionalMetricNames: state[module].additionalMetricNames - } -} - -export default connect(mapStateToProps, {changeObjective, addMetrics, editMetrics, deleteMetrics })(Objective); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Parameters.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Parameters.jsx deleted file mode 100644 index 88ef77a0135..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Parameters.jsx +++ /dev/null @@ -1,214 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Button from '@material-ui/core/Button'; -import Grid from '@material-ui/core/Grid'; -import TextField from '@material-ui/core/TextField'; -import OutlinedInput from '@material-ui/core/OutlinedInput'; -import InputLabel from '@material-ui/core/InputLabel'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import Select from '@material-ui/core/Select'; -import IconButton from '@material-ui/core/IconButton'; -import DeleteIcon from '@material-ui/icons/Delete'; -import Radio from '@material-ui/core/Radio'; -import RadioGroup from '@material-ui/core/RadioGroup'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Divider from '@material-ui/core/Divider'; -import Fab from '@material-ui/core/Fab'; -import AddIcon from '@material-ui/icons/Add'; - -import { addParameter, editParameter, deleteParameter, addListParameter, editListParameter, deleteListParameter } from '../../../../actions/hpCreateActions'; - - -const module = "hpCreate"; - - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '80%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, - formControl: { - margin: 4, - width: '100%', - }, - selectEmpty: { - marginTop: 10, - }, - group: { - flexDirection: 'row', - justifyContent: 'space-around', - }, - divider: { - margin: 5, - }, - addButton: { - margin: 10, - }, - fab: { - margin: 2, - }, -}) - -const Parameters = (props) => { - - const classes = useStyles(); - - const onDelete = (index) => (event) => { - props.deleteParameter(index); - } - - const onGeneralEdit = (index, field) => (event) => { - props.editParameter(index, field, event.target.value); - } - - const onParamAdd = (index) => (event) => { - props.addListParameter(index); - } - - const onParamEdit = (paramIndex, index) => (event) => { - props.editListParameter(paramIndex, index, event.target.value); - } - - const onParamDelete = (paramIndex, index) => (event) => { - props.deleteListParameter(paramIndex, index); - } - - return ( -
- - {props.parameters.map((param, i) => { - return ( -
- - - - - - - - Parameter Type - - - - - - - } label="FeasibleSpace" /> - } label="List" /> - - - - {param.feasibleSpace === "list" && - (param.list.map((element, elIndex) => { - return ( -
- - - - -
- ) - })) - - } - {param.feasibleSpace === "feasibleSpace" && -
- - -
- } -
- - {param.feasibleSpace === "list" && - - - - } - - - - - - -
- -
- ) - })} -
- ) -} - - -const mapStateToProps = state => { - return { - parameters: state[module].parameters, - allParameterTypes: state[module].allParameterTypes, - } -} - -export default connect(mapStateToProps, { addParameter, editParameter, deleteParameter, addListParameter, editListParameter, deleteListParameter })(Parameters); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Trial.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Trial.jsx deleted file mode 100644 index 0d3595645d6..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/Params/Trial.jsx +++ /dev/null @@ -1,102 +0,0 @@ -import React from 'react'; -import withStyles from '@material-ui/styles/withStyles'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import OutlinedInput from '@material-ui/core/OutlinedInput'; -import InputLabel from '@material-ui/core/InputLabel'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import Select from '@material-ui/core/Select'; - -import { connect } from 'react-redux'; -import { changeTrial } from '../../../../actions/hpCreateActions'; -import { fetchTrialTemplates } from '../../../../actions/templateActions'; - -const module = "hpCreate"; -const templateModule = "template"; - -const styles = theme => ({ - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - section: { - padding: 4, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, - formControl: { - margin: 4, - width: '100%', - }, - selectEmpty: { - marginTop: 10, - }, -}) - -class TrialSpecParam extends React.Component { - - componentDidMount() { - this.props.fetchTrialTemplates(); - } - - onTrialChange = (event) => { - this.props.changeTrial(event.target.value); - } - - render() { - const names = this.props.templates.map((template, i) => template.name) - - const { classes } = this.props - return ( -
- - - - - - - {"TrialSpec"} - - - - - - Trial Spec - - - - - -
- ) - } -} - - -const mapStateToProps = state => { - return { - trial: state[module].trial, - templates: state[templateModule].trialTemplates, - } -} - -export default connect(mapStateToProps, { changeTrial, fetchTrialTemplates })(withStyles(styles)(TrialSpecParam)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/YAML.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Create/YAML.jsx deleted file mode 100644 index fa9be6d9da1..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Create/YAML.jsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import 'brace/mode/javascript'; -import 'brace/theme/tomorrow'; -import AceEditor from 'react-ace'; -import Button from '@material-ui/core/Button'; - -import { changeYaml } from '../../../actions/hpCreateActions'; -import { submitYaml } from '../../../actions/generalActions'; - -const module = "hpCreate"; - -const useStyles = makeStyles ({ - root: { - flexGrow: 1, - }, - editor: { - margin: '0 auto', - }, - submit: { - textAlign: 'center', - marginTop: 10, - }, - progress: { - height: 10, - margin: 10, - }, - close: { - padding: 4, - }, -}); - - -const YAML = (props) => { - - const onYamlChange = (value) => { - props.changeYaml(value); - }; - - const submitWholeYaml = () => { - props.submitYaml(props.yaml); - }; - - const classes = useStyles(); - return ( -
-

Generate

-
- {/* {props.loading && } */} -
- -
-
- -
-
- ); -}; - -const mapStateToProps = (state) => { - return { - yaml: state[module].currentYaml, - }; -}; - - -export default connect(mapStateToProps, { changeYaml, submitYaml })(YAML); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/FilterPanel.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/FilterPanel.jsx deleted file mode 100644 index b19b7c5b863..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/FilterPanel.jsx +++ /dev/null @@ -1,81 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import { withStyles } from '@material-ui/core/styles'; - -import TextField from '@material-ui/core/TextField'; -import FormGroup from '@material-ui/core/FormGroup'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Switch from '@material-ui/core/Switch'; -import Button from '@material-ui/core/Button'; - -import { filterJobs, changeType, fetchHPJobs } from '../../../actions/hpMonitorActions'; - - -const module = "hpMonitor"; - - -const styles = theme => ({ - textField: { - marginLeft: theme.spacing.unit, - marginRight: theme.spacing.unit, - }, - filter: { - margin: '0 auto', - textAlign: 'center', - }, -}); - -const FilterPanel = (props) => { - - const { classes } = props; - - const handleType = (name) => (event) => { - props.changeType(name, event.target.checked); - } - - return ( -
- - props.filterJobs(event.target.value)} - margin="normal" - variant="outlined" - /> - { - Object.keys(props.filterType).map((filter, i) => { - return( - - } - label={filter} - /> - ); - }) - } - - -
- ) -} - -const mapStateToProps = state => { - return { - filter: state[module].filter, - filterType: state[module].filterType, - } -} - -export default connect(mapStateToProps, { filterJobs, changeType, fetchHPJobs })(withStyles(styles)(FilterPanel)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobInfo.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobInfo.jsx deleted file mode 100644 index a358870880f..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobInfo.jsx +++ /dev/null @@ -1,71 +0,0 @@ -import React from 'react' -import { connect } from 'react-redux' -import { withStyles } from '@material-ui/core'; -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; -import { Link } from 'react-router-dom'; -import LinearProgress from '@material-ui/core/LinearProgress'; - - -import { fetchHPJobInfo } from '../../../actions/hpMonitorActions'; - -import HPJobPlot from './HPJobPlot'; -import HPJobTable from './HPJobTable'; -import TrialInfoDialog from './TrialInfoDialog'; - -const module = "hpMonitor"; - -const styles = theme => ({ - root: { - width: '90%', - margin: '0 auto', - padding: 20, - }, - loading: { - marginTop: 30, - }, - header: { - marginTop: 30, - textAlign: "center" - } -}) - -class HPJobInfo extends React.Component { - - componentDidMount() { - this.props.fetchHPJobInfo(this.props.match.params.name); - } - - render () { - const { classes } = this.props; - return ( -
- - - - {this.props.loading ? - - : -
- - Experiment Name: {this.props.match.params.name} - -
- - - -
- } -
- ) - } -} - -const mapStateToProps = (state) => ({ - loading: state[module].loading, -}) - - -export default connect(mapStateToProps, { fetchHPJobInfo })(withStyles(styles)(HPJobInfo)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobList.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobList.jsx deleted file mode 100644 index 5a65ced35d7..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobList.jsx +++ /dev/null @@ -1,92 +0,0 @@ -import React from 'react'; -import {connect} from 'react-redux'; -import { withStyles } from '@material-ui/core/styles'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import { Link } from 'react-router-dom'; -import { ListItemSecondaryAction, IconButton } from '@material-ui/core'; - -import { openDeleteExperimentDialog } from '../../../actions/generalActions'; -import DeleteDialog from '../../Menu/DeleteDialog'; - -import ScheduleIcon from '@material-ui/icons/Schedule'; -import RestoreIcon from '@material-ui/icons/Restore'; -import HighlightOffIcon from '@material-ui/icons/HighlightOff'; -import DoneIcon from '@material-ui/icons/Done'; -import DeleteIcon from '@material-ui/icons/Delete'; -import HourglassFullIcon from '@material-ui/icons/HourglassFull'; - -const module = "hpMonitor"; - -const styles = theme => ({ - created: { - color: theme.colors.created, - }, - running: { - color: theme.colors.running, - }, - restarting: { - color: theme.colors.restarting - }, - succeeded: { - color: theme.colors.succeeded, - }, - failed: { - color: theme.colors.failed, - }, -}); - - -const HPJobList = (props) => { - - const { classes } = props; - - const onDeleteExperiment = (experimentName) => (event) => { - props.openDeleteExperimentDialog(experimentName); - } - - return ( -
- - {props.filteredJobsList.map((job, i) => { - let icon; - if (job.status === 'Created') { - icon = () - } else if (job.status === 'Running') { - icon = () - } else if (job.status === 'Restarting') { - icon = () - } else if (job.status === 'Succeeded') { - icon = () - } else if (job.status === 'Failed') { - icon = () - } - return ( - - - {icon} - - - - - - - - - ); - })} - - -
- ) -} - -const mapStateToProps = (state) => { - return { - filteredJobsList: state[module].filteredJobsList, - } -} - -export default connect(mapStateToProps, { openDeleteExperimentDialog })(withStyles(styles)(HPJobList)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobMonitor.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobMonitor.jsx deleted file mode 100644 index 4f380e44503..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobMonitor.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react'; -import { withStyles } from '@material-ui/core/styles'; - -import FilterPanel from './FilterPanel'; -import HPJobList from './HPJobList'; - -import { fetchHPJobs } from '../../../actions/hpMonitorActions'; -import { connect } from 'react-redux' - - -const styles = theme => ({ - root: { - width: '90%', - margin: '0 auto', - }, -}); - -class HPJobMonitor extends React.Component { - - componentDidMount() { - this.props.fetchHPJobs(); - } - - render () { - const { classes } = this.props; - - return ( -
-

Monitor

- - -
- ) - } -} - - -export default connect(null, { fetchHPJobs })(withStyles(styles)(HPJobMonitor)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobPlot.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobPlot.jsx deleted file mode 100644 index d36b320958b..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobPlot.jsx +++ /dev/null @@ -1,94 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; - -import { connect } from 'react-redux'; -import Plot from 'react-plotly.js'; - -const module = "hpMonitor"; - -const useStyles = makeStyles({ - root: { - textAlign: 'center', - } -}) - -const HPJobPlot = (props) => { - const classes = useStyles(); - let dimensions = []; - - if (props.jobData && props.jobData.length > 1) { - // everything for the third column - let header = props.jobData[0]; - let data = props.jobData.slice(1); - for(let i = 1; i < data[0].length; i++) { - if (header[i] !== '') { - let track = { - label: header[i], - } - let flag = "number"; - let values = []; - for (let j = 0; j < data.length; j++) { - let number = Number(data[j][i]) - if (isNaN(number)) { - flag = "string"; - values.push(data[j][i]); - } else { - values.push(number) - } - } - track.values = values; - if (flag === "number" && flag !== "string") { - track.range = [Math.min.apply(null, values), Math.max.apply(null, values)]; - if (Math.min.apply(null, values) < 1) { - track.tickformat = ".3f" - } else { - track.tickformat = "d" - } - } else { - // check logic - // track.ticktext = values; - let options = new Set(values); - options = [...options] - let mapping = {}; - for (let k = 0; k < options.length; k++) { - mapping[options[k]] = k; - } - track.tickvals = options.map((option, index) => index); - track.ticktext = options.map((option, index) => option); - track.values = values.map((value, index) => mapping[value]) - track.constraintrange = [0, values.length]; - } - dimensions.push(track) - - } - } - } - - - return ( -
- {props.jobData.length > 1 && - - } -
- ) -} - -const mapStateToProps = (state) => ({ - jobData: state[module].jobData, -}) - -export default connect(mapStateToProps, null)(HPJobPlot); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobTable.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobTable.jsx deleted file mode 100644 index 28493d4ca03..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/HPJobTable.jsx +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react'; -import { withStyles } from '@material-ui/core/styles'; -import Table from '@material-ui/core/Table'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import TableHead from '@material-ui/core/TableHead'; -import TableRow from '@material-ui/core/TableRow'; -import Paper from '@material-ui/core/Paper'; - -import { connect } from 'react-redux'; -import { fetchHPJobTrialInfo } from '../../../actions/hpMonitorActions'; - -const module = "hpMonitor"; - -const styles = theme => ({ - root: { - width: '100%', - marginTop: theme.spacing.unit * 3, - overflowX: 'auto', - }, - table: { - minWidth: 700, - }, - hover: { - '&:hover': { - cursor: "pointer", - } - } -}); - -class HPJobTable extends React.Component { - - fetchAndOpenDialog = (trialName) => (event) => { - this.props.fetchHPJobTrialInfo(trialName); - } - - render () { - const { classes } = this.props; - - let header = []; - let data = []; - if (this.props.jobData && this.props.jobData.length > 1) { - header = this.props.jobData[0]; - data = this.props.jobData.slice(1) - } - return ( - - {this.props.jobData.length > 1 && - - - - {header.map(header => ( - {header} - ))} - - - - {data.map((row, id) => ( - - {row.map((element, index) => { - if (index === 0) { - return ( - - {element} - - ) - } else { - return ( - {element} - ) - } - })} - - ))} - -
- } -
- ); - } -} - - -const mapStateToProps = (state) => ({ - jobData: state[module].jobData, -}) - -export default connect(mapStateToProps, { fetchHPJobTrialInfo })(withStyles(styles)(HPJobTable)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/TrialInfoDialog.jsx b/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/TrialInfoDialog.jsx deleted file mode 100644 index f1716a392b8..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/HP/Monitor/TrialInfoDialog.jsx +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react'; -import { withStyles } from '@material-ui/styles'; -import Dialog from '@material-ui/core/Dialog'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import { connect } from 'react-redux'; - -import { closeDialog } from '../../../actions/hpMonitorActions'; -import Plot from 'react-plotly.js'; - - -const module = "hpMonitor"; - -const styles = theme => ({ - header: { - textAlign: "center" - } -}) - - -const TrialInfoDialog = (props) => { - const { classes } = props; - - let dataToPlot = []; - if (props.trialData.length !== 0) { - let data = props.trialData.slice(1); - let tracks = {}; - for(let i = 0; i < data.length; i++) { - if (typeof tracks[data[i][0]] !== "undefined") { - tracks[data[i][0]].x.push(data[i][1]); - tracks[data[i][0]].y.push(Number(data[i][2])); - } else { - tracks[data[i][0]] = {}; - tracks[data[i][0]].x = [data[i][1]]; - tracks[data[i][0]].y = [Number(data[i][2])]; - } - } - - //For plot legend - let keys = Object.keys(tracks); - keys.map((key, i) => { - if (key !== "") { - dataToPlot.push({ - x: tracks[key].x, - y: tracks[key].y, - type: "scatter", - mode: "line", - name: key, - }) - } - }) - } - return ( - - {"Trial data"} - - - - - ); -} - -const mapStateToProps = state => { - return { - open: state[module].dialogOpen, - trialData: state[module].trialData, - } -} - -export default connect(mapStateToProps, { closeDialog })(withStyles(styles)(TrialInfoDialog)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Menu/DeleteDialog.jsx b/pkg/ui/v1alpha2/frontend/src/components/Menu/DeleteDialog.jsx deleted file mode 100644 index fbb5c9b3743..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Menu/DeleteDialog.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import React from 'react'; -import Button from '@material-ui/core/Button'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogContentText from '@material-ui/core/DialogContentText'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import makeStyles from '@material-ui/styles/makeStyles'; - -import { connect } from 'react-redux'; -import { deleteExperiment, closeDeleteExperimentDialog } from '../../actions/generalActions'; - - -const module = "general"; - -const useStyles = makeStyles({ - root: { - } - }) - -const DeleteDialog = (props) => { - const classes = useStyles(); - - const onDelete = () => { - props.deleteExperiment(props.deleteExperimentName); - } - - return ( - - {"Delete Experiment?"} - - - Are you sure you want to delete this experiment? - - - - - - - - ) -} - -const mapStateToProps = (state) => ({ - open: state[module].deleteDialog, - deleteExperimentName: state[module].deleteExperimentName, -}) - -export default connect(mapStateToProps, { closeDeleteExperimentDialog, deleteExperiment })(DeleteDialog); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Menu/Header.jsx b/pkg/ui/v1alpha2/frontend/src/components/Menu/Header.jsx deleted file mode 100644 index 267f777985b..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Menu/Header.jsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import Typography from '@material-ui/core/Typography'; -import IconButton from '@material-ui/core/IconButton'; -import MenuIcon from '@material-ui/icons/Menu'; -import { Link } from 'react-router-dom'; - -import Menu from './Menu'; - -import { connect } from 'react-redux'; -import { toggleMenu } from '../../actions/generalActions'; - - -const useStyles = makeStyles({ - root: { - flexGrow: 1, - }, - grow: { - flexGrow: 1, - }, - menuButton: { - marginLeft: -12, - marginRight: 20, - }, - link: { - textDecoration: 'none', - } -}); - -const Header = (props) => { - const classes = useStyles(); - - const toggleMenu = (event) => { - props.toggleMenu(true); - } - - return ( -
- - - - - - - Katib - - - - -
- ) -} - -export default connect(null, { toggleMenu } )(Header); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Menu/Main.jsx b/pkg/ui/v1alpha2/frontend/src/components/Menu/Main.jsx deleted file mode 100644 index cfcdc4e18f9..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Menu/Main.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; -import { makeStyles } from '@material-ui/styles'; -import Paper from '@material-ui/core/Paper'; -import Typography from '@material-ui/core/Typography'; -import Grid from '@material-ui/core/Grid'; -import Button from '@material-ui/core/Button'; -import { Link } from 'react-router-dom'; - - -const useStyles = makeStyles({ - root: { - margin: '0 auto', - marginTop: 50, - flexGrow: 1, - width: '50%', - height: 400, - textAlign: 'center', - }, - item: { - padding: "40px !important", - }, - block: { - backgroundColor: '#4e4e4e', - height: '100%', - width: '100%', - padding: 40, - '&:hover': { - backgroundColor: 'black', - } - }, -}) - -const Main = (props) => { - - const classes = useStyles(); - - return ( - - - Welcome to Katib - - - Choose type of experiment - -
- - - - - Hyperparameter Tuning - - - - - - - Neural Architecture Search - - - - -
- - For additional information on Kubeflow visit
website - - - For additional information on Katib visit github - - - ) -} - -export default Main; diff --git a/pkg/ui/v1alpha2/frontend/src/components/Menu/Menu.jsx b/pkg/ui/v1alpha2/frontend/src/components/Menu/Menu.jsx deleted file mode 100644 index 78a19eeadc8..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Menu/Menu.jsx +++ /dev/null @@ -1,186 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Drawer from '@material-ui/core/Drawer'; -import List from '@material-ui/core/List'; -import Typography from '@material-ui/core/Typography'; -import Divider from '@material-ui/core/Divider'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import Collapse from '@material-ui/core/Collapse'; - - -import TuneIcon from '@material-ui/icons/Tune'; -import NoteAddIcon from '@material-ui/icons/NoteAdd'; -import WatchLaterIcon from '@material-ui/icons/WatchLater'; -import SearchIcon from '@material-ui/icons/Search'; -import SetttingsIcon from '@material-ui/icons/Settings'; -import ExpandLess from '@material-ui/icons/ExpandLess'; -import ExpandMore from '@material-ui/icons/ExpandMore'; -import InfoIcon from '@material-ui/icons/Info'; - -import { Link } from 'react-router-dom'; - -import { connect } from 'react-redux'; -import { toggleMenu } from '../../actions/generalActions'; - -const module = "general"; - -const useStyles = makeStyles({ - list: { - width: 250, - }, - nested: { - paddingLeft: 10 * 4, - }, -}); - -const Menu = (props) => { - - const [hp, setHP] = React.useState(false); - const [nas, setNAS] = React.useState(false); - - const toggleHP = () => { - setHP(!hp); - }; - - const toggleNAS = () => { - setNAS(!nas); - }; - - const classes = useStyles(); - - const closeMenu = () => { - props.toggleMenu(false); - }; - - // Add links - const color = "primary"; - const iconColor = "primary"; - const variant = "title"; - return ( -
- - - {/* HP */} - - - - - - - HP - - - {hp ? : } - - - - - - - - - - Submit - - - - - - - - - - Monitor - - - - - - - {/* NAS */} - - - - - - - NAS - - - {hp ? : } - - - - - - - - - - Submit - - - - - - - - - - Monitor - - - - - - - {/* TRIAL MANIFESTS */} - - - - - - - Trial Manifests - - - - - {/* METRICS COLLECTOR */} - - - - - - - Metrics Collector Manifests - - - - - {/* ABOUT */} - - - - - - - About - - - - - -
- ) -} - -const mapStateToProps = (state) => { - return { - menuOpen: state[module].menuOpen, - }; -}; - -export default connect(mapStateToProps, { toggleMenu })(Menu); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Menu/Snack.jsx b/pkg/ui/v1alpha2/frontend/src/components/Menu/Snack.jsx deleted file mode 100644 index 22a37806457..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Menu/Snack.jsx +++ /dev/null @@ -1,66 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Snackbar from '@material-ui/core/Snackbar'; -import IconButton from '@material-ui/core/IconButton'; - -import CloseIcon from '@material-ui/icons/Close'; - -import { connect } from 'react-redux'; -import { closeSnackbar } from '../../actions/generalActions'; - -const module = "general"; - - -const useStyles = makeStyles({ - root: { - flexGrow: 1, - marginTop: 40, - }, - close: { - padding: 4, - } -}); - - -const Snack = (props) => { - - const classes = useStyles(); - - const vertical = "top"; - const horizontal = "center"; - return ( - {props.snackText}} - action={[ - - - , - ]} - /> - ) -}; - -const mapStateToProps = (state) => { - return { - snackText: state[module].snackText, - snackOpen: state[module].snackOpen, - } -} - -export default connect(mapStateToProps, { closeSnackbar })(Snack); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/NAS.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/NAS.jsx deleted file mode 100644 index a3e59f203c1..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/NAS.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; -import { Tabs } from 'antd'; -import "antd/dist/antd.css"; - -import YAML from './YAML'; -import NASParameters from './NASParameters'; - - -const TabPane = Tabs.TabPane; - - -const useStyles = makeStyles({ - root: { - flexGrow: 1, - marginTop: 40, - }, -}); - - -const NAS = (props) => { - const classes = useStyles(); - - return ( -
- - - - - - - - -
- ); -}; - -export default NAS; diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/NASParameters.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/NASParameters.jsx deleted file mode 100644 index 170cc87dd6d..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/NASParameters.jsx +++ /dev/null @@ -1,206 +0,0 @@ -import React from 'react'; - -import PropTypes from 'prop-types'; -import withStyles from '@material-ui/styles/withStyles'; -import Button from '@material-ui/core/Button'; -import Grid from '@material-ui/core/Grid'; -import Typography from '@material-ui/core/Typography'; - -import CommonParametersMeta from './Params/CommonMeta'; -import CommonParametersSpec from './Params/CommonSpec'; -import Objective from "./Params/Objective" -import Algorithm from "./Params/Algorithm" -import TrialSpecParam from './Params/Trial'; - -import { submitNASJob } from '../../../actions/nasCreateActions'; - - -import { connect } from 'react-redux'; -import NASConfig from './Params/NASConfig'; - -const module = "nasCreate"; - -const styles = theme => ({ - root: { - width: '90%', - margin: '0 auto', - }, - submit: { - textAlign: 'center', - marginTop: 10, - }, - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - }, - section: { - padding: 4, - }, - parameter: { - padding: 2, - }, - formControl: { - margin: 4, - width: '100%', - }, - selectEmpty: { - marginTop: 10, - }, - addButton: { - margin: 10, - } -}) - -const SectionInTypography = (name, classes) => { - return ( -
- - - - {name} - -
-
-
-
- ) -} - -// probably get render into a function -const deCapitalizeFirstLetterAndAppend = (source, destination) => { - source.map((parameter, i) => { - let value = Number(parameter.value) - let name = parameter.name.charAt(0).toLowerCase() + parameter.name.slice(1) - destination[name] = (isNaN(value) ? parameter.value : value) - }) -} - -const addAlgorithmSettings = (spec, destination) => { - spec.map((parameter, i) => { - destination.push(parameter) - }) -} - -const addOperations = (source, destination) => { - source.map((operation, index) => { - let parameters = [] - operation.parameters.map((param, i) => { - let tempParam = {} - tempParam.name = param.name - tempParam.parametertype = param.parameterType - tempParam.feasibleSpace = {} - if (param.feasibleSpace === "list") { - tempParam.feasibleSpace.list = param.list.map((param, i) => param.value) - } else { - tempParam.feasibleSpace.min = param.min - tempParam.feasibleSpace.max = param.max - tempParam.feasibleSpace.step = param.step - } - parameters.push(tempParam) - }) - destination.push({ - operationType: operation.operationType, - parameters: parameters, - }) - }) -} - -const NASParameters = (props) => { - const submitNASJob = () => { - let data = {} - - data.metadata = {} - deCapitalizeFirstLetterAndAppend(props.commonParametersMetadata, data.metadata) - - data.spec = {} - deCapitalizeFirstLetterAndAppend(props.commonParametersSpec, data.spec) - - data.spec.objective = {} - deCapitalizeFirstLetterAndAppend(props.objective, data.spec.objective) - data.spec.objective.additionalMetricNames = props.additionalMetricNames.map((metrics, i) => metrics.value) - - data.spec.algorithm = {} - data.spec.algorithm.algorithmName = props.algorithmName - data.spec.algorithm.algorithmSettings = [] - addAlgorithmSettings(props.algorithmSettings, data.spec.algorithm.algorithmSettings) - - data.spec.nasConfig = {} - data.spec.nasConfig.graphConfig = { - numLayers: Number(props.numLayers), - inputSizes: props.inputSize.map(size => Number(size)), - outputSizes: props.outputSize.map(size => Number(size)), - } - data.spec.nasConfig.operations = [] - addOperations(props.operations, data.spec.nasConfig.operations) - - - //TODO: Add support not only for default ConfigMap for Trial-Templates - data.spec.trialTemplate = { - goTemplate: { - templateSpec: { - configMapName: "trial-template", - configMapNamespace: data.metadata.namespace, - templatePath: props.trial, - } - } - } - - props.submitNASJob(data) - } - - const { classes } = props; - - return ( -
- {/* Common Metadata */} - {SectionInTypography("Metadata", classes)} - - {SectionInTypography("Common Parameters", classes)} - - {SectionInTypography("Objective", classes)} - - {SectionInTypography("Algorithm", classes)} - - {SectionInTypography("NAS Config", classes)} - - {SectionInTypography("Trial Spec", classes)} - -
- -
-
- ) -} - -// TODO: think of a better way of passing those -const mapStateToProps = (state) => ({ - commonParametersMetadata: state[module].commonParametersMetadata, - commonParametersSpec: state[module].commonParametersSpec, - objective: state[module].objective, - additionalMetricNames: state[module].additionalMetricNames, - algorithmName: state[module].algorithmName, - algorithmSettings: state[module].algorithmSettings, - numLayers: state[module].numLayers, - inputSize: state[module].inputSize, - outputSize: state[module].outputSize, - operations: state[module].operations, - trial: state[module].trial -}) - -//TODO: Added validation and remove it -// NASParameters.propTypes = { -// numLayers: PropTypes.number, -// trial: PropTypes.string, -// requestNumber: PropTypes.number, -// suggestionAlgorithm: PropTypes.string, -// metricsName: PropTypes.arrayOf(PropTypes.string), -// } - -export default connect(mapStateToProps, { submitNASJob })(withStyles(styles)(NASParameters)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Algorithm.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Algorithm.jsx deleted file mode 100644 index 1cb28bc4eeb..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Algorithm.jsx +++ /dev/null @@ -1,160 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Button from '@material-ui/core/Button'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import OutlinedInput from '@material-ui/core/OutlinedInput'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import Select from '@material-ui/core/Select'; -import InputLabel from '@material-ui/core/InputLabel'; -import TextField from '@material-ui/core/TextField'; -import IconButton from '@material-ui/core/IconButton'; - -import DeleteIcon from '@material-ui/icons/Delete'; - -import { connect } from 'react-redux'; -import { changeAlgorithmName, addAlgorithmSetting, changeAlgorithmSetting, deleteAlgorithmSetting } from '../../../../actions/nasCreateActions'; - -const module = "nasCreate"; - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '80%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, - icon: { - padding: 4, - margin: '0 auto', - verticalAlign: "middle !important", - }, - formControl: { - margin: 4, - width: '100%', - }, - addButton: { - margin: 10, - } -}) - -const Algorithm = (props) => { - - const classes = useStyles(); - - const onAlgorithmNameChange = (event) => { - props.changeAlgorithmName(event.target.value); - } - - const onAddAlgorithmSetting = () => { - props.addAlgorithmSetting(); - } - - const onChangeAlgorithmSetting = (name, index) => (event) => { - props.changeAlgorithmSetting(index, name, event.target.value); - } - - const onDeleteAlgorithmSetting= (index) => (event) => { - props.deleteAlgorithmSetting(index); - } - - return ( -
- -
- - - - - - - {"Algorithm Name"} - - - - - - Algorithm Name - - - - - -
-
- {props.algorithmSettings.map((param, i) => { - return ( -
- - - - - - - - - - - - - - -
- ) - })} -
- ) -} - - -const mapStateToProps = state => { - return { - algorithmName: state[module].algorithmName, - allAlgorithms: state[module].allAlgorithms, - algorithmSettings: state[module].algorithmSettings - } -} - -export default connect(mapStateToProps, { changeAlgorithmName, addAlgorithmSetting, changeAlgorithmSetting, deleteAlgorithmSetting })(Algorithm); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/CommonMeta.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/CommonMeta.jsx deleted file mode 100644 index 4c0a98fe079..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/CommonMeta.jsx +++ /dev/null @@ -1,75 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import TextField from '@material-ui/core/TextField'; - -import { changeMeta } from '../../../../actions/nasCreateActions'; - - -const module = "nasCreate"; - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, -}) - -const CommonParametersMeta = (props) => { - const classes = useStyles(); - - const onMetaChange = (param) => (event) => { - props.changeMeta(param, event.target.value); - } - - return ( -
- {props.commonParametersMetadata.map((param, i) => { - return ( -
- - - - - - - {param.name} - - - - - - -
- ) - })} -
- ) -} - - -const mapStateToProps = state => { - return { - commonParametersMetadata: state[module].commonParametersMetadata, - } -} - -export default connect(mapStateToProps, { changeMeta })(CommonParametersMeta); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/CommonSpec.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/CommonSpec.jsx deleted file mode 100644 index 3424d9536f2..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/CommonSpec.jsx +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import TextField from '@material-ui/core/TextField'; - -import { changeSpec} from '../../../../actions/nasCreateActions'; - - -const module = "nasCreate"; - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, -}) - -const CommonParametersSpec = (props) => { - - const classes = useStyles(); - - const onSpecChange = (name) => (event) => { - props.changeSpec(name, event.target.value); - } - - return ( -
- {props.commonParametersSpec.map((param, i) => { - return ( -
- - - - - - - {param.name} - - - - - - -
- ) - })} -
- ) -} - - -const mapStateToProps = state => { - return { - commonParametersSpec: state[module].commonParametersSpec - } -} - -export default connect(mapStateToProps, { changeSpec })(CommonParametersSpec); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/NASConfig.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/NASConfig.jsx deleted file mode 100644 index 3c541222a4d..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/NASConfig.jsx +++ /dev/null @@ -1,424 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Button from '@material-ui/core/Button'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import TextField from '@material-ui/core/TextField'; -import IconButton from '@material-ui/core/IconButton'; -import AddIcon from '@material-ui/icons/Add'; -import DeleteIcon from '@material-ui/icons/Delete'; -import Fab from '@material-ui/core/Fab'; -import Divider from '@material-ui/core/Divider'; -import Select from '@material-ui/core/Select'; -import OutlinedInput from '@material-ui/core/OutlinedInput'; -import InputLabel from '@material-ui/core/InputLabel'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; - -import Radio from '@material-ui/core/Radio'; -import RadioGroup from '@material-ui/core/RadioGroup'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; - - -import { editNumLayers, addSize, editSize, deleteSize, addOperation, deleteOperation, changeOperation, addParameter, changeParameter, deleteParameter, addListParameter, editListParameter, deleteListParameter } from '../../../../actions/nasCreateActions'; - -const module = "nasCreate"; - - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '80%' - }, - numLayers: { - padding: 2, - marginBottom: 30, - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, - formControl: { - margin: 4, - width: '100%', - }, - selectEmpty: { - marginTop: 10, - }, - group: { - flexDirection: 'row', - justifyContent: 'space-around', - }, - divider: { - margin: 5, - }, - addButton: { - margin: 10, - }, - fab: { - margin: 2, - }, - section: { - marginTop: 20 - } -}) - -const SectionInTypography = (name, classes, variant) => { - return ( -
- - - - {name} - -
-
-
-
- ) -} - - -const NASConfig = (props) => { - - const classes = useStyles(); - - const onEditNumLayers = () => (event) => { - props.editNumLayers(event.target.value); - } - const onAddSize = (type) => (event) => { - props.addSize(type); - } - - const onEditSize = (index, type) => (event) => { - props.editSize(type, index, event.target.value); - } - - const onDeleteSize = (index, type) => (event) => { - props.deleteSize(type, index); - } - - const onDeleteOperation = (index) => (event) => { - props.deleteOperation(index); - } - - const onChangeOperation = (index) => (event) => { - props.changeOperation(index, event.target.value); - } - - const onAddParameter = (opIndex) => (event) => { - props.addParameter(opIndex); - } - - const onChangeParameter = (opIndex, paramIndex, name) => (event) => { - props.changeParameter(opIndex, paramIndex, name, event.target.value); - } - - const onDeleteParameter = (opIndex, paramIndex) => (event) => { - props.deleteParameter(opIndex, paramIndex); - } - - const onAddListParameter = (opIndex, paramIndex) => (event) => { - props.addListParameter(opIndex, paramIndex); - } - - const onDeleteListParameter = (opIndex, paramIndex, listIndex) => (event) => { - props.deleteListParameter(opIndex, paramIndex, listIndex); - } - - const onEditListParameter = (opIndex, paramIndex, listIndex) => (event) => { - props.editListParameter(opIndex, paramIndex, listIndex, event.target.value); - } - - return ( -
- {/* NUM LAYERS */} -
- - - - - - - {"NumLayers"} - - - - - - -
- {/* INPUT SIZE */} -
- - - - - - - {"InputSizes"} - - - - {props.inputSize.map((size, index) => { - return ( -
- - - - -
- ) - })} -
- - - - - -
-
- {/* OUTPUT SIZE */} -
- - - - - - - {"OutputSizes"} - - - - {props.outputSize.map((size, index) => { - return ( -
- - - - -
- ) - })} -
- - - - - -
-
- {/* OPERATIONS */} - {SectionInTypography("Operations", classes, "h6")} -
- -
- { - props.operations.map((operation, opIndex) => { - return ( -
-
- - - - OperationType - - - - - - - - - - -
-
-
- -
-
- {operation.parameters.map((param, paramIndex) => { - return ( -
- - - - - - - - Parameter Type - - - - - - - } label="FeasibleSpace" /> - } label="List" /> - - - - {param.feasibleSpace === "list" && - (param.list.map((element, elIndex) => { - return ( -
- - - - -
- ) - })) - - } - {param.feasibleSpace === "feasibleSpace" && -
- - - -
- } -
- - {param.feasibleSpace === "list" && - - - - } - - - - - - -
-
- ) - })} - -
- ) - }) - } -
- ) -} - - -const mapStateToProps = state => { - return { - numLayers: state[module].numLayers, - inputSize: state[module].inputSize, - outputSize: state[module].outputSize, - operations: state[module].operations, - allParameterTypes: state[module].allParameterTypes, - } -} - -export default connect(mapStateToProps, { editNumLayers, addSize, editSize, deleteSize, addOperation, deleteOperation, changeOperation, addParameter, changeParameter, deleteParameter, addListParameter, editListParameter, deleteListParameter })(NASConfig); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Objective.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Objective.jsx deleted file mode 100644 index da40fd233a3..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Objective.jsx +++ /dev/null @@ -1,178 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import TextField from '@material-ui/core/TextField'; -import IconButton from '@material-ui/core/IconButton'; -import DeleteIcon from '@material-ui/icons/Delete'; -import Fab from '@material-ui/core/Fab'; -import AddIcon from '@material-ui/icons/Add'; -import FormControl from '@material-ui/core/FormControl'; -import Select from '@material-ui/core/Select'; -import InputLabel from '@material-ui/core/InputLabel'; -import OutlinedInput from '@material-ui/core/OutlinedInput'; -import MenuItem from '@material-ui/core/MenuItem'; - -import { changeObjective, addMetrics, editMetrics, deleteMetrics } from '../../../../actions/nasCreateActions'; - - -const module = "nasCreate"; - -const useStyles = makeStyles({ - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%' - }, - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, - selectBox: { - width: 150 - } -}) - -const Objective = (props) => { - - const classes = useStyles(); - - const onObjectiveChange = (name) => (event) => { - props.changeObjective(name, event.target.value); - } - - const onMetricsEdit = (index) => (event) => { - props.editMetrics(index, event.target.value); - } - - const onMetricsDelete = (index) => (event) => { - props.deleteMetrics(index); - } - - return ( -
- {props.objective.map((param, i) => { - return ( - param.name === "Type" ? -
- - - - - - - {param.name} - - - - - - Objective Type - - - - - -
- : -
- - - - - - - {param.name} - - - - - - -
- ) - })} -
- - - - - - - AdditionalMetricNames - - - - { - props.additionalMetricNames.map((metrics, mIndex) => { - return ( - - - - - - - - - - - ) - }) - } - - - - - - - -
-
- ) -} - - -const mapStateToProps = state => { - return { - allObjectiveTypes: state[module].allObjectiveTypes, - objective: state[module].objective, - additionalMetricNames: state[module].additionalMetricNames - } -} - -export default connect(mapStateToProps, {changeObjective, addMetrics, editMetrics, deleteMetrics })(Objective); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Trial.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Trial.jsx deleted file mode 100644 index cabe3abe306..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/Params/Trial.jsx +++ /dev/null @@ -1,102 +0,0 @@ -import React from 'react'; -import withStyles from '@material-ui/styles/withStyles'; -import Grid from '@material-ui/core/Grid'; -import Tooltip from '@material-ui/core/Tooltip'; -import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; -import Typography from '@material-ui/core/Typography'; -import OutlinedInput from '@material-ui/core/OutlinedInput'; -import InputLabel from '@material-ui/core/InputLabel'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import Select from '@material-ui/core/Select'; - -import { connect } from 'react-redux'; -import { changeTrial } from '../../../../actions/nasCreateActions'; -import { fetchTrialTemplates } from '../../../../actions/templateActions'; - -const module = "nasCreate"; -const templateModule = "template"; - -const styles = theme => ({ - help: { - padding: 4 / 2, - verticalAlign: "middle", - marginRight: 5, - }, - section: { - padding: 4, - }, - parameter: { - padding: 2, - marginBottom: 10, - }, - formControl: { - margin: 4, - width: '100%', - }, - selectEmpty: { - marginTop: 10, - }, -}) - -class TrialSpecParam extends React.Component { - - componentDidMount() { - this.props.fetchTrialTemplates(); - } - - onTrialChange = (event) => { - this.props.changeTrial(event.target.value); - } - - render() { - const names = this.props.templates.map((template, i) => template.name) - - const { classes } = this.props - return ( -
- - - - - - - {"TrialSpec"} - - - - - - Trial Spec - - - - - -
- ) - } -} - - -const mapStateToProps = state => { - return { - trial: state[module].trial, - templates: state[templateModule].trialTemplates, - } -} - -export default connect(mapStateToProps, { changeTrial, fetchTrialTemplates })(withStyles(styles)(TrialSpecParam)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/YAML.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/YAML.jsx deleted file mode 100644 index 1882180df4a..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Create/YAML.jsx +++ /dev/null @@ -1,83 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import makeStyles from '@material-ui/styles/makeStyles'; -import 'brace/mode/javascript'; -import 'brace/theme/tomorrow'; -import AceEditor from 'react-ace'; -import Button from '@material-ui/core/Button'; - -import { changeYaml } from '../../../actions/nasCreateActions'; -import { submitYaml } from '../../../actions/generalActions'; - -const module = "nasCreate"; - -const useStyles = makeStyles ({ - root: { - width: '90%', - margin: '0 auto', - }, - editor: { - margin: '0 auto', - }, - submit: { - textAlign: 'center', - marginTop: 10, - }, - progress: { - height: 10, - margin: 10, - }, - close: { - padding: 4, - }, -}); - - -const YAML = (props) => { - - const onYamlChange = (value) => { - props.changeYaml(value); - }; - - const submitWholeYaml = () => { - props.submitYaml(props.yaml); - }; - - const classes = useStyles(); - return ( -
-

Generate

-
- {/* {props.loading && } */} -
- -
-
- -
-
- ); -}; - -const mapStateToProps = (state) => { - return { - yaml: state[module].currentYaml, - }; -}; - - -export default connect(mapStateToProps, { changeYaml, submitYaml })(YAML); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/FilterPanel.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/FilterPanel.jsx deleted file mode 100644 index dc3b6d2a658..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/FilterPanel.jsx +++ /dev/null @@ -1,81 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import { withStyles } from '@material-ui/core/styles'; - -import TextField from '@material-ui/core/TextField'; -import FormGroup from '@material-ui/core/FormGroup'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Switch from '@material-ui/core/Switch'; -import Button from '@material-ui/core/Button'; - -import { filterJobs, changeType, fetchNASJobs } from '../../../actions/nasMonitorActions'; - - -const module = "nasMonitor"; - - -const styles = theme => ({ - textField: { - marginLeft: theme.spacing.unit, - marginRight: theme.spacing.unit, - }, - filter: { - margin: '0 auto', - textAlign: 'center', - }, -}); - -const FilterPanel = (props) => { - - const { classes } = props; - - const handleType = (name) => (event) => { - props.changeType(name, event.target.checked); - } - - return ( -
- - props.filterJobs(event.target.value)} - margin="normal" - variant="outlined" - /> - { - Object.keys(props.filterType).map((filter, i) => { - return( - - } - label={filter} - /> - ); - }) - } - - -
- ) -} - -const mapStateToProps = state => { - return { - filter: state[module].filter, - filterType: state[module].filterType, - } -} - -export default connect(mapStateToProps, { filterJobs, changeType, fetchNASJobs })(withStyles(styles)(FilterPanel)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobInfo.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobInfo.jsx deleted file mode 100644 index 229cdeae55e..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobInfo.jsx +++ /dev/null @@ -1,90 +0,0 @@ -import React from 'react' -import { connect } from 'react-redux' -import { withStyles } from '@material-ui/core'; -import Button from '@material-ui/core/Button'; -import { Link } from 'react-router-dom'; -import ExpansionPanel from '@material-ui/core/ExpansionPanel'; -import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary'; -import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails'; -import Typography from '@material-ui/core/Typography'; -import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import LinearProgress from '@material-ui/core/LinearProgress'; - -import { fetchNASJobInfo } from '../../../actions/nasMonitorActions'; - -import NASJobStepInfo from './NASJobStepInfo'; - -const module = "nasMonitor"; - -const styles = theme => ({ - root: { - width: '90%', - margin: '0 auto', - paddingTop: 20, - }, - heading: { - fontSize: theme.typography.pxToRem(15), - fontWeight: theme.typography.fontWeightRegular, - }, - panel: { - width: '100%', - }, - header: { - marginTop: 30, - textAlign: "center" - } -}) - - -class NASJobInfo extends React.Component { - - componentDidMount() { - this.props.fetchNASJobInfo(this.props.match.params.name); - } - - render () { - const { classes } = this.props; - return ( -
- - - - {this.props.loading ? - - : -
- - Experiment Name: {this.props.match.params.name} - -
- {this.props.steps.map((step, i) => { - return ( - - }> - {step.name} - - - - - - ) - })} -
- } - -
- ) - } -} - -const mapStateToProps = (state) => { - return { - steps: state[module].steps, - loading: state[module].loading, - } -} - - -export default connect(mapStateToProps, { fetchNASJobInfo })(withStyles(styles)(NASJobInfo)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobList.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobList.jsx deleted file mode 100644 index 44872b364d0..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobList.jsx +++ /dev/null @@ -1,92 +0,0 @@ -import React from 'react'; -import {connect} from 'react-redux'; -import { withStyles } from '@material-ui/core/styles'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import { Link } from 'react-router-dom'; -import { ListItemSecondaryAction, IconButton } from '@material-ui/core'; - -import { openDeleteExperimentDialog } from '../../../actions/generalActions'; -import DeleteDialog from '../../Menu/DeleteDialog'; -import ScheduleIcon from '@material-ui/icons/Schedule'; -import RestoreIcon from '@material-ui/icons/Restore'; -import HighlightOffIcon from '@material-ui/icons/HighlightOff'; -import DoneIcon from '@material-ui/icons/Done'; -import DeleteIcon from '@material-ui/icons/Delete'; -import HourglassFullIcon from '@material-ui/icons/HourglassFull'; - -const module = "nasMonitor"; - - -const styles = theme => ({ - created: { - color: theme.colors.created, - }, - running: { - color: theme.colors.running, - }, - restarting: { - color: theme.colors.restarting - }, - succeeded: { - color: theme.colors.succeeded, - }, - failed: { - color: theme.colors.failed, - }, -}); - - -const NASJobList = (props) => { - - const { classes } = props; - - const onDeleteExperiment = (experimentName) => (event) => { - props.openDeleteExperimentDialog(experimentName); - } - - return ( -
- - {props.filteredJobsList.map((job, i) => { - let icon; - if (job.status === 'Created') { - icon = () - } else if (job.status === 'Running') { - icon = () - } else if (job.status === 'Restarting') { - icon = () - } else if (job.status === 'Succeeded') { - icon = () - } else if (job.status === 'Failed') { - icon = () - } - return ( - - - {icon} - - - - - - - - - ); - })} - - -
- ) -} - -const mapStateToProps = (state) => { - return { - filteredJobsList: state[module].filteredJobsList, - } -} - -export default connect(mapStateToProps, { openDeleteExperimentDialog })(withStyles(styles)(NASJobList)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobMonitor.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobMonitor.jsx deleted file mode 100644 index 2298d1327f7..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobMonitor.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import { withStyles } from '@material-ui/core/styles'; - -import FilterPanel from './FilterPanel'; -import NASJobList from './NASJobList'; - -import { connect } from 'react-redux'; - -import { fetchNASJobs } from '../../../actions/nasMonitorActions'; - - -const styles = theme => ({ - root: { - width: '90%', - margin: '0 auto', - }, -}); - -class NASJobMonitor extends React.Component { - - componentDidMount() { - this.props.fetchNASJobs(); - } - - render() { - - const { classes } = this.props; - return ( -
-

Monitor

- - -
- ) - } -} - - -export default connect(null, { fetchNASJobs })(withStyles(styles)(NASJobMonitor)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobStepInfo.jsx b/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobStepInfo.jsx deleted file mode 100644 index a82d1cbec62..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/NAS/Monitor/NASJobStepInfo.jsx +++ /dev/null @@ -1,61 +0,0 @@ -import React from 'react'; -import { withStyles } from '@material-ui/core'; -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; - -import * as d3 from 'd3' -import * as d3Graphviz from 'd3-graphviz' - - -const styles = theme => ({ - root: { - margin: '0 auto', - textAlign: 'center', - } -}) - -class NASJobStepInfo extends React.Component { - - componentDidMount() { - - const id = `graph${this.props.id}` - d3.select(`#${id}`) - .graphviz() - .renderDot(this.props.step.architecture) - .width(640) - .height(480) - .fit(true) - } - - render() { - - const { step, classes } = this.props; - const id = `graph${this.props.id}` - return ( -
- - Architecture for Trial: {step.trialname} - -
-
- {step.metricsname.map((metrics, index) => { - return ( - - {step.metricsname[index]}: {step.metricsvalue[index]}. - - ) - })} -
- {/* TODO: add link in backend */} - - - -
- ) - } -} - - -export default withStyles(styles)(NASJobStepInfo); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Templates/Collector.jsx b/pkg/ui/v1alpha2/frontend/src/components/Templates/Collector.jsx deleted file mode 100644 index dd457b403a5..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Templates/Collector.jsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; -import withStyles from '@material-ui/styles/withStyles'; - -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; - -import TemplateList from './Common/TemplateList'; - -import { connect } from 'react-redux'; -import { openDialog, fetchCollectorTemplates } from '../../actions/templateActions'; -import AddDialog from './Common/AddDialog'; - -const styles = theme => ({ - root: { - flexGrow: 1, - marginTop: 40, - }, -}); - - -class Collector extends React.Component{ - - componentDidMount() { - this.props.fetchCollectorTemplates(); - } - - openAddDialog = () => { - this.props.openDialog("add"); - } - - render() { - - const { classes } = this.props; - - const type = "collector"; - - return ( -
- - Collector Manifests - - - - - - -
- ) - } -} -export default connect(null, { openDialog, fetchCollectorTemplates })(withStyles(styles)(Collector)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/AddDialog.jsx b/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/AddDialog.jsx deleted file mode 100644 index e286ed30612..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/AddDialog.jsx +++ /dev/null @@ -1,122 +0,0 @@ -import React from 'react'; -import withStyles from '@material-ui/styles/withStyles'; - -import Button from '@material-ui/core/Button'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import TextField from '@material-ui/core/TextField'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import Slide from '@material-ui/core/Slide'; -import AceEditor from 'react-ace'; - -import { connect } from 'react-redux'; -import { closeDialog, addTemplate } from '../../../actions/templateActions'; - -const module = "template"; - -const styles = theme => ({ - textField: { - marginLeft: 4, - marginRight: 4, - width: 400, - marginBottom: 10, - }, -}); - -function Transition(props) { - return -} - -// FIX DIALOG TEXTFIELD SIZE - -class AddDialog extends React.Component { - - state = { - name: '', - yaml: '', - } - - onChange = (name) => (event) => { - this.setState({ - [name]: event.target.value - }) - } - - onChangeYaml = (name) => (value) => { - this.setState({ - [name]: value, - }) - } - - addTemplate = () => { - this.props.addTemplate(this.state.name, this.state.yaml, this.props.type, "add"); - } - - render () { - const { classes } = this.props; - - return ( -
- - - {"Adding a template"} - - - -
- - {/* */} -
- - - - -
-
- ) - } -} - -const mapStateToProps = (state) => { - return { - addOpen: state[module].addOpen, - edittedTemplate: state[module].edittedTemplate, - }; -}; - -export default connect(mapStateToProps, { closeDialog, addTemplate })(withStyles(styles)(AddDialog)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/DeleteDialog.jsx b/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/DeleteDialog.jsx deleted file mode 100644 index 6bdd134675f..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/DeleteDialog.jsx +++ /dev/null @@ -1,71 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; - -import Button from '@material-ui/core/Button'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogContentText from '@material-ui/core/DialogContentText'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import Slide from '@material-ui/core/Slide'; - -import { connect } from 'react-redux'; -import { closeDialog, deleteTemplate } from '../../../actions/templateActions'; - -const module = "template"; - -const useStyles = makeStyles({ - -}); - -function Transition(props) { - return -} - -const DeleteDialog = (props) => { - const classes = useStyles(); - - const deleteTemplate = (type) => (event) => { - props.deleteTemplate(props.currentTemplateName, type, "delete"); - } - - return ( -
- - - {"Are you sure?"} - - - - Are you sure you want to delete this template? - - - - - - - -
- ) -} - -const mapStateToProps = (state) => { - return { - deleteOpen: state[module].deleteOpen, - currentTemplateIndex: state[module].currentTemplateIndex, - currentTemplateName: state[module].currentTemplateName, - }; -}; - -export default connect(mapStateToProps, { closeDialog, deleteTemplate })(DeleteDialog); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/EditDialog.jsx b/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/EditDialog.jsx deleted file mode 100644 index be500acef11..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/EditDialog.jsx +++ /dev/null @@ -1,110 +0,0 @@ -import React from 'react'; -import withStyles from '@material-ui/styles/withStyles'; - -import Button from '@material-ui/core/Button'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import TextField from '@material-ui/core/TextField'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import Slide from '@material-ui/core/Slide'; - -import { connect } from 'react-redux'; -import { closeDialog, changeTemplate, editTemplate } from '../../../actions/templateActions'; - -const module = "template"; - -const styles = theme => ({ - textField: { - margin: 10, - width: 400, - }, -}); - -function Transition(props) { - return -} - -// FIX DIALOG TEXTFIELD SIZE - -class EditDialog extends React.Component { - - state = { - name: '', - yaml: '', - } - - componentDidMount() { - this.setState({ - name: this.props.edittedTemplate.name, - yaml: this.props.edittedTemplate.yaml - }) - } - - componentWillReceiveProps(newProps) { - this.setState({ - name: newProps.edittedTemplate.name, - yaml: newProps.edittedTemplate.yaml, - }) - } - - submitEditTemplate = () => { - this.props.editTemplate(this.state.name, this.state.yaml, this.props.type, "edit"); - } - - render () { - const { classes } = this.props; - return ( -
- - - {"Editing a template"} - - - this.setState({ - name: event.target.value - })} - /> -
- this.setState({ - yaml: event.target.value - })} - /> -
- - - - -
-
- ) - } -} - -const mapStateToProps = (state) => { - return { - editOpen: state[module].editOpen, - currentTemplateIndex: state[module].currentTemplateIndex, - edittedTemplate: state[module].edittedTemplate, - }; -}; - -export default connect(mapStateToProps, { closeDialog, changeTemplate, editTemplate })(withStyles(styles)(EditDialog)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/TemplateList.jsx b/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/TemplateList.jsx deleted file mode 100644 index 3055d73fc51..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/TemplateList.jsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; -import { withStyles } from '@material-ui/core/styles'; -import ExpansionPanel from '@material-ui/core/ExpansionPanel'; -import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary'; -import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails'; -import Typography from '@material-ui/core/Typography'; -import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; - -import TemplatePanel from './TemplatePanel'; -import EditDialog from './EditDialog'; -import DeleteDialog from './DeleteDialog'; - -import { connect } from 'react-redux'; - -const module = "template"; - - -const styles = theme => ({ - root: { - marginTop: 40, - width: '100%', - }, - heading: { - fontSize: theme.typography.pxToRem(24), - fontWeight: theme.typography.fontWeightRegular, - }, -}); - -class TemplateList extends React.Component { - - - render () { - const { classes } = this.props; - const templates = (this.props.type === "trial" ? this.props.trialTemplates : this.props.collectorTemplates); - return ( -
- {templates.map((template, index) => { - return ( - - }> - - {template.name} - - - - - - - - - ) - })} -
- ) - } -} - -const mapStateToProps = (state) => { - return { - collectorTemplates: state[module].collectorTemplates, - trialTemplates: state[module].trialTemplates, - }; -}; - -export default connect(mapStateToProps, null)(withStyles(styles)(TemplateList)); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/TemplatePanel.jsx b/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/TemplatePanel.jsx deleted file mode 100644 index 150699a0db3..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Templates/Common/TemplatePanel.jsx +++ /dev/null @@ -1,91 +0,0 @@ -import React from 'react'; -import makeStyles from '@material-ui/styles/makeStyles'; - -import Button from '@material-ui/core/Button'; -import Grid from '@material-ui/core/Grid'; - -import { connect } from 'react-redux'; - -import DeleteIcon from '@material-ui/icons/Delete'; -import CreateIcon from '@material-ui/icons/Create'; -import TextField from '@material-ui/core/TextField'; - -import { openDialog } from '../../../actions/templateActions'; - -// const module = "template"; - -const useStyles = makeStyles({ - root: { - flexGrow: 1, - }, - grid: { - marginTop: 30, - textAlign: 'right', - }, - icon: { - margin: 4, - }, - textField: { - width: '100%', - }, - input: { - color: 'black !important', - fontSize: 24 - } -}); - -const TemplatePanel = (props) => { - - const classes = useStyles(); - - const openEditDialog = (index) => (event) => { - props.openDialog("edit", index, props.type); - }; - - const openDeleteDialog = (index) => (event) => { - props.openDialog("delete", index, props.type, "delete"); - }; - - return ( -
- - -
- - - - - - - - -
- ) -} - -const mapStateToProps = (state) => { - return { - - }; -}; - - -export default connect(mapStateToProps, { openDialog })(TemplatePanel); diff --git a/pkg/ui/v1alpha2/frontend/src/components/Templates/Trial.jsx b/pkg/ui/v1alpha2/frontend/src/components/Templates/Trial.jsx deleted file mode 100644 index b595799a833..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/components/Templates/Trial.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react'; -import withStyles from '@material-ui/styles/withStyles'; - -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; - -import TemplateList from './Common/TemplateList'; - -import { connect } from 'react-redux'; -import { openDialog, fetchTrialTemplates } from '../../actions/templateActions'; -import AddDialog from './Common/AddDialog'; - - -const styles = theme => ({ - root: { - flexGrow: 1, - marginTop: 40, - }, -}); - -class Trial extends React.Component { - - componentDidMount() { - this.props.fetchTrialTemplates(); - } - - openAddDialog = () => { - this.props.openDialog("add"); - } - - render () { - const { classes } = this.props; - - const type = "trial"; - - return ( -
- - Trial Manifests - - - - - - -
- ) - } -} -export default connect(null, { openDialog, fetchTrialTemplates })(withStyles(styles)(Trial)); diff --git a/pkg/ui/v1alpha2/frontend/src/index.js b/pkg/ui/v1alpha2/frontend/src/index.js deleted file mode 100755 index 017fa97e44e..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/index.js +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './components/App'; -import * as serviceWorker from './serviceWorker'; -import CssBaseline from '@material-ui/core/CssBaseline'; -import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles'; -import configureStore from './store'; -import rootSaga from './sagas'; - -import { HashRouter as Router } from 'react-router-dom'; - -import { Provider } from 'react-redux'; - -const store = configureStore(); - -store.runSaga(rootSaga); - -const theme = createMuiTheme({ - palette: { - primary: { - main: '#000', - }, - secondary: { - main: '#fff', - }, - }, - colors: { - created: '#2304bd', - running: '#8b8ffb', - restarting: '#1eb9af', - succeeded: '#63f291', - failed: '#f26363', - }, - typography: { - fontFamily: 'open sans,-apple-system,BlinkMacSystemFont,segoe ui,Roboto,helvetica neue,Arial,sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol', - } -}); - - -ReactDOM.render( - - - - - - - - - , document.getElementById('root')); - -// If you want your app to work offline and load faster, you can change -// unregister() to register() below. Note this comes with some pitfalls. -// Learn more about service workers: http://bit.ly/CRA-PWA -serviceWorker.unregister(); diff --git a/pkg/ui/v1alpha2/frontend/src/reducers/general.js b/pkg/ui/v1alpha2/frontend/src/reducers/general.js deleted file mode 100644 index d0820359025..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/reducers/general.js +++ /dev/null @@ -1,105 +0,0 @@ -import * as actions from '../actions/generalActions'; -import * as nasCreateActions from '../actions/nasCreateActions'; -import * as hpCreateActions from '../actions/hpCreateActions'; - -const initialState = { - menuOpen: false, - snackOpen: false, - snackText: "", - deleteDialog: false, - deleteId: '', -}; - -const generalReducer = (state = initialState, action) => { - switch (action.type) { - case actions.TOGGLE_MENU: - return { - ...state, - menuOpen: action.state, - }; - case actions.CLOSE_SNACKBAR: - return { - ...state, - snackOpen: false, - }; - case actions.SUBMIT_YAML_SUCCESS: - return { - ...state, - snackOpen: true, - snackText: "Successfully submitted", - } - case actions.SUBMIT_YAML_FAILURE: - return { - ...state, - snackOpen: true, - snackText: action.message, - } - case actions.DELETE_EXPERIMENT_FAILURE: - return { - ...state, - deleteDialog: false, - snackOpen: true, - snackText: "Whoops, something went wrong", - } - case actions.DELETE_EXPERIMENT_SUCCESS: - return { - ...state, - deleteDialog: false, - snackOpen: true, - snackText: "Successfully deleted. Press Update button", - } - case actions.OPEN_DELETE_EXPERIMENT_DIALOG: - return { - ...state, - deleteDialog: true, - deleteExperimentName: action.experimentName, - } - case actions.CLOSE_DELETE_EXPERIMENT_DIALOG: - return { - ...state, - deleteDialog: false, - } - case nasCreateActions.SUBMIT_NAS_JOB_REQUEST: - return { - ...state, - loading: true, - } - case nasCreateActions.SUBMIT_NAS_JOB_SUCCESS: - return { - ...state, - loading: false, - snackOpen: true, - snackText: "Successfully submitted", - } - case nasCreateActions.SUBMIT_NAS_JOB_FAILURE: - return { - ...state, - loading: false, - snackOpen: true, - snackText: action.message, - } - case hpCreateActions.SUBMIT_HP_JOB_REQUEST: - return { - ...state, - loading: true, - } - case hpCreateActions.SUBMIT_HP_JOB_SUCCESS: - return { - ...state, - loading: false, - snackOpen: true, - snackText: "Successfully submitted", - } - case hpCreateActions.SUBMIT_HP_JOB_FAILURE: - return { - ...state, - loading: false, - snackOpen: true, - snackText: action.message, - } - default: - return state; - } -}; - -export default generalReducer; diff --git a/pkg/ui/v1alpha2/frontend/src/reducers/hpCreate.js b/pkg/ui/v1alpha2/frontend/src/reducers/hpCreate.js deleted file mode 100644 index ad3f8ffe1a0..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/reducers/hpCreate.js +++ /dev/null @@ -1,249 +0,0 @@ -import * as actions from '../actions/hpCreateActions'; - -const initialState = { - loading: false, - commonParametersMetadata: [ - { - name: "Name", - value: "random-experiment", - description: "A name of an experiment" - }, - { - name: "Namespace", - value: "kubeflow", - description: "Namespace to deploy an experiment" - } - ], - commonParametersSpec: [ - { - name: "ParallelTrialCount", - value: "3", - description: "How many trials can be processed in parallel" - }, - { - name: "MaxTrialCount", - value: "12", - description: "Max completed trials to mark experiment as succeeded" - }, - { - name: "MaxFailedTrialCount", - value: "3", - description: "Max failed trials to mark experiment as failed" - } - ], - allObjectiveTypes: ["minimize", "maximize"], - objective: [ - { - name: "Type", - value: "maximize", - description: "Type of optimization" - }, - { - name: "Goal", - value: "0.99", - description: "Goal of optimization" - }, - { - name: "ObjectiveMetricName", - value: "Validation-accuracy", - description: "Name for the objective metric" - } - ], - additionalMetricNames: [ - { - value: "accuracy" - } - ], - algorithmName: "random", - allAlgorithms: ["grid", "random", "hyperband", "bayesianoptimization"], - algorithmSettings: [ - - ], - parameters: [ - { - name: "--lr", - parameterType: "double", - feasibleSpace: "feasibleSpace", - min: "0.01", - max: "0.03", - list: [], - }, - { - name: "--num-layers", - parameterType: "int", - feasibleSpace: "feasibleSpace", - min: "2", - max: "5", - list: [], - }, - { - name: "--optimizer", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - list: [ - { - value: "sgd", - }, - { - value: "adam", - }, - { - value: "ftrl" - } - ], - }, - ], - allParameterTypes: ["int", "double", "categorical"], - trial: "cpuTrialTemplate.yaml", - currentYaml: '', -}; - -const filterValue = (obj, key) => { - return obj.findIndex(p => p.name === key) -}; - -const hpCreateReducer = (state = initialState, action) => { - switch (action.type) { - case actions.CHANGE_YAML_HP: - return { - ...state, - currentYaml: action.payload, - } - case actions.CHANGE_META_HP: - let meta = state.commonParametersMetadata.slice(); - let index = filterValue(meta, action.name); - meta[index].value = action.value; - return { - ...state, - commonParametersMetadata: meta, - } - case actions.CHANGE_SPEC_HP: - let spec = state.commonParametersSpec.slice(); - index = filterValue(spec, action.name); - spec[index].value = action.value; - return { - ...state, - commonParametersSpec: spec, - } - case actions.CHANGE_OBJECTIVE_HP: - let obj = state.objective.slice(); - index = filterValue(obj, action.name); - obj[index].value = action.value; - return { - ...state, - objective: obj, - } - case actions.ADD_METRICS_HP: - let additionalMetricNames = state.additionalMetricNames.slice() - additionalMetricNames.push({ - value: "", - }) - return { - ...state, - additionalMetricNames: additionalMetricNames, - } - case actions.DELETE_METRICS_HP: - additionalMetricNames = state.additionalMetricNames.slice() - additionalMetricNames.splice(action.index, 1) - return { - ...state, - additionalMetricNames: additionalMetricNames, - } - case actions.EDIT_METRICS_HP: - additionalMetricNames = state.additionalMetricNames.slice() - additionalMetricNames[action.index].value = action.value - return { - ...state, - additionalMetricNames: additionalMetricNames, - } - case actions.CHANGE_ALGORITHM_NAME_HP: - return { - ...state, - algorithmName: action.algorithmName, - } - case actions.ADD_ALGORITHM_SETTING_HP: - let algorithmSettings = state.algorithmSettings.slice(); - let setting = {name: "", value: ""}; - algorithmSettings.push(setting); - return { - ...state, - algorithmSettings: algorithmSettings, - } - case actions.CHANGE_ALGORITHM_SETTING_HP: - algorithmSettings = state.algorithmSettings.slice(); - algorithmSettings[action.index][action.field] = action.value; - return { - ...state, - algorithmSettings: algorithmSettings, - } - case actions.DELETE_ALGORITHM_SETTING_HP: - algorithmSettings = state.algorithmSettings.slice(); - algorithmSettings.splice(action.index, 1); - return { - ...state, - algorithmSettings: algorithmSettings, - } - case actions.ADD_PARAMETER_HP: - let parameters = state.parameters.slice(); - parameters.push({ - name: "", - parameterType: "", - feasibleSpace: "feasibleSpace", - min: "", - max: "", - list: [], - }) - return { - ...state, - parameters: parameters, - } - case actions.EDIT_PARAMETER_HP: - parameters = state.parameters.slice(); - parameters[action.index][action.field] = action.value; - return { - ...state, - parameters: parameters, - } - case actions.DELETE_PARAMETER_HP: - parameters = state.parameters.slice(); - parameters.splice(action.index, 1); - return { - ...state, - parameters: parameters, - } - case actions.ADD_LIST_PARAMETER_HP: - parameters = state.parameters.slice(); - parameters[action.paramIndex].list.push({ - value: "", - }) - return { - ...state, - parameters: parameters - } - case actions.EDIT_LIST_PARAMETER_HP: - parameters = state.parameters.slice(); - parameters[action.paramIndex].list[action.index].value = action.value; - return { - ...state, - parameters: parameters - } - case actions.DELETE_LIST_PARAMETER_HP: - parameters = state.parameters.slice(); - parameters[action.paramIndex].list.splice(action.index, 1); - return { - ...state, - parameters: parameters - } - case actions.CHANGE_TRIAL_HP: - return { - ...state, - trial: action.trial, - } - default: - return state; - } -}; - -export default hpCreateReducer; diff --git a/pkg/ui/v1alpha2/frontend/src/reducers/hpMonitor.js b/pkg/ui/v1alpha2/frontend/src/reducers/hpMonitor.js deleted file mode 100644 index 208d34aa17c..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/reducers/hpMonitor.js +++ /dev/null @@ -1,107 +0,0 @@ -import * as actions from '../actions/hpMonitorActions'; - -const initialState = { - filter: '', - filterType: { - "Created": true, - "Running": true, - "Restarting": true, - "Succeeded": true, - "Failed": true, - }, - jobsList: [ - ], - filteredJobsList: [ - ], - jobData: [ - ], - trialData: [ - ], - dialogOpen: false, - loading: false, -}; - -const hpMonitorReducer = (state = initialState, action) => { - switch (action.type) { - case actions.FILTER_JOBS: - let jobs = state.jobsList.slice(); - let newList = jobs.filter(job => job.name.includes(action.filter)); - - let avTypes = Object.assign({}, state.filterType); - var typeKeys = Object.keys(avTypes); - - var avFilters = typeKeys.filter((key) => { - return avTypes[key] - }); - - let filteredJobs = newList.filter(job => avFilters.includes(job.status)); - - return { - ...state, - filteredJobsList: filteredJobs, - filter: action.filter, - } - case actions.CHANGE_TYPE: - const types = Object.assign({}, state.filterType) - types[action.filter] = action.checked; - var keys = Object.keys(types); - - var filters = keys.filter((key) => { - return types[key] - }); - const jobsList = state.jobsList.slice(); - const filtered = jobsList.filter(job => filters.includes(job.status)); - - return { - ...state, - filterType: types, - filteredJobsList: filtered, - } - case actions.FETCH_HP_JOBS_SUCCESS: - jobs = action.jobs - avTypes = Object.assign({}, state.filterType); - typeKeys = Object.keys(avTypes); - - avFilters = typeKeys.filter((key) => { - return avTypes[key] - }); - - filteredJobs = jobs.filter(job => avFilters.includes(job.status)); - return { - ...state, - jobsList: action.jobs, - filteredJobsList: filteredJobs, - } - case actions.FETCH_HP_JOB_INFO_REQUEST: - return { - ...state, - loading: true, - } - case actions.FETCH_HP_JOB_INFO_SUCCESS: - return { - ...state, - jobData: action.jobData, - loading: false, - } - case actions.FETCH_HP_JOB_INFO_FAILURE: - return { - ...state, - loading: false, - } - case actions.FETCH_HP_JOB_TRIAL_INFO_SUCCESS: - return { - ...state, - trialData: action.trialData, - dialogOpen: true, - } - case actions.CLOSE_DIALOG: - return { - ...state, - dialogOpen: false, - } - default: - return state; - } -}; - -export default hpMonitorReducer; diff --git a/pkg/ui/v1alpha2/frontend/src/reducers/index.js b/pkg/ui/v1alpha2/frontend/src/reducers/index.js deleted file mode 100644 index 6c443a5a1f2..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/reducers/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import { combineReducers } from 'redux' -import generalReducer from './general'; -import nasCreateReducer from './nasCreate'; -import nasMonitorReducer from './nasMonitor'; -import hpCreateReducer from './hpCreate'; -import templateReducer from './template'; -import hpMonitorReducer from './hpMonitor'; - -const rootReducer = combineReducers({ - ["general"]: generalReducer, - ["template"]: templateReducer, - ["hpCreate"]: hpCreateReducer, - ["hpMonitor"]: hpMonitorReducer, - ["nasCreate"]: nasCreateReducer, - ["nasMonitor"]: nasMonitorReducer, -}) - -export default rootReducer; diff --git a/pkg/ui/v1alpha2/frontend/src/reducers/nasCreate.js b/pkg/ui/v1alpha2/frontend/src/reducers/nasCreate.js deleted file mode 100644 index 978d1b74891..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/reducers/nasCreate.js +++ /dev/null @@ -1,563 +0,0 @@ -import * as actions from '../actions/nasCreateActions'; - -const initialState = { - commonParametersMetadata: [ - { - name: "Name", - value: "nasrl-example", - description: "A name of an experiment" - }, - { - name: "Namespace", - value: "kubeflow", - description: "Namespace to deploy an experiment" - } - ], - commonParametersSpec: [ - { - name: "ParallelTrialCount", - value: "3", - description: "How many trials can be processed in parallel" - }, - { - name: "MaxTrialCount", - value: "12", - description: "Max completed trials to mark experiment as succeeded" - }, - { - name: "MaxFailedTrialCount", - value: "3", - description: "Max failed trials to mark experiment as failed" - } - ], - allObjectiveTypes: ["minimize", "maximize"], - objective: [ - { - name: "Type", - value: "maximize", - description: "Type of optimization" - }, - { - name: "Goal", - value: "0.99", - description: "Goal of optimization" - }, - { - name: "ObjectiveMetricName", - value: "Validation-Accuracy", - description: "Name for the objective metric" - } - ], - additionalMetricNames: [], - algorithmName: "nasrl", - allAlgorithms: ["nasrl", "nasenvelopenet"], - algorithmSettings: [ - { - name: "lstm_num_cells", - value: "64", - }, - { - name: "lstm_num_layers", - value: "1", - }, - { - name: "lstm_keep_prob", - value: "1.0", - }, - { - name: "optimizer", - value: "adam", - }, - { - name: "init_learning_rate", - value: "1e-3", - }, - { - name: "lr_decay_start", - value: "0", - }, - { - name: "lr_decay_every", - value: "1000", - }, - { - name: "lr_decay_rate", - value: "0.9", - }, - { - name: "skip-target", - value: "0.4", - }, - { - name: "skip-weight", - value: "0.8", - }, - { - name: "l2_reg", - value: "0", - }, - { - name: "entropy_weight", - value: "1e-4", - }, - { - name: "baseline_decay", - value: "0.9999", - } - ], - //Graph Config - numLayers: '8', - inputSize: ['32', '32', '3'], - outputSize: ['10'], - operations: [ - { - operationType: "convolution", - parameters: [ - { - name: "filter_size", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "3", - }, - { - value: "5", - }, - { - value: "7", - } - ], - }, - { - name: "num_filter", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "32", - }, - { - value: "48", - }, - { - value: "64", - }, - { - value: "96", - }, - { - value: "128", - } - ], - }, - { - name: "stride", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "1", - }, - { - value: "2", - } - ], - }, - ] - }, - { - operationType: "separable_convolution", - parameters: [ - { - name: "filter_size", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "3", - }, - { - value: "5", - }, - { - value: "7", - }, - ], - }, - { - name: "num_filter", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "32", - }, - { - value: "48", - }, - { - value: "64", - }, - { - value: "96", - }, - { - value: "128", - }, - ], - }, - { - name: "stride", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "1", - }, - { - value: "2", - }, - ], - }, - { - name: "depth_multiplier", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "1", - }, - { - value: "2", - }, - ], - }, - ], - }, - { - operationType: "depthwise_convolution", - parameters: [ - { - name: "filter_size", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "3", - }, - { - value: "5", - }, - { - value: "7", - }, - ], - }, - { - name: "stride", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "1", - }, - { - value: "2", - }, - ], - }, - { - name: "depth_multiplier", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "1", - }, - { - value: "2", - }, - ], - }, - ], - }, - { - operationType: "reduction", - parameters: [ - { - name: "reduction_type", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - { - value: "max_pooling", - }, - { - value: "avg_pooling", - }, - ], - }, - { - name: "pool_size", - parameterType: "int", - feasibleSpace: "feasibleSpace", - min: "2", - max: "3", - step: "1", - list: [], - }, - ], - }, - ], - allParameterTypes: ["int", "double", "categorical"], - trial: 'nasRLTrialTemplate.yaml', - currentYaml: '', - snackText: '', - snackOpen: false, -}; - -const filterValue = (obj, key) => { - return obj.findIndex(p => p.name === key) -}; - -const nasCreateReducer = (state = initialState, action) => { - switch (action.type) { - case actions.CHANGE_YAML_NAS: - return { - ...state, - currentYaml: action.payload, - } - case actions.CHANGE_META_NAS: - let meta = state.commonParametersMetadata.slice(); - let index = filterValue(meta, action.name); - meta[index].value = action.value; - return { - ...state, - commonParametersMetadata: meta, - } - case actions.CHANGE_SPEC_NAS: - let spec = state.commonParametersSpec.slice(); - index = filterValue(spec, action.name); - spec[index].value = action.value; - return { - ...state, - commonParametersSpec: spec, - } - case actions.CHANGE_OBJECTIVE_NAS: - let obj = state.objective.slice(); - index = filterValue(obj, action.name); - obj[index].value = action.value; - return { - ...state, - objective: obj, - } - case actions.ADD_METRICS_NAS: - let additionalMetricNames = state.additionalMetricNames.slice() - additionalMetricNames.push({ - value: "", - }) - return { - ...state, - additionalMetricNames: additionalMetricNames, - } - case actions.DELETE_METRICS_NAS: - additionalMetricNames = state.additionalMetricNames.slice() - additionalMetricNames.splice(action.index, 1) - return { - ...state, - additionalMetricNames: additionalMetricNames, - } - case actions.EDIT_METRICS_NAS: - additionalMetricNames = state.additionalMetricNames.slice() - additionalMetricNames[action.index].value = action.value - return { - ...state, - additionalMetricNames: additionalMetricNames, - } - case actions.CHANGE_ALGORITHM_NAME_NAS: - return { - ...state, - algorithmName: action.algorithmName, - } - case actions.ADD_ALGORITHM_SETTING_NAS: - let algorithmSettings = state.algorithmSettings.slice(); - let setting = {name: "", value: ""}; - algorithmSettings.push(setting); - return { - ...state, - algorithmSettings: algorithmSettings, - } - case actions.CHANGE_ALGORITHM_SETTING_NAS: - algorithmSettings = state.algorithmSettings.slice(); - algorithmSettings[action.index][action.field] = action.value; - return { - ...state, - algorithmSettings: algorithmSettings, - } - case actions.DELETE_ALGORITHM_SETTING_NAS: - algorithmSettings = state.algorithmSettings.slice(); - algorithmSettings.splice(action.index, 1); - return { - ...state, - algorithmSettings: algorithmSettings, - } - case actions.EDIT_NUM_LAYERS: - let numLayers = action.value; - return { - ...state, - numLayers: numLayers - } - case actions.ADD_SIZE: - let size = state[action.sizeType].slice(); - size.push("0") - return { - ...state, - [action.sizeType]: size, - } - case actions.EDIT_SIZE: - size = state[action.sizeType].slice(); - size[action.index] = action.value; - return { - ...state, - [action.sizeType]: size, - } - case actions.DELETE_SIZE: - size = state[action.sizeType].slice(); - size.splice(action.index, 1); - return { - ...state, - [action.sizeType]: size, - } - case actions.ADD_OPERATION: - let operations = state.operations.slice(); - operations.push({ - operationType: "", - parameters: [], - }); - return { - ...state, - operations, - } - case actions.DELETE_OPERATION: - operations = state.operations.slice(); - operations.splice(action.index, 1); - return { - ...state, - operations, - } - case actions.CHANGE_OPERATION: - operations = state.operations.slice(); - operations[action.index].operationType = action.value; - return { - ...state, - operations, - } - case actions.ADD_PARAMETER_NAS: - operations = state.operations.slice(); - operations[action.opIndex].parameters.push( - { - name: "", - parameterType: "categorical", - feasibleSpace: "list", - min: "", - max: "", - step: "", - list: [ - ], - } - ) - return { - ...state, - operations, - } - case actions.CHANGE_PARAMETER_NAS: - operations = state.operations.slice(); - operations[action.opIndex].parameters[action.paramIndex][action.field] = action.value; - return { - ...state, - operations, - } - case actions.DELETE_PARAMETER_NAS: - operations = state.operations.slice(); - operations[action.opIndex].parameters.splice(action.paramIndex, 1); - return { - ...state, - operations, - } - case actions.ADD_LIST_PARAMETER_NAS: - operations = state.operations.slice(); - operations[action.opIndex].parameters[action.paramIndex].list.push( - { - //TODO: Remove it? - // name: "", - value: "", - } - ) - return { - ...state, - operations, - } - case actions.DELETE_LIST_PARAMETER_NAS: - operations = state.operations.slice(); - operations[action.opIndex].parameters[action.paramIndex].list.splice(action.listIndex, 1); - return { - ...state, - operations, - } - case actions.EDIT_LIST_PARAMETER_NAS: - operations = state.operations.slice(); - operations[action.opIndex].parameters[action.paramIndex].list[action.listIndex].value = action.value; - return { - ...state, - operations, - } - case actions.CHANGE_TRIAL_NAS: - return { - ...state, - trial: action.trial, - } - case actions.CLOSE_SNACKBAR: - return { - ...state, - snackOpen: false, - } - default: - return state; - } -}; - -export default nasCreateReducer; diff --git a/pkg/ui/v1alpha2/frontend/src/reducers/nasMonitor.js b/pkg/ui/v1alpha2/frontend/src/reducers/nasMonitor.js deleted file mode 100644 index 87ddcfdff6f..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/reducers/nasMonitor.js +++ /dev/null @@ -1,95 +0,0 @@ -import * as actions from '../actions/nasMonitorActions'; - -const initialState = { - filter: '', - filterType: { - "Created": true, - "Running": true, - "Restarting": true, - "Succeeded": true, - "Failed": true, - }, - jobsList: [ - ], - filteredJobsList: [ - ], - loading: false, - steps: [ - - ] -}; - -const nasMonitorReducer = (state = initialState, action) => { - switch (action.type) { - case actions.FILTER_JOBS: - let jobs = state.jobsList.slice(); - let newList = jobs.filter(job => job.name.includes(action.filter)); - - let avTypes = Object.assign({}, state.filterType); - var typeKeys = Object.keys(avTypes); - - var avFilters = typeKeys.filter((key) => { - return avTypes[key] - }); - - let filteredJobs = newList.filter(job => avFilters.includes(job.status)); - - return { - ...state, - filteredJobsList: filteredJobs, - filter: action.filter, - } - case actions.CHANGE_TYPE: - const types = Object.assign({}, state.filterType) - types[action.filter] = action.checked; - var keys = Object.keys(types); - - var filters = keys.filter((key) => { - return types[key] - }); - const jobsList = state.jobsList.slice(); - const filtered = jobsList.filter(job => filters.includes(job.status)); - - return { - ...state, - filterType: types, - filteredJobsList: filtered, - } - case actions.FETCH_NAS_JOBS_SUCCESS: - jobs = action.jobs - avTypes = Object.assign({}, state.filterType); - typeKeys = Object.keys(avTypes); - - avFilters = typeKeys.filter((key) => { - return avTypes[key] - }); - - filteredJobs = jobs.filter(job => avFilters.includes(job.status)); - return { - ...state, - jobsList: action.jobs, - filteredJobsList: filteredJobs, - } - case actions.FETCH_NAS_JOB_INFO_REQUEST: - return { - ...state, - loading: true, - } - case actions.FETCH_NAS_JOB_INFO_FAILURE: - return { - ...state, - loading: false, - } - case actions.FETCH_NAS_JOB_INFO_SUCCESS: - return { - ...state, - loading: false, - steps: action.steps, - } - default: - return state; - } -}; - - -export default nasMonitorReducer; diff --git a/pkg/ui/v1alpha2/frontend/src/reducers/template.js b/pkg/ui/v1alpha2/frontend/src/reducers/template.js deleted file mode 100644 index 0d8d196ecca..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/reducers/template.js +++ /dev/null @@ -1,137 +0,0 @@ -import * as actions from '../actions/templateActions'; - -const initialState = { - menuOpen: false, - addOpen: false, - editOpen: false, - deleteOpen: false, - trialTemplates: [], - collectorTemplates: [], - newTemplateName: '', - newTemplateYaml: '', - currentTemplateIndex: '', - edittedTemplate: { - name: '', - yaml: '', - }, - currentTemplateName: '', -}; - -const rootReducer = (state = initialState, action) => { - switch (action.type) { - case actions.CLOSE_DIALOG: - return { - ...state, - editOpen: false, - addOpen: false, - deleteOpen: false, - } - case actions.OPEN_DIALOG: - switch(action.dialogType) { - case "delete": - switch(action.templateType) { - case "trial": - return { - ...state, - deleteOpen: true, - currentTemplateIndex: action.index, - currentTemplateName: state.trialTemplates[action.index].name, - } - case "collector": - return { - ...state, - deleteOpen: true, - currentTemplateIndex: action.index, - currentTemplateName: state.collectorTemplates[action.index].name, - } - default: - return { - ...state, - } - } - case "edit": - switch(action.templateType) { - case "trial": - return { - ...state, - editOpen: true, - currentTemplateIndex: action.index, - edittedTemplate: state.trialTemplates[action.index], - } - case "collector": - return { - ...state, - editOpen: true, - currentTemplateIndex: action.index, - edittedTemplate: state.collectorTemplates[action.index], - } - default: - return { - ...state, - } - } - case "add": - return { - ...state, - addOpen: true, - }; - default: - return state; - } - case actions.CHANGE_TEMPLATE: - let edittedTemplate = state.edittedTemplate; - edittedTemplate[action.field] = action.value; - return { - ...state, - edittedTemplate: edittedTemplate, - } - case actions.FETCH_TRIAL_TEMPLATES_SUCCESS: - return { - ...state, - trialTemplates: action.templates, - } - case actions.FETCH_COLLECTOR_TEMPLATES_SUCCESS: - return { - ...state, - collectorTemplates: action.templates, - } - case actions.ADD_TEMPLATE_SUCCESS: - case actions.DELETE_TEMPLATE_SUCCESS: - case actions.EDIT_TEMPLATE_SUCCESS: - switch (action.templateType) { - case "trial": - return { - ...state, - addOpen: false, - deleteOpen: false, - editOpen: false, - trialTemplates: action.templates, - } - case "collector": - return { - ...state, - addOpen: false, - deleteOpen: false, - editOpen: false, - collectorTemplates: action.templates, - } - default: - return { - ...state, - } - } - case actions.ADD_TEMPLATE_FAILURE: - case actions.EDIT_TEMPLATE_FAILURE: - case actions.DELETE_TEMPLATE_FAILURE: - return { - ...state, - addOpen: false, - deleteOpen: false, - editOpen: false, - } - default: - return state; - } -}; - -export default rootReducer; diff --git a/pkg/ui/v1alpha2/frontend/src/sagas/index.js b/pkg/ui/v1alpha2/frontend/src/sagas/index.js deleted file mode 100644 index e015dbe0489..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/sagas/index.js +++ /dev/null @@ -1,690 +0,0 @@ -import { take, put, call, fork, select, all, takeEvery } from 'redux-saga/effects'; -import axios from 'axios'; -import * as templateActions from '../actions/templateActions'; -import * as hpMonitorActions from '../actions/hpMonitorActions'; -import * as hpCreateActions from '../actions/hpCreateActions'; -import * as nasMonitorActions from '../actions/nasMonitorActions'; -import * as nasCreateActions from '../actions/nasCreateActions'; -import * as generalActions from '../actions/generalActions'; - - -export const submitYaml = function *() { - while (true) { - const action = yield take(generalActions.SUBMIT_YAML_REQUEST); - try { - const result = yield call( - goSubmitYaml, - action.yaml - ) - if (result.status === 200) { - yield put({ - type: generalActions.SUBMIT_YAML_SUCCESS, - }) - } else { - yield put({ - type: generalActions.SUBMIT_YAML_FAILURE, - message: result.message, - }) - } - } catch (err) { - yield put({ - type: generalActions.SUBMIT_YAML_FAILURE, - }) - } - } -} - -const goSubmitYaml = function *(yaml) { - try { - const data = { - yaml - } - const result = yield call( - axios.post, - '/katib/submit_yaml/', - data, - ) - return result - } catch (err) { - return { - status: 500, - message: err.response.data, - } - } -} - -export const deleteExperiment = function *() { - while (true) { - const action = yield take(generalActions.DELETE_EXPERIMENT_REQUEST); - try { - const result = yield call( - goDeleteExperiment, - action.experimentName - ) - if (result.status === 200) { - yield put({ - type: generalActions.DELETE_EXPERIMENT_SUCCESS, - }) - } else { - yield put({ - type: generalActions.DELETE_EXPERIMENT_FAILURE, - }) - } - } catch (err) { - yield put({ - type: generalActions.DELETE_EXPERIMENT_FAILURE, - }) - } - } -} - -const goDeleteExperiment = function *(experimentName) { - try { - const result = yield call( - axios.get, - `/katib/delete_experiment/?experimentName=${experimentName}`, - ) - return result - } catch (err) { - yield put({ - type: generalActions.DELETE_EXPERIMENT_FAILURE, - }) - } -} - -export const submitHPJob = function *() { - while (true) { - const action = yield take(hpCreateActions.SUBMIT_HP_JOB_REQUEST); - try { - const result = yield call( - goSubmitHPJob, - action.data - ) - if (result.status === 200) { - yield put({ - type: hpCreateActions.SUBMIT_HP_JOB_SUCCESS, - }) - } else { - yield put({ - type: hpCreateActions.SUBMIT_HP_JOB_FAILURE, - message: result.message, - }) - } - } catch (err) { - yield put({ - type: hpCreateActions.SUBMIT_HP_JOB_FAILURE, - }) - } - } -} - -const goSubmitHPJob = function *(postData) { - try { - const data = { - postData - } - const result = yield call( - axios.post, - '/katib/submit_hp_job/', - data, - ) - return result - } catch (err) { - return { - status: 500, - message: err.response.data, - } - } -} - -export const fetchHPJobs = function *() { - while (true) { - const action = yield take(hpMonitorActions.FETCH_HP_JOBS_REQUEST); - try { - const result = yield call( - goFetchHPJobs - ) - if (result.status === 200) { - let data = Object.assign(result.data, {}) - data.map((template, i) => { - Object.keys(template).forEach(key => { - const value = template[key]; - delete template[key]; - template[key.toLowerCase()] = value; - }); - }) - yield put({ - type: hpMonitorActions.FETCH_HP_JOBS_SUCCESS, - jobs: data - }) - } else { - yield put({ - type: hpMonitorActions.FETCH_HP_JOBS_FAILURE, - }) - } - } catch (err) { - yield put({ - type: hpMonitorActions.FETCH_HP_JOBS_FAILURE, - }) - } - } -} - -const goFetchHPJobs = function *() { - try { - const result = yield call( - axios.get, - '/katib/fetch_hp_jobs/', - ) - return result - } catch (err) { - yield put({ - type: hpMonitorActions.FETCH_HP_JOBS_FAILURE, - }) - } -} - -export const fetchHPJobInfo = function *() { - while (true) { - const action = yield take(hpMonitorActions.FETCH_HP_JOB_INFO_REQUEST); - try { - const result = yield call( - goFetchHPJobInfo, - action.experimentName - ) - if (result.status === 200) { - let data = result.data.split("\n").map((line, i) => line.split(',')) - yield put({ - type: hpMonitorActions.FETCH_HP_JOB_INFO_SUCCESS, - jobData: data - }) - } else { - yield put({ - type: hpMonitorActions.FETCH_HP_JOB_INFO_FAILURE, - }) - } - } catch (err) { - yield put({ - type: hpMonitorActions.FETCH_HP_JOB_INFO_FAILURE, - }) - } - } -} - -const goFetchHPJobInfo = function *(experimentName) { - try { - const result = yield call( - axios.get, - `/katib/fetch_hp_job_info/?experimentName=${experimentName}`, - ) - return result - } catch (err) { - yield put({ - type: hpMonitorActions.FETCH_HP_JOB_INFO_FAILURE, - }) - } -} - -export const fetchHPJobTrialInfo = function *() { - while (true) { - const action = yield take(hpMonitorActions.FETCH_HP_JOB_TRIAL_INFO_REQUEST); - try { - const result = yield call( - gofetchHPJobTrialInfo, - action.trialName - ) - if (result.status === 200) { - let data = result.data.split("\n").map((line, i) => line.split(',')) - yield put({ - type: hpMonitorActions.FETCH_HP_JOB_TRIAL_INFO_SUCCESS, - trialData: data - }) - } else { - yield put({ - type: hpMonitorActions.FETCH_HP_JOB_TRIAL_INFO_FAILURE, - }) - } - } catch (err) { - yield put({ - type: hpMonitorActions.FETCH_HP_JOB_TRIAL_INFO_FAILURE, - }) - } - } -} - -const gofetchHPJobTrialInfo = function *(trialName) { - try { - const result = yield call( - axios.get, - `/katib/fetch_hp_job_trial_info/?trialName=${trialName}`, - ) - return result - } catch (err) { - yield put({ - type: hpMonitorActions.FETCH_HP_JOB_TRIAL_INFO_FAILURE, - }) - } -} - -export const submitNASJob = function *() { - while (true) { - const action = yield take(nasCreateActions.SUBMIT_NAS_JOB_REQUEST); - try { - const result = yield call( - goSubmitNASJob, - action.data - ) - if (result.status === 200) { - yield put({ - type: nasCreateActions.SUBMIT_NAS_JOB_SUCCESS, - }) - } else { - yield put({ - type: nasCreateActions.SUBMIT_NAS_JOB_FAILURE, - message: result.message, - }) - } - } catch (err) { - yield put({ - type: nasCreateActions.SUBMIT_NAS_JOB_FAILURE, - }) - } - } -} - -const goSubmitNASJob = function *(postData) { - try { - const data = { - postData - } - const result = yield call( - axios.post, - '/katib/submit_nas_job/', - data, - ) - return result - } catch (err) { - return { - status: 500, - message: err.response.data, - } - } -} - - -export const fetchNASJobs = function *() { - while (true) { - const action = yield take(nasMonitorActions.FETCH_NAS_JOBS_REQUEST); - try { - const result = yield call( - goFetchNASJobs - ) - if (result.status === 200) { - let data = Object.assign(result.data, {}) - data.map((template, i) => { - Object.keys(template).forEach(key => { - const value = template[key]; - delete template[key]; - template[key.toLowerCase()] = value; - }); - }) - yield put({ - type: nasMonitorActions.FETCH_NAS_JOBS_SUCCESS, - jobs: data - }) - } else { - yield put({ - type: nasMonitorActions.FETCH_NAS_JOBS_FAILURE, - }) - } - } catch (err) { - yield put({ - type: nasMonitorActions.FETCH_NAS_JOBS_FAILURE, - }) - } - } -} - -const goFetchNASJobs = function *() { - try { - const result = yield call( - axios.get, - '/katib/fetch_nas_jobs/', - ) - return result - } catch (err) { - yield put({ - type: nasMonitorActions.FETCH_NAS_JOBS_FAILURE, - }) - } -} - -export const fetchNASJobInfo = function *() { - while (true) { - const action = yield take(nasMonitorActions.FETCH_NAS_JOB_INFO_REQUEST); - try { - const result = yield call( - goFetchNASJobInfo, - action.experimentName - ) - if (result.status === 200) { - let data = Object.assign(result.data, {}) - data.map((template, i) => { - Object.keys(template).forEach(key => { - const value = template[key]; - delete template[key]; - template[key.toLowerCase()] = value; - }); - }) - yield put({ - type: nasMonitorActions.FETCH_NAS_JOB_INFO_SUCCESS, - steps: data, - }) - } else { - yield put({ - type: nasMonitorActions.FETCH_NAS_JOB_INFO_FAILURE, - }) - } - } catch (err) { - yield put({ - type: nasMonitorActions.FETCH_NAS_JOB_INFO_FAILURE, - }) - } - } -} - -const goFetchNASJobInfo = function *(experimentName) { - try { - const result = yield call( - axios.get, - `/katib/fetch_nas_job_info/?experimentName=${experimentName}`, - ) - return result - } catch (err) { - yield put({ - type: nasMonitorActions.FETCH_NAS_JOB_INFO_FAILURE, - }) - } -} - - -export const fetchTrialTemplates = function *() { - while (true) { - const action = yield take(templateActions.FETCH_TRIAL_TEMPLATES_REQUEST); - try { - const result = yield call( - goFetchTrialTemplates - ) - if (result.status === 200) { - let data = Object.assign(result.data, {}) - data.map((template, i) => { - Object.keys(template).forEach(key => { - const value = template[key]; - delete template[key]; - template[key.toLowerCase()] = value; - }); - }) - yield put({ - type: templateActions.FETCH_TRIAL_TEMPLATES_SUCCESS, - templates: data - }) - } else { - yield put({ - type: templateActions.FETCH_TRIAL_TEMPLATES_FAILURE, - }) - } - } catch (err) { - yield put({ - type: templateActions.FETCH_TRIAL_TEMPLATES_FAILURE, - }) - } - } -} - -const goFetchTrialTemplates = function *() { - try { - const result = yield call( - axios.get, - '/katib/fetch_trial_templates/', - ) - return result - } catch (err) { - yield put({ - type: templateActions.FETCH_TRIAL_TEMPLATES_FAILURE, - }) - } -} - -export const fetchCollectorTemplates = function *() { - while (true) { - const action = yield take(templateActions.FETCH_COLLECTOR_TEMPLATES_REQUEST); - try { - const result = yield call( - goFetchCollectorTemplates - ) - if (result.status === 200) { - let data = Object.assign(result.data, {}) - data.map((template, i) => { - Object.keys(template).forEach(key => { - const value = template[key]; - delete template[key]; - template[key.toLowerCase()] = value; - }); - }) - yield put({ - type: templateActions.FETCH_COLLECTOR_TEMPLATES_SUCCESS, - templates: data - }) - } else { - yield put({ - type: templateActions.FETCH_COLLECTOR_TEMPLATES_FAILURE, - }) - } - } catch (err) { - yield put({ - type: templateActions.FETCH_COLLECTOR_TEMPLATES_FAILURE, - }) - } - } -} - -const goFetchCollectorTemplates = function *() { - try { - const result = yield call( - axios.get, - '/katib/fetch_collector_templates/', - ) - return result - } catch (err) { - yield put({ - type: templateActions.FETCH_COLLECTOR_TEMPLATES_FAILURE, - }) - } -} - - -export const addTemplate = function *() { - while (true) { - const action = yield take(templateActions.ADD_TEMPLATE_REQUEST); - try { - const result = yield call( - goAddTemplate, - action.name, - action.yaml, - action.kind, - action.action - ) - if (result.status === 200) { - let data = Object.assign(result.data.Data, {}) - data.map((template, i) => { - Object.keys(template).forEach(key => { - const value = template[key]; - delete template[key]; - template[key.toLowerCase()] = value; - }); - }) - yield put({ - type: templateActions.ADD_TEMPLATE_SUCCESS, - templates: data, - templateType: result.data.TemplateType - }) - } else { - yield put({ - type: templateActions.ADD_TEMPLATE_FAILURE, - }) - } - } catch (err) { - yield put({ - type: templateActions.ADD_TEMPLATE_FAILURE, - }) - } - } -} - -const goAddTemplate = function *(name, yaml, kind, action) { - try { - const data = { - name, yaml, kind, action - } - const result = yield call( - axios.post, - '/katib/update_template/', - data, - ) - return result - } catch (err) { - yield put({ - type: templateActions.ADD_TEMPLATE_FAILURE, - }) - } -} - -export const editTemplate = function *() { - while (true) { - const action = yield take(templateActions.EDIT_TEMPLATE_REQUEST); - try { - const result = yield call( - goEditTemplate, - action.name, - action.yaml, - action.kind, - action.action - ) - if (result.status === 200) { - let data = Object.assign(result.data.Data, {}) - data.map((template, i) => { - Object.keys(template).forEach(key => { - const value = template[key]; - delete template[key]; - template[key.toLowerCase()] = value; - }); - }) - yield put({ - type: templateActions.EDIT_TEMPLATE_SUCCESS, - templates: data, - templateType: result.data.TemplateType - }) - } else { - yield put({ - type: templateActions.EDIT_TEMPLATE_FAILURE, - }) - } - } catch (err) { - yield put({ - type: templateActions.EDIT_TEMPLATE_FAILURE, - }) - } - } -} - -const goEditTemplate = function *(name, yaml, kind, action) { - try { - const data = { - name, yaml, kind, action - } - const result = yield call( - axios.post, - '/katib/update_template/', - data, - ) - return result - } catch (err) { - yield put({ - type: templateActions.EDIT_TEMPLATE_FAILURE, - }) - } -} - -export const deleteTemplate = function *() { - while (true) { - const action = yield take(templateActions.DELETE_TEMPLATE_REQUEST); - try { - const result = yield call( - goDeleteTemplate, - action.name, - action.kind, - action.action - ) - if (result.status === 200) { - let data = Object.assign(result.data.Data, {}) - data.map((template, i) => { - Object.keys(template).forEach(key => { - const value = template[key]; - delete template[key]; - template[key.toLowerCase()] = value; - }); - }) - yield put({ - type: templateActions.DELETE_TEMPLATE_SUCCESS, - templates: data, - templateType: result.data.TemplateType - }) - } else { - yield put({ - type: templateActions.DELETE_TEMPLATE_FAILURE, - }) - } - } catch (err) { - yield put({ - type: templateActions.DELETE_TEMPLATE_FAILURE, - }) - } - } -} - -const goDeleteTemplate = function *(name, kind, action) { - try { - const data = { - name, kind, action - } - const result = yield call( - axios.post, - '/katib/update_template/', - data, - ) - return result - } catch (err) { - yield put({ - type: templateActions.DELETE_TEMPLATE_FAILURE, - }) - } -} - -export default function* rootSaga() { - yield all([ - fork(fetchTrialTemplates), - fork(fetchCollectorTemplates), - fork(fetchHPJobs), - fork(fetchNASJobs), - fork(addTemplate), - fork(editTemplate), - fork(deleteTemplate), - fork(submitYaml), - fork(deleteExperiment), - fork(submitHPJob), - fork(submitNASJob), - fork(fetchHPJobInfo), - fork(fetchHPJobTrialInfo), - fork(fetchNASJobInfo) - ]); -}; diff --git a/pkg/ui/v1alpha2/frontend/src/serviceWorker.js b/pkg/ui/v1alpha2/frontend/src/serviceWorker.js deleted file mode 100755 index 2283ff9ced1..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/serviceWorker.js +++ /dev/null @@ -1,135 +0,0 @@ -// This optional code is used to register a service worker. -// register() is not called by default. - -// This lets the app load faster on subsequent visits in production, and gives -// it offline capabilities. However, it also means that developers (and users) -// will only see deployed updates on subsequent visits to a page, after all the -// existing tabs open on the page have been closed, since previously cached -// resources are updated in the background. - -// To learn more about the benefits of this model and instructions on how to -// opt-in, read http://bit.ly/CRA-PWA - -const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.1/8 is considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) -); - -export function register(config) { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { - // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); - if (publicUrl.origin !== window.location.origin) { - // Our service worker won't work if PUBLIC_URL is on a different origin - // from what our page is served on. This might happen if a CDN is used to - // serve assets; see https://github.com/facebook/create-react-app/issues/2374 - return; - } - - window.addEventListener('load', () => { - const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; - - if (isLocalhost) { - // This is running on localhost. Let's check if a service worker still exists or not. - checkValidServiceWorker(swUrl, config); - - // Add some additional logging to localhost, pointing developers to the - // service worker/PWA documentation. - navigator.serviceWorker.ready.then(() => { - console.log( - 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit http://bit.ly/CRA-PWA' - ); - }); - } else { - // Is not localhost. Just register service worker - registerValidSW(swUrl, config); - } - }); - } -} - -function registerValidSW(swUrl, config) { - navigator.serviceWorker - .register(swUrl) - .then(registration => { - registration.onupdatefound = () => { - const installingWorker = registration.installing; - if (installingWorker == null) { - return; - } - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the updated precached content has been fetched, - // but the previous service worker will still serve the older - // content until all client tabs are closed. - console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' - ); - - // Execute callback - if (config && config.onUpdate) { - config.onUpdate(registration); - } - } else { - // At this point, everything has been precached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); - - // Execute callback - if (config && config.onSuccess) { - config.onSuccess(registration); - } - } - } - }; - }; - }) - .catch(error => { - console.error('Error during service worker registration:', error); - }); -} - -function checkValidServiceWorker(swUrl, config) { - // Check if the service worker can be found. If it can't reload the page. - fetch(swUrl) - .then(response => { - // Ensure service worker exists, and that we really are getting a JS file. - const contentType = response.headers.get('content-type'); - if ( - response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) - ) { - // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { - registration.unregister().then(() => { - window.location.reload(); - }); - }); - } else { - // Service worker found. Proceed as normal. - registerValidSW(swUrl, config); - } - }) - .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); - }); -} - -export function unregister() { - if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(registration => { - registration.unregister(); - }); - } -} diff --git a/pkg/ui/v1alpha2/frontend/src/store/index.js b/pkg/ui/v1alpha2/frontend/src/store/index.js deleted file mode 100644 index efa374fabe9..00000000000 --- a/pkg/ui/v1alpha2/frontend/src/store/index.js +++ /dev/null @@ -1,24 +0,0 @@ -import { createStore, applyMiddleware, compose } from 'redux'; -import logger from 'redux-logger'; -import createSagaMiddleware, { END } from 'redux-saga'; -import rootReducer from '../reducers'; - - -export default function configureStore(initialState) { - const sagaMiddleware = createSagaMiddleware(); - - const store = createStore( - rootReducer, - initialState, - compose( - applyMiddleware( - sagaMiddleware, - logger - ) - ) - ); - - store.runSaga = sagaMiddleware.run; - store.close = () => store.dispatch(END); - return store; -} diff --git a/pkg/ui/v1alpha2/types.go b/pkg/ui/v1alpha2/types.go deleted file mode 100644 index c5717cd466b..00000000000 --- a/pkg/ui/v1alpha2/types.go +++ /dev/null @@ -1,56 +0,0 @@ -package ui - -import "github.com/kubeflow/katib/pkg/util/v1alpha2/katibclient" - -const maxMsgSize = 1<<31 - 1 - -var ( - // namespace = "default" - allowedHeaders = "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization, X-CSRF-Token" -) - -type Decoder struct { - Layers int `json:"num_layers"` - InputSize []int `json:"input_size"` - OutputSize []int `json:"output_size"` - Embedding map[int]*Block `json:"embedding"` -} - -type Block struct { - ID int `json:"opt_id"` - Type string `json:"opt_type"` - Param Option `json:"opt_params"` -} - -type Option struct { - FilterNumber string `json:"num_filter"` - FilterSize string `json:"filter_size"` - Stride string `json:"stride"` -} - -type JobView struct { - Name string - Status string -} - -type TemplateView struct { - Name string - Yaml string -} - -type KatibUIHandler struct { - katibClient katibclient.Client -} - -type TemplateResponse struct { - TemplateType string - Data []TemplateView -} - -type NNView struct { - Name string - TrialName string - Architecture string - MetricsName []string - MetricsValue []string -} diff --git a/pkg/ui/v1alpha2/util.go b/pkg/ui/v1alpha2/util.go deleted file mode 100644 index 7e2310f2093..00000000000 --- a/pkg/ui/v1alpha2/util.go +++ /dev/null @@ -1,140 +0,0 @@ -package ui - -import ( - "encoding/json" - "errors" - "net/http" - "strconv" - "strings" - - gographviz "github.com/awalterschulze/gographviz" -) - -func enableCors(w *http.ResponseWriter) { - (*w).Header().Set("Content-Type", "text/html; charset=utf-8") - (*w).Header().Set("Access-Control-Allow-Origin", "*") - (*w).Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE") - (*w).Header().Set("Access-Control-Allow-Headers", allowedHeaders) - (*w).Header().Set("Access-Control-Expose-Headers", "Access-Control-*") - (*w).Header().Set("Access-Control-Allow-Credentials", "true") -} - -func getTemplatesView(templates map[string]string) []TemplateView { - templatesView := make([]TemplateView, 0) - - for key := range templates { - templatesView = append(templatesView, TemplateView{Name: key, Yaml: templates[key]}) - } - return templatesView -} - -func (k *KatibUIHandler) updateTemplates(newTemplate map[string]interface{}, isDelete bool) (TemplateResponse, error) { - var currentTemplates map[string]string - var err error - - if newTemplate["kind"].(string) == "collector" { - currentTemplates, err = k.katibClient.GetMetricsCollectorTemplates() - if err != nil { - return TemplateResponse{}, errors.New("GetMetricsCollectorTemplates failed: " + err.Error()) - } - } else { - currentTemplates, err = k.katibClient.GetTrialTemplates() - if err != nil { - return TemplateResponse{}, errors.New("GetTrialTemplates failed: " + err.Error()) - } - } - - if isDelete { - delete(currentTemplates, newTemplate["name"].(string)) - } else { - currentTemplates[newTemplate["name"].(string)] = newTemplate["yaml"].(string) - } - - if newTemplate["kind"].(string) == "collector" { - err = k.katibClient.UpdateMetricsCollectorTemplates(currentTemplates) - if err != nil { - return TemplateResponse{}, errors.New("UpdateMetricsCollectorTemplates failed: " + err.Error()) - } - } else { - err = k.katibClient.UpdateTrialTemplates(currentTemplates) - if err != nil { - return TemplateResponse{}, errors.New("UpdateTrialTemplates failed: " + err.Error()) - } - } - - TemplateResponse := TemplateResponse{ - Data: getTemplatesView(currentTemplates), - TemplateType: newTemplate["kind"].(string), - } - return TemplateResponse, nil -} - -func getNodeString(block *Block) string { - var nodeString string - switch block.Type { - case "convolution": - nodeString += block.Param.FilterSize + "x" + block.Param.FilterSize - nodeString += " conv\n" - nodeString += block.Param.FilterSize + " channels" - case "separable_convolution": - nodeString += block.Param.FilterSize + "x" + block.Param.FilterSize - nodeString += " sep_conv\n" - nodeString += block.Param.FilterSize + " channels" - case "depthwise_convolution": - nodeString += block.Param.FilterSize + "x" + block.Param.FilterSize - nodeString += " depth_conv\n" - case "reduction": - // TODO: Need to be fixed - nodeString += "3x3 max_pooling" - } - return strconv.Quote(nodeString) -} - -func generateNNImage(architecture string, decoder string) string { - - var architectureInt [][]int - - if err := json.Unmarshal([]byte(architecture), &architectureInt); err != nil { - panic(err) - } - /* - Always has num_layers, input_size, output_size and embeding - Embeding is a map: int to Parameter - Parameter has id, type, Option - - Beforehand substite all ' to " and wrap the string in ` - */ - - replacedDecoder := strings.Replace(decoder, `'`, `"`, -1) - var decoderParsed Decoder - - err := json.Unmarshal([]byte(replacedDecoder), &decoderParsed) - if err != nil { - panic(err) - } - - graphAst, _ := gographviz.ParseString(`digraph G {}`) - graph := gographviz.NewGraph() - if err := gographviz.Analyse(graphAst, graph); err != nil { - panic(err) - } - graph.AddNode("G", "0", map[string]string{"label": strconv.Quote("Input")}) - var i int - for i = 0; i < len(architectureInt); i++ { - graph.AddNode("G", strconv.Itoa(i+1), map[string]string{"label": getNodeString(decoderParsed.Embedding[architectureInt[i][0]])}) - graph.AddEdge(strconv.Itoa(i), strconv.Itoa(i+1), true, nil) - for j := 1; j < i+1; j++ { - if architectureInt[i][j] == 1 { - graph.AddEdge(strconv.Itoa(j-1), strconv.Itoa(i+1), true, nil) - } - } - } - graph.AddNode("G", strconv.Itoa(i+1), map[string]string{"label": strconv.Quote("GlobalAvgPool")}) - graph.AddEdge(strconv.Itoa(i), strconv.Itoa(i+1), true, nil) - graph.AddNode("G", strconv.Itoa(i+2), map[string]string{"label": strconv.Quote("FullConnect\nSoftmax")}) - graph.AddEdge(strconv.Itoa(i+1), strconv.Itoa(i+2), true, nil) - graph.AddNode("G", strconv.Itoa(i+3), map[string]string{"label": strconv.Quote("Output")}) - graph.AddEdge(strconv.Itoa(i+2), strconv.Itoa(i+3), true, nil) - s := graph.String() - return s -} diff --git a/pkg/util/v1alpha2/katibclient/katib_client.go b/pkg/util/v1alpha2/katibclient/katib_client.go deleted file mode 100644 index a5e36f7986e..00000000000 --- a/pkg/util/v1alpha2/katibclient/katib_client.go +++ /dev/null @@ -1,190 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package katibclient - -import ( - "context" - "io/ioutil" - "strings" - - apiv1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/config" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - trialsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1alpha2" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/consts" -) - -type Client interface { - InjectClient(c client.Client) - GetExperimentList(namespace ...string) (*experimentsv1alpha2.ExperimentList, error) - CreateExperiment(experiment *experimentsv1alpha2.Experiment, namespace ...string) error - DeleteExperiment(experiment *experimentsv1alpha2.Experiment, namespace ...string) error - GetExperiment(name string, namespace ...string) (*experimentsv1alpha2.Experiment, error) - GetConfigMap(name string, namespace ...string) (map[string]string, error) - GetTrialList(name string, namespace ...string) (*trialsv1alpha2.TrialList, error) - GetTrialTemplates(namespace ...string) (map[string]string, error) - UpdateTrialTemplates(newTrialTemplates map[string]string, namespace ...string) error - GetMetricsCollectorTemplates(namespace ...string) (map[string]string, error) - UpdateMetricsCollectorTemplates(newMCTemplates map[string]string, namespace ...string) error -} - -type KatibClient struct { - client client.Client -} - -func NewWithGivenClient(c client.Client) Client { - return &KatibClient{ - client: c, - } -} - -func NewClient(options client.Options) (Client, error) { - cfg, err := config.GetConfig() - if err != nil { - return nil, err - } - experimentsv1alpha2.AddToScheme(scheme.Scheme) - trialsv1alpha2.AddToScheme(scheme.Scheme) - cl, err := client.New(cfg, options) - return &KatibClient{ - client: cl, - }, nil -} - -func (k *KatibClient) InjectClient(c client.Client) { - k.client = c -} - -func (k *KatibClient) GetExperimentList(namespace ...string) (*experimentsv1alpha2.ExperimentList, error) { - ns := getNamespace(namespace...) - expList := &experimentsv1alpha2.ExperimentList{} - listOpt := client.InNamespace(ns) - - if err := k.client.List(context.Background(), listOpt, expList); err != nil { - return expList, err - } - return expList, nil - -} - -func (k *KatibClient) GetTrialList(name string, namespace ...string) (*trialsv1alpha2.TrialList, error) { - ns := getNamespace(namespace...) - trialList := &trialsv1alpha2.TrialList{} - labels := map[string]string{consts.LabelExperimentName: name} - listOpt := &client.ListOptions{} - listOpt.MatchingLabels(labels).InNamespace(ns) - - if err := k.client.List(context.Background(), listOpt, trialList); err != nil { - return trialList, err - } - return trialList, nil - -} - -func (k *KatibClient) CreateExperiment(experiment *experimentsv1alpha2.Experiment, namespace ...string) error { - - if err := k.client.Create(context.Background(), experiment); err != nil { - return err - } - return nil -} - -func (k *KatibClient) DeleteExperiment(experiment *experimentsv1alpha2.Experiment, namespace ...string) error { - - if err := k.client.Delete(context.Background(), experiment); err != nil { - return err - } - return nil -} - -func (k *KatibClient) GetExperiment(name string, namespace ...string) (*experimentsv1alpha2.Experiment, error) { - ns := getNamespace(namespace...) - exp := &experimentsv1alpha2.Experiment{} - if err := k.client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: ns}, exp); err != nil { - return nil, err - } - return exp, nil -} - -func (k *KatibClient) GetConfigMap(name string, namespace ...string) (map[string]string, error) { - ns := getNamespace(namespace...) - configMap := &apiv1.ConfigMap{} - if err := k.client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: ns}, configMap); err != nil { - return map[string]string{}, err - } - return configMap.Data, nil -} - -func (k *KatibClient) GetTrialTemplates(namespace ...string) (map[string]string, error) { - - ns := getNamespace(namespace...) - trialTemplates := &apiv1.ConfigMap{} - - if err := k.client.Get(context.Background(), types.NamespacedName{Name: experimentsv1alpha2.DefaultTrialConfigMapName, Namespace: ns}, trialTemplates); err != nil { - return nil, err - } - return trialTemplates.Data, nil - -} - -func (k *KatibClient) UpdateTrialTemplates(newTrialTemplates map[string]string, namespace ...string) error { - ns := getNamespace(namespace...) - trialTemplates := &apiv1.ConfigMap{} - - if err := k.client.Get(context.Background(), types.NamespacedName{Name: experimentsv1alpha2.DefaultTrialConfigMapName, Namespace: ns}, trialTemplates); err != nil { - return err - } - trialTemplates.Data = newTrialTemplates - - if err := k.client.Update(context.Background(), trialTemplates); err != nil { - return err - } - return nil -} - -func (k *KatibClient) GetMetricsCollectorTemplates(namespace ...string) (map[string]string, error) { - ns := getNamespace(namespace...) - return k.GetConfigMap(experimentsv1alpha2.DefaultMetricsCollectorConfigMapName, ns) -} - -func (k *KatibClient) UpdateMetricsCollectorTemplates(newMCTemplates map[string]string, namespace ...string) error { - - ns := getNamespace(namespace...) - metricsCollectorTemplates := &apiv1.ConfigMap{} - - if err := k.client.Get(context.Background(), types.NamespacedName{Name: experimentsv1alpha2.DefaultMetricsCollectorConfigMapName, Namespace: ns}, metricsCollectorTemplates); err != nil { - return err - } - - metricsCollectorTemplates.Data = newMCTemplates - - if err := k.client.Update(context.Background(), metricsCollectorTemplates); err != nil { - return err - } - return nil -} - -func getNamespace(namespace ...string) string { - if len(namespace) == 0 { - data, _ := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") - return strings.TrimSpace(string(data)) - } - return namespace[0] -} diff --git a/pkg/util/v1alpha2/metricscollector/metricscollector.go b/pkg/util/v1alpha2/metricscollector/metricscollector.go deleted file mode 100644 index 70006b03729..00000000000 --- a/pkg/util/v1alpha2/metricscollector/metricscollector.go +++ /dev/null @@ -1,113 +0,0 @@ -package metricscollector - -import ( - "errors" - "fmt" - "strings" - "time" - - apiv1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/kubernetes" - "k8s.io/klog" - "sigs.k8s.io/controller-runtime/pkg/client/config" - - v1alpha2 "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - commonv1alpha2 "github.com/kubeflow/katib/pkg/common/v1alpha2" -) - -type MetricsCollector struct { - clientset *kubernetes.Clientset -} - -func NewMetricsCollector() (*MetricsCollector, error) { - config, err := config.GetConfig() - if err != nil { - return nil, err - } - clientset, err := kubernetes.NewForConfig(config) - if err != nil { - return nil, err - } - return &MetricsCollector{ - clientset: clientset, - }, nil - -} - -func (d *MetricsCollector) CollectObservationLog(tId string, jobKind string, metrics []string, namespace string) (*v1alpha2.ObservationLog, error) { - labelMap := commonv1alpha2.GetJobLabelMap(jobKind, tId) - pl, err := d.clientset.CoreV1().Pods(namespace).List(metav1.ListOptions{LabelSelector: labels.Set(labelMap).String(), IncludeUninitialized: true}) - if err != nil { - return nil, err - } - if len(pl.Items) == 0 { - return nil, fmt.Errorf("No Pods are found in Trial %v", tId) - } - logopt := apiv1.PodLogOptions{Timestamps: true} - logs, err := d.clientset.CoreV1().Pods(namespace).GetLogs(pl.Items[0].ObjectMeta.Name, &logopt).Do().Raw() - if err != nil { - return nil, err - } - if len(logs) == 0 { - return &v1alpha2.ObservationLog{}, nil - } - olog, err := d.parseLogs(tId, strings.Split(string(logs), "\n"), metrics) - return olog, err -} - -func (d *MetricsCollector) parseLogs(tId string, logs []string, metrics []string) (*v1alpha2.ObservationLog, error) { - var lasterr error - olog := &v1alpha2.ObservationLog{} - mlogs := []*v1alpha2.MetricLog{} - for _, logline := range logs { - if logline == "" { - continue - } - ls := strings.SplitN(logline, " ", 2) - if len(ls) != 2 { - klog.Errorf("Error parsing log: %s", logline) - lasterr = errors.New("Error parsing log") - continue - } - _, err := time.Parse(time.RFC3339Nano, ls[0]) - if err != nil { - klog.Errorf("Error parsing time %s: %v", ls[0], err) - lasterr = err - continue - } - kvpairs := strings.Fields(ls[1]) - for _, kv := range kvpairs { - v := strings.Split(kv, "=") - if len(v) > 2 { - klog.Infof("Ignoring trailing garbage: %s", kv) - } - if len(v) == 1 { - continue - } - metricName := "" - for _, m := range metrics { - if v[0] == m { - metricName = v[0] - } - } - if metricName == "" { - continue - } - timestamp := ls[0] - mlogs = append(mlogs, &v1alpha2.MetricLog{ - TimeStamp: timestamp, - Metric: &v1alpha2.Metric{ - Name: metricName, - Value: v[1], - }, - }) - } - } - olog.MetricLogs = mlogs - if lasterr != nil { - return olog, lasterr - } - return olog, nil -} diff --git a/pkg/util/v1alpha2/tfevent-metricscollector/__init__.py b/pkg/util/v1alpha2/tfevent-metricscollector/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/pkg/util/v1alpha2/tfevent-metricscollector/tfevent_loader.py b/pkg/util/v1alpha2/tfevent-metricscollector/tfevent_loader.py deleted file mode 100644 index 200fc6a4016..00000000000 --- a/pkg/util/v1alpha2/tfevent-metricscollector/tfevent_loader.py +++ /dev/null @@ -1,65 +0,0 @@ -import tensorflow as tf -import os -from datetime import datetime -import rfc3339 -import grpc -import api_pb2 -import api_pb2_grpc -import sys -from logging import getLogger, StreamHandler, INFO - -# TFEventFileParser parses tfevent files and returns an ObservationLog of the metrics specified. -# When the event file is under a directory(e.g. test dir), please specify "{{dirname}}/{{metrics name}}" -# For example, in the TensorFlow official tutorial for mnist with summary (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_with_summaries.py), -# the "accuracy" metric is saved under "train" and "test" directories. So in Katib, please specify name of metrics as "train/accuracy" and "test/accuracy". -class TFEventFileParser: - def find_all_files(self, directory): - for root, dirs, files in os.walk(directory): - yield root - for f in files: - yield os.path.join(root, f) - - def parse_summary(self, tfefile, metrics): - metric_logs = [] - for summary in tf.train.summary_iterator(tfefile): - paths=tfefile.split("/") - for v in summary.summary.value: - for m in metrics: - tag = str(v.tag) - if len(paths) >= 2 and len(m.split("/")) >= 2: - tag = str(paths[-2]+"/" + v.tag) - if tag.startswith(m): - ml = api_pb2.MetricLog( - time_stamp=rfc3339.rfc3339(datetime.fromtimestamp(summary.wall_time)), - metric=api_pb2.Metric( - name=m, - value=str(v.simple_value) - ) - ) - metric_logs.append(ml) - return metric_logs - -class MetricsCollector: - def __init__(self, metric_names): - self.logger = getLogger(__name__) - handler = StreamHandler() - handler.setLevel(INFO) - self.logger.setLevel(INFO) - self.logger.addHandler(handler) - self.logger.propagate = False - self.metrics = metric_names - self.parser = TFEventFileParser() - - def parse_file(self, directory): - mls = [] - for f in self.parser.find_all_files(directory): - if os.path.isdir(f): - continue - try: - self.logger.info(f + " will be parsed.") - mls = self.parser.parse_summary(f, self.metrics) - except Exception, e: - self.logger.warning("Unexpected error: "+ str(e)) - continue - return api_pb2.ObservationLog(metric_logs=mls) - diff --git a/pkg/webhook/v1alpha2/experiment/mutate_webhook.go b/pkg/webhook/v1alpha2/experiment/mutate_webhook.go deleted file mode 100644 index ecb55f206fc..00000000000 --- a/pkg/webhook/v1alpha2/experiment/mutate_webhook.go +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package experiment - -import ( - "context" - "net/http" - - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission/types" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" -) - -// experimentDefaulter that sets default fields in experiment -type experimentDefaulter struct { - client client.Client - decoder types.Decoder -} - -var _ admission.Handler = &experimentDefaulter{} - -func (e *experimentDefaulter) Handle(ctx context.Context, req types.Request) types.Response { - inst := &experimentsv1alpha2.Experiment{} - err := e.decoder.Decode(req, inst) - if err != nil { - return admission.ErrorResponse(http.StatusBadRequest, err) - } - - copy := inst.DeepCopy() - copy.SetDefault() - - return admission.PatchResponse(inst, copy) -} - -var _ inject.Client = &experimentDefaulter{} - -func (e *experimentDefaulter) InjectClient(c client.Client) error { - e.client = c - return nil -} - -var _ inject.Decoder = &experimentDefaulter{} - -func (e *experimentDefaulter) InjectDecoder(d types.Decoder) error { - e.decoder = d - return nil -} - -func NewExperimentDefaulter(c client.Client) *experimentDefaulter { - return &experimentDefaulter{ - client: c, - } -} diff --git a/pkg/webhook/v1alpha2/experiment/validation_webhook.go b/pkg/webhook/v1alpha2/experiment/validation_webhook.go deleted file mode 100644 index d7290fe0a9f..00000000000 --- a/pkg/webhook/v1alpha2/experiment/validation_webhook.go +++ /dev/null @@ -1,82 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package experiment - -import ( - "context" - "net/http" - - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission/types" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/managerclient" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/manifest" - "github.com/kubeflow/katib/pkg/webhook/v1alpha2/experiment/validator" -) - -// experimentValidator validates Pods -type experimentValidator struct { - admission.Handler - client client.Client - decoder types.Decoder - validator.Validator -} - -func NewExperimentValidator(c client.Client) *experimentValidator { - p := manifest.New(c) - mc := managerclient.New() - return &experimentValidator{ - Validator: validator.New(p, mc), - } -} - -func (v *experimentValidator) Handle(ctx context.Context, req types.Request) types.Response { - inst := &experimentsv1alpha2.Experiment{} - err := v.decoder.Decode(req, inst) - if err != nil { - return admission.ErrorResponse(http.StatusBadRequest, err) - } - err = v.ValidateExperiment(inst) - if err != nil { - return admission.ErrorResponse(http.StatusBadRequest, err) - } - return admission.ValidationResponse(true, "") -} - -// experimentValidator implements inject.Client. -// A client will be automatically injected. -var _ inject.Client = &experimentValidator{} - -// InjectClient injects the client. -func (v *experimentValidator) InjectClient(c client.Client) error { - v.client = c - v.Validator.InjectClient(c) - return nil -} - -// experimentValidator implements inject.Decoder. -// A decoder will be automatically injected. -var _ inject.Decoder = &experimentValidator{} - -// InjectDecoder injects the decoder. -func (v *experimentValidator) InjectDecoder(d types.Decoder) error { - v.decoder = d - return nil -} diff --git a/pkg/webhook/v1alpha2/experiment/validator/validator.go b/pkg/webhook/v1alpha2/experiment/validator/validator.go deleted file mode 100644 index 35b0ca57571..00000000000 --- a/pkg/webhook/v1alpha2/experiment/validator/validator.go +++ /dev/null @@ -1,212 +0,0 @@ -package validator - -import ( - "bytes" - "fmt" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - batchv1beta "k8s.io/api/batch/v1beta1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - k8syaml "k8s.io/apimachinery/pkg/util/yaml" - "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - - commonapiv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - commonv1alpha2 "github.com/kubeflow/katib/pkg/common/v1alpha2" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/managerclient" - "github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/manifest" -) - -var log = logf.Log.WithName("experiment-validating-webhook") - -type Validator interface { - ValidateExperiment(instance *experimentsv1alpha2.Experiment) error - InjectClient(c client.Client) -} - -type DefaultValidator struct { - manifest.Generator - managerclient.ManagerClient -} - -func New(generator manifest.Generator, managerClient managerclient.ManagerClient) Validator { - return &DefaultValidator{ - Generator: generator, - ManagerClient: managerClient, - } -} - -func (g *DefaultValidator) InjectClient(c client.Client) { - g.Generator.InjectClient(c) -} - -func (g *DefaultValidator) ValidateExperiment(instance *experimentsv1alpha2.Experiment) error { - if !instance.IsCreated() { - if err := g.validateForCreate(instance); err != nil { - return err - } - } - if err := g.validateObjective(instance.Spec.Objective); err != nil { - return err - } - if err := g.validateAlgorithm(instance.Spec.Algorithm); err != nil { - return err - } - - if err := g.validateTrialTemplate(instance); err != nil { - return err - } - - if len(instance.Spec.Parameters) == 0 && instance.Spec.NasConfig == nil { - return fmt.Errorf("spec.parameters or spec.nasConfig must be specified.") - } - - if len(instance.Spec.Parameters) > 0 && instance.Spec.NasConfig != nil { - return fmt.Errorf("Only one of spec.parameters and spec.nasConfig can be specified.") - } - - if err := g.validateAlgorithmSettings(instance); err != nil { - return err - } - - if err := g.validateMetricsCollector(instance); err != nil { - return err - } - - return nil -} - -func (g *DefaultValidator) validateAlgorithmSettings(inst *experimentsv1alpha2.Experiment) error { - - _, err := g.ValidateAlgorithmSettings(inst) - statusCode, _ := status.FromError(err) - - if statusCode.Code() == codes.Unknown { - return fmt.Errorf("Method ValidateAlgorithmSettings not found inside Suggestion service: %s", inst.Spec.Algorithm.AlgorithmName) - } - - if statusCode.Code() == codes.InvalidArgument || statusCode.Code() == codes.Unavailable { - return fmt.Errorf("ValidateAlgorithmSettings Error: %v", statusCode.Message()) - } - return nil - -} - -func (g *DefaultValidator) validateObjective(obj *commonapiv1alpha2.ObjectiveSpec) error { - if obj == nil { - return fmt.Errorf("No spec.objective specified.") - } - if obj.Type != commonapiv1alpha2.ObjectiveTypeMinimize && obj.Type != commonapiv1alpha2.ObjectiveTypeMaximize { - return fmt.Errorf("spec.objective.type must be %s or %s.", commonapiv1alpha2.ObjectiveTypeMinimize, commonapiv1alpha2.ObjectiveTypeMaximize) - } - if obj.ObjectiveMetricName == "" { - return fmt.Errorf("No spec.objective.objectiveMetricName specified.") - } - return nil -} - -func (g *DefaultValidator) validateAlgorithm(ag *experimentsv1alpha2.AlgorithmSpec) error { - if ag == nil { - return fmt.Errorf("No spec.algorithm specified.") - } - if ag.AlgorithmName == "" { - return fmt.Errorf("No spec.algorithm.name specified.") - } - - return nil -} - -func (g *DefaultValidator) validateTrialTemplate(instance *experimentsv1alpha2.Experiment) error { - trialName := fmt.Sprintf("%s-trial", instance.GetName()) - runSpec, err := g.GetRunSpec(instance, instance.GetName(), trialName, instance.GetNamespace()) - if err != nil { - return fmt.Errorf("Invalid spec.trialTemplate: %v.", err) - } - - bufSize := 1024 - buf := bytes.NewBufferString(runSpec) - - job := &unstructured.Unstructured{} - if err := k8syaml.NewYAMLOrJSONDecoder(buf, bufSize).Decode(job); err != nil { - return fmt.Errorf("Invalid spec.trialTemplate: %v.", err) - } - - if err := g.validateSupportedJob(job); err != nil { - return fmt.Errorf("Invalid spec.trialTemplate: %v.", err) - } - - if job.GetNamespace() != instance.GetNamespace() { - return fmt.Errorf("Invalid spec.trialTemplate: metadata.namespace should be %s or {{.NameSpace}}", instance.GetNamespace()) - } - if job.GetName() != trialName { - return fmt.Errorf("Invalid spec.trialTemplate: metadata.name should be {{.Trial}}") - } - return nil -} - -func (g *DefaultValidator) validateSupportedJob(job *unstructured.Unstructured) error { - gvk := job.GroupVersionKind() - supportedJobs := commonv1alpha2.GetSupportedJobList() - for _, sJob := range supportedJobs { - if gvk == sJob { - return nil - } - } - return fmt.Errorf("Job type %v not supported", gvk) -} - -func (g *DefaultValidator) validateForCreate(inst *experimentsv1alpha2.Experiment) error { - reply, err := g.PreCheckRegisterExperimentInDB(inst) - if err != nil { - return fmt.Errorf("Fail to check record for the experiment in DB: %v", err) - } else if !reply.CanRegister { - return fmt.Errorf("Record for the experiment has existed in DB; Please try to rename the experiment") - } else { - return nil - } -} - -func (g *DefaultValidator) validateMetricsCollector(inst *experimentsv1alpha2.Experiment) error { - BUFSIZE := 1024 - experimentName := inst.GetName() - trialName := fmt.Sprintf("%s-trial", inst.GetName()) - namespace := inst.GetNamespace() - var metricNames []string - metricNames = append(metricNames, inst.Spec.Objective.ObjectiveMetricName) - for _, mn := range inst.Spec.Objective.AdditionalMetricNames { - metricNames = append(metricNames, mn) - } - - runSpec, err := g.GetRunSpec(inst, experimentName, trialName, namespace) - if err != nil { - return fmt.Errorf("Invalid spec.trialTemplate: %v.", err) - } - - buf := bytes.NewBufferString(runSpec) - - job := &unstructured.Unstructured{} - if err := k8syaml.NewYAMLOrJSONDecoder(buf, BUFSIZE).Decode(job); err != nil { - return fmt.Errorf("Invalid spec.trialTemplate: %v.", err) - } - - mcm, err := g.GetMetricsCollectorManifest(experimentName, trialName, job.GetKind(), namespace, metricNames, inst.Spec.MetricsCollectorSpec) - if err != nil { - log.Info("getMetricsCollectorManifest error", "err", err) - return err - } - - buf = bytes.NewBufferString(mcm) - - mcjob := &batchv1beta.CronJob{} - if err := k8syaml.NewYAMLOrJSONDecoder(buf, BUFSIZE).Decode(&mcjob); err != nil { - log.Info("MetricsCollector Yaml decode error", "err", err) - return err - } - - if mcjob.GetNamespace() != namespace || mcjob.GetName() != trialName { - return fmt.Errorf("Invalid metricsCollector template.") - } - return nil -} diff --git a/pkg/webhook/v1alpha2/experiment/validator/validator_test.go b/pkg/webhook/v1alpha2/experiment/validator/validator_test.go deleted file mode 100644 index dfde0d1416f..00000000000 --- a/pkg/webhook/v1alpha2/experiment/validator/validator_test.go +++ /dev/null @@ -1,190 +0,0 @@ -package validator - -import ( - "testing" - - "github.com/golang/mock/gomock" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - - commonv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/common/v1alpha2" - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - api_pb "github.com/kubeflow/katib/pkg/apis/manager/v1alpha2" - managerclientmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/experiment/managerclient" - manifestmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/experiment/manifest" -) - -func init() { - logf.SetLogger(logf.ZapLogger(false)) -} - -func TestValidateTFJobTrialTemplate(t *testing.T) { - trialTFJobTemplate := `apiVersion: "kubeflow.org/v1" -kind: "TFJob" -metadata: - name: "dist-mnist-for-e2e-test" -spec: - tfReplicaSpecs: - Worker: - template: - spec: - containers: - - name: tensorflow - image: gaocegege/mnist:1` - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - mockCtrl2 := gomock.NewController(t) - defer mockCtrl2.Finish() - - p := manifestmock.NewMockGenerator(mockCtrl) - mc := managerclientmock.NewMockManagerClient(mockCtrl2) - g := New(p, mc) - - p.EXPECT().GetRunSpec(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(trialTFJobTemplate, nil) - mc.EXPECT().PreCheckRegisterExperimentInDB(gomock.Any()).Return( - &api_pb.PreCheckRegisterExperimentReply{ - CanRegister: true, - }, nil).AnyTimes() - - instance := newFakeInstance() - if err := g.(*DefaultValidator).validateTrialTemplate(instance); err == nil { - t.Errorf("Expected error, got nil") - } -} - -func TestValidateJobTrialTemplate(t *testing.T) { - trialJobTemplate := `apiVersion: "batch/v1" -kind: "Job" -metadata: - name: "fake-trial" - namespace: fakens` - - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - mockCtrl2 := gomock.NewController(t) - defer mockCtrl2.Finish() - - p := manifestmock.NewMockGenerator(mockCtrl) - mc := managerclientmock.NewMockManagerClient(mockCtrl2) - g := New(p, mc) - - p.EXPECT().GetRunSpec(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(trialJobTemplate, nil) - mc.EXPECT().PreCheckRegisterExperimentInDB(gomock.Any()).Return( - &api_pb.PreCheckRegisterExperimentReply{ - CanRegister: true, - }, nil).AnyTimes() - - instance := newFakeInstance() - if err := g.(*DefaultValidator).validateTrialTemplate(instance); err != nil { - t.Errorf("Expected nil, got err %v", err) - } -} - -func TestValidateExperiment(t *testing.T) { - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - mockCtrl2 := gomock.NewController(t) - defer mockCtrl2.Finish() - - p := manifestmock.NewMockGenerator(mockCtrl) - mc := managerclientmock.NewMockManagerClient(mockCtrl2) - g := New(p, mc) - - trialJobTemplate := `apiVersion: "batch/v1" -kind: "Job" -metadata: - name: "fake-trial" - namespace: fakens` - - metricsCollectorTemplate := `apiVersion: batch/v1beta1 -kind: CronJob -metadata: - name: fake-trial - namespace: fakens -spec: - schedule: "*/1 * * * *"` - - p.EXPECT().GetRunSpec(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(trialJobTemplate, nil).AnyTimes() - p.EXPECT().GetMetricsCollectorManifest( - gomock.Any(), gomock.Any(), gomock.Any(), - gomock.Any(), gomock.Any(), gomock.Any()). - Return(metricsCollectorTemplate, nil).AnyTimes() - mc.EXPECT().PreCheckRegisterExperimentInDB(gomock.Any()).Return( - &api_pb.PreCheckRegisterExperimentReply{ - CanRegister: true, - }, nil).AnyTimes() - - mc.EXPECT().ValidateAlgorithmSettings(gomock.Any()).Return( - &api_pb.ValidateAlgorithmSettingsReply{}, nil).AnyTimes() - - tcs := []struct { - Instance *experimentsv1alpha2.Experiment - Err bool - }{ - { - Instance: func() *experimentsv1alpha2.Experiment { - i := newFakeInstance() - i.Spec.Objective = nil - return i - }(), - Err: true, - }, - { - Instance: func() *experimentsv1alpha2.Experiment { - i := newFakeInstance() - i.Spec.Algorithm = nil - return i - }(), - Err: true, - }, - { - Instance: newFakeInstance(), - Err: false, - }, - } - - for _, tc := range tcs { - err := g.ValidateExperiment(tc.Instance) - if !tc.Err && err != nil { - t.Errorf("Expected nil, got %v", err) - } else if tc.Err && err == nil { - t.Errorf("Expected err, got nil") - } - } -} - -func newFakeInstance() *experimentsv1alpha2.Experiment { - goal := 0.11 - return &experimentsv1alpha2.Experiment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "fake", - Namespace: "fakens", - }, - Spec: experimentsv1alpha2.ExperimentSpec{ - Objective: &commonv1alpha2.ObjectiveSpec{ - Type: commonv1alpha2.ObjectiveTypeMaximize, - Goal: &goal, - ObjectiveMetricName: "testme", - }, - Algorithm: &experimentsv1alpha2.AlgorithmSpec{ - AlgorithmName: "test", - AlgorithmSettings: []experimentsv1alpha2.AlgorithmSetting{ - { - Name: "test1", - Value: "value1", - }, - }, - }, - Parameters: []experimentsv1alpha2.ParameterSpec{ - { - Name: "test", - ParameterType: experimentsv1alpha2.ParameterTypeCategorical, - FeasibleSpace: experimentsv1alpha2.FeasibleSpace{ - List: []string{"1", "2"}, - }, - }, - }, - }, - } -} diff --git a/pkg/webhook/v1alpha2/webhook.go b/pkg/webhook/v1alpha2/webhook.go deleted file mode 100644 index 6d7eaa6a2d4..00000000000 --- a/pkg/webhook/v1alpha2/webhook.go +++ /dev/null @@ -1,88 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package webhook - -import ( - "os" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - "github.com/kubeflow/katib/pkg/webhook/v1alpha2/experiment" - - admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" - "k8s.io/apimachinery/pkg/types" - - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder" -) - -const katibControllerName = "katib-controller" - -func AddToManager(m manager.Manager) error { - server, err := webhook.NewServer("katib-admission-server", m, webhook.ServerOptions{ - CertDir: "/tmp/cert", - BootstrapOptions: &webhook.BootstrapOptions{ - Secret: &types.NamespacedName{ - Namespace: os.Getenv(experimentsv1alpha2.DefaultKatibNamespaceEnvName), - Name: katibControllerName, - }, - Service: &webhook.Service{ - Namespace: os.Getenv(experimentsv1alpha2.DefaultKatibNamespaceEnvName), - Name: katibControllerName, - Selectors: map[string]string{ - "app": katibControllerName, - }, - }, - ValidatingWebhookConfigName: "katib-validating-webhook-config", - MutatingWebhookConfigName: "katib-mutating-webhook-config", - }, - }) - if err != nil { - return err - } - - if err := register(m, server); err != nil { - return err - } - - return nil -} - -func register(manager manager.Manager, server *webhook.Server) error { - mutatingWebhook, err := builder.NewWebhookBuilder(). - Name("mutating.experiment.katib.kubeflow.org"). - Mutating(). - Operations(admissionregistrationv1beta1.Create, admissionregistrationv1beta1.Update). - WithManager(manager). - ForType(&experimentsv1alpha2.Experiment{}). - Handlers(experiment.NewExperimentDefaulter(manager.GetClient())). - Build() - if err != nil { - return err - } - validatingWebhook, err := builder.NewWebhookBuilder(). - Name("validating.experiment.katib.kubeflow.org"). - Validating(). - Operations(admissionregistrationv1beta1.Create, admissionregistrationv1beta1.Update). - WithManager(manager). - ForType(&experimentsv1alpha2.Experiment{}). - Handlers(experiment.NewExperimentValidator(manager.GetClient())). - Build() - if err != nil { - return err - } - return server.Register(mutatingWebhook, validatingWebhook) -} diff --git a/prow_config.yaml b/prow_config.yaml index 7448b10daf4..1af6c41934f 100644 --- a/prow_config.yaml +++ b/prow_config.yaml @@ -1,89 +1,6 @@ # This file configures the workflows to trigger in our Prow jobs. # see kubeflow/testing/py/run_e2e_workflow.py workflows: - - app_dir: kubeflow/katib/test/workflows - component: workflows-v1alpha2 - name: e2e-v1alpha2 - job_types: - - presubmit - include_dirs: - - pkg/apis/controller/common/v1alpha2/* - - pkg/apis/controller/experiments/v1alpha2/* - - pkg/apis/controller/trials/v1alpha2/* - - pkg/apis/controller/*.go - - pkg/apis/manager/health/* - - pkg/apis/manager/v1alpha2/* - - pkg/common/v1alpha2/* - - pkg/controller.v1alpha2/* - - pkg/db/v1alpha2/* - - pkg/earlystopping/v1alpha2/* - - pkg/manager/v1alpha2/* - - pkg/manager/modelstore/* - - pkg/suggestion/v1alpha2/* - - pkg/ui/v1alpha2/* - - pkg/webhook/v1alpha2/* - - cmd/earlystopping/medianstopping/v1alpha2/* - - cmd/katib-controller/v1alpha2/* - - cmd/manager/v1alpha2/* - - cmd/manager-rest/v1alpha2/* - - cmd/metricscollector/v1alpha2/* - - cmd/suggestion/bayesianoptimization/v1alpha2/* - - cmd/suggestion/grid/v1alpha2/* - - cmd/suggestion/hyperband/v1alpha2/* - - cmd/suggestion/nasenvelopenet/v1alpha2/* - - cmd/suggestion/nasrl/v1alpha2/* - - cmd/suggestion/random/v1alpha2/* - - cmd/tfevent-metricscollector/v1alpha2/* - - cmd/ui/v1alpha2/* - - pkg/util/v1alpha2/* - - test/e2e/v1alpha2/* - - test/scripts/v1alpha2/* - - test/workflows/* - - manifests/v1alpha2/* - - scripts/v1alpha2/* - - vendor/* - params: - registry: "gcr.io/kubeflow-ci" - - app_dir: kubeflow/katib/test/workflows - component: workflows-v1alpha2 - name: e2e-v1alpha2 - job_types: - - postsubmit - include_dirs: - - pkg/apis/controller/common/v1alpha2/* - - pkg/apis/controller/experiments/v1alpha2/* - - pkg/apis/controller/trials/v1alpha2/* - - pkg/apis/controller/*.go - - pkg/apis/manager/health/* - - pkg/apis/manager/v1alpha2/* - - pkg/common/v1alpha2/* - - pkg/controller.v1alpha2/* - - pkg/db/v1alpha2/* - - pkg/earlystopping/v1alpha2/* - - pkg/manager/v1alpha2/* - - pkg/manager/modelstore/* - - pkg/suggestion/v1alpha2/* - - pkg/ui/v1alpha2/* - - pkg/webhook/v1alpha2/* - - cmd/earlystopping/medianstopping/v1alpha2/* - - cmd/katib-controller/v1alpha2/* - - cmd/manager/v1alpha2/* - - cmd/manager-rest/v1alpha2/* - - cmd/metricscollector/v1alpha2/* - - cmd/suggestion/bayesianoptimization/v1alpha2/* - - cmd/suggestion/grid/v1alpha2/* - - cmd/suggestion/hyperband/v1alpha2/* - - cmd/suggestion/nasenvelopenet/v1alpha2/* - - cmd/suggestion/nasrl/v1alpha2/* - - cmd/suggestion/random/v1alpha2/* - - cmd/tfevent-metricscollector/v1alpha2/* - - cmd/ui/v1alpha2/* - - pkg/util/v1alpha2/* - - test/scripts/v1alpha2/* - - test/workflows/* - - vendor/* - params: - registry: "gcr.io/kubeflow-images-public" - app_dir: kubeflow/katib/test/workflows component: workflows-v1alpha3 name: e2e-v1alpha3 diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index 57d955678f3..75a6d5c6f2f 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -21,23 +21,6 @@ set -o pipefail SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. cd ${SCRIPT_ROOT} -echo "Generating v1alpha2 ManagerClient..." -mockgen -package mock -destination pkg/mock/v1alpha2/api/manager.go github.com/kubeflow/katib/pkg/apis/manager/v1alpha2 ManagerClient -echo "Generating v1alpha2 SuggestionClient..." -mockgen -package mock -destination pkg/mock/v1alpha2/api/suggestion.go github.com/kubeflow/katib/pkg/apis/manager/v1alpha2 SuggestionClient -echo "Generating v1alpha2 KatibDBInterface..." -mockgen -package mock -destination pkg/mock/v1alpha2/db/db.go github.com/kubeflow/katib/pkg/db/v1alpha2 KatibDBInterface -echo "Generating v1alpha2 Generator..." -mockgen -package mock -destination pkg/mock/v1alpha2/experiment/manifest/generator.go github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/manifest Generator -echo "Generating v1alpha2 KatibClient..." -mockgen -package mock -destination pkg/mock/v1alpha2/util/katibclient/katibclient.go github.com/kubeflow/katib/pkg/util/v1alpha2/katibclient Client -echo "Generating v1alpha2 ManagerClient in Trial Controller..." -mockgen -package mock -destination pkg/mock/v1alpha2/trial/managerclient/katibmanager.go github.com/kubeflow/katib/pkg/controller.v1alpha2/trial/managerclient ManagerClient -echo "Generating v1alpha2 ManagerClient in Experiment Controller..." -mockgen -package mock -destination pkg/mock/v1alpha2/experiment/managerclient/managerclient.go github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/managerclient ManagerClient -echo "Generating v1alpha2 Suggestion in Experiment Controller..." -mockgen -package mock -destination pkg/mock/v1alpha2/experiment/suggestion/suggestion.go github.com/kubeflow/katib/pkg/controller.v1alpha2/experiment/suggestion Suggestion - echo "Generating v1alpha3 ManagerClient..." mockgen -package mock -destination pkg/mock/v1alpha3/api/manager.go github.com/kubeflow/katib/pkg/apis/manager/v1alpha3 ManagerClient echo "Generating v1alpha3 SuggestionClient..." diff --git a/scripts/v1alpha2/build.sh b/scripts/v1alpha2/build.sh deleted file mode 100755 index b1e6f24c104..00000000000 --- a/scripts/v1alpha2/build.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail - -PREFIX="katib" -CMD_PREFIX="cmd" -MACHINE_ARCH=`uname -m` - -SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/../.. - -cd ${SCRIPT_ROOT} - -echo "Building core image..." -docker build -t ${PREFIX}/v1alpha2/katib-controller -f ${CMD_PREFIX}/katib-controller/v1alpha2/Dockerfile . -docker build -t ${PREFIX}/v1alpha2/katib-manager -f ${CMD_PREFIX}/manager/v1alpha2/Dockerfile . -docker build -t ${PREFIX}/v1alpha2/katib-manager-rest -f ${CMD_PREFIX}/manager-rest/v1alpha2/Dockerfile . -docker build -t ${PREFIX}/v1alpha2/metrics-collector -f ${CMD_PREFIX}/metricscollector/v1alpha2/Dockerfile . - -echo "Building UI image..." -docker build -t ${PREFIX}/v1alpha2/katib-ui -f ${CMD_PREFIX}/ui/v1alpha2/Dockerfile . - -echo "Building TF Event metrics collector image..." -if [ $MACHINE_ARCH == "aarch64" ]; then - docker build -t ${PREFIX}/v1alpha2/tfevent-metrics-collector -f ${CMD_PREFIX}/tfevent-metricscollector/v1alpha2/Dockerfile.aarch64 . -else - docker build -t ${PREFIX}/v1alpha2/tfevent-metrics-collector -f ${CMD_PREFIX}/tfevent-metricscollector/v1alpha2/Dockerfile . -fi - -echo "Building suggestion images..." -docker build -t ${PREFIX}/v1alpha2/suggestion-random -f ${CMD_PREFIX}/suggestion/random/v1alpha2/Dockerfile . -docker build -t ${PREFIX}/v1alpha2/suggestion-bayesianoptimization -f ${CMD_PREFIX}/suggestion/bayesianoptimization/v1alpha2/Dockerfile . -docker build -t ${PREFIX}/v1alpha2/suggestion-grid -f ${CMD_PREFIX}/suggestion/grid/v1alpha2/Dockerfile . -docker build -t ${PREFIX}/v1alpha2/suggestion-hyperband -f ${CMD_PREFIX}/suggestion/hyperband/v1alpha2/Dockerfile . -if [ $MACHINE_ARCH == "aarch64" ]; then - docker build -t ${PREFIX}/v1alpha2/suggestion-nasrl -f ${CMD_PREFIX}/suggestion/nasrl/v1alpha2/Dockerfile.aarch64 . -else - docker build -t ${PREFIX}/v1alpha2/suggestion-nasrl -f ${CMD_PREFIX}/suggestion/nasrl/v1alpha2/Dockerfile . -fi diff --git a/scripts/v1alpha2/deploy.sh b/scripts/v1alpha2/deploy.sh deleted file mode 100755 index 2a6b5bedf86..00000000000 --- a/scripts/v1alpha2/deploy.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail -set -o xtrace - -SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/../.. - -cd ${SCRIPT_ROOT} -kubectl apply -f manifests/v1alpha2 -kubectl apply -f manifests/v1alpha2/katib-controller -kubectl apply -f manifests/v1alpha2/manager -kubectl apply -f manifests/v1alpha2/manager-rest -kubectl apply -f manifests/v1alpha2/pv -kubectl apply -f manifests/v1alpha2/db -kubectl apply -f manifests/v1alpha2/ui -kubectl apply -f manifests/v1alpha2/suggestion/random -kubectl apply -f manifests/v1alpha2/suggestion/bayesianoptimization -kubectl apply -f manifests/v1alpha2/suggestion/nasrl -kubectl apply -f manifests/v1alpha2/suggestion/grid -kubectl apply -f manifests/v1alpha2/suggestion/hyperband -cd - > /dev/null diff --git a/scripts/v1alpha2/undeploy.sh b/scripts/v1alpha2/undeploy.sh deleted file mode 100755 index 24153698820..00000000000 --- a/scripts/v1alpha2/undeploy.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail -set -o xtrace - -# Delete CR first -experiments=`kubectl get experiments --all-namespaces | awk '{if (NR>1) {print $1"/"$2}}'` -for s in $experiments -do - ns=`echo $s|cut -d "/" -f 1` - exp=`echo $s|cut -d "/" -f 2` - kubectl delete experiments $exp -n $ns -done - -SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/../.. - -cd ${SCRIPT_ROOT} -kubectl delete -f manifests/v1alpha2/katib-controller -kubectl delete -f manifests/v1alpha2/manager -kubectl delete -f manifests/v1alpha2/manager-rest -kubectl delete -f manifests/v1alpha2/db -kubectl delete -f manifests/v1alpha2/ui -kubectl delete -f manifests/v1alpha2/pv -kubectl delete -f manifests/v1alpha2/suggestion/random -kubectl delete -f manifests/v1alpha2/suggestion/bayesianoptimization -kubectl delete -f manifests/v1alpha2/suggestion/nasrl -kubectl delete -f manifests/v1alpha2/suggestion/grid -kubectl delete -f manifests/v1alpha2 -cd - > /dev/null diff --git a/test/e2e/v1alpha2/invalid-experiment.yaml b/test/e2e/v1alpha2/invalid-experiment.yaml deleted file mode 100644 index 5014e80f35f..00000000000 --- a/test/e2e/v1alpha2/invalid-experiment.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: "kubeflow.org/v1alpha2" -kind: Experiment -metadata: - namespace: kubeflow - name: invalid-experiment -spec: - maxTrialCount: 13 - maxFailedTrialCount: 3 - objective: - type: maximize - goal: 0.99 - objectiveMetricName: Validation-accuracy - additionalMetricNames: - - accuracy - algorithm: - algorithmName: random - trialTemplate: - goTemplate: - rawTemplate: |- - apiVersion: batch/v1 - kind: invalid-kind # invalid - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - restartPolicy: Never - parameters: - - name: --lr - parameterType: double - feasibleSpace: - min: "0.01" - max: "0.03" - - name: --num-layers - parameterType: int - feasibleSpace: - min: "2" - max: "5" - - name: --optimizer - parameterType: categorical - feasibleSpace: - list: - - sgd - - adam - - ftrl diff --git a/test/e2e/v1alpha2/run-e2e-experiment.go b/test/e2e/v1alpha2/run-e2e-experiment.go deleted file mode 100644 index 7e9fe34c5c1..00000000000 --- a/test/e2e/v1alpha2/run-e2e-experiment.go +++ /dev/null @@ -1,102 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "io/ioutil" - "log" - "os" - "time" - - k8syaml "k8s.io/apimachinery/pkg/util/yaml" - _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" - "sigs.k8s.io/controller-runtime/pkg/client" - - experimentsv1alpha2 "github.com/kubeflow/katib/pkg/apis/controller/experiments/v1alpha2" - "github.com/kubeflow/katib/pkg/util/v1alpha2/katibclient" -) - -const ( - timeout = 20 * time.Minute -) - -func verifyResult(exp *experimentsv1alpha2.Experiment) error { - if len(exp.Status.CurrentOptimalTrial.ParameterAssignments) == 0 { - return fmt.Errorf("Best parameter assignments not updated in status") - } - - if len(exp.Status.CurrentOptimalTrial.Observation.Metrics) == 0 { - return fmt.Errorf("Bst metrics not updated in status") - } - - metric := exp.Status.CurrentOptimalTrial.Observation.Metrics[0] - if metric.Name != exp.Spec.Objective.ObjectiveMetricName { - return fmt.Errorf("Best objective metric not updated in status") - } - return nil -} - -func main() { - if len(os.Args) != 2 { - log.Fatal("Experiment name is missing") - } - expName := os.Args[1] - b, err := ioutil.ReadFile(expName) - if err != nil { - log.Fatal("Error in reading file ", err) - } - exp := &experimentsv1alpha2.Experiment{} - buf := bytes.NewBufferString(string(b)) - if err = k8syaml.NewYAMLOrJSONDecoder(buf, 1024).Decode(exp); err != nil { - log.Fatal("Yaml decode error ", err) - } - kclient, err := katibclient.NewClient(client.Options{}) - if err != nil { - log.Fatal("NewClient for Katib failed: ", err) - } - var maxtrials int32 = 3 - var paralleltrials int32 = 2 - exp.Spec.MaxTrialCount = &maxtrials - exp.Spec.ParallelTrialCount = ¶lleltrials - err = kclient.CreateExperiment(exp) - if err != nil { - log.Fatal("CreateExperiment from YAML failed: ", err) - } - - for endTime := time.Now().Add(timeout); time.Now().Before(endTime); { - exp, err = kclient.GetExperiment(exp.Name, exp.Namespace) - if err != nil { - log.Fatal("Get Experiment error ", err) - } - if exp.IsCompleted() { - log.Printf("Job %v finished", exp.Name) - break - } - log.Printf("Waiting for job %v to finish. [ %v trials running %v succeeded ]", exp.Name, exp.Status.TrialsRunning, exp.Status.TrialsSucceeded) - time.Sleep(20 * time.Second) - } - - if !exp.IsCompleted() { - log.Fatal("Experiment run timed out") - } - - if exp.Status.Trials != *exp.Spec.MaxTrialCount { - log.Fatal("All trials are not run in the experiment ", exp.Status.Trials, exp.Spec.MaxTrialCount) - } - - if exp.Status.TrialsSucceeded != *exp.Spec.MaxTrialCount { - log.Fatal("All trials are not successful ", exp.Status.TrialsSucceeded, *exp.Spec.MaxTrialCount) - } - err = verifyResult(exp) - if err != nil { - log.Fatal(err) - } - - log.Printf("Experiment has recorded best current Optimal Trial %v", exp.Status.CurrentOptimalTrial) - err = kclient.DeleteExperiment(exp) - if err != nil { - log.Printf("CreateExperiment from YAML failed: %v", err) - return - } - log.Printf("Experiment %v deleted", exp.Name) -} diff --git a/test/e2e/v1alpha2/test-katib-manager.py b/test/e2e/v1alpha2/test-katib-manager.py deleted file mode 100644 index 9bbde429031..00000000000 --- a/test/e2e/v1alpha2/test-katib-manager.py +++ /dev/null @@ -1,147 +0,0 @@ -import logging -import grpc -import api_pb2 -import api_pb2_grpc - -logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s') -logger = logging.getLogger(__name__) - -TEST_TRIAL = "test_trial" -TEST_EXPERIMENT = "test_experiment" - -def register_experiment(stub): - obj = api_pb2.ObjectiveSpec(type=1, goal=0.09, objective_metric_name="loss") - algo = api_pb2.AlgorithmSpec(algorithm_name="random") - feasible_space = api_pb2.FeasibleSpace(min="1", max="5") - parameter_specs = api_pb2.ExperimentSpec.ParameterSpecs() - parameter_specs.parameters.add(name="lr", parameter_type=api_pb2.DOUBLE, feasible_space=feasible_space) - exp_spec = api_pb2.ExperimentSpec(objective=obj, - algorithm=algo, - trial_template="run-mnist", - metrics_collector_spec="metrics-collector", - parallel_trial_count=2, - max_trial_count=9) - exp_status = api_pb2.ExperimentStatus(condition=1, - start_time="2019-04-28T14:09:15Z", - completion_time="2019-04-28T16:09:15Z") - exp = api_pb2.Experiment(spec=exp_spec, - name=TEST_EXPERIMENT, - status=exp_status) - try: - stub.RegisterExperiment(api_pb2.RegisterExperimentRequest(experiment=exp), 10) - logger.info("Register experiment %s successfully" % TEST_EXPERIMENT) - except: - logger.error("Failed to Register experiment", exc_info=True) - raise - -def update_experiment_status(stub): - try: - new = api_pb2.ExperimentStatus(condition=2,start_time="2019-04-28T17:09:15Z",completion_time="2019-04-28T18:09:15Z") - stub.UpdateExperimentStatus(api_pb2.UpdateExperimentStatusRequest(experiment_name=TEST_EXPERIMENT, new_status=new),10) - logger.info("Update status of experiment %s successfully" % TEST_EXPERIMENT) - except: - logger.error("Fail to update status of experiment", exc_info=True) - raise - -def get_experiment(stub): - try: - exp = stub.GetExperiment(api_pb2.GetExperimentRequest(experiment_name=TEST_EXPERIMENT), 10) - if exp and exp.experiment.name == TEST_EXPERIMENT: - logger.info("Get experiment %s successfully" % TEST_EXPERIMENT) - else: - raise Exception() - except: - logger.error("Failed to get experiment %s" % TEST_EXPERIMENT, exc_info=True) - raise - -def delete_experiment(stub): - try: - stub.DeleteExperiment(api_pb2.DeleteExperimentRequest(experiment_name=TEST_EXPERIMENT), 10) - logger.info("Delete experiment %s successfully" % TEST_EXPERIMENT) - except: - logger.error("Failed to delete experiment %s" % TEST_EXPERIMENT, exc_info=True) - raise - -def register_trial(stub): - try: - obj = api_pb2.ObjectiveSpec(type=1, goal=0.09, objective_metric_name="loss") - parameters = api_pb2.TrialSpec.ParameterAssignments(assignments=[api_pb2.ParameterAssignment(name="rl", value="0.01")]) - spec = api_pb2.TrialSpec(experiment_name=TEST_EXPERIMENT, - objective=obj, - run_spec="a batch/job resource", - metrics_collector_spec="metrics/collector", - parameter_assignments=parameters) - observation = api_pb2.Observation(metrics=[api_pb2.Metric(name="loss", value="0.54")]) - status = api_pb2.TrialStatus(condition=2, - observation=observation, - start_time="2019-04-28T17:09:15Z", - completion_time="2019-04-28T18:09:15Z") - t = api_pb2.Trial(name=TEST_TRIAL, status=status, spec=spec) - stub.RegisterTrial(api_pb2.RegisterTrialRequest(trial=t), 10) - logger.info("Register trial %s successfully" % TEST_TRIAL) - except: - logger.error("Failed to register trial %s" % TEST_TRIAL, exc_info=True) - raise - -def get_trial(stub): - try: - reply = stub.GetTrial(api_pb2.GetTrialRequest(trial_name=TEST_TRIAL), 10) - trial = reply.trial - if trial and trial.name == TEST_TRIAL: - logger.info("Get trial %s successfully" % TEST_TRIAL) - else: - raise Exception() - except: - logger.error("Failed to get trial %s" % TEST_TRIAL, exc_info=True) - raise - -def get_random_algo_suggestion(stub): - try: - reply = stub.GetSuggestions(api_pb2.GetSuggestionsRequest(experiment_name=TEST_EXPERIMENT, - algorithm_name="random", - request_number=1), 10) - trials = reply.trials - - if len(trials) == 1 and trials[0].spec.experiment_name == TEST_EXPERIMENT: - logger.info("Get random algorithm suggestion successfully") - else: - raise Exception() - except: - logger.error("Failed to get trial %s" % TEST_TRIAL, exc_info=True) - raise - -def get_grid_algo_suggestion(stub): - try: - reply = stub.GetSuggestions(api_pb2.GetSuggestionsRequest(experiment_name=TEST_EXPERIMENT, - algorithm_name="grid", - request_number=1), 10) - trials = reply.trials - - if len(trials) == 1 and trials[0].spec.experiment_name == TEST_EXPERIMENT: - logger.info("Get grid algorithm suggestion successfully") - else: - raise Exception() - except: - logger.error("Failed to get trial %s" % TEST_TRIAL, exc_info=True) - raise - -def test(): - with grpc.insecure_channel('127.0.0.1:6789') as channel: - stub = api_pb2_grpc.ManagerStub(channel) - register_experiment(stub) - get_experiment(stub) - update_experiment_status(stub) - register_trial(stub) - get_trial(stub) - get_random_algo_suggestion(stub) - get_grid_algo_suggestion(stub) - delete_experiment(stub) - try: - get_trial(stub) - except: - return 0 - else: - exit(1) - -if __name__ == '__main__': - test() diff --git a/test/e2e/v1alpha2/test_requirements.txt b/test/e2e/v1alpha2/test_requirements.txt deleted file mode 100644 index ff4c69d2c7e..00000000000 --- a/test/e2e/v1alpha2/test_requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -grpcio -gcloud -protobuf diff --git a/test/e2e/v1alpha2/valid-experiment.yaml b/test/e2e/v1alpha2/valid-experiment.yaml deleted file mode 100644 index 6746194eecc..00000000000 --- a/test/e2e/v1alpha2/valid-experiment.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: "kubeflow.org/v1alpha2" -kind: Experiment -metadata: - namespace: kubeflow - name: valid-experiment -spec: - maxTrialCount: 13 - maxFailedTrialCount: 3 - objective: - type: maximize - goal: 0.99 - objectiveMetricName: Validation-accuracy - additionalMetricNames: - - accuracy - algorithm: - algorithmName: random - trialTemplate: - goTemplate: - rawTemplate: |- - apiVersion: batch/v1 - kind: Job - metadata: - name: {{.Trial}} - namespace: {{.NameSpace}} - spec: - template: - spec: - containers: - - name: {{.Trial}} - image: katib/mxnet-mnist-example - command: - - "python" - - "/mxnet/example/image-classification/train_mnist.py" - - "--batch-size=64" - restartPolicy: Never - parameters: - - name: --lr - parameterType: double - feasibleSpace: - min: "0.01" - max: "0.03" - - name: --num-layers - parameterType: int - feasibleSpace: - min: "2" - max: "5" - - name: --optimizer - parameterType: categorical - feasibleSpace: - list: - - sgd - - adam - - ftrl diff --git a/test/scripts/v1alpha2/build-earlystopping-median.sh b/test/scripts/v1alpha2/build-earlystopping-median.sh deleted file mode 100755 index 4da082329f6..00000000000 --- a/test/scripts/v1alpha2/build-earlystopping-median.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -exit 0 - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-earlystopping-median -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} - -#cp cmd/earlystopping/medianstopping/Dockerfile . -#gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/earlystopping-medianstopping:${VERSION} --project=${PROJECT} -#gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/earlystopping-medianstopping:${VERSION} ${REGISTRY}/${REPO_NAME}/earlystopping-medianstopping:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-katib-controller.sh b/test/scripts/v1alpha2/build-katib-controller.sh deleted file mode 100755 index 1c3cfd77920..00000000000 --- a/test/scripts/v1alpha2/build-katib-controller.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-katib-controller -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} -cp cmd/katib-controller/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/katib-controller:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/katib-controller:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/katib-controller:latest --verbosity=info - -cd ${GO_DIR} -cp cmd/metricscollector/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/metrics-collector:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/metrics-collector:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/metrics-collector:latest --verbosity=info - -cd ${GO_DIR} -cp cmd/tfevent-metricscollector/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/tfevent-metrics-collector:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/tfevent-metrics-collector:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/tfevent-metrics-collector:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-manager-rest.sh b/test/scripts/v1alpha2/build-manager-rest.sh deleted file mode 100755 index 19a7d018c6c..00000000000 --- a/test/scripts/v1alpha2/build-manager-rest.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-manager-rest -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} -cp cmd/manager-rest/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/katib-manager-rest:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/katib-manager-rest:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/katib-manager-rest:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-manager.sh b/test/scripts/v1alpha2/build-manager.sh deleted file mode 100755 index 8acf7cf3caf..00000000000 --- a/test/scripts/v1alpha2/build-manager.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-manager -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} -cp cmd/manager/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/katib-manager:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/katib-manager:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/katib-manager:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-suggestion-bo.sh b/test/scripts/v1alpha2/build-suggestion-bo.sh deleted file mode 100755 index 56c38002fea..00000000000 --- a/test/scripts/v1alpha2/build-suggestion-bo.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-suggestion-bo -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} - -cp cmd/suggestion/bayesianoptimization/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-bayesianoptimization:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-bayesianoptimization:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-bayesianoptimization:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-suggestion-grid.sh b/test/scripts/v1alpha2/build-suggestion-grid.sh deleted file mode 100755 index 83d03f5aba6..00000000000 --- a/test/scripts/v1alpha2/build-suggestion-grid.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-suggestion-grid -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} - -cp cmd/suggestion/grid/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-grid:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-grid:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-grid:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-suggestion-hyperband.sh b/test/scripts/v1alpha2/build-suggestion-hyperband.sh deleted file mode 100755 index 6299ece5834..00000000000 --- a/test/scripts/v1alpha2/build-suggestion-hyperband.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-suggestion-hyperband -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} - -cp cmd/suggestion/hyperband/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-hyperband:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-hyperband:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-hyperband:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-suggestion-nasenvelopenet.sh b/test/scripts/v1alpha2/build-suggestion-nasenvelopenet.sh deleted file mode 100755 index de1a5da7210..00000000000 --- a/test/scripts/v1alpha2/build-suggestion-nasenvelopenet.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -exit 0 - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-suggestion-nasenvelopenet -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} - -cp cmd/suggestion/nasenvelopenet/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/suggestion-nasenvelopenet:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/suggestion-nasenvelopenet:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-nasenvelopenet:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-suggestion-nasrl.sh b/test/scripts/v1alpha2/build-suggestion-nasrl.sh deleted file mode 100755 index 228aff3b32e..00000000000 --- a/test/scripts/v1alpha2/build-suggestion-nasrl.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-suggestion-nasrl -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} - -cp cmd/suggestion/nasrl/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-nasrl:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-nasrl:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-nasrl:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-suggestion-random.sh b/test/scripts/v1alpha2/build-suggestion-random.sh deleted file mode 100755 index 523204eba83..00000000000 --- a/test/scripts/v1alpha2/build-suggestion-random.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-suggestion-random -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} - -cp cmd/suggestion/random/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-random:${VERSION} --project=${PROJECT} -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-random:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/suggestion-random:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-tc-nasrl-cifar10.sh b/test/scripts/v1alpha2/build-tc-nasrl-cifar10.sh deleted file mode 100755 index 397d7d5395d..00000000000 --- a/test/scripts/v1alpha2/build-tc-nasrl-cifar10.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-training-container-nasrl-cifar10 -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r examples ${GO_DIR}/examples - -cd ${GO_DIR} - -cp examples/v1alpha2/NAS-training-containers/RL-cifar10/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/training-container-nasrl-cifar10:${VERSION} --project=${PROJECT} --timeout=20m -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/training-container-nasrl-cifar10:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/training-container-nasrl-cifar10:latest --verbosity=info diff --git a/test/scripts/v1alpha2/build-ui.sh b/test/scripts/v1alpha2/build-ui.sh deleted file mode 100755 index 72df59fff91..00000000000 --- a/test/scripts/v1alpha2/build-ui.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubeflow Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build an image from our argo workflow -exit 0 - -set -o errexit -set -o nounset -set -o pipefail - -export PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH} -REGISTRY="${GCP_REGISTRY}" -PROJECT="${GCP_PROJECT}" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME}-katib-ui -VERSION=$(git describe --tags --always --dirty) - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Copy source to GOPATH" -mkdir -p ${GO_DIR} -cp -r cmd ${GO_DIR}/cmd -cp -r pkg ${GO_DIR}/pkg -cp -r vendor ${GO_DIR}/vendor - -cd ${GO_DIR} - -cp cmd/ui/v1alpha2/Dockerfile . -gcloud builds submit . --tag=${REGISTRY}/${REPO_NAME}/v1alpha2/katib-ui:${VERSION} --project=${PROJECT} --timeout=20m -gcloud container images add-tag --quiet ${REGISTRY}/${REPO_NAME}/v1alpha2/katib-ui:${VERSION} ${REGISTRY}/${REPO_NAME}/v1alpha2/katib-ui:latest --verbosity=info diff --git a/test/scripts/v1alpha2/create-cluster.sh b/test/scripts/v1alpha2/create-cluster.sh deleted file mode 100755 index 8b56adc1fa1..00000000000 --- a/test/scripts/v1alpha2/create-cluster.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build a cluster and create a namespace from our -# argo workflow - - -set -o errexit -set -o nounset -set -o pipefail - -CLUSTER_NAME="${CLUSTER_NAME}" -ZONE="${GCP_ZONE}" -PROJECT="${GCP_PROJECT}" -NAMESPACE="${DEPLOY_NAMESPACE}" - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} -echo "Creating GPU cluster" -gcloud --project ${PROJECT} beta container clusters create ${CLUSTER_NAME} \ - --zone ${ZONE} \ - --cluster-version 1.12 -echo "Configuring kubectl" -gcloud --project ${PROJECT} container clusters get-credentials ${CLUSTER_NAME} \ - --zone ${ZONE} diff --git a/test/scripts/v1alpha2/delete-cluster.sh b/test/scripts/v1alpha2/delete-cluster.sh deleted file mode 100755 index 16e1864003c..00000000000 --- a/test/scripts/v1alpha2/delete-cluster.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build a cluster and create a namespace from our -# argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -CLUSTER_NAME="${CLUSTER_NAME}" -ZONE="${GCP_ZONE}" -PROJECT="${GCP_PROJECT}" - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} -echo "Tearing down the cluster" -gcloud container clusters delete ${CLUSTER_NAME} --zone=${ZONE} --project=${PROJECT} diff --git a/test/scripts/v1alpha2/python-tests.sh b/test/scripts/v1alpha2/python-tests.sh deleted file mode 100755 index e0c7653e5b6..00000000000 --- a/test/scripts/v1alpha2/python-tests.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to run the python tests in the argo workflow - -exit 0 - -pip install -r cmd/suggestion/bayesianoptimization/v1alpha2/requirements.txt -pip install -r pkg/suggestion/test_requirements.txt -python setup.py develop -pylint pkg/suggestion/v1alpha2/bayesianoptimization/src --disable=fixme --exit-zero --reports=y -pytest pkg/suggestion/v1alpha2/tests --verbose --cov=pkg/suggestion/bayesianoptimization/src --cov-report term-missing diff --git a/test/scripts/v1alpha2/run-tests.sh b/test/scripts/v1alpha2/run-tests.sh deleted file mode 100755 index f2cab65912e..00000000000 --- a/test/scripts/v1alpha2/run-tests.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This shell script is used to build a cluster and create a namespace from our -# argo workflow - -set -o errexit -set -o nounset -set -o pipefail - -CLUSTER_NAME="${CLUSTER_NAME}" -ZONE="${GCP_ZONE}" -PROJECT="${GCP_PROJECT}" -NAMESPACE="${DEPLOY_NAMESPACE}" -REGISTRY="${GCP_REGISTRY}" -# VERSION=$(git describe --tags --always --dirty) -VERSION="latest" -GO_DIR=${GOPATH}/src/github.com/${REPO_OWNER}/${REPO_NAME} - -echo "Activating service-account" -gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} - -echo "Configuring kubectl" - -echo "CLUSTER_NAME: ${CLUSTER_NAME}" -echo "ZONE: ${GCP_ZONE}" -echo "PROJECT: ${GCP_PROJECT}" - -gcloud --project ${PROJECT} container clusters get-credentials ${CLUSTER_NAME} \ - --zone ${ZONE} -kubectl config set-context $(kubectl config current-context) --namespace=default -USER=`gcloud config get-value account` - -kubectl apply -f - << EOF -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: cluster-admins -subjects: -- kind: User - name: $USER -roleRef: - kind: ClusterRole - name: cluster-admin - apiGroup: "" -EOF - -#This is required. But I don't know why. -# VERSION=${VERSION/%?/} - -echo "Install Katib " -echo "REGISTRY ${REGISTRY}" -echo "REPO_NAME ${REPO_NAME}" -echo "VERSION ${VERSION}" - -sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/katib-controller@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/katib-controller:${VERSION}@" manifests/v1alpha2/katib-controller/katib-controller.yaml -sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/metrics-collector@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/metrics-collector:${VERSION}@" manifests/v1alpha2/katib-controller/metricsControllerConfigMap.yaml -sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/katib-manager@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/katib-manager:${VERSION}@" manifests/v1alpha2/manager/deployment.yaml -sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/katib-manager-rest@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/katib-manager-rest:${VERSION}@" manifests/v1alpha2/manager-rest/deployment.yaml -#sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/katib-ui@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/katib-ui:${VERSION}@" manifests/v1alpha2/ui/deployment.yaml -sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/suggestion-random@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/suggestion-random:${VERSION}@" manifests/v1alpha2/suggestion/random/deployment.yaml -sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/suggestion-bayesianoptimization@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/suggestion-bayesianoptimization:${VERSION}@" manifests/v1alpha2/suggestion/bayesianoptimization/deployment.yaml -sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/suggestion-nasrl@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/suggestion-nasrl:${VERSION}@" manifests/v1alpha2/suggestion/nasrl/deployment.yaml -sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/suggestion-grid@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/suggestion-grid:${VERSION}@" manifests/v1alpha2/suggestion/grid/deployment.yaml -sed -i -e "s@image: gcr.io\/kubeflow-images-public\/katib\/v1alpha2\/suggestion-hyperband@image: ${REGISTRY}\/${REPO_NAME}\/v1alpha2\/suggestion-hyperband:${VERSION}@" manifests/v1alpha2/suggestion/hyperband/deployment.yaml - -./scripts/v1alpha2/deploy.sh - -TIMEOUT=120 -PODNUM=$(kubectl get deploy -n kubeflow | grep -v NAME | wc -l) -until kubectl get pods -n kubeflow | grep Running | [[ $(wc -l) -eq $PODNUM ]]; do - echo Pod Status $(kubectl get pods -n kubeflow | grep "1/1" | wc -l)/$PODNUM - - sleep 10 - TIMEOUT=$(( TIMEOUT - 1 )) - if [[ $TIMEOUT -eq 0 ]];then - echo "NG" - kubectl get pods -n kubeflow - exit 1 - fi -done - -echo "All Katib components are running." -kubectl version -kubectl cluster-info -echo "Katib deployments" -kubectl -n kubeflow get deploy -echo "Katib services" -kubectl -n kubeflow get svc -echo "Katib pods" -kubectl -n kubeflow get pod - -mkdir -p ${GO_DIR} -cp -r . ${GO_DIR}/ -cp -r pkg/apis/manager/v1alpha2/python/* ${GO_DIR}/test/e2e/v1alpha2 -cd ${GO_DIR}/test/e2e/v1alpha2 -kubectl apply -f valid-experiment.yaml -kubectl delete -f valid-experiment.yaml -set +o errexit -kubectl apply -f invalid-experiment.yaml -if [ $? -ne 1 ]; then - echo "Failed to create invalid-experiment: return code $?" - exit 1 -fi -set -o errexit -kubectl -n kubeflow port-forward $(kubectl -n kubeflow get pod -o=name | grep katib-manager | grep -v katib-manager-rest |sed -e "s@pods\/@@") 6789:6789 & -echo "kubectl port-forward start" -sleep 5 -TIMEOUT=120 -until curl localhost:6789 || [ $TIMEOUT -eq 0 ]; do - sleep 5 - TIMEOUT=$(( TIMEOUT - 1 )) -done - -curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py -python get-pip.py -pip install -r test_requirements.txt -python test-katib-manager.py - -echo "Running e2e grid experiment" -export KUBECONFIG=$HOME/.kube/config -go run run-e2e-experiment.go ../../../examples/v1alpha2/grid-example.yaml -exit 0 diff --git a/test/unit/v1alpha2/crds/pytorchjob_v1.yaml b/test/unit/v1alpha2/crds/pytorchjob_v1.yaml deleted file mode 100644 index 697294be50f..00000000000 --- a/test/unit/v1alpha2/crds/pytorchjob_v1.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: pytorchjobs.kubeflow.org -spec: - group: kubeflow.org - version: v1 - scope: Namespaced - names: - kind: PyTorchJob - singular: pytorchjob - plural: pytorchjobs diff --git a/test/unit/v1alpha2/crds/tfjob_v1.yaml b/test/unit/v1alpha2/crds/tfjob_v1.yaml deleted file mode 100644 index 580ca69aa8c..00000000000 --- a/test/unit/v1alpha2/crds/tfjob_v1.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: tfjobs.kubeflow.org -spec: - group: kubeflow.org - version: v1 - scope: Namespaced - names: - kind: TFJob - singular: tfjob - plural: tfjobs diff --git a/test/workflows/components/params.libsonnet b/test/workflows/components/params.libsonnet index af81748dd06..101ad94db37 100644 --- a/test/workflows/components/params.libsonnet +++ b/test/workflows/components/params.libsonnet @@ -14,13 +14,5 @@ prow_env: "JOB_NAME=katib-v1alpha3-presubmit-test,JOB_TYPE=presubmit,PULL_NUMBER=374,REPO_NAME=k8s,REPO_OWNER=tensorflow,BUILD_NUMBER=6e32", versionTag: null, }, - "workflows-v1alpha2": { - bucket: "kubeflow-ci_temp", - name: "some-very-very-very-very-very-long-name-katib-v1alpha2-presubmit-test-374-6e32", - namespace: "kubeflow-test-infra", - registry: "gcr.io/kubbeflow-ci", - prow_env: "JOB_NAME=katib-v1alpha2-presubmit-test,JOB_TYPE=presubmit,PULL_NUMBER=374,REPO_NAME=k8s,REPO_OWNER=tensorflow,BUILD_NUMBER=6e32", - versionTag: null, - }, }, } diff --git a/test/workflows/components/workflows-v1alpha2.jsonnet b/test/workflows/components/workflows-v1alpha2.jsonnet deleted file mode 100644 index fee3eb85652..00000000000 --- a/test/workflows/components/workflows-v1alpha2.jsonnet +++ /dev/null @@ -1,14 +0,0 @@ -local params = std.extVar("__ksonnet/params").components["workflows-v1alpha2"]; - -local k = import 'k.libsonnet'; -local workflows = import 'workflows-v1alpha2.libsonnet'; -local namespace = params.namespace; - -// TODO(jlewi): Can we make name default so some random unique value? -// I didn't see any routines in the standard library for datetime or random. -local name = params.name; - -local prowEnv = workflows.parseEnv(params.prow_env); -local bucket = params.bucket; - -std.prune(k.core.v1.list.new([workflows.parts(namespace, name, params).e2e(prowEnv, bucket)])) diff --git a/test/workflows/components/workflows-v1alpha2.libsonnet b/test/workflows/components/workflows-v1alpha2.libsonnet deleted file mode 100644 index e409e662278..00000000000 --- a/test/workflows/components/workflows-v1alpha2.libsonnet +++ /dev/null @@ -1,370 +0,0 @@ -{ - // TODO(https://github.com/ksonnet/ksonnet/issues/222): Taking namespace as an argument is a work around for the fact that ksonnet - // doesn't support automatically piping in the namespace from the environment to prototypes. - - // convert a list of two items into a map representing an environment variable - // TODO(jlewi): Should we move this into kubeflow/core/util.libsonnet - listToMap:: function(v) - { - name: v[0], - value: v[1], - }, - - // Function to turn comma separated list of prow environment variables into a dictionary. - parseEnv:: function(v) - local pieces = std.split(v, ","); - if v != "" && std.length(pieces) > 0 then - std.map( - function(i) $.listToMap(std.split(i, "=")), - std.split(v, ",") - ) - else [], - - - // default parameters. - defaultParams:: { - project:: "kubeflow-ci", - zone:: "us-east1-d", - // Default registry to use. - //registry:: "gcr.io/" + $.defaultParams.project, - - // The image tag to use. - // Defaults to a value based on the name. - versionTag:: null, - - // The name of the secret containing GCP credentials. - gcpCredentialsSecretName:: "kubeflow-testing-credentials", - }, - - // overrides is a dictionary of parameters to provide in addition to defaults. - parts(namespace, name, overrides):: { - // Workflow to run the e2e test. - e2e(prow_env, bucket): - local params = $.defaultParams + overrides; - - // mountPath is the directory where the volume to store the test data - // should be mounted. - local mountPath = "/mnt/" + "test-data-volume"; - // testDir is the root directory for all data for a particular test run. - local testDir = mountPath + "/" + name; - // outputDir is the directory to sync to GCS to contain the output for this job. - local outputDir = testDir + "/output"; - local artifactsDir = outputDir + "/artifacts"; - local goDir = testDir + "/go"; - // Source directory where all repos should be checked out - local srcRootDir = testDir + "/src"; - // The directory containing the kubeflow/katib repo - local srcDir = srcRootDir + "/kubeflow/katib"; - local testWorkerImage = "gcr.io/kubeflow-ci/test-worker:v20190802-c6f9140-e3b0c4"; - local pythonImage = "python:3.6-jessie"; - // The name of the NFS volume claim to use for test files. - // local nfsVolumeClaim = "kubeflow-testing"; - local nfsVolumeClaim = "nfs-external"; - // The name to use for the volume to use to contain test data. - local dataVolume = "kubeflow-test-volume"; - local versionTag = if params.versionTag != null then - params.versionTag - else name; - - // The namespace on the cluster we spin up to deploy into. - local deployNamespace = "kubeflow"; - // The directory within the kubeflow_testing submodule containing - // py scripts to use. - local k8sPy = srcDir; - local kubeflowPy = srcRootDir + "/kubeflow/testing/py"; - - local project = params.project; - // GKE cluster to use - // We need to truncate the cluster to no more than 40 characters because - // cluster names can be a max of 40 characters. - // We expect the suffix of the cluster name to be unique salt. - // We prepend a z because cluster name must start with an alphanumeric character - // and if we cut the prefix we might end up starting with "-" or other invalid - // character for first character. - local cluster = - if std.length(name) > 40 then - "z" + std.substr(name, std.length(name) - 39, 39) - else - name; - local zone = params.zone; - local registry = params.registry; - local chart = srcDir + "/katib-chart"; - { - // Build an Argo template to execute a particular command. - // step_name: Name for the template - // command: List to pass as the container command. - buildTemplate(step_name, image, command):: { - name: step_name, - container: { - command: command, - image: image, - workingDir: srcDir, - env: [ - { - // Add the source directories to the python path. - name: "PYTHONPATH", - value: k8sPy + ":" + kubeflowPy, - }, - { - // Set the GOPATH - name: "GOPATH", - value: goDir, - }, - { - name: "CLUSTER_NAME", - value: cluster, - }, - { - name: "GCP_ZONE", - value: zone, - }, - { - name: "GCP_PROJECT", - value: project, - }, - { - name: "GCP_REGISTRY", - value: registry, - }, - { - name: "DEPLOY_NAMESPACE", - value: deployNamespace, - }, - { - name: "GOOGLE_APPLICATION_CREDENTIALS", - value: "/secret/gcp-credentials/key.json", - }, - { - name: "GIT_TOKEN", - valueFrom: { - secretKeyRef: { - name: "github-token", - key: "github_token", - }, - }, - }, - ] + prow_env, - volumeMounts: [ - { - name: dataVolume, - mountPath: mountPath, - }, - { - name: "github-token", - mountPath: "/secret/github-token", - }, - { - name: "gcp-credentials", - mountPath: "/secret/gcp-credentials", - }, - ], - }, - }, // buildTemplate - - apiVersion: "argoproj.io/v1alpha1", - kind: "Workflow", - metadata: { - name: name, - namespace: namespace, - }, - // TODO(jlewi): Use OnExit to run cleanup steps. - spec: { - entrypoint: "e2e", - volumes: [ - { - name: "github-token", - secret: { - secretName: "github-token", - }, - }, - { - name: "gcp-credentials", - secret: { - secretName: params.gcpCredentialsSecretName, - }, - }, - { - name: dataVolume, - persistentVolumeClaim: { - claimName: nfsVolumeClaim, - }, - }, - ], // volumes - // onExit specifies the template that should always run when the workflow completes. - onExit: "exit-handler", - templates: [ - { - name: "e2e", - steps: [ - [{ - name: "checkout", - template: "checkout", - }], - [ - { - name: "python-tests", - template: "python-tests", - }, - { - name: "build-suggestion-bo", - template: "build-suggestion-bo", - }, - { - name: "build-suggestion-nasrl", - template: "build-suggestion-nasrl", - }, - { - name: "build-manager", - template: "build-manager", - }, - { - name: "build-manager-rest", - template: "build-manager-rest", - }, - { - name: "build-katib-controller", - template: "build-katib-controller", - }, - { - name: "build-suggestion-random", - template: "build-suggestion-random", - }, - { - name: "build-suggestion-grid", - template: "build-suggestion-grid", - }, - { - name: "build-suggestion-hyperband", - template: "build-suggestion-hyperband", - }, - { - name: "build-earlystopping-median", - template: "build-earlystopping-median", - }, - { - name: "build-ui", - template: "build-ui", - }, - { - name: "create-pr-symlink", - template: "create-pr-symlink", - }, - //{ - // name: "build-tc-nasrl-cifar10", - // template: "build-tc-nasrl-cifar10", - //}, - ], - [ - { - name: "setup-cluster", - template: "setup-cluster", - }, - ], - [ - { - name: "run-e2e-tests", - template: "run-tests", - }, - ], - ], - }, - { - name: "exit-handler", - steps: [ - [{ - name: "teardown-cluster", - template: "teardown-cluster", - - }], - [{ - name: "copy-artifacts", - template: "copy-artifacts", - }], - ], - }, - { - name: "checkout", - container: { - command: [ - "/usr/local/bin/checkout.sh", - srcRootDir, - ], - env: prow_env + [{ - name: "EXTRA_REPOS", - value: "kubeflow/testing@HEAD", - }], - image: testWorkerImage, - volumeMounts: [ - { - name: dataVolume, - mountPath: mountPath, - }, - ], - }, - }, // checkout - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("setup-cluster",testWorkerImage, [ - "test/scripts/v1alpha2/create-cluster.sh", - ]), // setup cluster - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("python-tests", pythonImage, [ - "test/scripts/v1alpha2/python-tests.sh", - ]), // run python tests - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("run-tests", testWorkerImage, [ - "test/scripts/v1alpha2/run-tests.sh", - ]), // run tests - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("create-pr-symlink", testWorkerImage, [ - "python", - "-m", - "kubeflow.testing.prow_artifacts", - "--artifacts_dir=" + outputDir, - "create_pr_symlink", - "--bucket=" + bucket, - ]), // create-pr-symlink - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("teardown-cluster",testWorkerImage, [ - "test/scripts/v1alpha2/delete-cluster.sh", - ]), // teardown cluster - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("copy-artifacts", testWorkerImage, [ - "python", - "-m", - "kubeflow.testing.prow_artifacts", - "--artifacts_dir=" + outputDir, - "copy_artifacts", - "--bucket=" + bucket, - ]), // copy-artifacts - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-manager", testWorkerImage, [ - "test/scripts/v1alpha2/build-manager.sh", - ]), // build-manager - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-manager-rest", testWorkerImage, [ - "test/scripts/v1alpha2/build-manager-rest.sh", - ]), // build-manager-rest - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-katib-controller", testWorkerImage, [ - "test/scripts/v1alpha2/build-katib-controller.sh", - ]), // build-katib-controller - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-suggestion-random", testWorkerImage, [ - "test/scripts/v1alpha2/build-suggestion-random.sh", - ]), // build-suggestion-random - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-suggestion-grid", testWorkerImage, [ - "test/scripts/v1alpha2/build-suggestion-grid.sh", - ]), // build-suggestion-grid - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-suggestion-hyperband", testWorkerImage, [ - "test/scripts/v1alpha2/build-suggestion-hyperband.sh", - ]), // build-suggestion-hyperband - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-suggestion-bo", testWorkerImage, [ - "test/scripts/v1alpha2/build-suggestion-bo.sh", - ]), // build-suggestion-bo - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-suggestion-nasrl", testWorkerImage, [ - "test/scripts/v1alpha2/build-suggestion-nasrl.sh", - ]), // build-suggestion-nasrl - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-earlystopping-median", testWorkerImage, [ - "test/scripts/v1alpha2/build-earlystopping-median.sh", - ]), // build-earlystopping-median - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-ui", testWorkerImage, [ - "test/scripts/v1alpha2/build-ui.sh", - ]), // build-ui - $.parts(namespace, name, overrides).e2e(prow_env, bucket).buildTemplate("build-tc-nasrl-cifar10", testWorkerImage, [ - "test/scripts/v1alpha2/build-tc-nasrl-cifar10.sh", - ]), // build-tc-nasrl-cifar10 - ], // templates - }, - }, // e2e - }, // parts -}