From 4a4f24041ee6407f19f289307fe35607780c3bbd Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Thu, 26 Apr 2018 17:29:40 +0900 Subject: [PATCH 01/15] Refine API Signed-off-by: YujiOshima --- cmd/cli/get-study.go | 23 +- cmd/manager/Dockerfile | 2 +- cmd/manager/main.go | 447 ++-- dlk/.gitignore | 24 - dlk/Dockerfile | 10 - dlk/dlkctl/.gitignore | 1 - dlk/dlkctl/bash-cmp.go | 33 - dlk/dlkctl/del-lt.go | 129 -- dlk/dlkctl/del.go | 35 - dlk/dlkctl/dlkctl.go | 31 - dlk/dlkctl/get-lt.go | 177 -- dlk/dlkctl/get-lts.go | 168 -- dlk/dlkctl/get.go | 36 - dlk/dlkctl/logs.go | 196 -- dlk/dlkctl/root.go | 200 -- dlk/dlkctl/run.go | 511 ----- dlk/dlkctl/utils/dockerUtils.go | 438 ---- dlk/dlkctl/utils/flagUtils.go | 342 --- dlk/dlkctl/version.go | 41 - dlk/dlkmanager/.gitignore | 1 - dlk/dlkmanager/api/api.go | 29 - dlk/dlkmanager/bash-cmp.go | 33 - dlk/dlkmanager/client.go | 234 -- dlk/dlkmanager/configs/flags.go | 177 -- dlk/dlkmanager/datastore/dataStoreMap.go | 134 -- dlk/dlkmanager/datastore/learningTaskData.go | 63 - dlk/dlkmanager/delete.go | 54 - dlk/dlkmanager/dlkmanager.go | 95 - dlk/dlkmanager/get.go | 135 -- dlk/dlkmanager/jobs.go | 236 -- dlk/dlkmanager/learningTask.go | 476 ---- dlk/dlkmanager/post.go | 228 -- dlk/dlkmanager/put.go | 12 - dlk/dlkmanager/services.go | 90 - docs/MinikubeDemo/MinikubeDemo.md | 30 + docs/MinikubeDemo/deploy.sh | 12 + docs/MinikubeDemo/manifests/0-namespace.yaml | 4 + .../manifests/modeldb/backend/deployment.yaml | 32 + .../manifests/modeldb/backend/service.yaml | 17 + .../manifests/modeldb/db/deployment.yaml | 30 + .../manifests/modeldb/db/service.yaml | 17 + .../modeldb/frontend/deployment.yaml | 36 + .../manifests/modeldb/frontend/service.yaml | 18 + .../manifests/vizier/core/deployment.yaml | 37 + .../manifests/vizier/core/rbac.yaml | 37 + .../manifests/vizier/core/service.yaml | 19 + .../manifests/vizier/db/deployment.yaml | 37 + .../manifests/vizier/db/service.yaml | 17 + .../medianstopping/deployment.yaml | 30 + .../earlystopping/medianstopping/service.yaml | 17 + .../vizier/suggestion/grid/deployment.yaml | 30 + .../vizier/suggestion/grid/service.yaml | 17 + .../vizier/suggestion/random/deployment.yaml | 30 + .../vizier/suggestion/random/service.yaml | 17 + docs/MinikubeDemo/radom-suggest-demo.go | 172 ++ examples/random.yml | 55 - manifests/vizier/core/rbac.yaml | 14 +- pkg/api/api.pb.go | 1937 +++++++++-------- pkg/api/api.proto | 239 +- pkg/db/db_init.go | 55 +- pkg/db/interface.go | 436 +++- pkg/db/interface_test.go | 18 +- pkg/earlystopping/medianstopping.go | 103 +- pkg/earlystopping/types.go | 3 +- pkg/manager/modelstore/modeldb.go | 10 +- pkg/manager/worker/dlk/dlk.go | 301 --- pkg/manager/worker/interface.go | 70 +- pkg/manager/worker/kubernetes/kubernetes.go | 362 ++- pkg/manager/worker/nvdocker/nvidia-docker.go | 455 ---- pkg/suggestion/grid_service.go | 104 +- pkg/suggestion/hyperband_service.go | 522 +++-- pkg/suggestion/random_service.go | 74 +- pkg/suggestion/types.go | 4 +- scripts/build.sh | 11 +- 74 files changed, 3055 insertions(+), 7215 deletions(-) delete mode 100644 dlk/.gitignore delete mode 100644 dlk/Dockerfile delete mode 100644 dlk/dlkctl/.gitignore delete mode 100644 dlk/dlkctl/bash-cmp.go delete mode 100644 dlk/dlkctl/del-lt.go delete mode 100644 dlk/dlkctl/del.go delete mode 100644 dlk/dlkctl/dlkctl.go delete mode 100644 dlk/dlkctl/get-lt.go delete mode 100644 dlk/dlkctl/get-lts.go delete mode 100644 dlk/dlkctl/get.go delete mode 100644 dlk/dlkctl/logs.go delete mode 100644 dlk/dlkctl/root.go delete mode 100644 dlk/dlkctl/run.go delete mode 100644 dlk/dlkctl/utils/dockerUtils.go delete mode 100644 dlk/dlkctl/utils/flagUtils.go delete mode 100644 dlk/dlkctl/version.go delete mode 100644 dlk/dlkmanager/.gitignore delete mode 100644 dlk/dlkmanager/api/api.go delete mode 100644 dlk/dlkmanager/bash-cmp.go delete mode 100644 dlk/dlkmanager/client.go delete mode 100644 dlk/dlkmanager/configs/flags.go delete mode 100644 dlk/dlkmanager/datastore/dataStoreMap.go delete mode 100644 dlk/dlkmanager/datastore/learningTaskData.go delete mode 100644 dlk/dlkmanager/delete.go delete mode 100644 dlk/dlkmanager/dlkmanager.go delete mode 100644 dlk/dlkmanager/get.go delete mode 100644 dlk/dlkmanager/jobs.go delete mode 100644 dlk/dlkmanager/learningTask.go delete mode 100644 dlk/dlkmanager/post.go delete mode 100644 dlk/dlkmanager/put.go delete mode 100644 dlk/dlkmanager/services.go create mode 100644 docs/MinikubeDemo/MinikubeDemo.md create mode 100755 docs/MinikubeDemo/deploy.sh create mode 100644 docs/MinikubeDemo/manifests/0-namespace.yaml create mode 100644 docs/MinikubeDemo/manifests/modeldb/backend/deployment.yaml create mode 100644 docs/MinikubeDemo/manifests/modeldb/backend/service.yaml create mode 100644 docs/MinikubeDemo/manifests/modeldb/db/deployment.yaml create mode 100644 docs/MinikubeDemo/manifests/modeldb/db/service.yaml create mode 100644 docs/MinikubeDemo/manifests/modeldb/frontend/deployment.yaml create mode 100644 docs/MinikubeDemo/manifests/modeldb/frontend/service.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/core/deployment.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/core/rbac.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/core/service.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/db/deployment.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/db/service.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/service.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/suggestion/grid/deployment.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/suggestion/grid/service.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/suggestion/random/deployment.yaml create mode 100644 docs/MinikubeDemo/manifests/vizier/suggestion/random/service.yaml create mode 100644 docs/MinikubeDemo/radom-suggest-demo.go delete mode 100644 examples/random.yml delete mode 100644 pkg/manager/worker/dlk/dlk.go delete mode 100644 pkg/manager/worker/nvdocker/nvidia-docker.go diff --git a/cmd/cli/get-study.go b/cmd/cli/get-study.go index 70e4ad550de..50f4b04cb4b 100644 --- a/cmd/cli/get-study.go +++ b/cmd/cli/get-study.go @@ -44,40 +44,39 @@ func getStudy(cmd *cobra.Command, args []string) { defer conn.Close() c := api.NewManagerClient(conn) - req := &api.GetStudiesRequest{} - r, err := c.GetStudies(context.Background(), req) + req := &api.GetStudyListRequest{} + r, err := c.GetStudyList(context.Background(), req) if err != nil { log.Fatalf("GetStudy failed: %v", err) return } - var sis []*api.StudyInfo + result = []*api.StudyOverviews{} // Search study if Study ID or name is set if len(args) > 0 { - for _, si := range r.StudyInfos { + for _, si := range r.StudyOverviews { if utf8.RuneCountInString(args[0]) >= 7 { if strings.HasPrefix(si.StudyId, args[0]) { - sis = append(sis, si) + result = append(result, si) break } } if si.Name == args[0] { - sis = append(sis, si) + result = append(result, si) break } } } else { - sis = r.StudyInfos + result = r.StudyOverviews } w := new(tabwriter.Writer) w.Init(os.Stdout, 0, 8, 0, '\t', tabwriter.TabIndent) - fmt.Fprintln(w, "StudyID\tName\tOwner\tRunning\tCompleted") - for _, si := range sis { - fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%d\n", + fmt.Fprintln(w, "StudyID\tName\tOwner") + for _, si := range result { + fmt.Fprintf(w, "%s\t%s\t%sn", string([]rune(si.StudyId)[:7]), si.Name, si.Owner, - si.RunningTrialNum, - si.CompletedTrialNum) + ) } w.Flush() } diff --git a/cmd/manager/Dockerfile b/cmd/manager/Dockerfile index 1085552cb50..a25a0310d07 100644 --- a/cmd/manager/Dockerfile +++ b/cmd/manager/Dockerfile @@ -9,4 +9,4 @@ WORKDIR /app COPY --from=build-env /go/src/github.com/kubeflow/katib/cmd/manager/vizier-manager /app/ COPY --from=build-env /go/src/github.com/kubeflow/katib/pkg/manager/visualise / ENTRYPOINT ["./vizier-manager"] -CMD ["-w", "dlk"] +CMD ["-w", "kubernetes"] diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 4ed80b2001a..25500a46305 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -6,24 +6,17 @@ import ( "flag" "log" "net" - "strconv" "strings" - "time" pb "github.com/kubeflow/katib/pkg/api" kdb "github.com/kubeflow/katib/pkg/db" "github.com/kubeflow/katib/pkg/manager/modelstore" tbif "github.com/kubeflow/katib/pkg/manager/visualise/tensorboard" "github.com/kubeflow/katib/pkg/manager/worker" - dlkwif "github.com/kubeflow/katib/pkg/manager/worker/dlk" k8swif "github.com/kubeflow/katib/pkg/manager/worker/kubernetes" - nvdwif "github.com/kubeflow/katib/pkg/manager/worker/nvdocker" "google.golang.org/grpc" "google.golang.org/grpc/reflection" - - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/clientcmd" ) const ( @@ -47,308 +40,209 @@ type server struct { StudyChList map[string]studyCh } -func (s *server) saveCompletedModels(studyID string, conf *pb.StudyConfig) error { - ret, err := s.GetSavedModels(context.Background(), &pb.GetSavedModelsRequest{StudyName: conf.Name}) +func (s *server) CreateStudy(ctx context.Context, in *pb.CreateStudyRequest) (*pb.CreateStudyReply, error) { + if in == nil || in.StudyConfig == nil { + return &pb.CreateStudyReply{}, errors.New("StudyConfig is missing.") + } + studyID, err := dbIf.CreateStudy(in.StudyConfig) if err != nil { - log.Printf("GetSavedModels Err %v", err) - return err + return &pb.CreateStudyReply{}, err } - ts, err := dbIf.GetTrialList(studyID) + s.SaveStudy(ctx, &pb.SaveStudyRequest{ + StudyName: in.StudyConfig.Name, + Owner: in.StudyConfig.Owner, + Description: "StudyID: " + studyID, + }) + return &pb.CreateStudyReply{StudyId: studyID}, nil +} + +func (s *server) GetStudy(ctx context.Context, in *pb.GetStudyRequest) (*pb.GetStudyReply, error) { + sc, err := dbIf.GetStudyConfig(in.StudyId) + return &pb.GetStudyReply{StudyConfig: sc}, err +} + +func (s *server) GetStudyList(ctx context.Context, in *pb.GetStudyListRequest) (*pb.GetStudyListReply, error) { + sl, err := dbIf.GetStudyList() if err != nil { - log.Printf("GetTrials Err %v", err) - return err + return &pb.GetStudyListReply{}, err } - for _, t := range ts { - tid := t.TrialId - tst, err := dbIf.GetTrialStatus(tid) + result := make([]*pb.StudyOverview, len(sl)) + for i, id := range sl { + sc, err := dbIf.GetStudyConfig(id) if err != nil { - log.Printf("GetTrialStatus Err %v", err) - continue - } - isin := false - if tst == pb.TrialState_COMPLETED { - for _, m := range ret.Models { - if m.TrialId == tid { - isin = true - break - } - } - if !isin { - met := make([]*pb.Metrics, len(conf.Metrics)) - for i, mn := range conf.Metrics { - l, _ := dbIf.GetTrialLogs(tid, &kdb.GetTrialLogOpts{Name: mn}) - if len(l) > 0 { - met[i] = &pb.Metrics{Name: mn, Value: l[len(l)-1].Value} - } - } - t, _ := dbIf.GetTrial(tid) - s.SaveModel(context.Background(), &pb.SaveModelRequest{ - Model: &pb.ModelInfo{ - StudyName: conf.Name, - TrialId: tid, - Parameters: t.ParameterSet, - Metrics: met, - ModelPath: conf.Mount.Pvc + ":" + "/logs/" + conf.Mount.Path + "/" + studyID + "-" + tid, - }, - TensorBoard: true, - }) - log.Printf("Trial %v in Study %v is saved", tid, conf.Name) - } + return &pb.GetStudyListReply{}, err } + result[i].Name = sc.Name + result[i].Owner = sc.Owner + result[i].Id = id } - return nil + return &pb.GetStudyListReply{StudyOverviews: result}, err } - -func (s *server) trialIteration(conf *pb.StudyConfig, studyID string, sCh studyCh) error { - defer delete(s.StudyChList, studyID) - defer s.wIF.CleanWorkers(studyID) - tm := time.NewTimer(1 * time.Second) - ei := 0 - var err error - for _, ec := range conf.EarlyStoppingParameters { - if ec.Name == "CheckInterval" { - ei, err = strconv.Atoi(ec.Value) - if err != nil { - ei = 0 - } +func (s *server) GetTrials(ctx context.Context, in *pb.GetTrialsRequest) (*pb.GetTrialsReply, error) { + tl, err := dbIf.GetTrialList(in.StudyId) + return &pb.GetTrialsReply{Trials: tl}, err +} +func (s *server) GetSuggestions(ctx context.Context, in *pb.GetSuggestionsRequest) (*pb.GetSuggestionsReply, error) { + suggestAlgorithm := "" + if in.SuggestionAlgorithm != "" { + suggestAlgorithm = in.SuggestionAlgorithm + } else { + sc, err := dbIf.GetStudyConfig(in.StudyId) + if err != nil { + return &pb.GetSuggestionsReply{Trials: []*pb.Trial{}}, err } + suggestAlgorithm = sc.DefaultSuggestionAlgorithm } - if ei == 0 { - ei = defaultEarlyStopInterval + if suggestAlgorithm == "" { + return &pb.GetSuggestionsReply{Trials: []*pb.Trial{}}, errors.New("No suggest algorithm specified") } - estm := time.NewTimer(time.Duration(ei) * time.Second) - strtm := time.NewTimer(defaultSaveInterval * time.Second) - log.Printf("Study %v start.", studyID) - log.Printf("Study conf %v", conf) - for { - select { - case <-tm.C: - if conf.SuggestAlgorithm != "" { - err := s.wIF.CheckRunningTrials(studyID, conf.ObjectiveValueName) - if err != nil { - return err - } - r, err := s.SuggestTrials(context.Background(), &pb.SuggestTrialsRequest{StudyId: studyID, SuggestAlgorithm: conf.SuggestAlgorithm, Configs: conf}) - if err != nil { - log.Printf("SuggestTrials failed %v", err) - return err - } - if r.Completed { - log.Printf("Study %v completed.", studyID) - return s.saveCompletedModels(studyID, conf) - } else if len(r.Trials) > 0 { - for _, trial := range r.Trials { - trial.Status = pb.TrialState_PENDING - trial.StudyId = studyID - err = dbIf.CreateTrial(trial) - if err != nil { - log.Printf("CreateTrial failed %v", err) - return err - } - } - err = s.wIF.SpawnWorkers(r.Trials, studyID) - if err != nil { - log.Printf("SpawnWorkers failed %v", err) - return err - } - } - tm.Reset(1 * time.Second) - } - case <-strtm.C: - s.saveCompletedModels(studyID, conf) - strtm.Reset(defaultSaveInterval * time.Second) - - case <-estm.C: - ret, err := s.EarlyStopping(context.Background(), &pb.EarlyStoppingRequest{StudyId: studyID, EarlyStoppingAlgorithm: conf.EarlyStoppingAlgorithm}) - if err != nil { - log.Printf("Early Stopping Error: %v", err) - } else { - if len(ret.Trials) > 0 { - for _, t := range ret.Trials { - s.CompleteTrial(context.Background(), &pb.CompleteTrialRequest{StudyId: studyID, TrialId: t.TrialId, IsComplete: false}) - } - } - } - estm.Reset(time.Duration(ei) * time.Second) - case <-sCh.stopCh: - log.Printf("Study %v is stopped.", studyID) - for _, t := range s.wIF.GetRunningTrials(studyID) { - t.Status = pb.TrialState_KILLED - } - return s.saveCompletedModels(studyID, conf) - case m := <-sCh.addMetricsCh: - conf.Metrics = append(conf.Metrics, m) - } - } - return nil -} -func (s *server) CreateStudy(ctx context.Context, in *pb.CreateStudyRequest) (*pb.CreateStudyReply, error) { - if in == nil || in.StudyConfig == nil { - return &pb.CreateStudyReply{}, errors.New("StudyConfig is missing.") + conn, err := grpc.Dial("vizier-suggestion-"+suggestAlgorithm+":6789", grpc.WithInsecure()) + if err != nil { + return &pb.GetSuggestionsReply{Trials: []*pb.Trial{}}, err } - if in.StudyConfig.ObjectiveValueName == "" { - return &pb.CreateStudyReply{}, errors.New("Objective_Value_Name is required.") + defer conn.Close() + c := pb.NewSuggestionClient(conn) + r, err := c.GetSuggestions(ctx, in) + if err != nil { + return &pb.GetSuggestionsReply{Trials: []*pb.Trial{}}, err } - - studyID, err := dbIf.CreateStudy(in.StudyConfig) - if in.StudyConfig.SuggestAlgorithm != "" { - _, err = s.InitializeSuggestService( - ctx, - &pb.InitializeSuggestServiceRequest{ - StudyId: studyID, - SuggestAlgorithm: in.StudyConfig.SuggestAlgorithm, - SuggestionParameters: in.StudyConfig.SuggestionParameters, - Configs: in.StudyConfig, - }, - ) + for i := range r.Trials { + err = dbIf.CreateTrial(r.Trials[i]) if err != nil { - return &pb.CreateStudyReply{}, err + return &pb.GetSuggestionsReply{Trials: []*pb.Trial{}}, err } - } else { - log.Printf("Suggestion Algorithm is not set.") } + return r, nil +} - if in.StudyConfig.EarlyStoppingAlgorithm != "" && in.StudyConfig.EarlyStoppingAlgorithm != "none" { - conn, err := grpc.Dial("vizier-earlystopping-"+in.StudyConfig.EarlyStoppingAlgorithm+":6789", grpc.WithInsecure()) - if err != nil { - return &pb.CreateStudyReply{}, err - } - defer conn.Close() - c := pb.NewEarlyStoppingClient(conn) - _, err = c.SetEarlyStoppingParameter( - context.Background(), - &pb.SetEarlyStoppingParameterRequest{ - StudyId: studyID, - EarlyStoppingParameters: in.StudyConfig.EarlyStoppingParameters, - }, - ) - if err != nil { - return &pb.CreateStudyReply{}, err - } - } - sCh := studyCh{stopCh: make(chan bool), addMetricsCh: make(chan string)} - _, err = s.SaveStudy(ctx, &pb.SaveStudyRequest{StudyName: in.StudyConfig.Name, Owner: in.StudyConfig.Owner}) +func (s *server) RunTrial(ctx context.Context, in *pb.RunTrialRequest) (*pb.RunTrialReply, error) { + wid, err := dbIf.CreateWorker( + &pb.Worker{ + StudyId: in.StudyId, + TrialId: in.TrialId, + Runtime: in.Runtime, + Config: in.WorkerConfig, + }) if err != nil { - return &pb.CreateStudyReply{}, err + return &pb.RunTrialReply{WorkerId: wid}, err } - go s.trialIteration(in.StudyConfig, studyID, sCh) - s.StudyChList[studyID] = sCh - return &pb.CreateStudyReply{StudyId: studyID}, nil + err = s.wIF.SpawnWorker(wid, in.WorkerConfig) + return &pb.RunTrialReply{WorkerId: wid}, err } -func (s *server) StopStudy(ctx context.Context, in *pb.StopStudyRequest) (*pb.StopStudyReply, error) { - sc, ok := s.StudyChList[in.StudyId] - if !ok { - return &pb.StopStudyReply{}, errors.New("Study Id not found") - } - sc.stopCh <- false - return &pb.StopStudyReply{}, nil +func (s *server) StopWorkers(ctx context.Context, in *pb.StopWorkersRequest) (*pb.StopWorkersReply, error) { + err := s.wIF.StopWorkers(in.StudyId, in.WorkerIds, in.IsComplete) + return &pb.StopWorkersReply{}, err } -func (s *server) GetStudies(ctx context.Context, in *pb.GetStudiesRequest) (*pb.GetStudiesReply, error) { - ss := make([]*pb.StudyInfo, len(s.StudyChList)) - i := 0 - for sid := range s.StudyChList { - sc, _ := dbIf.GetStudyConfig(sid) - ss[i] = &pb.StudyInfo{ - StudyId: sid, - Name: sc.Name, - Owner: sc.Owner, - RunningTrialNum: int32(len(s.wIF.GetRunningTrials(sid))), - CompletedTrialNum: int32(len(s.wIF.GetCompletedTrials(sid))), - } - i++ - } - return &pb.GetStudiesReply{StudyInfos: ss}, nil +func (s *server) GetWorkers(ctx context.Context, in *pb.GetWorkersRequest) (*pb.GetWorkersReply, error) { + ws, err := dbIf.GetWorkerList(in.StudyId) + return &pb.GetWorkersReply{Workers: ws}, err } -func (s *server) InitializeSuggestService(ctx context.Context, in *pb.InitializeSuggestServiceRequest) (*pb.InitializeSuggestServiceReply, error) { - conn, err := grpc.Dial("vizier-suggestion-"+in.SuggestAlgorithm+":6789", grpc.WithInsecure()) - if err != nil { - log.Printf("could not connect: %v", err) - return &pb.InitializeSuggestServiceReply{}, err +func (s *server) GetShouldStopWorkers(ctx context.Context, in *pb.GetShouldStopWorkersRequest) (*pb.GetShouldStopWorkersReply, error) { + EarlyStoppingAlgorithm := "" + if in.EarlyStoppingAlgorithm != "" { + EarlyStoppingAlgorithm = in.EarlyStoppingAlgorithm + } else { + sc, err := dbIf.GetStudyConfig(in.StudyId) + if err != nil { + return &pb.GetShouldStopWorkersReply{}, err + } + EarlyStoppingAlgorithm = sc.DefaultEarlyStoppingAlgorithm } - defer conn.Close() - c := pb.NewSuggestionClient(conn) - req := &pb.SetSuggestionParametersRequest{StudyId: in.StudyId, SuggestionParameters: in.SuggestionParameters, Configs: in.Configs} - _, err = c.SetSuggestionParameters(context.Background(), req) - if err != nil { - log.Printf("Set Suggestion Parameter failed: %v", err) + if EarlyStoppingAlgorithm == "" { + return &pb.GetShouldStopWorkersReply{}, errors.New("No EarlyStopping Algorithm specified") } - return &pb.InitializeSuggestServiceReply{}, err -} - -func (s *server) SuggestTrials(ctx context.Context, in *pb.SuggestTrialsRequest) (*pb.SuggestTrialsReply, error) { - var suggestAlgorithm string - - // TODO: only a few columns are needed but GetStudyConfig does a full retrieval - study, err := dbIf.GetStudyConfig(in.StudyId) + conn, err := grpc.Dial("vizier-earlystopping-"+EarlyStoppingAlgorithm+":6789", grpc.WithInsecure()) if err != nil { - return nil, err + return &pb.GetShouldStopWorkersReply{}, err } + defer conn.Close() + c := pb.NewEarlyStoppingClient(conn) + return c.GetShouldStopWorkers(context.Background(), in) +} - if in.SuggestAlgorithm != "" { - suggestAlgorithm = in.SuggestAlgorithm - } else if study.SuggestAlgorithm != "" { - suggestAlgorithm = study.SuggestAlgorithm +func (s *server) GetMetrics(ctx context.Context, in *pb.GetMetricsRequest) (*pb.GetMetricsReply, error) { + var mNames []string + if len(in.MetricsNames) > 0 { + mNames = in.MetricsNames } else { - return &pb.SuggestTrialsReply{Completed: false}, errors.New("No suggest algorithm specified") + sc, err := dbIf.GetStudyConfig(in.StudyId) + log.Printf("dbIf.GetStudyConfig(in.StudyId) %v", err) + if err != nil { + return &pb.GetMetricsReply{}, err + } + mNames = sc.Metrics } - - conn, err := grpc.Dial("vizier-suggestion-"+suggestAlgorithm+":6789", grpc.WithInsecure()) + err := s.wIF.UpdateWorkerStatus(in.StudyId) if err != nil { - return &pb.SuggestTrialsReply{Completed: false}, err + return &pb.GetMetricsReply{}, err + log.Printf("s.wIF.UpdateWorkerStatus(in.StudyId)%v", err) } - - defer conn.Close() - c := pb.NewSuggestionClient(conn) - cts := s.wIF.GetCompletedTrials(in.StudyId) - rts := s.wIF.GetRunningTrials(in.StudyId) - req := &pb.GenerateTrialsRequest{StudyId: in.StudyId, Configs: in.Configs, CompletedTrials: cts, RunningTrials: rts} - r, err := c.GenerateTrials(context.Background(), req) - if err != nil { - return &pb.SuggestTrialsReply{Completed: false}, err + mls := make([]*pb.MetricsLogSet, len(in.WorkerIds)) + for i, w := range in.WorkerIds { + mls[i] = &pb.MetricsLogSet{ + WorkerId: w, + MetricsLogs: make([]*pb.MetricsLog, len(mNames)), + } + for j, m := range mNames { + ls, err := dbIf.GetWorkerLogs(w, &kdb.GetWorkerLogOpts{Name: m}) + log.Printf("dbIf.GetWorkerLogs(w, &kdb.GetWorkerLogOpts{Name: m}) %v", err) + if err != nil { + return &pb.GetMetricsReply{}, err + } + mls[i].MetricsLogs[j] = &pb.MetricsLog{ + Name: m, + Values: make([]string, len(ls)), + } + for k, l := range ls { + mls[i].MetricsLogs[j].Values[k] = l.Value + } + } } - - // TODO: do async - return &pb.SuggestTrialsReply{Trials: r.Trials, Completed: r.Completed}, nil + return &pb.GetMetricsReply{MetricsLogSets: mls}, nil } -func (s *server) CompleteTrial(ctx context.Context, in *pb.CompleteTrialRequest) (*pb.CompleteTrialReply, error) { - err := s.wIF.CompleteTrial(in.StudyId, in.TrialId, in.IsComplete) - return &pb.CompleteTrialReply{}, err -} - -func (s *server) EarlyStopping(ctx context.Context, in *pb.EarlyStoppingRequest) (*pb.EarlyStoppingReply, error) { - if in.EarlyStoppingAlgorithm == "" || in.EarlyStoppingAlgorithm == "none" { - return &pb.EarlyStoppingReply{}, nil - } - conn, err := grpc.Dial("vizier-earlystopping-"+in.EarlyStoppingAlgorithm+":6789", grpc.WithInsecure()) - if err != nil { - return &pb.EarlyStoppingReply{}, err +func (s *server) SetSuggestionParameters(ctx context.Context, in *pb.SetSuggestionParametersRequest) (*pb.SetSuggestionParametersReply, error) { + var err error + var id string + if in.ParamId == "" { + id, err = dbIf.SetSuggestionParam(in.SuggestionAlgorithm, in.StudyId, in.SuggestionParameters) + } else { + id = in.ParamId + err = dbIf.UpdateSuggestionParam(in.ParamId, in.SuggestionParameters) } + return &pb.SetSuggestionParametersReply{ParamId: id}, err +} - defer conn.Close() - c := pb.NewEarlyStoppingClient(conn) - req := &pb.ShouldTrialStopRequest{StudyId: in.StudyId} - r, err := c.ShouldTrialStop(context.Background(), req) - if err != nil { - return &pb.EarlyStoppingReply{}, err +func (s *server) SetEarlyStoppingParameters(ctx context.Context, in *pb.SetEarlyStoppingParametersRequest) (*pb.SetEarlyStoppingParametersReply, error) { + var err error + var id string + if in.ParamId == "" { + id, err = dbIf.SetEarlyStopParam(in.EarlyStoppingAlgorithm, in.StudyId, in.EarlyStoppingParameters) + } else { + id = in.ParamId + err = dbIf.UpdateEarlyStopParam(in.ParamId, in.EarlyStoppingParameters) } - - // TODO: do async - return &pb.EarlyStoppingReply{Trials: r.Trials}, nil + return &pb.SetEarlyStoppingParametersReply{ParamId: id}, err } -func (s *server) GetObjectValue(context.Context, *pb.GetObjectValueRequest) (*pb.GetObjectValueReply, error) { - return nil, errors.New("not implemented") +func (s *server) GetSuggestionParameters(ctx context.Context, in *pb.GetSuggestionParametersRequest) (*pb.GetSuggestionParametersReply, error) { + ps, err := dbIf.GetSuggestionParam(in.ParamId) + return &pb.GetSuggestionParametersReply{SuggestionParameters: ps}, err } -func (s *server) AddMeasurementToTrials(context.Context, *pb.AddMeasurementToTrialsRequest) (*pb.AddMeasurementToTrialsReply, error) { +func (s *server) GetEarlyStoppingParameters(ctx context.Context, in *pb.GetEarlyStoppingParametersRequest) (*pb.GetEarlyStoppingParametersReply, error) { + ps, err := dbIf.GetEarlyStopParam(in.ParamId) + return &pb.GetEarlyStoppingParametersReply{EarlyStoppingParameters: ps}, err +} - return &pb.AddMeasurementToTrialsReply{}, nil +func (s *server) StopStudy(ctx context.Context, in *pb.StopStudyRequest) (*pb.StopStudyReply, error) { + err := s.wIF.CleanWorkers(in.StudyId) + return &pb.StopStudyReply{}, err } func (s *server) SaveStudy(ctx context.Context, in *pb.SaveStudyRequest) (*pb.SaveStudyReply, error) { @@ -360,7 +254,7 @@ func (s *server) SaveModel(ctx context.Context, in *pb.SaveModelRequest) (*pb.Sa if in.TensorBoard { ret, err := s.GetSavedModel(ctx, &pb.GetSavedModelRequest{ StudyName: in.Model.StudyName, - TrialId: in.Model.TrialId, + WorkerId: in.Model.WorkerId, }) if err != nil { log.Printf("Save Model failed %v", err) @@ -373,10 +267,12 @@ func (s *server) SaveModel(ctx context.Context, in *pb.SaveModelRequest) (*pb.Sa log.Printf("Invalid ModelPath %v", mountconf) return &pb.SaveModelReply{}, errors.New("Invalid ModelPath " + in.Model.ModelPath) } - err = tbif.SpawnTensorBoard(in.Model.TrialId, in.Model.StudyName, namespace, ingressHost, mountconf[0], mountconf[1]) - if err != nil { - log.Printf("SpawnTB failed %v", err) - return &pb.SaveModelReply{}, err + if in.TensorBoard { + err = tbif.SpawnTensorBoard(in.Model.WorkerId, in.Model.StudyName, namespace, ingressHost, mountconf[0], mountconf[1]) + if err != nil { + log.Printf("SpawnTB failed %v", err) + return &pb.SaveModelReply{}, err + } } } } @@ -417,22 +313,11 @@ func main() { switch *workerType { case "kubernetes": log.Printf("Worker: kubernetes\n") - // Notice: Missing in the repo. - kc, err := clientcmd.BuildConfigFromFlags("", "/conf/kubeconfig") - if err != nil { - log.Fatal(err) - } - clientset, err := kubernetes.NewForConfig(kc) + kw, err := k8swif.NewKubernetesWorkerInterface(dbIf) if err != nil { - log.Fatal(err) + log.Fatalf("Failed to Create Kubernetes Worker: %v", err) } - pb.RegisterManagerServer(s, &server{wIF: k8swif.NewKubernetesWorkerInterface(clientset, dbIf), msIf: modelstore.NewModelDB("modeldb-backend", "6543"), StudyChList: make(map[string]studyCh)}) - case "dlk": - log.Printf("Worker: dlk\n") - pb.RegisterManagerServer(s, &server{wIF: dlkwif.NewDlkWorkerInterface("http://dlk-manager:1323", namespace), msIf: modelstore.NewModelDB("modeldb-backend", "6543"), StudyChList: make(map[string]studyCh)}) - case "nv-docker": - log.Printf("Worker: nv-docker\n") - pb.RegisterManagerServer(s, &server{wIF: nvdwif.NewNvDockerWorkerInterface(), msIf: modelstore.NewModelDB("modeldb-backend", "6543"), StudyChList: make(map[string]studyCh)}) + pb.RegisterManagerServer(s, &server{wIF: kw, msIf: modelstore.NewModelDB("modeldb-backend", "6543"), StudyChList: make(map[string]studyCh)}) default: log.Fatalf("Unknown worker") } diff --git a/dlk/.gitignore b/dlk/.gitignore deleted file mode 100644 index daf913b1b34..00000000000 --- a/dlk/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/dlk/Dockerfile b/dlk/Dockerfile deleted file mode 100644 index 6e4eff78afe..00000000000 --- a/dlk/Dockerfile +++ /dev/null @@ -1,10 +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/dlk/dlkmanager -RUN go build -o dlkmanager - -FROM alpine:3.7 -WORKDIR /app -COPY --from=build-env /go/src/github.com/kubeflow/katib/dlk/dlkmanager/dlkmanager /app/ -ENTRYPOINT ["./dlkmanager"] diff --git a/dlk/dlkctl/.gitignore b/dlk/dlkctl/.gitignore deleted file mode 100644 index 7c29cf1d025..00000000000 --- a/dlk/dlkctl/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dlkctl diff --git a/dlk/dlkctl/bash-cmp.go b/dlk/dlkctl/bash-cmp.go deleted file mode 100644 index 1133aff4924..00000000000 --- a/dlk/dlkctl/bash-cmp.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -const ( - bcmpfile = "dlk-cli.sh" -) - -// NewCommandBashCmp generates bash completion file -func NewCommandBashCmp() *cobra.Command { - - cmd := &cobra.Command{ - Use: "bash", - Short: "generate bash completion file", - Long: `generate bash completion file, which is copied under /etc/bash_completion.d/`, - Args: cobra.NoArgs, - Run: genBashCmpFile, - } - - return cmd -} - -func genBashCmpFile(cmd *cobra.Command, args []string) { - - root := cmd.Root() - root.GenBashCompletionFile(bcmpfile) - fmt.Println("Bash Completeion File (" + bcmpfile + ") is generated. Please copy it under /etc/bash_completion.d/ and reset your terminal to use autocompletion.") - -} diff --git a/dlk/dlkctl/del-lt.go b/dlk/dlkctl/del-lt.go deleted file mode 100644 index 39420eb4f2a..00000000000 --- a/dlk/dlkctl/del-lt.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright © 2017 NAME HERE -// -// 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 main - -import ( - "fmt" - "net/http" - "os" - - "github.com/kubeflow/katib/dlk/dlkctl/utils" - "github.com/spf13/cobra" -) - -//NewCommandDelLearningTasks generate run cmd -func NewCommandDelLearningTasks() *cobra.Command { - cmd := &cobra.Command{ - Use: "learningtask", - Args: cobra.ExactArgs(1), - Short: "Delete learning task", - Long: `Delete learning task`, - Aliases: []string{"lt"}, - Run: delLearningTasks, - } - - //set local flag - utils.AddNameSpaceFlag(cmd) - - //add subcommand - - return cmd -} - -//exec parameter -type delLearningTaskConfig struct { - params utils.Params - pf *PersistentFlags -} - -//Main Proceduer of delete learningTask command -func delLearningTasks(cmd *cobra.Command, args []string) { - - //parameter check - fmt.Println("*** CHECK PARAMS ***") - dec := delLearningTaskConfig{} - err := dec.checkParams(cmd, args) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - fmt.Println("completed") - - fmt.Println("*** exec parameters ***") - dec.displayParams() - - //send Request DELETE /learningTasks results is stored in array of datastore.LearningTaskInfo - fmt.Println("*** send Request ***") - - err = dec.sendDelRequest(args[0]) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - fmt.Println("completed") -} - -//checkParams check and del exec parameter -func (dec *delLearningTaskConfig) checkParams(cmd *cobra.Command, args []string) error { - - //check and del persistent flag volume - var pf *PersistentFlags - pf, err := CheckPersistentFlags() - if err != nil { - return err - } - - //check Flags using common parameter checker - var params utils.Params - params, err = utils.CheckFlags(cmd) - if err != nil { - return err - } - - //set config values - dec.pf = pf - dec.params = params - - return err -} - -//sendDelRequest send del learningTask request and return request results -func (dec *delLearningTaskConfig) sendDelRequest(lt string) error { - //set url - url := fmt.Sprintf("http://%s/learningTasks/%s/%s", dec.pf.endpoint, dec.params.Ns, lt) - - req, err := http.NewRequest("DELETE", url, nil) - if err != nil { - fmt.Printf("failed to create DELETE request: %s\n", err) - return err - } - - //send REST API Request - _, err = http.DefaultClient.Do(req) - if err != nil { - fmt.Println(err.Error()) - return err - } - - return err -} - -//displayParams display parameters used for sending delete learningTask request -func (dec *delLearningTaskConfig) displayParams() { - fmt.Printf("| %-30s : %s\n", "Search Namespace", dec.params.Ns) - fmt.Printf("| %-30s : %s\n", "dlkmanager endpoint", dec.pf.endpoint) -} diff --git a/dlk/dlkctl/del.go b/dlk/dlkctl/del.go deleted file mode 100644 index 60258dc3adb..00000000000 --- a/dlk/dlkctl/del.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright © 2017 NAME HERE -// -// 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 main - -import ( - "github.com/spf13/cobra" -) - -//NewCommandDel generate run cmd -func NewCommandDel() *cobra.Command { - cmd := &cobra.Command{ - Use: "del", - Short: "Delete resources", - Long: `Delete resources`, - } - - //set local flag - - //add subcommand - cmd.AddCommand(NewCommandDelLearningTasks()) - - return cmd -} diff --git a/dlk/dlkctl/dlkctl.go b/dlk/dlkctl/dlkctl.go deleted file mode 100644 index 03602380ee0..00000000000 --- a/dlk/dlkctl/dlkctl.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © 2017 NAME HERE -// -// 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 main - -import ( - "fmt" - "os" -) - -//Entry point -func main() { - //init command - dlkctl := NewRootCommand() - if err := dlkctl.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } - -} diff --git a/dlk/dlkctl/get-lt.go b/dlk/dlkctl/get-lt.go deleted file mode 100644 index 20bc6a26fd5..00000000000 --- a/dlk/dlkctl/get-lt.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright © 2017 NAME HERE -// -// 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 main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "os" - "sort" - - "github.com/kubeflow/katib/dlk/dlkmanager/datastore" - - "github.com/kubeflow/katib/dlk/dlkctl/utils" - "github.com/spf13/cobra" -) - -//NewCommandGetLearningTasks generate run cmd -func NewCommandGetLearningTask() *cobra.Command { - cmd := &cobra.Command{ - Use: "learningtask", - Args: cobra.ExactArgs(1), - Short: "Display LearningTask Info", - Long: `Display Information of a specified learningTask`, - Aliases: []string{"lt"}, - Run: getLearningTask, - } - - //set local flag - utils.AddNameSpaceFlag(cmd) - - //add subcommand - - return cmd -} - -//exec parameter -type getLearningTaskConfig struct { - params utils.Params - pf *PersistentFlags -} - -//Main Proceduer of get learningTasks command -func getLearningTask(cmd *cobra.Command, args []string) { - - //parameter check - fmt.Println("*** CHECK PARAMS ***") - gec := getLearningTaskConfig{} - err := gec.checkParams(cmd, args) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - fmt.Println("completed") - fmt.Println("*** exec parameters ***") - gec.displayParams() - - //send Request GET /learningTasks results is stored in array of datastore.LearningTaskInfo - fmt.Println("*** send Request ***") - rs, err := gec.sendGetRequest(args[0]) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - fmt.Println("completed") - - //show result - fmt.Println("*** result ***") - if rs.Name == "" { - fmt.Printf("learningTask %s does not exist\n", args[0]) - return - } - displayGetLearningTaskResult(rs) - -} - -//checkParams check and get exec parameter -func (gec *getLearningTaskConfig) checkParams(cmd *cobra.Command, args []string) error { - var err error - - //check and get persistent flag volume - var pf *PersistentFlags - pf, err = CheckPersistentFlags() - if err != nil { - return err - } - - //check Flags using common parameter checker - var params utils.Params - params, err = utils.CheckFlags(cmd) - if err != nil { - return err - } - - //set config values - gec.pf = pf - gec.params = params - - return err -} - -//sendGetRequest send get learningTask request and return request results -func (gec *getLearningTaskConfig) sendGetRequest(lt string) (*datastore.LearningTaskInfo, error) { - //set url - url := fmt.Sprintf("http://%s/learningTask/%s/%s", gec.pf.endpoint, gec.params.Ns, lt) - - //send REST API Request - resp, err := http.Get(url) - if err != nil { - fmt.Println(err.Error()) - return nil, err - } - defer resp.Body.Close() - - // get and decode response(json) - rs := &datastore.LearningTaskInfo{} - body, err := ioutil.ReadAll(resp.Body) - err = json.Unmarshal(body, rs) - if err != nil { - fmt.Println(err.Error()) - } - - return rs, err -} - -//displayParams display Result of the command -func displayGetLearningTaskResult(rs *datastore.LearningTaskInfo) { - //print body - format := "2006-01-02 15:04 MST" - fmt.Printf("| %-30s : %s\n", "learningTask", rs.Name) - fmt.Printf("| %-30s : %s\n", "NameSpace", rs.Ns) - fmt.Printf("| %-30s : %d\n", "GPU", rs.Gpu) - fmt.Printf("| %-30s : %d\n", "NrPS", rs.NrPS) - fmt.Printf("| %-30s : %d\n", "NrWorker", rs.NrWorker) - fmt.Printf("| %-30s : %s\n", "Created", rs.Created.Format(format)) - fmt.Printf("| %-30s : %s\n", "Status", rs.State) - fmt.Printf("| %-30s : %s\n", "PsImage", rs.PsImage) - fmt.Printf("| %-30s : %s\n", "WorkerImage", rs.WorkerImage) - fmt.Printf("| %-30s : %s\n", "Scheduler", rs.Scheduler) - fmt.Printf("| %-30s : %d\n", "Timeout", rs.Timeout) - fmt.Printf("| %-30s : %s\n", "PVC", rs.Pvc) - fmt.Printf("| %-30s : %d\n", "Priority", rs.Priority) - fmt.Printf("| %-30s : %s\n", "ExecTime", rs.ExecTime) - - //pod state - var keys []string - for key := range rs.PodState { - keys = append(keys, key) - } - sort.Strings(keys) - fmt.Printf("| %-30s :\n", "PodState") - for _, key := range keys { - fmt.Printf("| %-40s: %s\n", key, rs.PodState[key]) - } - -} - -//displayParams display parameters used for sending get learningTask request -func (gec *getLearningTaskConfig) displayParams() { - fmt.Printf("| %-30s : %s\n", "Search Namespace", gec.params.Ns) - fmt.Printf("| %-30s : %s\n", "dlkmanager endpoint", gec.pf.endpoint) - -} diff --git a/dlk/dlkctl/get-lts.go b/dlk/dlkctl/get-lts.go deleted file mode 100644 index 4e66e932d18..00000000000 --- a/dlk/dlkctl/get-lts.go +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright © 2017 NAME HERE -// -// 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 main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "os" - - "github.com/kubeflow/katib/dlk/dlkmanager/datastore" - - "github.com/kubeflow/katib/dlk/dlkctl/utils" - "github.com/spf13/cobra" -) - -//NewCommandGetLearningTasks generate run cmd -func NewCommandGetLearningTasks() *cobra.Command { - cmd := &cobra.Command{ - Use: "learningtasks", - Args: cobra.NoArgs, - Short: "Display LearningTasks List", - Long: `Display list of learningTasks`, - Aliases: []string{"lts"}, - Run: getLearningTasks, - } - - //set local flag - utils.AddNameSpaceFlag(cmd) - - //add subcommand - - return cmd -} - -//exec parameter -type getLearningTasksConfig struct { - params utils.Params - pf *PersistentFlags -} - -//Main Proceduer of get learningTasks command -func getLearningTasks(cmd *cobra.Command, args []string) { - - //parameter check - fmt.Println("*** CHECK PARAMS ***") - gec := getLearningTasksConfig{} - err := gec.checkParams(cmd, args) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - fmt.Println("completed") - fmt.Println("*** exec parameters ***") - gec.displayParams() - - //send Request GET /learningTasks results is stored in array of datastore.LearningTaskInfo - fmt.Println("*** send Request ***") - rs, err := gec.sendGetRequest() - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - //show result - fmt.Println("*** result ***") - displayGetLearningTasksResult(rs) - -} - -//checkParams check and get exec parameter -func (gec *getLearningTasksConfig) checkParams(cmd *cobra.Command, args []string) error { - var err error - - //check and get persistent flag volume - var pf *PersistentFlags - pf, err = CheckPersistentFlags() - if err != nil { - return err - } - - //check Flags using common parameter checker - var params utils.Params - params, err = utils.CheckFlags(cmd) - if err != nil { - return err - } - - //set config values - gec.pf = pf - gec.params = params - - return err -} - -//sendGetRequest send get learningTask request and return request results -func (gec *getLearningTasksConfig) sendGetRequest() ([]datastore.LearningTaskInfo, error) { - //set url - url := fmt.Sprintf("http://%s/learningTasks/%s", gec.pf.endpoint, gec.params.Ns) - - //send REST API Request - resp, err := http.Get(url) - if err != nil { - fmt.Println(err.Error()) - return nil, err - } - defer resp.Body.Close() - - // get and decode response(json) - rs := []datastore.LearningTaskInfo{} - body, err := ioutil.ReadAll(resp.Body) - err = json.Unmarshal(body, &rs) - if err != nil { - fmt.Println(err.Error()) - } - - return rs, err -} - -//displayParams display Result of the command -func displayGetLearningTasksResult(rs []datastore.LearningTaskInfo) { - - //print header - fmt.Printf("%-40s", "learningTask name") - fmt.Printf("%-10s", "namespace") - fmt.Printf("%-5s", "gpu") - fmt.Printf("%-5s", "NrPS") - fmt.Printf("%-10s", "NrWorker") - fmt.Printf("%-25s", "created") - fmt.Printf("%-10s", "priority") - fmt.Printf("%-15s", "status") - fmt.Printf("%-20s\n", "ExecTime") - - //print body - format := "2006-01-02 15:04 MST" - for _, i := range rs { - fmt.Printf("%-40s", i.Name) - fmt.Printf("%-10s", i.Ns) - fmt.Printf("%-5d", i.Gpu) - fmt.Printf("%-5d", i.NrPS) - fmt.Printf("%-10d", i.NrWorker) - fmt.Printf("%-25s", i.Created.Format(format)) - fmt.Printf("%-10d", i.Priority) - fmt.Printf("%-15s", i.State) - fmt.Printf("%-20s\n", i.ExecTime) - } -} - -//displayParams display parameters used for sending get learningTask request -func (gec *getLearningTasksConfig) displayParams() { - fmt.Printf("| %-30s : %s\n", "Search Namespace", gec.params.Ns) - fmt.Printf("| %-30s : %s\n", "dlkmanager endpoint", gec.pf.endpoint) - -} diff --git a/dlk/dlkctl/get.go b/dlk/dlkctl/get.go deleted file mode 100644 index fbecf3e8f18..00000000000 --- a/dlk/dlkctl/get.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright © 2017 NAME HERE -// -// 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 main - -import ( - "github.com/spf13/cobra" -) - -//NewCommandGet generate run cmd -func NewCommandGet() *cobra.Command { - cmd := &cobra.Command{ - Use: "get", - Short: "Display one or many resources", - Long: `list of resorces comannd can display includes: learningTasks`, - } - - //set local flag - - //add subcommand - cmd.AddCommand(NewCommandGetLearningTask()) - cmd.AddCommand(NewCommandGetLearningTasks()) - - return cmd -} diff --git a/dlk/dlkctl/logs.go b/dlk/dlkctl/logs.go deleted file mode 100644 index 03b63effe06..00000000000 --- a/dlk/dlkctl/logs.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright © 2017 NAME HERE -// -// 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 main - -import ( - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "os" - "time" - - "github.com/kubeflow/katib/dlk/dlkctl/utils" - "github.com/kubeflow/katib/dlk/dlkmanager/datastore" - "github.com/spf13/cobra" -) - -//LogsConfig :logs exec parameter -type LogsConfig struct { - params utils.Params - pf *PersistentFlags -} - -//NewCommandLogs generate logs cmd -func NewCommandLogs() *cobra.Command { - cmd := &cobra.Command{ - Use: "logs learningTaskName [ps|worker|all]", - Short: "Display LearningTasks' output Log", - Long: `Display LearningTasks' stderr and stdout Log`, - Aliases: []string{"log"}, - Run: getLogs, - Args: func(cmd *cobra.Command, args []string) error { - if len(args) == 0 { - return errors.New("must specify learningtask and jobType to display logs") - } else if len(args) == 1 { - return fmt.Errorf("jobType must be specified for learningTask \"%s\", choose one of: [ps worker all]", args[0]) - } else if len(args) == 2 { - switch args[1] { - case "ps": - case "worker": - case "all": - break - default: - return fmt.Errorf("argument \"%s\" is not vaild jobType, choose one of: [ps worker all]", args[1]) - } - } else if len(args) > 2 { - return errors.New("too may arguments") - } - return nil - }, - } - - //set local flag - utils.AddNameSpaceFlag(cmd) - utils.AddSinceTimeFlag(cmd) - //add subcommand - - return cmd -} - -// logs comand entry point -func getLogs(cmd *cobra.Command, args []string) { - - //parameter check - fmt.Println("*** CHECK PARAMS ***") - lc := LogsConfig{} - err := lc.checkParams(cmd, args) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - fmt.Println("completed") - - fmt.Println("*** GET LOGS ***") - - //sent GET request - rs, err := lc.sendGetRequest(args[0], args[1]) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - //print result - err = lc.printResult(rs, args[0]) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - -} - -//checkParams get and check cli input -func (lc *LogsConfig) checkParams(cmd *cobra.Command, args []string) error { - var err error - - //check persistent flag - var pf *PersistentFlags - pf, err = CheckPersistentFlags() - if err != nil { - return err - } - - //check Flags using common parameter checker - var params utils.Params - params, err = utils.CheckFlags(cmd) - if err != nil { - return err - } - - //set config values - lc.pf = pf - lc.params = params - - return err -} - -//sendGetRequest send get logs request and return request results -func (lc *LogsConfig) sendGetRequest(lt string, jobType string) (*datastore.LtLogInfo, error) { - //set url - str := fmt.Sprintf("http://%s/learningTasks/logs/%s/%s/%s", lc.pf.endpoint, lc.params.Ns, lt, jobType) - reqURL, err := url.Parse(str) - if err != nil { - return nil, err - } - - //if sinceTime is specified,set the value as querry parameter - if lc.params.SinceTime != "" { - parameters := url.Values{} - parameters.Add("sinceTime", lc.params.SinceTime) - reqURL.RawQuery = parameters.Encode() - } - //send REST API Request - fmt.Println(reqURL.String()) - resp, err := http.Get(reqURL.String()) - if err != nil { - fmt.Println(err.Error()) - return nil, err - } - defer resp.Body.Close() - - // get and decode response(json) - rs := &datastore.LtLogInfo{} - body, err := ioutil.ReadAll(resp.Body) - if resp.StatusCode != http.StatusOK { - return nil, errors.New(string(body[:])) - } - err = json.Unmarshal(body, rs) - if err != nil { - fmt.Println(err.Error()) - } - - return rs, err -} - -//printResult print Log request result -func (lc *LogsConfig) printResult(rs *datastore.LtLogInfo, lt string) error { - //check whether learningTask exist or not - if rs.LtName == "" { - return fmt.Errorf("learningTask \"%s\" not found", lt) - } - - srcLayout := "2006-01-02T15:04:05Z" - timezone := time.Local - - for i, pod := range rs.PodLogs { - // Job Name: learningtask-2018-2-6-16-0-52-ps-0 - fmt.Printf("Job Name: %s\n", pod.PodName) - - for _, log := range pod.Logs { - t, err := time.Parse(srcLayout, log.Time) - if err != nil { - fmt.Println(err) - } - - // [2018-02-06 07:04:14 UTC] starting a server - fmt.Printf("[%s] %s\n", t.In(timezone).Format(time.RFC3339), log.Value) - } - if i != len(rs.PodLogs)-1 { - fmt.Println("") - } - } - return nil -} diff --git a/dlk/dlkctl/root.go b/dlk/dlkctl/root.go deleted file mode 100644 index 2af47bb03ac..00000000000 --- a/dlk/dlkctl/root.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright © 2017 NAME HERE -// -// 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 main - -import ( - "errors" - "fmt" - "os" - "os/user" - - "github.com/spf13/cobra" - "github.com/spf13/viper" -) - -const ( - dconfig = ".dlkctlconfig" -) - -//PersistentFlags is used for pass persistent flag value to other command -type PersistentFlags struct { - cfgFile string - endpoint string - registry string - docker string - username string -} - -var cfgFile string - -// NewRootCommand represents the base command when called without any subcommands -func NewRootCommand() *cobra.Command { - - cmd := &cobra.Command{ - Use: "dlkctl", - Short: "dlk cli program", - Long: `this is dlk control cli program using cobra framework`, - } - - //initialize config - initFlag(cmd) - - //add command - //POST - cmd.AddCommand(NewCommandRun()) - //GET - cmd.AddCommand(NewCommandGet()) - cmd.AddCommand(NewCommandLogs()) - //PUT - - //DELETE - cmd.AddCommand(NewCommandDel()) - - //MISC - cmd.AddCommand(NewCommandVersion()) - - //Generate bash completion file - cmd.AddCommand(NewCommandBashCmp()) - - return cmd -} - -//CheckPersistentFlags check values is not empty and retun values -func CheckPersistentFlags() (*PersistentFlags, error) { - var err error - //get home dir for error message - i, _ := user.Current() - conf := i.HomeDir + "/" + dconfig - - //dlkmanager REST API endpoint - e := viper.GetString("endpoint") - if e == "" { - err = errors.New("dlkmanager REST API endpoint is not specified,use --endpoint or edit " + conf + " to provide value") - return nil, err - } - - //registry endpoint - r := viper.GetString("registry") - if r == "" { - err = errors.New("registry endpoint is not specified,use --registry or edit " + conf + " to provide value") - return nil, err - } - - //docker daemon API listen ip - d := viper.GetString("docker") - if d == "" { - err = errors.New("docker daeom API endpoint is not specified,use --docker or edit " + conf + " to provide value") - return nil, err - } - - //username - u := viper.GetString("user") - if u == "" { - err = errors.New("username is not specified,use --user or edit " + conf + " to provide value") - return nil, err - } - rtn := PersistentFlags{ - endpoint: e, - registry: r, - docker: d, - username: u, - } - - return &rtn, err -} - -//initFlag manage persistent flags -func initFlag(cmd *cobra.Command) { - cobra.OnInitialize(initConfig) - // add Pesistent flags - cmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.dlkctlconfig)") - cmd.PersistentFlags().String("endpoint", "localhost:1323", "dlkmanager API endpoint") - cmd.PersistentFlags().String("registry", "localhost:5000", "docker registry endpoint") - cmd.PersistentFlags().String("docker", "localhost:2375", "docker daemon API listen address") - cmd.PersistentFlags().String("user", "user", "username (default= $HOME/"+dconfig) - - //bind viper - viper.BindPFlag("endpoint", cmd.PersistentFlags().Lookup("endpoint")) - viper.BindPFlag("registry", cmd.PersistentFlags().Lookup("registry")) - viper.BindPFlag("docker", cmd.PersistentFlags().Lookup("docker")) - viper.BindPFlag("user", cmd.PersistentFlags().Lookup("user")) -} - -// initConfig reads in config file and ENV variables if set. -func initConfig() { - var c string - if cfgFile != "" { - // Use config file from the flag. - c = cfgFile - // check existance - _, err := os.Stat(c) - if err != nil { - fmt.Printf("ERROR file not found: %s\n", c) - os.Exit(1) - } - - } else { - // Find home directory. - u, err := user.Current() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - c = u.HomeDir + "/" + dconfig - - // check existance - _, err = os.Stat(c) - if err != nil { - fmt.Println("config file not found") - fmt.Printf("Generate Config File : %s\n", c) - createConfig(c) - fmt.Println("Edit the config and re-excute command") - os.Exit(0) - } - - } - - viper.SetConfigFile(c) - viper.SetConfigType("toml") - // If a config file is found, read it in. - if err := viper.ReadInConfig(); err == nil { - fmt.Println("Using config file:", viper.ConfigFileUsed()) - } else { - panic(err) - } - -} - -//createConfig generate config file -func createConfig(c string) { - //create new conig and write out info - w, err := os.Create(c) - if err != nil { - fmt.Printf("Cannot Generate configfile : %s", dconfig) - os.Exit(1) - } - user, err := user.Current() - - fmt.Fprintf(w, "#dlkmanager api server endpoint\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "endpoint", "localhost:1323") - fmt.Fprintf(w, "#docker registry address\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "registry", "localhost:5000") - fmt.Fprintf(w, "#docker daemon API listen address\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "docker", "localhost:2375") - fmt.Fprintf(w, "#username\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "user", user.Username) - -} diff --git a/dlk/dlkctl/run.go b/dlk/dlkctl/run.go deleted file mode 100644 index 0ff9db017a0..00000000000 --- a/dlk/dlkctl/run.go +++ /dev/null @@ -1,511 +0,0 @@ -// 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 main - -import ( - "archive/tar" - "bufio" - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "path/filepath" - "strings" - "time" - - "github.com/kubeflow/katib/dlk/dlkctl/utils" - "github.com/kubeflow/katib/dlk/dlkmanager/api" - - "github.com/spf13/cobra" -) - -const ( - dockerImage = "tensorflow/tensorflow" - dockerImageGpu = "tensorflow/tensorflow:latest-gpu" - tempDir = "/tmp/dlkctl" -) - -type runConfig struct { - script *os.File - params utils.Params - pf *PersistentFlags -} - -// Image Names -type ImageNames struct { - psImage string - workerImage string -} - -//NewCommandRun generate run cmd -func NewCommandRun() *cobra.Command { - cmd := &cobra.Command{ - Use: "run | --image | --psRawImage --workerRawImage ", - Args: cobra.MaximumNArgs(1), - Short: "create new-learningTask", - Long: `create new-learningTask`, - Run: runWorkflow, - } - - //set local flag - utils.AddImageFlag(cmd) - utils.AddNameSpaceFlag(cmd) - utils.AddNameFlag(cmd) - utils.AddSchedulerFlag(cmd) - utils.AddNrPsFlag(cmd) - utils.AddNrWorkerFlag(cmd) - utils.AddGpuFlag(cmd) - utils.AddPsRawImageFlag(cmd) - utils.AddWorkerRawImageFlag(cmd) - utils.AddDryRunFlag(cmd) - utils.AddBaseImageFlag(cmd) - utils.AddEntryPointFlag(cmd) - utils.AddParametersFlag(cmd) - utils.AddTimeoutFlag(cmd) - utils.AddPvcFlag(cmd) - utils.AddMountPathFlag(cmd) - utils.AddPriorityFlag(cmd) - //add subcommand - return cmd -} - -//Main Proceduer of run command -func runWorkflow(cmd *cobra.Command, args []string) { - - //parameter check,init parameters - //if neither workload file nor docker imagename is specified,then show help - fmt.Println("*** CHECK PARAMS ***") - rc := runConfig{} - err := rc.checkParams(cmd, args) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - cli := utils.NewDockerClient(rc.pf.docker, rc.pf.registry) - - exist := false - if rc.params.Image != "" { - //search the docker image on private registry - exist, err = cli.IsImageExistOnRegistry(rc.params.Image, rc.pf.username) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - fmt.Println("Completed") - } - - rc.displayParams() - - //image names which are used for pulling images - //from private registry or docker hub - var imgNames ImageNames - //if image name or raw image name is specified and workload file is not specified - if rc.script == nil { - // raw image is specified - if rc.params.PsRawImage != "" || rc.params.WorkerRawImage != "" { - // if raw image name is not specifed, default image is used - if rc.params.PsRawImage != "" { - imgNames.psImage = rc.params.PsRawImage - } else { - imgNames.psImage = dockerImage - } - if rc.params.WorkerRawImage != "" { - imgNames.workerImage = rc.params.WorkerRawImage - } else { - if rc.params.Gpu > 0 { - imgNames.workerImage = dockerImageGpu - } else { - imgNames.workerImage = dockerImage - } - } - // if image name is specified and image exist on registry - } else if exist { - imgNames.psImage = fmt.Sprintf("%s/%s/%s", cli.RegistryInterface, rc.pf.username, rc.params.Image) - imgNames.workerImage = imgNames.psImage - } else { - fmt.Printf("image: %s is not exists on the registry(%s)\n", rc.params.Image, cli.RegistryInterface) - os.Exit(1) - } - - } else { //if workload file is specified - //create docker images - fmt.Println("*** CREATE Docker Image ***") - imgNames, err = rc.createDockerImage(cli) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - fmt.Printf("%-30s : %s\n", "REPOSITORY NAME for NON-GPU", imgNames.psImage) - if rc.params.Gpu > 0 { - fmt.Printf("%-30s : %s\n", "REPOSITORY NAME for GPU", imgNames.workerImage) - } - fmt.Println("Completed") - //push images from local to private registry - fmt.Println("*** Push Docker Image To Registry ***") - if !rc.params.DryRun { - // push non-gpu image - err = cli.PushImage(imgNames.psImage) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - // push gpu image - if rc.params.Gpu > 0 { - err = cli.PushImage(imgNames.workerImage) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - } - } - fmt.Println("Completed") - - } - - //Send LearningTask Request to API server - fmt.Println("*** Send LearningTask Request to API Server ***") - fmt.Printf("LearningTask Name: %s\n", rc.params.Name) - err = rc.sendLearningTaskRequest(imgNames) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - fmt.Println("Completed. \ndone") -} - -//checkParams check args and flag vailidity and return runConfig struct -func (rc *runConfig) checkParams(cmd *cobra.Command, args []string) error { - var err error - - //check and get persistent flag volume - var pf *PersistentFlags - pf, err = CheckPersistentFlags() - if err != nil { - return err - } - - //check Flags using common parameter checker - var params utils.Params - params, err = utils.CheckFlags(cmd) - if err != nil { - return err - } - - // check if neither workload.py, image nor raw images is specified - if len(args) == 0 && params.Image == "" && - params.PsRawImage == "" && params.WorkerRawImage == "" { - err = errors.New("either workload.py, image name, or raw image names is required to execute request") - return err - } - - var script *os.File - - //get time in order to use in name auto-generation prcess - now := time.Now() - - //if workload file is specfied,then open it - if len(args) == 1 { - script, err = os.Open(args[0]) - if err != nil { - return err - } - } - - //check image name - //if image name is not specified, automatically generate it - //-yy-mm-dd-hh-MM-ss - if params.Image == "" && params.PsRawImage == "" && params.WorkerRawImage == "" { - - var s string - sname := filepath.Base(script.Name()) - i := strings.LastIndex(sname, ".") - if i != -1 { - s = sname[0:i] - } else { - s = sname - } - params.Image = fmt.Sprintf("%s-%d-%d-%d-%d-%d-%d", - s, now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second()) - } - - // if learningTask name is not specified,then generate - if params.Name == "" { - params.Name = fmt.Sprintf("%s-%d-%d-%d-%d-%d-%d", "learningtask", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second()) - } - - rc.script = script - rc.params = params - rc.pf = pf - - return err -} - -//createDockerImage build Docker images using docker REST API -//return: image names(ImageNames) -func (rc *runConfig) createDockerImage(cli *utils.DockerClient) (imgnm ImageNames, err error) { - - //push image names for ps and worker - var imageNames ImageNames - imageNames.psImage = fmt.Sprintf("%s/%s/%s", cli.RegistryInterface, rc.pf.username, rc.params.Image) - if rc.params.Gpu > 0 { - imageNames.workerImage = imageNames.psImage + ":latest-gpu" - } else { - imageNames.workerImage = imageNames.psImage - } - - //dry run - if rc.params.DryRun { - return imageNames, nil - } - - //TO build using Docker API,api require context file witch is tar file contains dockerfile - //generate dockerfile and compress it. this function return *File of generated tar - //build non-gpu image - gpuf := false - cctx, err := rc.generateDockerContext(gpuf) - if err != nil { - return ImageNames{}, err - } - - ccfile, err := os.Open(cctx) - if err != nil { - return ImageNames{}, err - } - - err = cli.BuildNewImage(imageNames.psImage, ccfile) - if err != nil { - return ImageNames{}, err - } - - //build gpu image - if rc.params.Gpu > 0 { - gpuf = true - // file descriptor is moved back to top of - // workload file - rc.script.Seek(0, os.SEEK_SET) - gctx, err := rc.generateDockerContext(gpuf) - if err != nil { - return ImageNames{}, err - } - - gcfile, err := os.Open(gctx) - if err != nil { - return ImageNames{}, err - } - - err = cli.BuildNewImage(imageNames.workerImage, gcfile) - if err != nil { - return ImageNames{}, err - } - } - - return imageNames, err -} - -//generateDockerContext create dockerfile and compress files required by build REST api -func (rc *runConfig) generateDockerContext(gpuf bool) (string, error) { - - //set temporary output dir,and generate it - dir := tempDir + "/" + rc.params.Image - if gpuf { - dir += "-g" - } - err := os.MkdirAll(dir, 0755) - if err != nil { - return "", err - } - - //create dockerfile - //set base image - //high priority: --baseImage flag - var base string - if rc.params.BaseImage != "" { - base = rc.params.BaseImage - - } else if rc.params.Gpu > 0 { //if #of Gpu is specified, - if gpuf { // for gpu, use tensorflow-with-gpu image - base = dockerImageGpu - } else { // for non-gpu, use tensorflow-non-gpu image - base = dockerImage - } - } else { // use tensorflow-non-gpu image - base = dockerImage - } - //create dockerfile - df := []string{} - df = append(df, "FROM "+base) - df = append(df, "MAINTAINER dlkctl") - df = append(df, "RUN mkdir /script") - df = append(df, "ADD "+filepath.Base(rc.script.Name())+" /script/") - df = append(df, "WORKDIR /script") - - file := dir + "/" + "Dockerfile" - ofile, err := os.Create(file) - if err != nil { - return "", err - } - - w := bufio.NewWriter(ofile) - for _, str := range df { - fmt.Fprintln(w, str) - } - w.Flush() - - //copy workload script to context dir - dst, err := os.Create(dir + "/" + filepath.Base(rc.script.Name())) - if err != nil { - return "", err - } - _, err = io.Copy(dst, rc.script) - dst.Close() - //compress it - path, err := makeTar(dir) - - return path, err -} - -//makeTar function compress a directory specified by passed argument into tar file and produce output within the pash -func makeTar(dirPath string) (string, error) { - //create output tar file - dstStr := dirPath + "/context.tar" - dst, err := os.Create(dstStr) - if err != nil { - return "", err - } - defer dst.Close() - - //get all items within src dir - files, err := ioutil.ReadDir(dirPath) - if err != nil { - return "", err - } - - //add each item into tar file - var fileWriter io.WriteCloser = dst - tarfileWriter := tar.NewWriter(fileWriter) - defer tarfileWriter.Close() - - for _, fileInfo := range files { - - //if items is dir then skip;otherwise add to tar file - if fileInfo.IsDir() || fileInfo.Name() == "context.tar" { - continue - } - file, err := os.Open(dirPath + string(filepath.Separator) + fileInfo.Name()) - if err != nil { - return "", err - } - - defer file.Close() - - // set tar header - header := new(tar.Header) - header.Name = fileInfo.Name() - header.Size = fileInfo.Size() - header.Mode = int64(fileInfo.Mode()) - header.ModTime = fileInfo.ModTime() - - err = tarfileWriter.WriteHeader(header) - if err != nil { - return "", err - } - - //copy file - _, err = io.Copy(tarfileWriter, file) - if err != nil { - return "", err - } - - } - - return dstStr, err -} - -//sendLearningTaskRequest send REST API Request using json -func (rc *runConfig) sendLearningTaskRequest(imageName ImageNames) error { - //set url - url := fmt.Sprintf("http://%s/learningTask", rc.pf.endpoint) - // construct json using runconfig parameter - j := api.LTConfig{ - PsImage: imageName.psImage, - WorkerImage: imageName.workerImage, - Ns: rc.params.Ns, - Scheduler: rc.params.Scheduler, - Name: rc.params.Name, - NrPS: rc.params.NrPs, - NrWorker: rc.params.NrWorker, - Gpu: rc.params.Gpu, - DryRun: rc.params.DryRun, - EntryPoint: rc.params.EntryPoint, - Parameters: rc.params.Parameters, - Timeout: rc.params.Timeout, - Pvc: rc.params.Pvc, - MountPath: rc.params.MountPath, - Priority: rc.params.Priority, - User: rc.pf.username, - } - - //encode json - b, err := json.Marshal(j) - if err != nil { - return err - } - //send REST API Request - resp, err := http.Post(url, "application/json", bytes.NewReader(b)) - if err != nil { - return err - } - defer resp.Body.Close() - - // TODO verbose - //fmt.Println("response Status:", resp.Status) - return err -} - -func (rc *runConfig) displayParams() { - fmt.Println("** exec parameters ************") - if rc.script != nil { - fmt.Printf("| %-30s : %s\n", "workload script", rc.script.Name()) - } - fmt.Printf("| %-30s : %s\n", "dlkmanager endpoint", rc.pf.endpoint) - fmt.Printf("| %-30s : %s\n", "docker daemon API endpoint", rc.pf.docker) - fmt.Printf("| %-30s : %s\n", "docker registry endpoint", rc.pf.registry) - fmt.Printf("| %-30s : %s\n", "user name", rc.pf.username) - if rc.params.Image != "" { - fmt.Printf("| %-30s : %s\n", "docker image", rc.params.Image) - } - if rc.params.BaseImage != "" { - fmt.Printf("| %-30s : %s\n", "docker base image", rc.params.BaseImage) - } - if rc.params.PsRawImage != "" { - fmt.Printf("| %-30s : %s\n", "PS Raw docker image", rc.params.PsRawImage) - } - if rc.params.WorkerRawImage != "" { - fmt.Printf("| %-30s : %s\n", "Worker Raw docker image", rc.params.WorkerRawImage) - } - if rc.params.EntryPoint != "" { - fmt.Printf("| %-30s : \"%s\"\n", "Entry Point", rc.params.EntryPoint) - } - - if rc.params.Parameters != "" { - fmt.Printf("| %-30s : \"%s\"\n", "container exec Parameters", rc.params.Parameters) - } - fmt.Printf("| %-30s : %s\n", "k8s namespace", rc.params.Ns) - fmt.Printf("| %-30s : %s\n", "learningTask name", rc.params.Name) - fmt.Printf("| %-30s : %s\n", "scheduler name", rc.params.Scheduler) - fmt.Printf("| %-30s : %d\n", "# of PS", rc.params.NrPs) - fmt.Printf("| %-30s : %d\n", "# of worker", rc.params.NrWorker) - fmt.Printf("| %-30s : %d\n", "gpu", rc.params.Gpu) - fmt.Printf("| %-30s : %t\n", "dry-run", rc.params.DryRun) - fmt.Printf("| %-30s : %d\n", "timeout", rc.params.Timeout) - fmt.Printf("| %-30s : %s\n", "persistent volume claim", rc.params.Pvc) - fmt.Printf("| %-30s : %s\n", "nfs mount path", rc.params.MountPath) - fmt.Printf("| %-30s : %d\n", "priority", rc.params.Priority) -} diff --git a/dlk/dlkctl/utils/dockerUtils.go b/dlk/dlkctl/utils/dockerUtils.go deleted file mode 100644 index 874c0034bc6..00000000000 --- a/dlk/dlkctl/utils/dockerUtils.go +++ /dev/null @@ -1,438 +0,0 @@ -package utils - -import ( - "crypto/tls" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "net/http" - "os" - "strings" -) - -//DockerImage is data domain for docker image -type DockerImage struct { - ID string `json:"Id"` - ParentID string `json:"ParentID"` - RepoTags []string `json:"RepoTags"` - RepoDigests []string `json:"RepoDigests"` - Created int `json:"Created"` - Size int `json:"Size"` - VirtualSize int `json:"VirtualSize"` - SharedSize int `json:"SharedSize"` - Containers int `json:"Containers"` -} - -//Tags is structure for store docker registry Search API result -type Tags struct { - SearchName string `json:"name"` - TagNames []string `json:"tags"` -} - -// Repositories is list of docker images on private registry -type Repositories struct { - ImgNames []string `json:"repositories"` -} - -//DockerClient provides docker operation functions -type DockerClient struct { - Cli *http.Client - DockerInterface string - RegistryInterface string -} - -// GetImageListOnRegistry method related constructor -const ( - Catalog = "/v2/_catalog" // catalog - N = "n=100" // Index and number to get images - Last = "last=" // last image name index - Errmsg = "Can't get last image name" // error message -) - -//NewDockerClient returns docker client Strunct instance -func NewDockerClient(dockerAPI string, registryAPI string) *DockerClient { - //insecure setting - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } - //init Client with default value - cli := &http.Client{Transport: tr} - dockerInterface := dockerAPI - registryInterface := registryAPI - rtn := DockerClient{ - Cli: cli, - DockerInterface: dockerInterface, - RegistryInterface: registryInterface, - } - - return &rtn -} - -// ListImage equals to docker images command -func (c *DockerClient) ListImage() ([]DockerImage, error) { - //construct REST API - url := "http://" + c.DockerInterface + "/images/json" - - //create request GET + url - req, _ := http.NewRequest("GET", url, nil) - - //send request - res, err := c.Cli.Do(req) - fmt.Println("SEND: " + url) - if err != nil { - return nil, err - } - defer res.Body.Close() - - //get result - body, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, err - } - - var Images []DockerImage - err = json.Unmarshal(body, &Images) - - return Images, err -} - -//SearchOnRegistry return tag list of the specified images on registry -func (c *DockerClient) SearchOnRegistry(image string, user string) (*Tags, error) { - url := fmt.Sprintf("https://%s/v2/%s/%s/tags/list", c.RegistryInterface, user, image) - - //create request GET + url - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - //send request - res, err := c.Cli.Do(req) - if err != nil { - return nil, err - } - - defer res.Body.Close() - - //get result - body, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, err - } - - rtn := &Tags{} - - err = json.Unmarshal(body, rtn) - if err != nil { - return nil, err - } - //TODO display when verbose flag is true - //fmt.Println("Search word: " + rtn.SearchName) - //for _, tag := range rtn.TagNames { - // fmt.Println(tag) - //} - - return rtn, err - -} - -//GetImageListOnRegistry returns list of all images on registry -func (c *DockerClient) GetImageListOnRegistry() ([]Repositories, error) { - - var err error - var last string // "&last=" - - // https:///v2/_catalog?n= - url := fmt.Sprintf("https://%s", c.RegistryInterface) - url += Catalog + "?" + N - - rtn := []Repositories{} // image list - - for { - //create request GET + url - req, err := http.NewRequest("GET", url+last, nil) - if err != nil { - return nil, err - } - - //send request - res, err := c.Cli.Do(req) - if err != nil { - return nil, err - } - - defer res.Body.Close() - - //get result - body, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, err - } - - rep := &Repositories{} - - err = json.Unmarshal(body, rep) - if err != nil { - return nil, err - } - - rtn = append(rtn, *rep) - - // if there are no images to get on registry any more, - // finish to get ones - if len(res.Header["Link"]) == 0 { - break - } - - // if there are still images to get on registry, - // retrieve last image name from GET response - for _, l := range res.Header["Link"] { - - if strings.Contains(l, Catalog) && - strings.Contains(l, Last) && - strings.Contains(l, N) && - strings.Contains(l, "rel=\"next\"") { - - fr := strings.LastIndex(l, Last) - if fr == -1 { - err = errors.New(Errmsg) - return nil, err - } - fr += len(Last) - - to := strings.LastIndex(l, "&"+N) - if to == -1 { - err = errors.New(Errmsg) - return nil, err - } - - img := l[fr:to] - - img = strings.Replace(img, "%2F", "/", 1) - - last = "&" + Last + img - - break - } - } - } - return rtn, err -} - -//IsImageExistOnRegistry check whether image exist on registry or not -func (c *DockerClient) IsImageExistOnRegistry(imageName string, user string) (bool, error) { - - var tag string - var image string - - //init return valiable with false. set it true when image found on registry - exist := false - - //check imageName contains both image name and tag - i := strings.LastIndex(imageName, ":") - //get imagename and tag name from passed arg - if i < 0 { - image = imageName - tag = "latest" - } else { - image = imageName[:i] - tag = imageName[i+1:] - } - // search images using user/image as search keyword and get list of tags - tags, err := c.SearchOnRegistry(image, user) - if err != nil { - return false, err - } - - //check expected tag exist or not. on exists,return true - for _, item := range tags.TagNames { - if item == tag { - exist = true - break - } - } - - return exist, err -} - -//IsImageExistLocally check whether image exist locally or not -func (c *DockerClient) IsImageExistLocally(target string) (bool, error) { - - //if passed name not contains tag,then add :latest - t := target - if !strings.Contains(target, ":") { - t += ":latest" - } - - //get local docker image list - list, err := c.ListImage() - if err != nil { - return false, err - } - rtn := false - - // if list contains target(t) image,then return true - for _, images := range list { - for _, image := range images.RepoTags { - if image == t { - rtn = true - break - } - - } - - } - return rtn, err -} - -//BuildNewImage generate new docker image based on passed parameter -func (c *DockerClient) BuildNewImage(tag string, contextTar *os.File) error { - //set url - url := fmt.Sprintf("http://%s/build?t=%s", c.DockerInterface, tag) - - //send build request - //TODO display when verbose flag is true - //fmt.Printf("BUILD REQUEST: %s, binary: %s\n", url, contextTar.Name()) - resp, err := http.Post(url, "binary/octet-stream", contextTar) - if err != nil { - return err - } - defer resp.Body.Close() - - //Read result - s, err := ioutil.ReadAll(resp.Body) - //error handling - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("docker build error: context=%s \n%s", contextTar.Name(), s) - } - return err -} - -//PushImage push image -func (c *DockerClient) PushImage(image string) error { - url := fmt.Sprintf("http://%s/images/%s/push", c.DockerInterface, image) - auth := fmt.Sprintf("{serveraddress: %s}", c.RegistryInterface) - - //create request GET + url - //TODO display when verbose flag is true - //fmt.Println("PUSH: " + url) - req, err := http.NewRequest("POST", url, nil) - if err != nil { - return err - } - - req.Header.Set("X-Registry-Auth", auth) - - //send request - res, err := c.Cli.Do(req) - if err != nil { - return err - } - defer res.Body.Close() - - //get result - _, err = ioutil.ReadAll(res.Body) - //TODO verbose - if res.StatusCode != http.StatusOK { - err = fmt.Errorf("Push Error: status code: %s, url:%s", res.Status, url) - } else { - fmt.Println(res.Status) - } - - return err - -} - -//GetImageDigest return passed docker image digest on registry -func (c *DockerClient) GetImageDigest(image string, tag string) (string, error) { - - //remove "/" if imagename start with it - img := image - if strings.HasPrefix(image, "/") { - img = image[1:] - } - - //remove ":" if tagname start with it - tg := tag - if strings.HasPrefix(image, ":") { - img = image[1:] - } - - url := fmt.Sprintf("https://%s/v2/%s/manifests/%s", c.RegistryInterface, img, tg) - req, _ := http.NewRequest("GET", url, nil) - - //header - req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json") - //send request - res, err := c.Cli.Do(req) - if err != nil { - return "", err - } - defer res.Body.Close() - - //check response code - if res.StatusCode != http.StatusOK { - fmt.Println(url) - return "", fmt.Errorf("no such image, image: %s tag: %s", img, tg) - } - - digest := res.Header.Get("Docker-Content-Digest") - - //should be dead code - if digest == "" { - return "", fmt.Errorf("No 'Docker-Content-Digest' in response header, url: %s", url) - } - - return digest, nil -} - -//SeparateTagrepoIntoImageAndTag return image name and tag separately -func (c *DockerClient) SeparateTagrepoIntoImageAndTag(repotag string) (string, string) { - - tag := "" - image := repotag - - //remove registry url - if strings.HasPrefix(image, c.RegistryInterface) { - image = image[len(c.RegistryInterface):] - } - - if strings.HasPrefix(image, "/") { - image = image[1:] - } - - fmt.Println(image) - i := strings.Index(image, ":") - if i != -1 { - tag = image[i+1:] - image = image[:i] - } - - return image, tag -} - -//GetImageDigest return passed docker image digest on registry -func (c *DockerClient) DeleteImage(image string, digest string) error { - //remove "/" if imagename start with it - img := image - if strings.HasPrefix(image, "/") { - img = image[1:] - } - - url := fmt.Sprintf("https://%s/v2/%s/manifests/%s", c.RegistryInterface, img, digest) - req, _ := http.NewRequest("DELETE", url, nil) - - //send request - res, err := c.Cli.Do(req) - if err != nil { - return err - } - defer res.Body.Close() - - //check response code - if res.StatusCode != http.StatusAccepted { - return fmt.Errorf("delete image error image: %s digest:%s code: %s", img, digest, res.Status) - } - - return nil -} diff --git a/dlk/dlkctl/utils/flagUtils.go b/dlk/dlkctl/utils/flagUtils.go deleted file mode 100644 index 45bd907526b..00000000000 --- a/dlk/dlkctl/utils/flagUtils.go +++ /dev/null @@ -1,342 +0,0 @@ -package utils - -import ( - "fmt" - "os" - "path/filepath" - "time" - - "github.com/spf13/cobra" -) - -//Params is struct for containing flag parameter value -type Params struct { - Image string - Ns string - Name string - Scheduler string - NrPs int - NrWorker int - Gpu int - DryRun bool - PsRawImage string - WorkerRawImage string - BaseImage string - EntryPoint string - Parameters string - Timeout int - Pvc string - MountPath string - Priority int - SinceTime string - GpuImg bool -} - -const ( - PrioMIN = 0 // lowest priority - PrioMAX = 100 // highest priority -) - -//CheckFlags checks flags value vailidity and return these value -func CheckFlags(cmd *cobra.Command) (p Params, er error) { - var rtn = Params{} - var err error - e := false - - //image parameter - if cmd.Flags().Lookup("image") != nil { - rtn.Image, err = cmd.Flags().GetString("image") - if err != nil { - return Params{}, err - } - } - - //namespace parameter - if cmd.Flags().Lookup("ns") != nil { - rtn.Ns, err = cmd.Flags().GetString("ns") - if err != nil { - return Params{}, err - } - } - - //learning task name parameter - if cmd.Flags().Lookup("name") != nil { - rtn.Name, err = cmd.Flags().GetString("name") - if err != nil { - return Params{}, err - } - } - - //scheduler parameter - if cmd.Flags().Lookup("scheduler") != nil { - rtn.Scheduler, err = cmd.Flags().GetString("scheduler") - if err != nil { - return Params{}, err - } - } - - //number of parameter server - if cmd.Flags().Lookup("nrPs") != nil { - rtn.NrPs, err = cmd.Flags().GetInt("nrPs") - if err != nil { - return Params{}, err - } else if rtn.NrPs < 0 { - fmt.Println("flag: --nrPs must be equal to or greater than 0") - e = true - } - } - - //number of worker parameter - if cmd.Flags().Lookup("nrWorker") != nil { - rtn.NrWorker, err = cmd.Flags().GetInt("nrWorker") - if err != nil { - return Params{}, err - } else if rtn.NrWorker < 1 { - fmt.Println("flag: --nrWorker must be greater than 0") - e = true - } - } - - // number of worker must be 1 - // in case number of parameter server is 0 - if rtn.NrPs == 0 && rtn.NrWorker > 1 { - fmt.Println("flag: --nrWorker must be 1 in case --nrPs is 0") - e = true - } - - //Gpu parameter - if cmd.Flags().Lookup("gpu") != nil { - rtn.Gpu, err = cmd.Flags().GetInt("gpu") - if err != nil { - return Params{}, err - } else if rtn.Gpu < 0 { - fmt.Println("flag: --gpu must be equal to or greater than 0") - e = true - } - } - - // timeout parameter - if cmd.Flags().Lookup("timeout") != nil { - rtn.Timeout, err = cmd.Flags().GetInt("timeout") - if err != nil { - return Params{}, err - } - } - - // persistent volume claim parameter - if cmd.Flags().Lookup("pvc") != nil { - rtn.Pvc, err = cmd.Flags().GetString("pvc") - if err != nil { - return Params{}, err - } - } - - // nfs mount path parameter - if cmd.Flags().Lookup("mpath") != nil { - rtn.MountPath, err = cmd.Flags().GetString("mpath") - if err != nil { - return Params{}, err - } - // Check whether the path is absolute - if rtn.MountPath != "" && !filepath.IsAbs(rtn.MountPath) { - fmt.Println("flag: --mpath specified path is not absolute") - e = true - } - } - - // Without persistent volume claim, nfs mount path is specified only - if rtn.Pvc == "" && rtn.MountPath != "" { - fmt.Println("flag: --mpath must be specified along with persistent volume claim") - e = true - } - - // priority parameter - if cmd.Flags().Lookup("priority") != nil { - rtn.Priority, err = cmd.Flags().GetInt("priority") - if err != nil { - return Params{}, err - } else if rtn.Priority < PrioMIN || rtn.Priority > PrioMAX { - fmt.Println("flag: --priority must be from 0(lowest) to 100(highest)") - e = true - } - } - - //ps raw image parameter - if cmd.Flags().Lookup("psRawImage") != nil { - rtn.PsRawImage, err = cmd.Flags().GetString("psRawImage") - if err != nil { - return Params{}, err - } - } - - //worker raw image parameter - if cmd.Flags().Lookup("workerRawImage") != nil { - rtn.WorkerRawImage, err = cmd.Flags().GetString("workerRawImage") - if err != nil { - return Params{}, err - } - } - - //both image and raw images can't be specified at the same time - if rtn.Image != "" && (rtn.PsRawImage != "" || rtn.WorkerRawImage != "") { - fmt.Println("don't specify both --image and --ps/workerRawImage") - e = true - } - - //docker base image parameter - if cmd.Flags().Lookup("baseImage") != nil { - rtn.BaseImage, err = cmd.Flags().GetString("baseImage") - if err != nil { - return Params{}, err - } - } - - //docker container entry point - if cmd.Flags().Lookup("entryPoint") != nil { - rtn.EntryPoint, err = cmd.Flags().GetString("entryPoint") - if err != nil { - return Params{}, err - } - } - - //docker container exec parameters - if cmd.Flags().Lookup("parameters") != nil { - rtn.Parameters, err = cmd.Flags().GetString("parameters") - if err != nil { - return Params{}, err - } - } - - //gpu image parameter - if cmd.Flags().Lookup("gpu-image") != nil { - rtn.GpuImg, err = cmd.Flags().GetBool("gpu-image") - if err != nil { - return Params{}, err - } - } - - //DryRun parameter - if cmd.Flags().Lookup("dry-run") != nil { - rtn.DryRun, err = cmd.Flags().GetBool("dry-run") - if err != nil { - return Params{}, err - } else if e { - cmd.Help() - os.Exit(1) - } - } - - //start time of duration specification - if cmd.Flags().Lookup("sinceTime") != nil { - rtn.SinceTime, err = cmd.Flags().GetString("sinceTime") - //Require RFC3339 formated string - if rtn.SinceTime != "" { - _, err := time.Parse(time.RFC3339, rtn.SinceTime) - if err != nil { - return Params{}, err - } - } - } - - return rtn, err -} - -// AddDryRunFlag set dry run flag to passed command -func AddDryRunFlag(cmd *cobra.Command) { - cmd.Flags().Bool("dry-run", false, "only print the object that would be sent,without sending it") -} - -// AddImageFlag set docker image name for learning task -func AddImageFlag(cmd *cobra.Command) { - cmd.Flags().String("image", "", "set docker image name") -} - -// AddNameSpaceFlag identify which namespace in k8s request will be deployed -func AddNameSpaceFlag(cmd *cobra.Command) { - cmd.Flags().String("ns", "default", "set namespace in which request deploy") -} - -// AddNameFlag set learning task name -func AddNameFlag(cmd *cobra.Command) { - cmd.Flags().String("name", "", "set learning task name,if not present,dlkctl generate it automatically") -} - -// AddSchedulerFlag set scheduler name which pick up and assign the dlk request to node -func AddSchedulerFlag(cmd *cobra.Command) { - cmd.Flags().String("scheduler", "dlk", "set scheduler name which pick up and assign the dlk request to node") -} - -// AddNrPsFlag set number of parameter server -func AddNrPsFlag(cmd *cobra.Command) { - cmd.Flags().Int("nrPs", 1, "set number of PS") -} - -// AddNrWorkerFlag set number of worker server -func AddNrWorkerFlag(cmd *cobra.Command) { - cmd.Flags().Int("nrWorker", 1, "set number of Worker") -} - -//AddGpuFlag enable use of GPU tensorflow Image and set limit number of gpu -func AddGpuFlag(cmd *cobra.Command) { - cmd.Flags().Int("gpu", 0, "use gpu tensorflow image and set limit number of gpu ") -} - -// AddPsRawImageFlag set ps docker image name (directly passed to job objects) -func AddPsRawImageFlag(cmd *cobra.Command) { - cmd.Flags().String("psRawImage", "", "set ps docker image name (directly passed to job objects)") -} - -// AddWorkerRawImageFlag set worker docker image name (directly passed to job objects) -func AddWorkerRawImageFlag(cmd *cobra.Command) { - cmd.Flags().String("workerRawImage", "", "set worker docker image name (directly passed to job objects)") -} - -//AddTypeFlag add a flag which filter output by their role -func AddTypeFlag(cmd *cobra.Command) { - cmd.Flags().String("type", "", "expected value: [worker,ps]. display only worker or ps related object") -} - -//AddBaseImageFlag add a flag which specify can docker base image -func AddBaseImageFlag(cmd *cobra.Command) { - cmd.Flags().String("baseImage", "", "docker base image") -} - -//AddEntryPointFlag add a flag which specify docker base image -func AddEntryPointFlag(cmd *cobra.Command) { - cmd.Flags().String("entryPoint", "", "docker container entry point") -} - -//AddParametersFlag add a flag which specify docker container cmd parameter -func AddParametersFlag(cmd *cobra.Command) { - cmd.Flags().String("parameters", "", "docker container exec parameter") -} - -//AddTimeoutFlag add a flag which specify timeout of each learning task -func AddTimeoutFlag(cmd *cobra.Command) { - cmd.Flags().Int("timeout", 0, "timeout of each learning task") -} - -//AddPvcFlag add a flag which specify persistent volume claim -func AddPvcFlag(cmd *cobra.Command) { - cmd.Flags().String("pvc", "", "persistent volume claim") -} - -//AddMountPathFlag add a flag which specify nfs mount path -func AddMountPathFlag(cmd *cobra.Command) { - cmd.Flags().String("mpath", "", "nfs mount path (dafault \"/default-path\")") -} - -//AddPriorityFlag add a flag which specify learning task priority -func AddPriorityFlag(cmd *cobra.Command) { - cmd.Flags().Int("priority", 0, "learning task priority (default 0 | 0:lowest - 100:highest)") -} - -//AddSinceTimeFlag add a flag which specify start time of duration specification -func AddSinceTimeFlag(cmd *cobra.Command) { - cmd.Flags().String("sinceTime", "", "Only return logs after a specific time (RFC3339).defaults to all logs") -} - -//AddGpuImageFlag set a flag which specify whether gpu image is created or not -func AddGpuImageFlag(cmd *cobra.Command) { - cmd.Flags().Bool("gpu-image", false, "create docker image for gpu as well (dafault false)") -} diff --git a/dlk/dlkctl/version.go b/dlk/dlkctl/version.go deleted file mode 100644 index fcbf3036b27..00000000000 --- a/dlk/dlkctl/version.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright © 2017 NAME HERE -// -// 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 main - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -var version = "dlkctl v1.0" - -// NewCommandVersion return the version command -func NewCommandVersion() *cobra.Command { - - cmd := &cobra.Command{ - Use: "version", - Short: "display the version of dlkctl", - Long: `display the version of dlkctl`, - Args: cobra.NoArgs, - Run: displayVersion, - } - - return cmd -} - -func displayVersion(cmd *cobra.Command, args []string) { - fmt.Println(version) -} diff --git a/dlk/dlkmanager/.gitignore b/dlk/dlkmanager/.gitignore deleted file mode 100644 index 9923e9be2df..00000000000 --- a/dlk/dlkmanager/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dlkmanager diff --git a/dlk/dlkmanager/api/api.go b/dlk/dlkmanager/api/api.go deleted file mode 100644 index bff34c42db2..00000000000 --- a/dlk/dlkmanager/api/api.go +++ /dev/null @@ -1,29 +0,0 @@ -package api - -// Learning Task Env Config -type EnvConf struct { - Name string `json:"name"` - Value string `json:"value"` -} - -// Learning Task Config -type LTConfig struct { - PsImage string `json:"psImg"` // PS image for the container in the pod(s) - WorkerImage string `json:"wkImg"` // Worker image for the container in the pod(s) - Ns string `json:"ns"` // Namespace for the new pod(s) - Scheduler string `json:"scheduler"` // A name of scheduler that should schedule the pod(s) - Name string `json:"name"` // A name of learning task - NrPS int `json:"nrPS"` // A number of parameter servers - NrWorker int `json:"nrWorker"` // A number of workers - Gpu int `json:"gpu"` // A number of required GPU for each task - DryRun bool `json:"dry-run"` - EntryPoint string `json:"entryPoint"` - Parameters string `json:"parameters"` - Timeout int `json:"timeout"` // timeout of each learning task, unit is second - Pvc string `json:"pvc"` // persistent volume claim - MountPath string `json:"mpath"` // nfs mount path - Priority int `json:"priority"` // learning task priority - User string `json:"user"` // user name - Envs []EnvConf `json:"envs"` - PullSecret string `json:"pullSecret"` -} diff --git a/dlk/dlkmanager/bash-cmp.go b/dlk/dlkmanager/bash-cmp.go deleted file mode 100644 index ab0cc70707b..00000000000 --- a/dlk/dlkmanager/bash-cmp.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -const ( - bcmpfile = "dlkmanager.sh" -) - -// NewCommandBashCmp generates bash completion file -func NewCommandBashCmp() *cobra.Command { - - cmd := &cobra.Command{ - Use: "bash", - Short: "generate bash completion file", - Long: `generate bash completion file, which is copied under /etc/bash_completion.d/`, - Args: cobra.NoArgs, - Run: genBashCmpFile, - } - - return cmd -} - -func genBashCmpFile(cmd *cobra.Command, args []string) { - - root := cmd.Root() - root.GenBashCompletionFile(bcmpfile) - fmt.Println("Bash Completeion File (" + bcmpfile + ") is generated. Please copy it under /etc/bash_completion.d/ and reset your terminal to use autocompletion.") - -} diff --git a/dlk/dlkmanager/client.go b/dlk/dlkmanager/client.go deleted file mode 100644 index 2443eefaa4b..00000000000 --- a/dlk/dlkmanager/client.go +++ /dev/null @@ -1,234 +0,0 @@ -package main - -import ( - "fmt" - "time" - - "k8s.io/api/core/v1" - api "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes" - restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/cache" -) - -type clientConfig struct { - Addr string - SchedulerName string -} - -type client struct { - apisrvClient *kubernetes.Clientset - unscheduledPodCh chan *api.Pod - nodeAddCh chan *api.Node - nodeDeleteCh chan *api.Node - nodeUpdateCh chan *api.Node -} - -func checkNodeHealth(node *api.Node) bool { - // Skip the master node - if node.Spec.Unschedulable { - return false - } - // Skip unhealty node - for _, c := range node.Status.Conditions { - var desireStatus string - switch c.Type { - case "Ready": - desireStatus = "True" - default: - desireStatus = "False" - } - if string(c.Status) != desireStatus { - return false - } - } - for _, t := range node.Spec.Taints { - switch t.Effect { - case api.TaintEffectNoSchedule, - api.TaintEffectPreferNoSchedule, - api.TaintEffectNoExecute: - return false - } - } - return true -} -func clientNew(cfg clientConfig, podChanSize int) (*client, error) { - // restCfg := &restclient.Config{ - // Host: fmt.Sprintf("http://%s", cfg.Addr), - // QPS: 1000, - // Burst: 1000, - // } - config, err := restclient.InClusterConfig() - if err != nil { - return nil, err - } - clientset, err := kubernetes.NewForConfig(config) - if err != nil { - return nil, err - } - - pch := make(chan *api.Pod, podChanSize) - - // Create informer to watch on unscheduled Pods (non-failed non-succeeded pods with an empty node binding) - sel := "spec.nodeName==" + "" + ",status.phase!=" + string(api.PodSucceeded) + ",status.phase!=" + string(api.PodFailed) - informer := cache.NewSharedInformer( - &cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { - options.FieldSelector = sel - return clientset.CoreV1().Pods("").List(options) - }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { - options.FieldSelector = sel - return clientset.CoreV1().Pods("").Watch(options) - }, - }, - &api.Pod{}, - 0, - ) - // Add event handlers for the addition, update and deletion of the pods watched by the above informer - informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - pod := obj.(*api.Pod) - // fmt.Printf("pod: %v\n", pod) - // fmt.Printf("pod.Spec.SchedulerName: %s\n", pod.Spec.SchedulerName) - if pod.Spec.SchedulerName != cfg.SchedulerName { - return - } - pch <- pod - }, - UpdateFunc: func(oldObj, newObj interface{}) {}, - DeleteFunc: func(obj interface{}) {}, - }) - stopCh := make(chan struct{}) - go informer.Run(stopCh) - - naddch := make(chan *api.Node, 100) - nupdatech := make(chan *api.Node, 100) - ndeletech := make(chan *api.Node, 100) - // Informer for watching the addition and removal of nodes in the cluster - lw := cache.NewListWatchFromClient(clientset.CoreV1().RESTClient(), "nodes", api.NamespaceAll, fields.Everything()) - _, nodeInformer := cache.NewInformer(lw, &v1.Node{}, 0, - cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - node := obj.(*api.Node) - if !checkNodeHealth(node) { - return - } - naddch <- node - }, - UpdateFunc: func(oldObj, newObj interface{}) { - oldNode := oldObj.(*api.Node) - newNode := newObj.(*api.Node) - if !checkNodeHealth(newNode) { - ndeletech <- oldNode - } else { - nupdatech <- newNode - } - }, - DeleteFunc: func(obj interface{}) { - node := obj.(*api.Node) - ndeletech <- node - }, - }, - ) - stopCh2 := make(chan struct{}) - go nodeInformer.Run(stopCh2) - - return &client{ - apisrvClient: clientset, - unscheduledPodCh: pch, - nodeAddCh: naddch, - nodeDeleteCh: ndeletech, - nodeUpdateCh: nupdatech, - }, nil -} - -type PodChan <-chan *api.Pod - -func (c *client) GetUnscheduledPodChan() PodChan { - return c.unscheduledPodCh -} - -type NodeChan <-chan *api.Node - -func (c *client) GetNodeAddChan() NodeChan { - return c.nodeAddCh -} - -func (c *client) GetNodeUpdateChan() NodeChan { - return c.nodeUpdateCh -} - -func (c *client) GetNodeDeleteChan() NodeChan { - return c.nodeDeleteCh -} - -// Write out node bindings -func (c *client) AssignBinding(ns string, bindings []*api.Binding) error { - for _, binding := range bindings { - err := c.apisrvClient.CoreV1().Pods(ns).Bind(binding) - // err := c.apisrvClient.CoreV1().Pods(ns).Bind(&v1.Binding{ - // ObjectMeta: metav1.ObjectMeta{Namespace: ns, Name: name, UID: ob.UID}, - // Target: api.ObjectReference{ - // Kind: "Node", - // Name: parseNodeID(ob.NodeID), - // }, - // }) - if err != nil { - panic(err) - } - } - return nil -} - -// Returns a batch of pods or blocks until there is at least on pod creation call back -// The timeout specifies how long to wait for another pod on the pod channel before returning -// the batch of pods that need to be scheduled -func (c *client) GetPodBatch(timeout time.Duration) []*api.Pod { - batchedPods := make([]*api.Pod, 0) - - fmt.Printf("Waiting for a pod scheduling request\n") - - // Check for first pod, block until at least 1 is available - pod := <-c.unscheduledPodCh - batchedPods = append(batchedPods, pod) - - // Set timer for timeout between successive pods - timer := time.NewTimer(timeout) - done := make(chan bool) - go func() { - <-timer.C - done <- true - }() - - fmt.Printf("Batching pod scheduling requests\n") - numPods := 1 - //fmt.Printf("Number of pods requests: %d", numPods) - // Poll until done from timeout - // TODO: Put a cap on the batch size since this could go on forever - finish := false - for !finish { - select { - case pod = <-c.unscheduledPodCh: - numPods++ - fmt.Printf("\rNumber of pods requests: %d", numPods) - batchedPods = append(batchedPods, pod) - // Refresh the timeout for next pod - timer.Reset(timeout) - case <-done: - finish = true - fmt.Printf("\n") - default: - // Do nothing and keep polling until timeout - } - } - return batchedPods -} - -func (c *client) GetClientset() *kubernetes.Clientset { - return c.apisrvClient -} diff --git a/dlk/dlkmanager/configs/flags.go b/dlk/dlkmanager/configs/flags.go deleted file mode 100644 index b684f715e3b..00000000000 --- a/dlk/dlkmanager/configs/flags.go +++ /dev/null @@ -1,177 +0,0 @@ -package configs - -import ( - "fmt" - "os" - "os/user" - - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - "github.com/spf13/viper" -) - -//PersistentFlags is used for pass persistent flag value to other command -type PersistentFlags struct { - cfgFile string - Addr string - Mt int - Pbt int - Nbt int - Pcs int - FakeMachines bool - Nm int - Scheduler string - Ns string - Logdir string - Loglvl int - Username string -} - -const ( - defaultConfig = ".dlkmanagerconfig" -) - -var ( - cfgFile string - Pflg PersistentFlags -) - -//SetFlags init cobra flags -func SetFlags(cmd *cobra.Command) { - cobra.OnInitialize(initConfig) - - cmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/"+defaultConfig) - cmd.PersistentFlags().String("addr", "localhost:6443", "k8s api endpoint") - cmd.PersistentFlags().Int("mt", 1000, "maximum number of tasks per machine") - cmd.PersistentFlags().Int("pbt", 2, "pods batch timeout in seconds") - cmd.PersistentFlags().Int("nbt", 2, "node batch timeout in seconds") - cmd.PersistentFlags().Int("pcs", 5000, "pod channel size in client's pod informer") - // Fake the machine topology, only useful for testing when the API server has no nodes - cmd.PersistentFlags().Bool("fakeMachines", false, "fake the machine topology if running without a real cluster") - cmd.PersistentFlags().Int("nm", 2, "number of machines, only needed if faking the resource topology") - cmd.PersistentFlags().String("scheduler", "default-scheduler", "a name of this scheduler") - cmd.PersistentFlags().String("ns", "default", "k8s default namespace") - cmd.PersistentFlags().String("logdir", "/tmp/", "log directory") - cmd.PersistentFlags().Int("loglvl", 4, "log level (default is info level)") - cmd.PersistentFlags().String("user", "user", "username (default = $HOME/"+defaultConfig) - - //bind viper - viper.BindPFlag("addr", cmd.PersistentFlags().Lookup("addr")) - viper.BindPFlag("mt", cmd.PersistentFlags().Lookup("mt")) - viper.BindPFlag("pbt", cmd.PersistentFlags().Lookup("pbt")) - viper.BindPFlag("nbt", cmd.PersistentFlags().Lookup("nbt")) - viper.BindPFlag("pcs", cmd.PersistentFlags().Lookup("pcs")) - viper.BindPFlag("fakeMachines", cmd.PersistentFlags().Lookup("fakeMachines")) - viper.BindPFlag("nm", cmd.PersistentFlags().Lookup("nm")) - viper.BindPFlag("scheduler", cmd.PersistentFlags().Lookup("scheduler")) - viper.BindPFlag("ns", cmd.PersistentFlags().Lookup("ns")) - viper.BindPFlag("logdir", cmd.PersistentFlags().Lookup("logdir")) - viper.BindPFlag("loglvl", cmd.PersistentFlags().Lookup("loglvl")) - viper.BindPFlag("user", cmd.PersistentFlags().Lookup("user")) -} - -// initConfig reads in config file and ENV variables if set. -func initConfig() { - var c string - if cfgFile != "" { - // Use config file from the flag. - c = cfgFile - // check existance - _, err := os.Stat(c) - if err != nil { - log.WithFields(log.Fields{ - "File Name": c, - "Error": err, - }).Error("file not found") - os.Exit(1) - } - } else { - // Find user home directory. - u, err := user.Current() - if err != nil { - log.WithFields(log.Fields{ - "Error": err, - }).Error("current user not aquired") - os.Exit(1) - } - - // Set default path and config file - c = u.HomeDir + "/" + defaultConfig - - // check existance - _, err = os.Stat(c) - if err != nil { - log.Info("config file not found") - log.Info(fmt.Sprintf("Generate Config File : %s", c)) - createConfig(c) - log.Info("Edit the config and re-excute command") - //os.Exit(0) - } - - } - - viper.SetConfigFile(c) - viper.SetConfigType("toml") - // If a config file is found, read it in. - if err := viper.ReadInConfig(); err == nil { - log.Info(fmt.Sprintf("Using config file: %s", viper.ConfigFileUsed())) - } else { - log.WithFields(log.Fields{ - "File Name": c, - "Error": err, - }).Error("config file not found") - panic(err) - } - - Pflg.Addr = viper.GetString("addr") - Pflg.Mt = viper.GetInt("mt") - Pflg.Pbt = viper.GetInt("pbt") - Pflg.Nbt = viper.GetInt("nbt") - Pflg.Pcs = viper.GetInt("pcs") - Pflg.FakeMachines = viper.GetBool("fakeMachines") - Pflg.Nm = viper.GetInt("nm") - Pflg.Scheduler = viper.GetString("scheduler") - Pflg.Ns = viper.GetString("ns") - Pflg.Logdir = viper.GetString("logdir") - Pflg.Loglvl = viper.GetInt("loglvl") - Pflg.Username = viper.GetString("user") -} - -//createConfig generate config file -func createConfig(c string) { - //create new config and write out info - w, err := os.Create(c) - if err != nil { - log.WithFields(log.Fields{ - "File Name": c, - "Error": err, - }).Error("Cannot Generate configfile") - os.Exit(1) - } - user, err := user.Current() - - fmt.Fprintf(w, "#k8s api endpoint\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "addr", "localhost:6443") - fmt.Fprintf(w, "#maximum number of tasks per machine\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "mt", "1000") - fmt.Fprintf(w, "#pods batch timeout in seconds\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "pbt", "2") - fmt.Fprintf(w, "#node batch timeout in seconds\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "nbt", "2") - fmt.Fprintf(w, "#pod channel size in client's pod informer\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "pcs", "5000") - fmt.Fprintf(w, "#fake the machine topology if running without a real cluster\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "fakeMachines", "false") - fmt.Fprintf(w, "#number of machines, only needed if faking the resource topology\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "nm", "2") - fmt.Fprintf(w, "#a name of this scheduler\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "scheduler", "default-scheduler") - fmt.Fprintf(w, "#k8s default namespace\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "ns", "default") - fmt.Fprintf(w, "#log directory\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "logdir", "/tmp/") - fmt.Fprintf(w, "#log level\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "loglvl", "4") - fmt.Fprintf(w, "#username\n") - fmt.Fprintf(w, "%s = '%s'\n\n", "user", user.Username) -} diff --git a/dlk/dlkmanager/datastore/dataStoreMap.go b/dlk/dlkmanager/datastore/dataStoreMap.go deleted file mode 100644 index 08e171c7b7a..00000000000 --- a/dlk/dlkmanager/datastore/dataStoreMap.go +++ /dev/null @@ -1,134 +0,0 @@ -package datastore - -import ( - "errors" - "fmt" - "reflect" - "sync" - - log "github.com/sirupsen/logrus" -) - -//LearningTaskMap is implementation of LearningTaskData interface -type LearningTaskMap struct { - learningTaskMap map[string]*LearningTaskInfo -} - -var pool LearningTaskMap -var mutex sync.RWMutex - -//GetLearningTaskMap is singleton impl of LearningTaskMap instance -func GetLearningTaskMap() LearningTaskMap { - //initialze map if it is not yet - if pool.learningTaskMap == nil { - pool = LearningTaskMap{} - pool.learningTaskMap = make(map[string]*LearningTaskInfo) - mutex = sync.RWMutex{} - log.Debug("data store map initialized") - } - - return pool -} - -//Get method returns LearningTaskInfo coressponding to passed learningTask name -func (pool LearningTaskMap) Get(lt string) (LearningTaskInfo, error) { - - //get and return LearningTaskinfo - mutex.RLock() - rtn, ok := pool.learningTaskMap[lt] - mutex.RUnlock() - - //error check if ok is false, then there is no such item - if !ok { - err := fmt.Errorf("Item not found. key:%s", lt) - return LearningTaskInfo{}, err - } - - return *rtn, nil -} - -//Put method store passed struct into map -func (pool LearningTaskMap) Put(lt LearningTaskInfo) error { - - var err error - key := lt.Name - if key == "" { - //basically dead code - err = errors.New("learningTask has no name") - return err - } - - mutex.Lock() - pool.learningTaskMap[key] = < - mutex.Unlock() - - return nil -} - -//Remove method store passed struct into map -func (pool LearningTaskMap) Remove(lt string) error { - mutex.Lock() - defer mutex.Unlock() - - //check key existstance - _, exist := pool.learningTaskMap[lt] - if !exist { - return fmt.Errorf("Item not found. key:%s", lt) - } - - delete(pool.learningTaskMap, lt) - - return nil -} - -//GetAll method returns all learningTasks info from map -func (pool LearningTaskMap) GetAll() ([]LearningTaskInfo, error) { - - var err error - var rtn []LearningTaskInfo - //get and return LearningTaskinfo - mutex.RLock() - keys := reflect.ValueOf(pool.learningTaskMap).MapKeys() - - for _, key := range keys { - rtn = append(rtn, *pool.learningTaskMap[key.String()]) - } - mutex.RUnlock() - - return rtn, err -} - -func (pool LearningTaskMap) UpdateState(lt string, state string, time string) error { - mutex.Lock() - defer mutex.Unlock() - - var info *LearningTaskInfo - var ok bool - if info, ok = pool.learningTaskMap[lt]; !ok { - return fmt.Errorf("learningTask %s not found", lt) - } - - info.State = state - - // set learning task exec time - if time != "" { - info.ExecTime = time - } - - return nil -} - -// UpdatePodState update pod's state value -func (pool LearningTaskMap) UpdatePodState(lt string, pod string, state string) error { - mutex.Lock() - defer mutex.Unlock() - - var info *LearningTaskInfo - var ok bool - if info, ok = pool.learningTaskMap[lt]; !ok { - return fmt.Errorf("learningTask %s not found", lt) - } - - info.PodState[pod] = state - return nil -} diff --git a/dlk/dlkmanager/datastore/learningTaskData.go b/dlk/dlkmanager/datastore/learningTaskData.go deleted file mode 100644 index 0f88ffb2584..00000000000 --- a/dlk/dlkmanager/datastore/learningTaskData.go +++ /dev/null @@ -1,63 +0,0 @@ -package datastore - -import ( - "time" -) - -// Log Object -type LogObj struct { - Time string `json"time"` - Value string `json"value"` -} - -// Pod Log Info -type PodLogInfo struct { - PodName string `json"podname"` - Logs []LogObj `json:"logs"` -} - -// LearningTask Log Info -type LtLogInfo struct { - LtName string `json:"ltname"` - PodLogs []PodLogInfo `json:"podlogs"` -} - -// LearningTaskInfo is structure for experiment and related job,svc list -type LearningTaskInfo struct { - PsImage string `json:"psImg"` - WorkerImage string `json:"wkImg"` - Ns string `json:"ns"` - Scheduler string `json:"scheduler"` - Name string `json:"name"` - NrPS int `json:"nrPS"` - NrWorker int `json:"nrWorker"` - Gpu int `json:"gpu"` - Jobs []string `json:"jobs"` - Services []string `json:"services"` - Created time.Time - ExecTime string - User string `json:"user"` - Timeout int `json:"timeout"` - Pvc string `json:"pvc"` - MountPath string `json:"mpath"` - Priority int `json:"priority"` - State string `json:"state"` - PodState map[string]string `json:"podState"` -} - -// LearningTaskData is interface for manage requested experiments -type LearningTaskData interface { - Get(string) (LearningTaskInfo, error) - GetAll() ([]LearningTaskInfo, error) - Put(LearningTaskInfo) error - Remove(string) error - UpdateState(lt string, state string, time string) error - UpdatePodState(lt string, pod string, state string) error -} - -//Accesor is access interface for experiment datastore -var Accesor LearningTaskData - -func init() { - Accesor = GetLearningTaskMap() -} diff --git a/dlk/dlkmanager/delete.go b/dlk/dlkmanager/delete.go deleted file mode 100644 index ba8585dbf35..00000000000 --- a/dlk/dlkmanager/delete.go +++ /dev/null @@ -1,54 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - - "github.com/kubeflow/katib/dlk/dlkmanager/datastore" - "github.com/labstack/echo" - lgr "github.com/sirupsen/logrus" -) - -func deleteLearningTask(c echo.Context) error { - - // get parameter - ns := c.Param("namespace") - ltName := c.Param("lt") - - log.WithFields( - lgr.Fields{ - "API CALLED": "DELETE /learningTasks", - "namespace": ns, - "lt": ltName, - "access from": c.RealIP(), - }).Info("delete learningTask") - - defer runningLTMu.Unlock() - runningLTMu.Lock() - // learning task is running - if lt, ok := runningLearningTasks[ltName]; ok { - - // notify learning task deletion - lt.deleteCh <- true - } else { - defer completedLTMu.Unlock() - completedLTMu.Lock() - - // learning task is completed - if lt, ok = completedLearningTasks[ltName]; ok { - fmt.Println("learning task is completed") - return c.NoContent(http.StatusOK) - } else { - fmt.Println("learning task is not found within namespace") - return c.NoContent(http.StatusNotFound) - } - } - - // delete LearningTask Info - err := datastore.Accesor.Remove(ltName) - if err != nil { - return c.String(http.StatusInternalServerError, err.Error()) - } - - return c.NoContent(http.StatusOK) -} diff --git a/dlk/dlkmanager/dlkmanager.go b/dlk/dlkmanager/dlkmanager.go deleted file mode 100644 index e200e427df4..00000000000 --- a/dlk/dlkmanager/dlkmanager.go +++ /dev/null @@ -1,95 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/kubeflow/katib/dlk/dlkmanager/configs" - "github.com/labstack/echo" // Web server framework for REST API - lgr "github.com/sirupsen/logrus" // logging framework - "github.com/spf13/cobra" -) - -var ( - log = lgr.New() // Creates a new logger -) - -/* -// log file inital setting -func logSetting() (*os.File, error) { - log.Formatter = new(lgr.TextFormatter) // log format setting - log.Level = lgr.DebugLevel // log level setting - - logfile, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666) - if err != nil { - log.Info("Failed to log to file, using default stderr") - - log.Out = logfile // log output to file - - return logfile, err -} -*/ - -func apiMain() { - log.Formatter = new(lgr.TextFormatter) // log format setting - log.Level = lgr.DebugLevel // log level setting - log.Out = os.Stdout // log output to console - - /* - // log file initial setting - lfile, err := logSetting() - if err != nil { - log.Error(err) - } - */ - - // Echo instance - e := echo.New() - - // Routes - e.POST("/learningTask", runLearningTask) - e.GET("/learningTasks/:namespace", getLearningTasks) - e.GET("/learningTask/:namespace/:lt", getLearningTask) - e.GET("/learningTasks/logs/:namespace/:lt/:role", getLearningTaskLogs) - e.PUT("/learningTask", updateLearningTask) - e.DELETE("/learningTasks/:namespace/:lt", deleteLearningTask) - - // Start server - e.Logger.Fatal(e.Start(":1323")) - - // lfile.Close() // log file closed -} - -func main() { - - //init command - cmd := NewRootCommand() - if err := cmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } -} - -// NewRootCommand represents the base command when called without any subcommands -func NewRootCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "dlkmanager", - Short: "dlkmanager", - Long: `dlkmanager`, - Run: run, - } - - //initialize config - configs.SetFlags(cmd) - - //add command - //Generate bash completion file - cmd.AddCommand(NewCommandBashCmp()) - - return cmd -} - -func run(cmd *cobra.Command, args []string) { - apiMain() - //schedMain() -} diff --git a/dlk/dlkmanager/get.go b/dlk/dlkmanager/get.go deleted file mode 100644 index d25e31287d4..00000000000 --- a/dlk/dlkmanager/get.go +++ /dev/null @@ -1,135 +0,0 @@ -package main - -import ( - "net/http" - "time" - - "github.com/kubeflow/katib/dlk/dlkmanager/datastore" - "github.com/labstack/echo" - lgr "github.com/sirupsen/logrus" -) - -func getLearningTasks(c echo.Context) error { - - //get parameter - ns := c.Param("namespace") - - log.WithFields( - lgr.Fields{ - "API CALLED": "GET /learningTasks", - "namespace": ns, - "access from": c.RealIP(), - }).Info("return learningTasks list") - - //get All LearningTasks - data, _ := datastore.Accesor.GetAll() - - //filtering by namespace - rtn := []datastore.LearningTaskInfo{} - - for _, d := range data { - if d.Ns == ns { - rtn = append(rtn, d) - } - } - - //return result - return c.JSON(http.StatusOK, rtn) - -} - -func getLearningTask(c echo.Context) error { - - //get parameter - ns := c.Param("namespace") - ltName := c.Param("lt") - - log.WithFields( - lgr.Fields{ - "API CALLED": "GET /learningTask", - "namespace": ns, - "lt": ltName, - "access from": c.RealIP(), - }).Info("return learningTask") - - //get LearningTask Info - rtn, err := datastore.Accesor.Get(ltName) - if err != nil { - return c.JSON(http.StatusNotFound, datastore.LearningTaskInfo{}) - } - - //return result - return c.JSON(http.StatusOK, rtn) -} - -func getLearningTaskLogs(c echo.Context) error { - - //get parameter - ns := c.Param("namespace") - ltName := c.Param("lt") - role := c.Param("role") - sinceTime := c.QueryParam("sinceTime") - //set default if not specified - if sinceTime == "" { - sinceTime = "1700-01-01T01:01:01Z" - } - - //check time string format RFC3339 - st, err := time.Parse(time.RFC3339, sinceTime) - if err != nil { - return c.String(http.StatusBadRequest, err.Error()) - } - - log.WithFields( - lgr.Fields{ - "API CALLED": "GET /learningTask/logs", - "namespace": ns, - "lt": ltName, - "role": role, - "sinceTime": c.QueryParam("sinceTime"), - "access from": c.RealIP(), - }).Info("return learningTask logs") - - //filtering by namespace - - var lt *learningTask - var ok bool - - defer runningLTMu.Unlock() - runningLTMu.Lock() - if lt, ok = runningLearningTasks[ltName]; !ok { - defer completedLTMu.Unlock() - completedLTMu.Lock() - if lt, ok = completedLearningTasks[ltName]; !ok { - return c.JSON(http.StatusNotFound, datastore.LtLogInfo{}) - } - } - - linfo := datastore.LtLogInfo{LtName: lt.name} - if role == "worker" || role == "all" { - for n, logs := range lt.workerLogs { - lobj := datastore.PodLogInfo{PodName: n} - for _, l := range logs { - if l.time.After(st) { - lobj.Logs = append(lobj.Logs, datastore.LogObj{Time: l.time.Time.Format(time.RFC3339), Value: l.value}) - } - } - linfo.PodLogs = append(linfo.PodLogs, lobj) - } - } - if role == "ps" || role == "all" { - for n, logs := range lt.psLogs { - lobj := datastore.PodLogInfo{PodName: n} - for _, l := range logs { - if l.time.After(st) { - lobj.Logs = append(lobj.Logs, datastore.LogObj{Time: l.time.Time.Format(time.RFC3339), Value: l.value}) - } - } - linfo.PodLogs = append(linfo.PodLogs, lobj) - } - } - - //return result - return c.JSON(http.StatusOK, linfo) - -} diff --git a/dlk/dlkmanager/jobs.go b/dlk/dlkmanager/jobs.go deleted file mode 100644 index fd02a7382da..00000000000 --- a/dlk/dlkmanager/jobs.go +++ /dev/null @@ -1,236 +0,0 @@ -package main - -import ( - "fmt" - "strconv" - "strings" - - batchv1 "k8s.io/api/batch/v1" - v1 "k8s.io/api/core/v1" - resource "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// Generate Job Template -func genJobTemplate(lt *learningTask) *batchv1.Job { - //construct entry point nad parameter - cmd := lt.ltc.EntryPoint - args := lt.ltc.Parameters - - template := &batchv1.Job{ - TypeMeta: metav1.TypeMeta{ - Kind: "Job", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "", // must be filled later - Labels: map[string]string{ - "priority": strconv.Itoa(lt.ltc.Priority), - }, - }, - Spec: batchv1.JobSpec{ - Template: v1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{}, // "type", "app", "learning-task", "nrPSes", "nrWorkers" must be filled - }, - - Spec: v1.PodSpec{ - SchedulerName: lt.ltc.Scheduler, - - Containers: []v1.Container{ - { - Name: "", - Command: strings.Fields(cmd), - Args: strings.Fields(args), - ImagePullPolicy: v1.PullAlways, - Ports: []v1.ContainerPort{ - v1.ContainerPort{ - ContainerPort: 2222, - }, - }, - }, - }, - RestartPolicy: v1.RestartPolicyOnFailure, - }, - }, - }, - } - - // Specified pvc is mounted to both PS and Worker Pods - if lt.pvc != nil { - if lt.ltc.Pvc != "" { - template.Spec.Template.Spec.Volumes = []v1.Volume{ - v1.Volume{ - Name: "pvc-mount-point", - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: lt.ltc.Pvc, - }, - }, - }, - } - - template.Spec.Template.Spec.Containers[0].VolumeMounts = []v1.VolumeMount{ - v1.VolumeMount{ - Name: "pvc-mount-point", - MountPath: lt.ltc.MountPath, - }, - } - } - } - - return template -} - -// PS Job -type psJob struct { - name string - job *batchv1.Job -} - -// Worker Job -type workerJob struct { - name string - job *batchv1.Job -} - -// Create PS Jobs -func newPSJobs(lt *learningTask, memberLists []string) []*psJob { - ret := make([]*psJob, lt.ltc.NrPS) - for i := 0; i < lt.ltc.NrPS; i++ { - template := genJobTemplate(lt) - psname := fmt.Sprintf("%s-ps-%d", lt.name, i) // FIXME: should be shared with services - template.ObjectMeta.Name = psname - template.Spec.Template.ObjectMeta.Labels["app"] = psname - template.Spec.Template.ObjectMeta.Labels["learning-task"] = lt.name - template.Spec.Template.ObjectMeta.Labels["nrPSes"] = fmt.Sprintf("%d", lt.ltc.NrPS) - template.Spec.Template.ObjectMeta.Labels["nrWorkers"] = fmt.Sprintf("%d", lt.ltc.NrWorker) - template.Spec.Template.ObjectMeta.Labels["type"] = "PS" - for _, e := range lt.ltc.Envs { - template.Spec.Template.Spec.Containers[0].Env = append(template.Spec.Template.Spec.Containers[0].Env, v1.EnvVar{Name: e.Name, Value: e.Value}) - } - template.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{ - v1.LocalObjectReference{ - Name: lt.ltc.PullSecret, - }, - } - - template.Spec.Template.Spec.Containers[0].Name = psname - template.Spec.Template.Spec.Containers[0].Args = - append(template.Spec.Template.Spec.Containers[0].Args, "--job_name=ps") - template.Spec.Template.Spec.Containers[0].Args = - append(template.Spec.Template.Spec.Containers[0].Args, fmt.Sprintf("--task_index=%d", i)) - template.Spec.Template.Spec.Containers[0].Args = - append(template.Spec.Template.Spec.Containers[0].Args, memberLists...) - template.Spec.Template.Spec.Containers[0].Image = lt.ltc.PsImage - - if template.Spec.Template.Spec.Volumes == nil { - template.Spec.Template.Spec.Volumes = []v1.Volume{} - } - hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate - vol := v1.Volume{ - Name: "nvidialib", - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{ - Path: "/usr/lib/nvidia", - Type: &hostPathDirectoryOrCreate, - }, - }, - } - template.Spec.Template.Spec.Volumes = append(template.Spec.Template.Spec.Volumes, vol) - - if template.Spec.Template.Spec.Volumes == nil { - template.Spec.Template.Spec.Containers[0].VolumeMounts = []v1.VolumeMount{} - } - volMnt := v1.VolumeMount{ - Name: "nvidialib", - MountPath: "/usr/local/nvidia", - ReadOnly: true, - } - template.Spec.Template.Spec.Containers[0].VolumeMounts = append(template.Spec.Template.Spec.Containers[0].VolumeMounts, volMnt) - - ret[i] = &psJob{ - name: psname, - job: template, - } - } - - return ret -} - -// Create Worker Jobs -func newWorkerJobs(lt *learningTask, memberLists []string) []*workerJob { - ret := make([]*workerJob, lt.ltc.NrWorker) - for i := 0; i < lt.ltc.NrWorker; i++ { - template := genJobTemplate(lt) - workername := fmt.Sprintf("%s-worker-%d", lt.name, i) // FIXME: should be shared with services - template.ObjectMeta.Name = workername - template.Spec.Template.ObjectMeta.Labels["type"] = "worker" - template.Spec.Template.ObjectMeta.Labels["app"] = workername - template.Spec.Template.ObjectMeta.Labels["learning-task"] = lt.name - template.Spec.Template.ObjectMeta.Labels["nrPSes"] = fmt.Sprintf("%d", lt.ltc.NrPS) - template.Spec.Template.ObjectMeta.Labels["nrWorkers"] = fmt.Sprintf("%d", lt.ltc.NrWorker) - template.Spec.Template.Spec.Containers[0].Name = workername - template.Spec.Template.Spec.Containers[0].Image = lt.ltc.WorkerImage - for _, e := range lt.ltc.Envs { - template.Spec.Template.Spec.Containers[0].Env = append(template.Spec.Template.Spec.Containers[0].Env, v1.EnvVar{Name: e.Name, Value: e.Value}) - } - template.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{ - v1.LocalObjectReference{ - Name: lt.ltc.PullSecret, - }, - } - - if lt.ltc.NrPS > 0 { - template.Spec.Template.Spec.Containers[0].Args = - append(template.Spec.Template.Spec.Containers[0].Args, "--job_name=worker") - template.Spec.Template.Spec.Containers[0].Args = - append(template.Spec.Template.Spec.Containers[0].Args, fmt.Sprintf("--task_index=%d", i)) - template.Spec.Template.Spec.Containers[0].Args = - append(template.Spec.Template.Spec.Containers[0].Args, memberLists...) - } - if lt.ltc.Gpu > 0 { - gpuReq, err := resource.ParseQuantity(strconv.Itoa(lt.ltc.Gpu)) - if err != nil { - return nil - } - template.Spec.Template.Spec.Containers[0].Resources = - v1.ResourceRequirements{ - Limits: v1.ResourceList{"nvidia.com/gpu": gpuReq}, - // Limits: v1.ResourceList{"alpha.kubernetes.io/nvidia-gpu": gpuReq}, - // Requests: v1.ResourceList{"alpha.kubernetes.io/nvidia-gpu": gpuReq}, - } - - // if template.Spec.Template.Spec.Volumes == nil { - // template.Spec.Template.Spec.Volumes = []v1.Volume{} - // } - // hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate - // vol := v1.Volume{ - // Name: "nvidialib", - // VolumeSource: v1.VolumeSource{ - // HostPath: &v1.HostPathVolumeSource{ - // Path: "/usr/lib/nvidia", - // Type: &hostPathDirectoryOrCreate, - // }, - // }, - // } - // template.Spec.Template.Spec.Volumes = append(template.Spec.Template.Spec.Volumes, vol) - // - // if template.Spec.Template.Spec.Volumes == nil { - // template.Spec.Template.Spec.Containers[0].VolumeMounts = []v1.VolumeMount{} - // } - // volMnt := v1.VolumeMount{ - // Name: "nvidialib", - // MountPath: "/usr/local/nvidia", - // ReadOnly: true, - // } - // template.Spec.Template.Spec.Containers[0].VolumeMounts = append(template.Spec.Template.Spec.Containers[0].VolumeMounts, volMnt) - } - - ret[i] = &workerJob{ - name: workername, - job: template, - } - } - - return ret -} diff --git a/dlk/dlkmanager/learningTask.go b/dlk/dlkmanager/learningTask.go deleted file mode 100644 index 6be465add93..00000000000 --- a/dlk/dlkmanager/learningTask.go +++ /dev/null @@ -1,476 +0,0 @@ -package main - -import ( - "fmt" - "os" - "strings" - "sync" - "time" - - "github.com/kubeflow/katib/dlk/dlkmanager/api" - "github.com/kubeflow/katib/dlk/dlkmanager/datastore" - - lgr "github.com/sirupsen/logrus" - batchv1 "k8s.io/api/batch/v1" - apiv1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" -) - -const ( - ltStateNotCompleted = "not completed" - ltStateCompleted = "completed" - ltStateStopped = "stopped" - ltStateDeleted = "deleted" - ltStateTimeout = "timeout" - ltStateRunning = "running" -) - -// Learning Task -type learningTask struct { - c *kubernetes.Clientset - ltc *api.LTConfig - pvc *apiv1.PersistentVolumeClaim - name string - - workers map[string]struct{} - nrCompletedWorkers int - workerCmpCh chan string - - psSvcs []*psService - workerSvcs []*workerService - - psJobs []*psJob - workerJobs []*workerJob - - deleteCh chan bool - stopCh chan (chan struct{}) - - psLogs map[string][]logObj - workerLogs map[string][]logObj - - nrWorkers, nrPSes int - nrReadyWorkers, nrReadyPSes int - pods []*apiv1.Pod - - running bool - - usingGPUsPerPod map[*apiv1.Pod]int - podToNode map[*apiv1.Pod]*apiv1.Node -} - -// Log Object -type logObj struct { - time metav1.Time - value string -} - -// Create Services -func (lt *learningTask) createServices() { - lt.psSvcs = newPSServices(lt.name, lt.ltc.NrPS) - lt.workerSvcs = newWorkerServices(lt.name, lt.ltc.NrWorker) - - for _, svc := range lt.psSvcs { - _, err := lt.c.CoreV1().Services(lt.ltc.Ns).Create(svc.svc) - if err != nil { - log.Error(fmt.Sprintf("failed to create a PS service %s: %s", svc.name, err)) - } - } - - for _, svc := range lt.workerSvcs { - _, err := lt.c.CoreV1().Services(lt.ltc.Ns).Create(svc.svc) - if err != nil { - log.Error(fmt.Sprintf("failed to create a worker service %s: %s", svc.name, err)) - } - } -} - -// Delete Services -func (lt *learningTask) deleteServices() { - for _, svc := range lt.psSvcs { - err := lt.c.CoreV1().Services(lt.ltc.Ns).Delete(svc.name, &metav1.DeleteOptions{}) - if err != nil { - log.Error(fmt.Sprintf("failed to delete a PS service %s: %s", svc.name, err)) - } - } - - for _, svc := range lt.workerSvcs { - err := lt.c.CoreV1().Services(lt.ltc.Ns).Delete(svc.name, &metav1.DeleteOptions{}) - if err != nil { - log.Error(fmt.Sprintf("failed to delete a worker service %s: %s", svc.name, err)) - } - } -} - -// Generate Member Lists -func (lt *learningTask) genMemberLists() []string { - workers := "--workers=" - for i, workerSvc := range lt.workerSvcs { - if i == 0 { - workers += fmt.Sprintf("%s:2222", workerSvc.name) - } else { - workers += fmt.Sprintf(",%s:2222", workerSvc.name) - } - } - - pses := "--parameter_servers=" - for i, psSvc := range lt.psSvcs { - if i == 0 { - pses += fmt.Sprintf("%s:2222", psSvc.name) - } else { - pses += fmt.Sprintf(",%s:2222", psSvc.name) - } - } - - return []string{ - workers, - pses, - } -} - -// Create Jobs -func (lt *learningTask) createJobs() { - memberLists := lt.genMemberLists() - - lt.psJobs = newPSJobs(lt, memberLists) - lt.workerJobs = newWorkerJobs(lt, memberLists) - - // Dry Run - if lt.ltc.DryRun { - log.Info(fmt.Sprintf("Dry Run: PS jobs = %#v", lt.psJobs)) - log.Info(fmt.Sprintf("Dry Run: Worker jobs = %#v", lt.workerJobs)) - return - } - - for _, job := range lt.psJobs { - _, err := lt.c.BatchV1().Jobs(lt.ltc.Ns).Create(job.job) - if err != nil { - log.Error(fmt.Sprintf("failed to create a PS job %s: %s", job.name, err)) - } - lt.psLogs[job.name] = []logObj{} - } - - for _, job := range lt.workerJobs { - _, err := lt.c.BatchV1().Jobs(lt.ltc.Ns).Create(job.job) - if err != nil { - log.Error(fmt.Sprintf("failed to create a worker job %s: %s", job.name, err)) - } - - lt.workers[job.name] = struct{}{} - lt.workerLogs[job.name] = []logObj{} - } -} - -// Cleanup Jobs -func (lt *learningTask) cleanupJobs() { - for _, job := range lt.psJobs { - err := lt.c.BatchV1().Jobs(lt.ltc.Ns).Delete(job.name, &metav1.DeleteOptions{}) - if err != nil { - log.Error(fmt.Sprintf("failed to delete a PS job %s: %s", job.name, err)) - } - } - - for _, job := range lt.workerJobs { - err := lt.c.BatchV1().Jobs(lt.ltc.Ns).Delete(job.name, &metav1.DeleteOptions{}) - if err != nil { - log.Error(fmt.Sprintf("failed to delete a worker job %s: %s", job.name, err)) - } - } - - pods, err := lt.c.CoreV1().Pods(lt.ltc.Ns).List(metav1.ListOptions{LabelSelector: fmt.Sprintf("learning-task=%s", lt.name)}) - if err != nil { - log.Error(fmt.Sprintf("failed to delete pods: %s", err)) - } - - for _, pod := range pods.Items { - log.Info(fmt.Sprintf("deleting pod %s", pod.ObjectMeta.Name)) - err = lt.c.CoreV1().Pods(lt.ltc.Ns).Delete(pod.ObjectMeta.Name, &metav1.DeleteOptions{}) - if err != nil { - log.Error(fmt.Sprintf("failed to delete pod %s: %s", pod.ObjectMeta.Name, err)) - } - } -} - -// Get Logs -func (lt *learningTask) getLogs(jobname string, namespace string, Logs *map[string][]logObj) { - pl, err := lt.c.CoreV1().Pods("").List(metav1.ListOptions{LabelSelector: "job-name=" + jobname}) - if err != nil { - log.Error(fmt.Sprintf("failed to obtain pod list: %s", err)) - os.Exit(1) - } - if len(pl.Items) != 0 { - var logs []byte - if len((*Logs)[jobname]) == 0 { - logs, _ = lt.c.CoreV1().Pods(namespace).GetLogs(pl.Items[0].ObjectMeta.Name, &apiv1.PodLogOptions{Timestamps: true}).Do().Raw() - } else { - logs, _ = lt.c.CoreV1().Pods(namespace).GetLogs(pl.Items[0].ObjectMeta.Name, &apiv1.PodLogOptions{SinceTime: &(*Logs)[jobname][len((*Logs)[jobname])-1].time, Timestamps: true}).Do().Raw() - } - if len(logs) > 1 && pl.Items[0].Status.Phase != apiv1.PodPending && pl.Items[0].Status.Phase != apiv1.PodUnknown { - logf := strings.Split(string(logs), "\n") - for _, l := range logf { - ll := strings.SplitN(l, " ", 2) - if len(ll) == 2 { - t, err := time.Parse(time.RFC3339, ll[0]) - if err == nil && (len((*Logs)[jobname]) == 0 || (*Logs)[jobname][len((*Logs)[jobname])-1].time.Time.Before(t)) { - (*Logs)[jobname] = append((*Logs)[jobname], logObj{time: metav1.Time{Time: t}, value: ll[1]}) - } - } - } - } - } -} - -// Polling Jobs -func (lt *learningTask) pollJobs() { - for _, job := range lt.psJobs { - lt.getLogs(job.name, lt.ltc.Ns, <.psLogs) - } - for _, job := range lt.workerJobs { - lt.getLogs(job.name, lt.ltc.Ns, <.workerLogs) - } - - if lt.nrCompletedWorkers == lt.ltc.NrWorker { - return - } - - jobList, err := lt.c.BatchV1().Jobs(lt.ltc.Ns).List(metav1.ListOptions{}) // TODO: label selector - if err != nil { - log.Error(fmt.Sprintf("failed to obtain job list: %s", err)) - os.Exit(1) - } - - for _, job := range jobList.Items { - if len(job.Status.Conditions) == 0 { - continue - } - - cond := job.Status.Conditions[0] - if _, ok := lt.workers[job.ObjectMeta.Name]; ok { - if cond.Type == batchv1.JobComplete || cond.Type == batchv1.JobFailed { - go func(lt *learningTask, name string) { - lt.workerCmpCh <- name - }(lt, job.ObjectMeta.Name) - } - } - delete(lt.workers, job.ObjectMeta.Name) - } - -} - -// Run Learning Task -func (lt *learningTask) run() { - - lt.createServices() - lt.createJobs() - - running := true - - timeoutCh := make(<-chan time.Time) - if lt.ltc.Timeout != 0 { - timeoutCh = time.After(time.Duration(lt.ltc.Timeout) * time.Second) - } - - // local learningtask status - state := ltStateNotCompleted - - // local pods status - podState := make(map[string]apiv1.PodPhase) - for _, worker := range lt.workerJobs { - podState[worker.name] = apiv1.PodPending - } - for _, ps := range lt.psJobs { - podState[ps.name] = apiv1.PodPending - } - // set init pod status value to datastore - for k := range podState { - datastore.Accesor.UpdatePodState(lt.name, k, ltStateNotCompleted) - } - - var stopCompleteNotifyCh chan struct{} - - for running { - select { - case cmpedWorker := <-lt.workerCmpCh: - log.Info(fmt.Sprintf("worker %s completed", cmpedWorker)) - lt.nrCompletedWorkers++ - - // if it is first complete worker,then set status to not complete - if lt.nrCompletedWorkers == 1 { - state = ltStateNotCompleted - datastore.Accesor.UpdateState(lt.name, state, "") - } - - if lt.nrCompletedWorkers == lt.ltc.NrWorker { - state = ltStateCompleted - running = false - break - } - - case <-time.After(1 * time.Second): - err := lt.checkPodStatus(podState) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - lt.pollJobs() - - if lt.nrCompletedWorkers == lt.ltc.NrWorker { - state = ltStateCompleted - running = false - break - } - - // if all worker is running,set state to running - if lt.nrCompletedWorkers == 0 && state != ltStateRunning { - i := 0 - for _, pState := range podState { - if pState != apiv1.PodRunning { - break - } - i++ - if i == len(podState) { - state = ltStateRunning - datastore.Accesor.UpdateState(lt.name, state, "") - } - } - } - - case stopCompleteNotifyCh = <-lt.stopCh: - log.Info(fmt.Sprintf("learning task %s stopped", lt.name)) - state = ltStateStopped - running = false - - case <-lt.deleteCh: - log.Info(fmt.Sprintf("learning task %s deleted", lt.name)) - state = ltStateDeleted - running = false - - case <-timeoutCh: - log.Infof("learning task %s stopped because of timeout (%d sec)", lt.name, lt.ltc.Timeout) - state = ltStateTimeout - running = false - } - } - - lt.cleanupJobs() - lt.deleteServices() - - // update PS pod state since it already deleted - for _, ps := range lt.psJobs { - datastore.Accesor.UpdatePodState(lt.name, ps.name, ltStateCompleted) - } - - // learning task exec time is calculated after task completion - et := "" - if state == ltStateCompleted { - // get learning task created time - ct, _ := datastore.Accesor.Get(lt.name) - dura := time.Since(ct.Created) - et = dura.Truncate(time.Millisecond).String() - } - - datastore.Accesor.UpdateState(lt.name, state, et) - - if state == ltStateStopped { - stopCompleteNotifyCh <- struct{}{} - return - } - - completedLTMu.Lock() - completedLearningTasks[lt.name] = runningLearningTasks[lt.name] - completedLTMu.Unlock() - - runningLTMu.Lock() - delete(runningLearningTasks, lt.name) - runningLTMu.Unlock() - - log.WithFields( - lgr.Fields{ - "learningTask": lt.name, - "state": state, - }).Info("learning task is completed") -} - -var ( - runningLearningTasks map[string]*learningTask - completedLearningTasks map[string]*learningTask - runningLTMu sync.Mutex - completedLTMu sync.Mutex -) - -func init() { - runningLearningTasks = make(map[string]*learningTask) - completedLearningTasks = make(map[string]*learningTask) -} - -// Creates Learning Task -func newLearningTask(lc *api.LTConfig, c *kubernetes.Clientset, pvc *apiv1.PersistentVolumeClaim) *learningTask { - ret := &learningTask{ - c: c, - ltc: lc, - pvc: pvc, - name: lc.Name, - nrCompletedWorkers: 0, - workerCmpCh: make(chan string), - workers: make(map[string]struct{}), - - deleteCh: make(chan bool), - stopCh: make(chan (chan struct{})), - psLogs: make(map[string][]logObj), - workerLogs: make(map[string][]logObj), - - nrPSes: lc.NrPS, - nrWorkers: lc.NrWorker, - - pods: make([]*apiv1.Pod, 0), - - usingGPUsPerPod: make(map[*apiv1.Pod]int), - podToNode: make(map[*apiv1.Pod]*apiv1.Node), - } - - runningLTMu.Lock() - runningLearningTasks[lc.Name] = ret - runningLTMu.Unlock() - - return ret -} - -func (lt *learningTask) checkPodStatus(podState map[string]apiv1.PodPhase) error { - // get pod infomation using learning-task label - label := fmt.Sprintf("learning-task=%s", lt.name) - pods, err := lt.c.Core().Pods("").List(metav1.ListOptions{LabelSelector: label}) - if err != nil { - return err - } else if pods.Size() == 0 { - return fmt.Errorf("no pod related to \"%s\" is found", lt.name) - } - - for _, pod := range pods.Items { - job := pod.Labels["job-name"] - current, ok := podState[job] - if !ok { - // must be dead code - log.Warnf("unknown job is detected. job name: %s", job) - } - - // if pod status change,then update local status - if pod.Status.Phase == current || pod.Status.Phase == apiv1.PodPending { - continue - } - - podState[job] = pod.Status.Phase - - // update pod status - if pod.Status.Phase == apiv1.PodRunning { - // PodRunning == "running" - datastore.Accesor.UpdatePodState(lt.name, job, ltStateRunning) - } else if pod.Status.Phase == apiv1.PodSucceeded { - // PodSuccessed == "complete" - datastore.Accesor.UpdatePodState(lt.name, job, ltStateCompleted) - } else { // Init,pending,containerCreating,Error = "not complete" - datastore.Accesor.UpdatePodState(lt.name, job, ltStateNotCompleted) - } - } - - return nil -} diff --git a/dlk/dlkmanager/post.go b/dlk/dlkmanager/post.go deleted file mode 100644 index 7ca55a1175f..00000000000 --- a/dlk/dlkmanager/post.go +++ /dev/null @@ -1,228 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "path/filepath" - "time" - - "github.com/kubeflow/katib/dlk/dlkmanager/configs" - - "github.com/kubeflow/katib/dlk/dlkmanager/api" - "github.com/kubeflow/katib/dlk/dlkmanager/datastore" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - restclient "k8s.io/client-go/rest" - - "github.com/labstack/echo" // Web server framework for REST API -) - -const ( - GPUMIN = 0 // minimum GPU number - GPUMAX = 3 // maximum GPU number - PrioMIN = 0 // lowest learning task priority - PrioMAX = 100 // highest learning task priority -) - -// POST's JSON -type RunParam struct { - LtConf *api.LTConfig -} - -func (r *RunParam) runParamChk() (code int) { - - // check whether both ps and worker images are specified - if r.LtConf.PsImage == "" || r.LtConf.WorkerImage == "" { - log.Error("ps image and/or worker image are not specified") - return http.StatusBadRequest - } - - if r.LtConf.Ns == "" { - r.LtConf.Ns = configs.Pflg.Ns - } - - if r.LtConf.Scheduler == "" { - r.LtConf.Scheduler = configs.Pflg.Scheduler - } - - if r.LtConf.Name == "" { - r.LtConf.Name = "" - } - - if r.LtConf.NrPS < 0 { - log.Error("NrPS is less than 0") - return http.StatusBadRequest - } - - if r.LtConf.NrWorker < 1 { - log.Error("NrWorker is less than 1") - return http.StatusBadRequest - } - - // number of worker must be 1 - // in case number of parameter server is 0 - if r.LtConf.NrPS == 0 && r.LtConf.NrWorker > 1 { - log.Error("NrWorker must be 1 in case NrPs is 0") - return http.StatusBadRequest - } - - if r.LtConf.Gpu < GPUMIN || r.LtConf.Gpu > GPUMAX { - log.Error("Gpu is out of range.") - return http.StatusBadRequest - } - - if r.LtConf.Priority < PrioMIN || r.LtConf.Priority > PrioMAX { - log.Error("Priority is out of range.") - return http.StatusBadRequest - } - - if r.LtConf.EntryPoint == "" { - r.LtConf.EntryPoint = "python /distributed-tensorflow-example.py" - } - - if r.LtConf.MountPath == "" { - r.LtConf.MountPath = "/default-path" - } - - // check mount path is absolute - if !filepath.IsAbs(r.LtConf.MountPath) { - log.Error("mount path is not absolute") - return http.StatusBadRequest - } - - log.Info(fmt.Sprintf("After RunParam is checked, RunParam = %#v", r)) - - return http.StatusOK -} - -func (r *RunParam) learningTaskInit() (lt *learningTask, code int) { - // Initialize the kubernetes client - // restCfg := &restclient.Config{ - // Host: fmt.Sprintf("http://%s", configs.Pflg.Addr), - // QPS: 1000, - // Burst: 1000, - // } - // Create the kubernetes client - - config, err := restclient.InClusterConfig() - if err != nil { - return nil, http.StatusBadRequest - } - k8scli, err := kubernetes.NewForConfig(config) - if err != nil { - log.Error(fmt.Sprintf("kubernetes client not created. error = %d", err)) - return nil, http.StatusInternalServerError - } - - // Check PersistentVolumeClaim - var pvc *corev1.PersistentVolumeClaim - var e bool - if r.LtConf.Pvc != "" { - pvc, e = r.checkPersistentVolumeClaim(k8scli) - if e { - return nil, http.StatusBadRequest - } - } - - if r.LtConf.Name == "" { - now := time.Now() - r.LtConf.Name = fmt.Sprintf("dlk-%d-%d-%d-%d-%d-%d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second()) - log.Info(fmt.Printf("generated learning task name: %s", r.LtConf.Name)) - } - - lt = newLearningTask(r.LtConf, k8scli, pvc) - return lt, http.StatusOK -} - -// Check PersistentVolumeClaim -func (r *RunParam) checkPersistentVolumeClaim(k8scli *kubernetes.Clientset) (pvc *corev1.PersistentVolumeClaim, e bool) { - - // Get PersistentVolumeClaim - getopt := metav1.GetOptions{} - getpvc, err := k8scli.CoreV1().PersistentVolumeClaims(r.LtConf.Ns).Get(r.LtConf.Pvc, getopt) - if err != nil { - log.Error(fmt.Sprintf("Specified pvc does not exist in combination with the specified namespace. error = %d", err)) - return nil, true - } - - ret := false - // Check Bind - if getpvc.Status.Phase != corev1.ClaimBound { - log.Error("pvc is not bound") - ret = true - } - - // Check AccessModes - incl := false - for _, mode := range getpvc.Status.AccessModes { - if mode == corev1.ReadWriteMany { - incl = true - break - } - } - if !incl { - log.Error("pvc access modes don't include ReadWriteMany") - ret = true - } - - return getpvc, ret -} - -// POST handling -func runLearningTask(c echo.Context) error { - - var code int - - // Extracts JSON - r := RunParam{LtConf: &api.LTConfig{}} - err := c.Bind(r.LtConf) - if err != nil { - log.Error(fmt.Sprintf("POST: JSON is not extracted. error = %d", err)) - return c.String(http.StatusInternalServerError, "Internal error.") - } - - log.Info(fmt.Sprintf("POST: JSON is extracted. RunParam = %#v", r)) - - code = r.runParamChk() - if code != http.StatusOK { - return c.String(code, "Input parameter value(s) are not correct.") - } - - lt, code := r.learningTaskInit() - if code != http.StatusOK { - return c.String(code, "Internal error.") - } - - if r.LtConf.DryRun { - return c.String(http.StatusOK, "Dry run is performed.") - } - - // Respond to CLI immediately, before learning task is finished. - c.String(http.StatusOK, "Command is performed.") - - //store learning task information into datastore for check learning tasks from get method - info := datastore.LearningTaskInfo{ - Name: lt.ltc.Name, - PsImage: lt.ltc.PsImage, - WorkerImage: lt.ltc.WorkerImage, - Ns: lt.ltc.Ns, - Scheduler: lt.ltc.Scheduler, - NrPS: lt.ltc.NrPS, - NrWorker: lt.ltc.NrWorker, - Gpu: lt.ltc.Gpu, - Created: time.Now(), - Timeout: lt.ltc.Timeout, - Pvc: lt.ltc.Pvc, - MountPath: lt.ltc.MountPath, - Priority: lt.ltc.Priority, - State: ltStateNotCompleted, - User: lt.ltc.User, - PodState: make(map[string]string), - } - datastore.Accesor.Put(info) - - go lt.run() - - return err -} diff --git a/dlk/dlkmanager/put.go b/dlk/dlkmanager/put.go deleted file mode 100644 index 71aa14c5363..00000000000 --- a/dlk/dlkmanager/put.go +++ /dev/null @@ -1,12 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/labstack/echo" -) - -func updateLearningTask(c echo.Context) error { - _, err := fmt.Println("updateLearningTask called") - return err -} diff --git a/dlk/dlkmanager/services.go b/dlk/dlkmanager/services.go deleted file mode 100644 index 8f9f4543100..00000000000 --- a/dlk/dlkmanager/services.go +++ /dev/null @@ -1,90 +0,0 @@ -package main - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" -) - -// Generate Service Template -func genSvcTemplate() *v1.Service { - return &v1.Service{ - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "", // must be filled by caller - Labels: map[string]string{}, - }, - Spec: v1.ServiceSpec{ - Selector: map[string]string{}, - Ports: []v1.ServicePort{ - v1.ServicePort{ - Protocol: v1.ProtocolTCP, - Port: 2222, - TargetPort: intstr.FromInt(2222), - }, - }, - }, - } -} - -// Generate PS Service -func genPSSvc(name string, ltName string) *v1.Service { - template := genSvcTemplate() - template.ObjectMeta.Name = name - template.ObjectMeta.Labels["learning-task"] = ltName - template.Spec.Selector["app"] = "tfd-ps" - return template -} - -// Generate Worker Service -func genWorkerSvc(name string, ltName string) *v1.Service { - template := genSvcTemplate() - template.ObjectMeta.Name = name - template.ObjectMeta.Labels["learning-task"] = ltName - template.Spec.Selector["app"] = "tfd-worker" - return template -} - -// PS Service -type psService struct { - name string - svc *v1.Service -} - -func newPSServices(ltName string, nrPS int) []*psService { - ret := make([]*psService, nrPS) - for i := 0; i < nrPS; i++ { - psname := fmt.Sprintf("%s-ps-%d", ltName, i) - svc := genPSSvc(psname, ltName) - svc.Spec.Selector["app"] = psname - ret[i] = &psService{ - name: psname, - svc: svc, - } - } - return ret -} - -// Worker Service -type workerService struct { - name string - svc *v1.Service -} - -func newWorkerServices(ltName string, nrWorker int) []*workerService { - ret := make([]*workerService, nrWorker) - for i := 0; i < nrWorker; i++ { - workername := fmt.Sprintf("%s-worker-%d", ltName, i) - svc := genWorkerSvc(workername, ltName) - svc.Spec.Selector["app"] = workername - ret[i] = &workerService{ - name: workername, - svc: svc, - } - } - return ret -} diff --git a/docs/MinikubeDemo/MinikubeDemo.md b/docs/MinikubeDemo/MinikubeDemo.md new file mode 100644 index 00000000000..15ab7b4cfb4 --- /dev/null +++ b/docs/MinikubeDemo/MinikubeDemo.md @@ -0,0 +1,30 @@ +# Simple Minikube Demo +You can deploy katib components and try a simple mnist demo on your laptop! +## Requirement +* VirtualBox +* Minikube +* kubectl +## deploy +Only type command `./deploy`. +A Minikube cluster and Katib components will be deployed! +You can check them with `kubectl get -n katib get pods`. +You don't worry if the `vizier-core` get an error. It will be recovered after DB will be prepared. +Wait until all components are Running status. + +## Create Study +``` +go run radom-suggest-demo.go +``` +Logs +``` +2018/04/26 17:43:26 Study ID n9debe3de9ef67c8 +2018/04/26 17:43:26 Study ID n9debe3de9ef67c8 StudyConfname:"random-demo" owner:"katib" optimization_type:MAXIMIZE optimization_goal:0.99 parameter_configs: > > default_suggestion_algorithm:"random" default_early_stopping_algorithm:"medianstopping" objective_value_name:"Validation-accuracy" metrics:"accuracy" metrics:"Validation-accuracy" +2018/04/26 17:43:26 Get Random Suggestions [trial_id:"i988add515f1ca4c" study_id:"n9debe3de9ef67c8" parameter_set: trial_id:"g7afad58be7da888" study_id:"n9debe3de9ef67c8" parameter_set: ] +2018/04/26 17:43:26 WorkerID p4482bfb5cdc17ee start +2018/04/26 17:43:26 WorkerID c19ca08ca4e6aab1 start +``` + +## UI +You can check your Model with Web UI. +Acsess to `http://192.168.99.100:30080/` +The Results will be saved automatically. diff --git a/docs/MinikubeDemo/deploy.sh b/docs/MinikubeDemo/deploy.sh new file mode 100755 index 00000000000..b07a1d7c5be --- /dev/null +++ b/docs/MinikubeDemo/deploy.sh @@ -0,0 +1,12 @@ +#/bin/bash +set -x +set -e +minikube start --disk-size 50g --memory 4096 --cpus 4 +kubectl apply -f manifests/0-namespace.yaml +kubectl apply -f manifests/modeldb/db +kubectl apply -f manifests/modeldb/backend +kubectl apply -f manifests/modeldb/frontend +kubectl apply -f manifests/vizier/db +kubectl apply -f manifests/vizier/core +kubectl apply -f manifests/vizier/suggestion/random +kubectl apply -f manifests/vizier/earlystopping/medianstopping diff --git a/docs/MinikubeDemo/manifests/0-namespace.yaml b/docs/MinikubeDemo/manifests/0-namespace.yaml new file mode 100644 index 00000000000..9bac532fac9 --- /dev/null +++ b/docs/MinikubeDemo/manifests/0-namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: katib diff --git a/docs/MinikubeDemo/manifests/modeldb/backend/deployment.yaml b/docs/MinikubeDemo/manifests/modeldb/backend/deployment.yaml new file mode 100644 index 00000000000..bc7fd1dc9f6 --- /dev/null +++ b/docs/MinikubeDemo/manifests/modeldb/backend/deployment.yaml @@ -0,0 +1,32 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: modeldb-backend + namespace: katib + labels: + app: modeldb + component: backend +spec: + replicas: 1 + template: + metadata: + name: modeldb-backend + labels: + app: modeldb + component: backend + spec: + containers: + - name: modeldb-backend + image: mitdbg/modeldb-backend:latest + args: + - 'modeldb-db' + ports: + - name: api + containerPort: 6543 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/MinikubeDemo/manifests/modeldb/backend/service.yaml b/docs/MinikubeDemo/manifests/modeldb/backend/service.yaml new file mode 100644 index 00000000000..71d9d5f7fe8 --- /dev/null +++ b/docs/MinikubeDemo/manifests/modeldb/backend/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: modeldb-backend + namespace: katib + labels: + app: modeldb + component: backend +spec: + type: ClusterIP + ports: + - port: 6543 + protocol: TCP + name: api + selector: + app: modeldb + component: backend diff --git a/docs/MinikubeDemo/manifests/modeldb/db/deployment.yaml b/docs/MinikubeDemo/manifests/modeldb/db/deployment.yaml new file mode 100644 index 00000000000..eaa83fa2db6 --- /dev/null +++ b/docs/MinikubeDemo/manifests/modeldb/db/deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: modeldb-db + namespace: katib + labels: + app: modeldb + component: db +spec: + replicas: 1 + template: + metadata: + name: modeldb-db + labels: + app: modeldb + component: db + spec: + containers: + - name: modeldb-db + image: mongo:3.4 + ports: + - name: dbapi + containerPort: 27017 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/MinikubeDemo/manifests/modeldb/db/service.yaml b/docs/MinikubeDemo/manifests/modeldb/db/service.yaml new file mode 100644 index 00000000000..966fb4155ea --- /dev/null +++ b/docs/MinikubeDemo/manifests/modeldb/db/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: modeldb-db + namespace: katib + labels: + app: modeldb + component: db +spec: + type: ClusterIP + ports: + - port: 27017 + protocol: TCP + name: dbapi + selector: + app: modeldb + component: db diff --git a/docs/MinikubeDemo/manifests/modeldb/frontend/deployment.yaml b/docs/MinikubeDemo/manifests/modeldb/frontend/deployment.yaml new file mode 100644 index 00000000000..9e4da69841c --- /dev/null +++ b/docs/MinikubeDemo/manifests/modeldb/frontend/deployment.yaml @@ -0,0 +1,36 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: modeldb-frontend + namespace: katib + labels: + app: modeldb + component: frontend +spec: + replicas: 1 + template: + metadata: + name: modeldb-frontend + labels: + app: modeldb + component: frontend + spec: + containers: + - name: modeldb-frontend + image: yujioshima/katib-frontend + imagePullPolicy: Always + args: + - 'modeldb-backend' + env: + - name: ROOT_PATH + value: "" + ports: + - name: webapi + containerPort: 3000 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/MinikubeDemo/manifests/modeldb/frontend/service.yaml b/docs/MinikubeDemo/manifests/modeldb/frontend/service.yaml new file mode 100644 index 00000000000..bc703ba8e91 --- /dev/null +++ b/docs/MinikubeDemo/manifests/modeldb/frontend/service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: modeldb-frontend + namespace: katib + labels: + app: modeldb + component: frontend +spec: + type: NodePort + ports: + - port: 3000 + protocol: TCP + nodePort: 30080 + name: ui + selector: + app: modeldb + component: frontend diff --git a/docs/MinikubeDemo/manifests/vizier/core/deployment.yaml b/docs/MinikubeDemo/manifests/vizier/core/deployment.yaml new file mode 100644 index 00000000000..698f9da3077 --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/core/deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-core + namespace: katib + labels: + app: vizier + component: core +spec: + replicas: 1 + template: + metadata: + name: vizier-core + labels: + app: vizier + component: core + spec: + serviceAccountName: vizier-core + containers: + - name: vizier-core + image: yujioshima/vizier-core + command: + - './vizier-manager' + - "-w" + - "kubernetes" + - "-i" + - "k-cluster.osrg.net" + ports: + - name: api + containerPort: 6789 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/MinikubeDemo/manifests/vizier/core/rbac.yaml b/docs/MinikubeDemo/manifests/vizier/core/rbac.yaml new file mode 100644 index 00000000000..a0858e752af --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/core/rbac.yaml @@ -0,0 +1,37 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: vizier-core +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: vizier-core +subjects: +- kind: ServiceAccount + name: vizier-core + namespace: katib +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: vizier-core +rules: + - apiGroups: [""] + resources: ["pods", "nodes", "nodes/*", "pods/log", "pods/status", "services", "persistentvolumes", "persistentvolumes/status","persistentvolumeclaims","persistentvolumeclaims/status"] + verbs: ["*"] + - apiGroups: ["batch"] + resources: ["jobs", "jobs/status"] + verbs: ["*"] + - verbs: ["*"] + apiGroups: ["extensions"] + resources: ["ingresses","ingresses/status","deployments","deployments/status"] + - verbs: ["*"] + apiGroups: [""] + resources: ["services"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vizier-core + namespace: katib diff --git a/docs/MinikubeDemo/manifests/vizier/core/service.yaml b/docs/MinikubeDemo/manifests/vizier/core/service.yaml new file mode 100644 index 00000000000..f41228ba7b0 --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/core/service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-core + namespace: katib + labels: + app: vizier + component: core +spec: +# type: ClusterIP + type: NodePort + ports: + - port: 6789 + protocol: TCP + nodePort: 30678 + name: api + selector: + app: vizier + component: core diff --git a/docs/MinikubeDemo/manifests/vizier/db/deployment.yaml b/docs/MinikubeDemo/manifests/vizier/db/deployment.yaml new file mode 100644 index 00000000000..bd4a9ef1958 --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/db/deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-db + namespace: katib + labels: + app: vizier + component: db +spec: + replicas: 1 + template: + metadata: + name: vizier-db + labels: + app: vizier + component: db + spec: + containers: + - name: vizier-db + image: mysql:8.0.3 + env: + - name: MYSQL_ROOT_PASSWORD + value: "test" + - name: MYSQL_ALLOW_EMPTY_PASSWORD + value: "true" + - name: MYSQL_DATABASE + value: "vizier" + ports: + - name: dbapi + containerPort: 3306 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/MinikubeDemo/manifests/vizier/db/service.yaml b/docs/MinikubeDemo/manifests/vizier/db/service.yaml new file mode 100644 index 00000000000..dde0b2c31a0 --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/db/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-db + namespace: katib + labels: + app: vizier + component: db +spec: + type: ClusterIP + ports: + - port: 3306 + protocol: TCP + name: dbapi + selector: + app: vizier + component: db diff --git a/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml b/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml new file mode 100644 index 00000000000..2b1743e73d1 --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-earlystopping-medianstopping + namespace: katib + labels: + app: vizier + component: earlystopping-medianstopping +spec: + replicas: 1 + template: + metadata: + name: vizier-earlystopping-medianstopping + labels: + app: vizier + component: earlystopping-medianstopping + spec: + containers: + - name: vizier-earlystopping-medianstopping + image: yujioshima/earlystopping-medianstopping + ports: + - name: api + containerPort: 6789 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/service.yaml b/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/service.yaml new file mode 100644 index 00000000000..dd6aa39c465 --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-earlystopping-medianstopping + namespace: katib + labels: + app: vizier + component: earlystopping-medianstopping +spec: + type: ClusterIP + ports: + - port: 6789 + protocol: TCP + name: api + selector: + app: vizier + component: earlystopping-medianstopping diff --git a/docs/MinikubeDemo/manifests/vizier/suggestion/grid/deployment.yaml b/docs/MinikubeDemo/manifests/vizier/suggestion/grid/deployment.yaml new file mode 100644 index 00000000000..8a2b01d8f3c --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/suggestion/grid/deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-suggestion-grid + namespace: katib + labels: + app: vizier + component: suggestion-grid +spec: + replicas: 1 + template: + metadata: + name: vizier-suggestion-grid + labels: + app: vizier + component: suggestion-grid + spec: + containers: + - name: vizier-suggestion-grid + image: yujioshima/suggestion-grid + ports: + - name: api + containerPort: 6789 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/MinikubeDemo/manifests/vizier/suggestion/grid/service.yaml b/docs/MinikubeDemo/manifests/vizier/suggestion/grid/service.yaml new file mode 100644 index 00000000000..4a1cf6b64a0 --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/suggestion/grid/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-suggestion-grid + namespace: katib + labels: + app: vizier + component: suggestion-grid +spec: + type: ClusterIP + ports: + - port: 6789 + protocol: TCP + name: api + selector: + app: vizier + component: suggestion-grid diff --git a/docs/MinikubeDemo/manifests/vizier/suggestion/random/deployment.yaml b/docs/MinikubeDemo/manifests/vizier/suggestion/random/deployment.yaml new file mode 100644 index 00000000000..5884741e045 --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/suggestion/random/deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-suggestion-random + namespace: katib + labels: + app: vizier + component: suggestion-random +spec: + replicas: 1 + template: + metadata: + name: vizier-suggestion-random + labels: + app: vizier + component: suggestion-random + spec: + containers: + - name: vizier-suggestion-random + image: yujioshima/suggestion-random + ports: + - name: api + containerPort: 6789 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/MinikubeDemo/manifests/vizier/suggestion/random/service.yaml b/docs/MinikubeDemo/manifests/vizier/suggestion/random/service.yaml new file mode 100644 index 00000000000..463cdca1da0 --- /dev/null +++ b/docs/MinikubeDemo/manifests/vizier/suggestion/random/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-suggestion-random + namespace: katib + labels: + app: vizier + component: suggestion-random +spec: + type: ClusterIP + ports: + - port: 6789 + protocol: TCP + name: api + selector: + app: vizier + component: suggestion-random diff --git a/docs/MinikubeDemo/radom-suggest-demo.go b/docs/MinikubeDemo/radom-suggest-demo.go new file mode 100644 index 00000000000..39ede12cfd3 --- /dev/null +++ b/docs/MinikubeDemo/radom-suggest-demo.go @@ -0,0 +1,172 @@ +package main + +import ( + "context" + "log" + "time" + + "github.com/kubeflow/katib/pkg/api" + "google.golang.org/grpc" +) + +const ( + manager = "192.168.99.100:30678" +) + +var studyConfig = api.StudyConfig{ + Name: "random-demo", + Owner: "katib", + OptimizationType: api.OptimizationType_MAXIMIZE, + OptimizationGoal: 0.99, + DefaultSuggestionAlgorithm: "random", + DefaultEarlyStoppingAlgorithm: "medianstopping", + ObjectiveValueName: "Validation-accuracy", + Metrics: []string{ + "accuracy", + }, + ParameterConfigs: &api.StudyConfig_ParameterConfigs{ + Configs: []*api.ParameterConfig{ + &api.ParameterConfig{ + Name: "--lr", + ParameterType: api.ParameterType_DOUBLE, + Feasible: &api.FeasibleSpace{ + Max: "0,03", + Min: "0.07", + }, + }, + }, + }, +} + +func main() { + conn, err := grpc.Dial(manager, grpc.WithInsecure()) + if err != nil { + log.Fatalf("could not connect: %v", err) + } + defer conn.Close() + c := api.NewManagerClient(conn) + createStudyreq := &api.CreateStudyRequest{ + StudyConfig: &studyConfig, + } + createStudyreply, err := c.CreateStudy(context.Background(), createStudyreq) + if err != nil { + log.Fatalf("StudyConfig Error %v", err) + } + studyId := createStudyreply.StudyId + log.Printf("Study ID %s", studyId) + getStudyreq := &api.GetStudyRequest{ + StudyId: studyId, + } + getStudyReply, err := c.GetStudy(context.Background(), getStudyreq) + if err != nil { + log.Fatalf("GetConfig Error %v", err) + } + log.Printf("Study ID %s StudyConf%v", studyId, getStudyReply.StudyConfig) + getRandomSuggestRequest := &api.GetSuggestionsRequest{ + StudyId: studyId, + SuggestionAlgorithm: "random", + RequestNumber: 2, + } + getRandomSuggestReply, err := c.GetSuggestions(context.Background(), getRandomSuggestRequest) + if err != nil { + log.Fatalf("GetSuggestion Error %v", err) + } + log.Printf("Get Random Suggestions %v", getRandomSuggestReply.Trials) + workerIds := make([]string, len(getRandomSuggestReply.Trials)) + workerParameter := make(map[string][]*api.Parameter) + for i, t := range getRandomSuggestReply.Trials { + rtr := &api.RunTrialRequest{ + StudyId: studyId, + TrialId: t.TrialId, + Runtime: "kubernetes", + WorkerConfig: &api.WorkerConfig{ + Image: "mxnet/python", + Command: []string{ + "python", + "/mxnet/example/image-classification/train_mnist.py", + "--batch-size=64", + }, + Gpu: 0, + Scheduler: "default-scheduler", + }, + } + for _, p := range t.ParameterSet { + rtr.WorkerConfig.Command = append(rtr.WorkerConfig.Command, p.Name) + rtr.WorkerConfig.Command = append(rtr.WorkerConfig.Command, p.Value) + } + workerReply, err := c.RunTrial(context.Background(), rtr) + if err != nil { + log.Fatalf("RunTrial Error %v", err) + } + workerIds[i] = workerReply.WorkerId + workerParameter[workerReply.WorkerId] = t.ParameterSet + saveModelRequest := &api.SaveModelRequest{ + Model: &api.ModelInfo{ + StudyName: studyConfig.Name, + WorkerId: workerReply.WorkerId, + Parameters: t.ParameterSet, + Metrics: []*api.Metrics{}, + ModelPath: "pvc:/Path/to/Model", + }, + DataSet: &api.DataSetInfo{ + Name: "Mnist", + Path: "/path/to/data", + }, + } + _, err = c.SaveModel(context.Background(), saveModelRequest) + if err != nil { + log.Fatalf("SaveModel Error %v", err) + } + log.Printf("WorkerID %s start\n", workerReply.WorkerId) + } + for true { + time.Sleep(10 * time.Second) + getMetricsRequest := &api.GetMetricsRequest{ + StudyId: studyId, + WorkerIds: workerIds, + } + getMetricsReply, err := c.GetMetrics(context.Background(), getMetricsRequest) + if err != nil { + log.Printf("GetMetErr %v", err) + continue + } + for _, mls := range getMetricsReply.MetricsLogSets { + if len(mls.MetricsLogs) > 0 { + log.Printf("WorkerID %s :", mls.WorkerId) + //Only Metrics can be updated. + saveModelRequest := &api.SaveModelRequest{ + Model: &api.ModelInfo{ + StudyName: studyConfig.Name, + WorkerId: mls.WorkerId, + Metrics: []*api.Metrics{}, + }, + } + for _, ml := range mls.MetricsLogs { + if len(ml.Values) > 0 { + log.Printf("\t Metrics Name %s Value %v", ml.Name, ml.Values[len(ml.Values)-1]) + saveModelRequest.Model.Metrics = append(saveModelRequest.Model.Metrics, &api.Metrics{Name: ml.Name, Value: ml.Values[len(ml.Values)-1]}) + } + } + _, err = c.SaveModel(context.Background(), saveModelRequest) + if err != nil { + log.Fatalf("SaveModel Error %v", err) + } + } + } + getWorkerRequest := &api.GetWorkersRequest{StudyId: studyId} + getWorkerReply, err := c.GetWorkers(context.Background(), getWorkerRequest) + if err != nil { + log.Fatalf("GetWorker Error %v", err) + } + completeCount := 0 + for _, w := range getWorkerReply.Workers { + if w.Status == api.State_COMPLETED { + completeCount++ + } + } + if completeCount == len(getWorkerReply.Workers) { + log.Printf("All Worker Completed!") + break + } + } +} diff --git a/examples/random.yml b/examples/random.yml deleted file mode 100644 index 8efafdf9e26..00000000000 --- a/examples/random.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: cifer10 -owner: root -optimizationtype: 2 -suggestalgorithm: random -autostopalgorithm: median -objectivevaluename: Validation-accuracy -scheduler: default-scheduler -image: mxnet/python:gpu -gpu: 2 -suggestionparameters: - - - name: SuggestionNum - value: 2 - - - name: MaxParallel - value: 2 -command: - - python - - /mxnet/example/image-classification/train_cifar10.py - - --batch-size=512 - - --gpus=0,1 -metrics: - - accuracy -parameterconfigs: - configs: - - - name: --lr - parametertype: 1 - feasible: - min: 0.03 - max: 0.07 - - - name: --lr-factor - parametertype: 1 - feasible: - min: 0.05 - max: 0.2 - - - name: --max-random-h - parametertype: 2 - feasible: - min: 26 - max: 46 - - - name: --max-random-l - parametertype: 2 - feasible: - min: 25 - max: 75 - - - name: --num-epochs - parametertype: 2 - feasible: - min: 3 - max: 3 diff --git a/manifests/vizier/core/rbac.yaml b/manifests/vizier/core/rbac.yaml index 51381e9b68e..b5482ad8951 100644 --- a/manifests/vizier/core/rbac.yaml +++ b/manifests/vizier/core/rbac.yaml @@ -17,11 +17,17 @@ apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: vizier-core rules: - - verbs: ["*"] - apiGroups: ["extensions"] + - apiGroups: [""] + resources: ["pods", "nodes", "nodes/*", "pods/log", "pods/status", "services", "persistentvolumes", "persistentvolumes/status","persistentvolumeclaims","persistentvolumeclaims/status"] + verbs: ["*"] + - apiGroups: ["batch"] + resources: ["jobs", "jobs/status"] + verbs: ["*"] + - apiGroups: ["extensions"] + verbs: ["*"] resources: ["ingresses","ingresses/status","deployments","deployments/status"] - - verbs: ["*"] - apiGroups: [""] + - apiGroups: [""] + verbs: ["*"] resources: ["services"] --- apiVersion: v1 diff --git a/pkg/api/api.pb.go b/pkg/api/api.pb.go index 4526cb037c3..dba49fb226b 100644 --- a/pkg/api/api.pb.go +++ b/pkg/api/api.pb.go @@ -11,32 +11,40 @@ It has these top-level messages: FeasibleSpace ParameterConfig Parameter + MetricsLogSet Metrics - EvaluationLog + MetricsLog SuggestionParameter EarlyStoppingParameter Tag MountConf + StudyOverview Trial + WorkerConfig + Worker StudyConfig CreateStudyRequest CreateStudyReply StopStudyRequest StopStudyReply - GetStudiesRequest - StudyInfo - GetStudiesReply - SuggestTrialsRequest - SuggestTrialsReply - CompleteTrialRequest - CompleteTrialReply - EarlyStoppingRequest - EarlyStoppingReply - GetObjectValueRequest - GetObjectValueReply - AddMeasurementToTrialsRequest - AddMeasurementToTrialsReply - StudyOverview + GetStudyRequest + GetStudyReply + GetStudyListRequest + GetStudyListReply + GetTrialsRequest + GetTrialsReply + RunTrialRequest + RunTrialReply + StopWorkersRequest + StopWorkersReply + GetWorkersRequest + GetWorkersReply + GetSuggestionsRequest + GetSuggestionsReply + GetShouldStopWorkersRequest + GetShouldStopWorkersReply + GetMetricsRequest + GetMetricsReply ModelInfo DataSetInfo SaveStudyRequest @@ -49,18 +57,16 @@ It has these top-level messages: GetSavedModelsReply GetSavedModelRequest GetSavedModelReply - InitializeSuggestServiceRequest - InitializeSuggestServiceReply - GenerateTrialsRequest - GenerateTrialsReply SetSuggestionParametersRequest SetSuggestionParametersReply + GetSuggestionParametersRequest + GetSuggestionParametersReply StopSuggestionRequest StopSuggestionReply - ShouldTrialStopRequest - ShouldTrialStopReply - SetEarlyStoppingParameterRequest - SetEarlyStoppingParameterReply + SetEarlyStoppingParametersRequest + SetEarlyStoppingParametersReply + GetEarlyStoppingParametersRequest + GetEarlyStoppingParametersReply */ package api @@ -141,24 +147,24 @@ func (x OptimizationType) String() string { func (OptimizationType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } // This value is stored as TINYINT in MySQL. -type TrialState int32 +type State int32 const ( - TrialState_PENDING TrialState = 0 - TrialState_RUNNING TrialState = 1 - TrialState_COMPLETED TrialState = 2 - TrialState_KILLED TrialState = 3 - TrialState_ERROR TrialState = 120 + State_PENDING State = 0 + State_RUNNING State = 1 + State_COMPLETED State = 2 + State_KILLED State = 3 + State_ERROR State = 120 ) -var TrialState_name = map[int32]string{ +var State_name = map[int32]string{ 0: "PENDING", 1: "RUNNING", 2: "COMPLETED", 3: "KILLED", 120: "ERROR", } -var TrialState_value = map[string]int32{ +var State_value = map[string]int32{ "PENDING": 0, "RUNNING": 1, "COMPLETED": 2, @@ -166,10 +172,10 @@ var TrialState_value = map[string]int32{ "ERROR": 120, } -func (x TrialState) String() string { - return proto.EnumName(TrialState_name, int32(x)) +func (x State) String() string { + return proto.EnumName(State_name, int32(x)) } -func (TrialState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } +func (State) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } type FeasibleSpace struct { Max string `protobuf:"bytes,1,opt,name=max" json:"max,omitempty"` @@ -268,6 +274,30 @@ func (m *Parameter) GetValue() string { return "" } +type MetricsLogSet struct { + WorkerId string `protobuf:"bytes,1,opt,name=worker_id,json=workerId" json:"worker_id,omitempty"` + MetricsLogs []*MetricsLog `protobuf:"bytes,2,rep,name=metrics_logs,json=metricsLogs" json:"metrics_logs,omitempty"` +} + +func (m *MetricsLogSet) Reset() { *m = MetricsLogSet{} } +func (m *MetricsLogSet) String() string { return proto.CompactTextString(m) } +func (*MetricsLogSet) ProtoMessage() {} +func (*MetricsLogSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *MetricsLogSet) GetWorkerId() string { + if m != nil { + return m.WorkerId + } + return "" +} + +func (m *MetricsLogSet) GetMetricsLogs() []*MetricsLog { + if m != nil { + return m.MetricsLogs + } + return nil +} + type Metrics struct { Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` @@ -276,7 +306,7 @@ type Metrics struct { func (m *Metrics) Reset() { *m = Metrics{} } func (m *Metrics) String() string { return proto.CompactTextString(m) } func (*Metrics) ProtoMessage() {} -func (*Metrics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } +func (*Metrics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } func (m *Metrics) GetName() string { if m != nil { @@ -292,26 +322,26 @@ func (m *Metrics) GetValue() string { return "" } -type EvaluationLog struct { - Time string `protobuf:"bytes,1,opt,name=time" json:"time,omitempty"` - Metrics []*Metrics `protobuf:"bytes,2,rep,name=metrics" json:"metrics,omitempty"` +type MetricsLog struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Values []string `protobuf:"bytes,2,rep,name=values" json:"values,omitempty"` } -func (m *EvaluationLog) Reset() { *m = EvaluationLog{} } -func (m *EvaluationLog) String() string { return proto.CompactTextString(m) } -func (*EvaluationLog) ProtoMessage() {} -func (*EvaluationLog) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } +func (m *MetricsLog) Reset() { *m = MetricsLog{} } +func (m *MetricsLog) String() string { return proto.CompactTextString(m) } +func (*MetricsLog) ProtoMessage() {} +func (*MetricsLog) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } -func (m *EvaluationLog) GetTime() string { +func (m *MetricsLog) GetName() string { if m != nil { - return m.Time + return m.Name } return "" } -func (m *EvaluationLog) GetMetrics() []*Metrics { +func (m *MetricsLog) GetValues() []string { if m != nil { - return m.Metrics + return m.Values } return nil } @@ -324,7 +354,7 @@ type SuggestionParameter struct { func (m *SuggestionParameter) Reset() { *m = SuggestionParameter{} } func (m *SuggestionParameter) String() string { return proto.CompactTextString(m) } func (*SuggestionParameter) ProtoMessage() {} -func (*SuggestionParameter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } +func (*SuggestionParameter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } func (m *SuggestionParameter) GetName() string { if m != nil { @@ -348,7 +378,7 @@ type EarlyStoppingParameter struct { func (m *EarlyStoppingParameter) Reset() { *m = EarlyStoppingParameter{} } func (m *EarlyStoppingParameter) String() string { return proto.CompactTextString(m) } func (*EarlyStoppingParameter) ProtoMessage() {} -func (*EarlyStoppingParameter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } +func (*EarlyStoppingParameter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } func (m *EarlyStoppingParameter) GetName() string { if m != nil { @@ -372,7 +402,7 @@ type Tag struct { func (m *Tag) Reset() { *m = Tag{} } func (m *Tag) String() string { return proto.CompactTextString(m) } func (*Tag) ProtoMessage() {} -func (*Tag) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } +func (*Tag) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } func (m *Tag) GetName() string { if m != nil { @@ -396,7 +426,7 @@ type MountConf struct { func (m *MountConf) Reset() { *m = MountConf{} } func (m *MountConf) String() string { return proto.CompactTextString(m) } func (*MountConf) ProtoMessage() {} -func (*MountConf) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } +func (*MountConf) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } func (m *MountConf) GetPvc() string { if m != nil { @@ -412,20 +442,59 @@ func (m *MountConf) GetPath() string { return "" } +type StudyOverview struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Owner string `protobuf:"bytes,2,opt,name=owner" json:"owner,omitempty"` + Id string `protobuf:"bytes,3,opt,name=id" json:"id,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description" json:"description,omitempty"` +} + +func (m *StudyOverview) Reset() { *m = StudyOverview{} } +func (m *StudyOverview) String() string { return proto.CompactTextString(m) } +func (*StudyOverview) ProtoMessage() {} +func (*StudyOverview) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } + +func (m *StudyOverview) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *StudyOverview) GetOwner() string { + if m != nil { + return m.Owner + } + return "" +} + +func (m *StudyOverview) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *StudyOverview) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + type Trial struct { - TrialId string `protobuf:"bytes,1,opt,name=trial_id,json=trialId" json:"trial_id,omitempty"` - StudyId string `protobuf:"bytes,2,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - ParameterSet []*Parameter `protobuf:"bytes,3,rep,name=parameter_set,json=parameterSet" json:"parameter_set,omitempty"` - Status TrialState `protobuf:"varint,4,opt,name=status,enum=api.TrialState" json:"status,omitempty"` - EvalLogs []*EvaluationLog `protobuf:"bytes,5,rep,name=eval_logs,json=evalLogs" json:"eval_logs,omitempty"` - ObjectiveValue string `protobuf:"bytes,6,opt,name=objective_value,json=objectiveValue" json:"objective_value,omitempty"` - Tags []*Tag `protobuf:"bytes,7,rep,name=tags" json:"tags,omitempty"` + TrialId string `protobuf:"bytes,1,opt,name=trial_id,json=trialId" json:"trial_id,omitempty"` + StudyId string `protobuf:"bytes,2,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + ParameterSet []*Parameter `protobuf:"bytes,3,rep,name=parameter_set,json=parameterSet" json:"parameter_set,omitempty"` + Status State `protobuf:"varint,4,opt,name=status,enum=api.State" json:"status,omitempty"` + ObjectiveValue string `protobuf:"bytes,5,opt,name=objective_value,json=objectiveValue" json:"objective_value,omitempty"` + Tags []*Tag `protobuf:"bytes,8,rep,name=tags" json:"tags,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{9} } +func (*Trial) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } func (m *Trial) GetTrialId() string { if m != nil { @@ -448,18 +517,11 @@ func (m *Trial) GetParameterSet() []*Parameter { return nil } -func (m *Trial) GetStatus() TrialState { +func (m *Trial) GetStatus() State { if m != nil { return m.Status } - return TrialState_PENDING -} - -func (m *Trial) GetEvalLogs() []*EvaluationLog { - if m != nil { - return m.EvalLogs - } - return nil + return State_PENDING } func (m *Trial) GetObjectiveValue() string { @@ -476,174 +538,222 @@ func (m *Trial) GetTags() []*Tag { return nil } -type StudyConfig struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Owner string `protobuf:"bytes,2,opt,name=owner" json:"owner,omitempty"` - OptimizationType OptimizationType `protobuf:"varint,3,opt,name=optimization_type,json=optimizationType,enum=api.OptimizationType" json:"optimization_type,omitempty"` - OptimizationGoal float64 `protobuf:"fixed64,4,opt,name=optimization_goal,json=optimizationGoal" json:"optimization_goal,omitempty"` - ParameterConfigs *StudyConfig_ParameterConfigs `protobuf:"bytes,5,opt,name=parameter_configs,json=parameterConfigs" json:"parameter_configs,omitempty"` - AccessPermissions []string `protobuf:"bytes,6,rep,name=access_permissions,json=accessPermissions" json:"access_permissions,omitempty"` - SuggestAlgorithm string `protobuf:"bytes,7,opt,name=suggest_algorithm,json=suggestAlgorithm" json:"suggest_algorithm,omitempty"` - EarlyStoppingAlgorithm string `protobuf:"bytes,8,opt,name=early_stopping_algorithm,json=earlyStoppingAlgorithm" json:"early_stopping_algorithm,omitempty"` - StudyTaskName string `protobuf:"bytes,9,opt,name=study_task_name,json=studyTaskName" json:"study_task_name,omitempty"` - SuggestionParameters []*SuggestionParameter `protobuf:"bytes,10,rep,name=suggestion_parameters,json=suggestionParameters" json:"suggestion_parameters,omitempty"` - EarlyStoppingParameters []*EarlyStoppingParameter `protobuf:"bytes,11,rep,name=early_stopping_parameters,json=earlyStoppingParameters" json:"early_stopping_parameters,omitempty"` - Tags []*Tag `protobuf:"bytes,12,rep,name=tags" json:"tags,omitempty"` - ObjectiveValueName string `protobuf:"bytes,13,opt,name=objective_value_name,json=objectiveValueName" json:"objective_value_name,omitempty"` - Metrics []string `protobuf:"bytes,14,rep,name=metrics" json:"metrics,omitempty"` - Image string `protobuf:"bytes,15,opt,name=image" json:"image,omitempty"` - Command []string `protobuf:"bytes,16,rep,name=command" json:"command,omitempty"` - Gpu int32 `protobuf:"varint,17,opt,name=gpu" json:"gpu,omitempty"` - Scheduler string `protobuf:"bytes,18,opt,name=scheduler" json:"scheduler,omitempty"` - Mount *MountConf `protobuf:"bytes,19,opt,name=mount" json:"mount,omitempty"` - PullSecret string `protobuf:"bytes,20,opt,name=pull_secret,json=pullSecret" json:"pull_secret,omitempty"` +type WorkerConfig struct { + Image string `protobuf:"bytes,1,opt,name=image" json:"image,omitempty"` + Command []string `protobuf:"bytes,2,rep,name=command" json:"command,omitempty"` + Gpu int32 `protobuf:"varint,3,opt,name=gpu" json:"gpu,omitempty"` + Scheduler string `protobuf:"bytes,4,opt,name=scheduler" json:"scheduler,omitempty"` + Mount *MountConf `protobuf:"bytes,5,opt,name=mount" json:"mount,omitempty"` + PullSecret string `protobuf:"bytes,6,opt,name=pull_secret,json=pullSecret" json:"pull_secret,omitempty"` } -func (m *StudyConfig) Reset() { *m = StudyConfig{} } -func (m *StudyConfig) String() string { return proto.CompactTextString(m) } -func (*StudyConfig) ProtoMessage() {} -func (*StudyConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } +func (m *WorkerConfig) Reset() { *m = WorkerConfig{} } +func (m *WorkerConfig) String() string { return proto.CompactTextString(m) } +func (*WorkerConfig) ProtoMessage() {} +func (*WorkerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } -func (m *StudyConfig) GetName() string { +func (m *WorkerConfig) GetImage() string { if m != nil { - return m.Name + return m.Image } return "" } -func (m *StudyConfig) GetOwner() string { +func (m *WorkerConfig) GetCommand() []string { if m != nil { - return m.Owner + return m.Command } - return "" + return nil } -func (m *StudyConfig) GetOptimizationType() OptimizationType { +func (m *WorkerConfig) GetGpu() int32 { if m != nil { - return m.OptimizationType + return m.Gpu } - return OptimizationType_UNKNOWN_OPTIMIZATION + return 0 } -func (m *StudyConfig) GetOptimizationGoal() float64 { +func (m *WorkerConfig) GetScheduler() string { if m != nil { - return m.OptimizationGoal + return m.Scheduler } - return 0 + return "" } -func (m *StudyConfig) GetParameterConfigs() *StudyConfig_ParameterConfigs { +func (m *WorkerConfig) GetMount() *MountConf { if m != nil { - return m.ParameterConfigs + return m.Mount } return nil } -func (m *StudyConfig) GetAccessPermissions() []string { +func (m *WorkerConfig) GetPullSecret() string { if m != nil { - return m.AccessPermissions + return m.PullSecret } - return nil + return "" } -func (m *StudyConfig) GetSuggestAlgorithm() string { +type Worker struct { + WorkerId string `protobuf:"bytes,1,opt,name=worker_id,json=workerId" json:"worker_id,omitempty"` + StudyId string `protobuf:"bytes,2,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + TrialId string `protobuf:"bytes,3,opt,name=trial_id,json=trialId" json:"trial_id,omitempty"` + Runtime string `protobuf:"bytes,4,opt,name=runtime" json:"runtime,omitempty"` + Status State `protobuf:"varint,5,opt,name=status,enum=api.State" json:"status,omitempty"` + Config *WorkerConfig `protobuf:"bytes,6,opt,name=config" json:"config,omitempty"` + Tags []*Tag `protobuf:"bytes,7,rep,name=tags" json:"tags,omitempty"` +} + +func (m *Worker) Reset() { *m = Worker{} } +func (m *Worker) String() string { return proto.CompactTextString(m) } +func (*Worker) ProtoMessage() {} +func (*Worker) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } + +func (m *Worker) GetWorkerId() string { if m != nil { - return m.SuggestAlgorithm + return m.WorkerId } return "" } -func (m *StudyConfig) GetEarlyStoppingAlgorithm() string { +func (m *Worker) GetStudyId() string { if m != nil { - return m.EarlyStoppingAlgorithm + return m.StudyId } return "" } -func (m *StudyConfig) GetStudyTaskName() string { +func (m *Worker) GetTrialId() string { if m != nil { - return m.StudyTaskName + return m.TrialId } return "" } -func (m *StudyConfig) GetSuggestionParameters() []*SuggestionParameter { +func (m *Worker) GetRuntime() string { if m != nil { - return m.SuggestionParameters + return m.Runtime } - return nil + return "" } -func (m *StudyConfig) GetEarlyStoppingParameters() []*EarlyStoppingParameter { +func (m *Worker) GetStatus() State { if m != nil { - return m.EarlyStoppingParameters + return m.Status + } + return State_PENDING +} + +func (m *Worker) GetConfig() *WorkerConfig { + if m != nil { + return m.Config } return nil } -func (m *StudyConfig) GetTags() []*Tag { +func (m *Worker) GetTags() []*Tag { if m != nil { return m.Tags } return nil } -func (m *StudyConfig) GetObjectiveValueName() string { +type StudyConfig struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Owner string `protobuf:"bytes,2,opt,name=owner" json:"owner,omitempty"` + OptimizationType OptimizationType `protobuf:"varint,3,opt,name=optimization_type,json=optimizationType,enum=api.OptimizationType" json:"optimization_type,omitempty"` + OptimizationGoal float64 `protobuf:"fixed64,4,opt,name=optimization_goal,json=optimizationGoal" json:"optimization_goal,omitempty"` + ParameterConfigs *StudyConfig_ParameterConfigs `protobuf:"bytes,5,opt,name=parameter_configs,json=parameterConfigs" json:"parameter_configs,omitempty"` + AccessPermissions []string `protobuf:"bytes,6,rep,name=access_permissions,json=accessPermissions" json:"access_permissions,omitempty"` + DefaultSuggestionAlgorithm string `protobuf:"bytes,7,opt,name=default_suggestion_algorithm,json=defaultSuggestionAlgorithm" json:"default_suggestion_algorithm,omitempty"` + DefaultEarlyStoppingAlgorithm string `protobuf:"bytes,8,opt,name=default_early_stopping_algorithm,json=defaultEarlyStoppingAlgorithm" json:"default_early_stopping_algorithm,omitempty"` + Tags []*Tag `protobuf:"bytes,9,rep,name=tags" json:"tags,omitempty"` + ObjectiveValueName string `protobuf:"bytes,10,opt,name=objective_value_name,json=objectiveValueName" json:"objective_value_name,omitempty"` + Metrics []string `protobuf:"bytes,11,rep,name=metrics" json:"metrics,omitempty"` +} + +func (m *StudyConfig) Reset() { *m = StudyConfig{} } +func (m *StudyConfig) String() string { return proto.CompactTextString(m) } +func (*StudyConfig) ProtoMessage() {} +func (*StudyConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } + +func (m *StudyConfig) GetName() string { if m != nil { - return m.ObjectiveValueName + return m.Name } return "" } -func (m *StudyConfig) GetMetrics() []string { +func (m *StudyConfig) GetOwner() string { if m != nil { - return m.Metrics + return m.Owner } - return nil + return "" } -func (m *StudyConfig) GetImage() string { +func (m *StudyConfig) GetOptimizationType() OptimizationType { if m != nil { - return m.Image + return m.OptimizationType } - return "" + return OptimizationType_UNKNOWN_OPTIMIZATION +} + +func (m *StudyConfig) GetOptimizationGoal() float64 { + if m != nil { + return m.OptimizationGoal + } + return 0 } -func (m *StudyConfig) GetCommand() []string { +func (m *StudyConfig) GetParameterConfigs() *StudyConfig_ParameterConfigs { if m != nil { - return m.Command + return m.ParameterConfigs } return nil } -func (m *StudyConfig) GetGpu() int32 { +func (m *StudyConfig) GetAccessPermissions() []string { if m != nil { - return m.Gpu + return m.AccessPermissions } - return 0 + return nil } -func (m *StudyConfig) GetScheduler() string { +func (m *StudyConfig) GetDefaultSuggestionAlgorithm() string { if m != nil { - return m.Scheduler + return m.DefaultSuggestionAlgorithm } return "" } -func (m *StudyConfig) GetMount() *MountConf { +func (m *StudyConfig) GetDefaultEarlyStoppingAlgorithm() string { if m != nil { - return m.Mount + return m.DefaultEarlyStoppingAlgorithm + } + return "" +} + +func (m *StudyConfig) GetTags() []*Tag { + if m != nil { + return m.Tags } return nil } -func (m *StudyConfig) GetPullSecret() string { +func (m *StudyConfig) GetObjectiveValueName() string { if m != nil { - return m.PullSecret + return m.ObjectiveValueName } return "" } +func (m *StudyConfig) GetMetrics() []string { + if m != nil { + return m.Metrics + } + return nil +} + type StudyConfig_ParameterConfigs struct { Configs []*ParameterConfig `protobuf:"bytes,1,rep,name=configs" json:"configs,omitempty"` } @@ -652,7 +762,7 @@ func (m *StudyConfig_ParameterConfigs) Reset() { *m = StudyConfig_Parame func (m *StudyConfig_ParameterConfigs) String() string { return proto.CompactTextString(m) } func (*StudyConfig_ParameterConfigs) ProtoMessage() {} func (*StudyConfig_ParameterConfigs) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{10, 0} + return fileDescriptor0, []int{14, 0} } func (m *StudyConfig_ParameterConfigs) GetConfigs() []*ParameterConfig { @@ -669,7 +779,7 @@ type CreateStudyRequest struct { func (m *CreateStudyRequest) Reset() { *m = CreateStudyRequest{} } func (m *CreateStudyRequest) String() string { return proto.CompactTextString(m) } func (*CreateStudyRequest) ProtoMessage() {} -func (*CreateStudyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } +func (*CreateStudyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } func (m *CreateStudyRequest) GetStudyConfig() *StudyConfig { if m != nil { @@ -685,7 +795,7 @@ type CreateStudyReply struct { func (m *CreateStudyReply) Reset() { *m = CreateStudyReply{} } func (m *CreateStudyReply) String() string { return proto.CompactTextString(m) } func (*CreateStudyReply) ProtoMessage() {} -func (*CreateStudyReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } +func (*CreateStudyReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } func (m *CreateStudyReply) GetStudyId() string { if m != nil { @@ -701,7 +811,7 @@ type StopStudyRequest struct { func (m *StopStudyRequest) Reset() { *m = StopStudyRequest{} } func (m *StopStudyRequest) String() string { return proto.CompactTextString(m) } func (*StopStudyRequest) ProtoMessage() {} -func (*StopStudyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } +func (*StopStudyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } func (m *StopStudyRequest) GetStudyId() string { if m != nil { @@ -716,316 +826,387 @@ type StopStudyReply struct { func (m *StopStudyReply) Reset() { *m = StopStudyReply{} } func (m *StopStudyReply) String() string { return proto.CompactTextString(m) } func (*StopStudyReply) ProtoMessage() {} -func (*StopStudyReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } - -type GetStudiesRequest struct { -} - -func (m *GetStudiesRequest) Reset() { *m = GetStudiesRequest{} } -func (m *GetStudiesRequest) String() string { return proto.CompactTextString(m) } -func (*GetStudiesRequest) ProtoMessage() {} -func (*GetStudiesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } +func (*StopStudyReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } -type StudyInfo struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` - Owner string `protobuf:"bytes,3,opt,name=owner" json:"owner,omitempty"` - RunningTrialNum int32 `protobuf:"varint,4,opt,name=running_trial_num,json=runningTrialNum" json:"running_trial_num,omitempty"` - CompletedTrialNum int32 `protobuf:"varint,5,opt,name=completed_trial_num,json=completedTrialNum" json:"completed_trial_num,omitempty"` +type GetStudyRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` } -func (m *StudyInfo) Reset() { *m = StudyInfo{} } -func (m *StudyInfo) String() string { return proto.CompactTextString(m) } -func (*StudyInfo) ProtoMessage() {} -func (*StudyInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } +func (m *GetStudyRequest) Reset() { *m = GetStudyRequest{} } +func (m *GetStudyRequest) String() string { return proto.CompactTextString(m) } +func (*GetStudyRequest) ProtoMessage() {} +func (*GetStudyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } -func (m *StudyInfo) GetStudyId() string { +func (m *GetStudyRequest) GetStudyId() string { if m != nil { return m.StudyId } return "" } -func (m *StudyInfo) GetName() string { - if m != nil { - return m.Name - } - return "" +type GetStudyReply struct { + StudyConfig *StudyConfig `protobuf:"bytes,1,opt,name=study_config,json=studyConfig" json:"study_config,omitempty"` } -func (m *StudyInfo) GetOwner() string { +func (m *GetStudyReply) Reset() { *m = GetStudyReply{} } +func (m *GetStudyReply) String() string { return proto.CompactTextString(m) } +func (*GetStudyReply) ProtoMessage() {} +func (*GetStudyReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } + +func (m *GetStudyReply) GetStudyConfig() *StudyConfig { if m != nil { - return m.Owner + return m.StudyConfig } - return "" + return nil +} + +type GetStudyListRequest struct { +} + +func (m *GetStudyListRequest) Reset() { *m = GetStudyListRequest{} } +func (m *GetStudyListRequest) String() string { return proto.CompactTextString(m) } +func (*GetStudyListRequest) ProtoMessage() {} +func (*GetStudyListRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } + +type GetStudyListReply struct { + StudyOverviews []*StudyOverview `protobuf:"bytes,1,rep,name=study_overviews,json=studyOverviews" json:"study_overviews,omitempty"` } -func (m *StudyInfo) GetRunningTrialNum() int32 { +func (m *GetStudyListReply) Reset() { *m = GetStudyListReply{} } +func (m *GetStudyListReply) String() string { return proto.CompactTextString(m) } +func (*GetStudyListReply) ProtoMessage() {} +func (*GetStudyListReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } + +func (m *GetStudyListReply) GetStudyOverviews() []*StudyOverview { if m != nil { - return m.RunningTrialNum + return m.StudyOverviews } - return 0 + return nil +} + +type GetTrialsRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` } -func (m *StudyInfo) GetCompletedTrialNum() int32 { +func (m *GetTrialsRequest) Reset() { *m = GetTrialsRequest{} } +func (m *GetTrialsRequest) String() string { return proto.CompactTextString(m) } +func (*GetTrialsRequest) ProtoMessage() {} +func (*GetTrialsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } + +func (m *GetTrialsRequest) GetStudyId() string { if m != nil { - return m.CompletedTrialNum + return m.StudyId } - return 0 + return "" } -type GetStudiesReply struct { - StudyInfos []*StudyInfo `protobuf:"bytes,1,rep,name=study_infos,json=studyInfos" json:"study_infos,omitempty"` +type GetTrialsReply struct { + Trials []*Trial `protobuf:"bytes,1,rep,name=trials" json:"trials,omitempty"` } -func (m *GetStudiesReply) Reset() { *m = GetStudiesReply{} } -func (m *GetStudiesReply) String() string { return proto.CompactTextString(m) } -func (*GetStudiesReply) ProtoMessage() {} -func (*GetStudiesReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } +func (m *GetTrialsReply) Reset() { *m = GetTrialsReply{} } +func (m *GetTrialsReply) String() string { return proto.CompactTextString(m) } +func (*GetTrialsReply) ProtoMessage() {} +func (*GetTrialsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } -func (m *GetStudiesReply) GetStudyInfos() []*StudyInfo { +func (m *GetTrialsReply) GetTrials() []*Trial { if m != nil { - return m.StudyInfos + return m.Trials } return nil } -type SuggestTrialsRequest struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - SuggestAlgorithm string `protobuf:"bytes,2,opt,name=suggest_algorithm,json=suggestAlgorithm" json:"suggest_algorithm,omitempty"` - Configs *StudyConfig `protobuf:"bytes,3,opt,name=configs" json:"configs,omitempty"` +type RunTrialRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + TrialId string `protobuf:"bytes,2,opt,name=trial_id,json=trialId" json:"trial_id,omitempty"` + Runtime string `protobuf:"bytes,3,opt,name=runtime" json:"runtime,omitempty"` + WorkerConfig *WorkerConfig `protobuf:"bytes,4,opt,name=worker_config,json=workerConfig" json:"worker_config,omitempty"` } -func (m *SuggestTrialsRequest) Reset() { *m = SuggestTrialsRequest{} } -func (m *SuggestTrialsRequest) String() string { return proto.CompactTextString(m) } -func (*SuggestTrialsRequest) ProtoMessage() {} -func (*SuggestTrialsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } +func (m *RunTrialRequest) Reset() { *m = RunTrialRequest{} } +func (m *RunTrialRequest) String() string { return proto.CompactTextString(m) } +func (*RunTrialRequest) ProtoMessage() {} +func (*RunTrialRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } -func (m *SuggestTrialsRequest) GetStudyId() string { +func (m *RunTrialRequest) GetStudyId() string { if m != nil { return m.StudyId } return "" } -func (m *SuggestTrialsRequest) GetSuggestAlgorithm() string { +func (m *RunTrialRequest) GetTrialId() string { if m != nil { - return m.SuggestAlgorithm + return m.TrialId } return "" } -func (m *SuggestTrialsRequest) GetConfigs() *StudyConfig { +func (m *RunTrialRequest) GetRuntime() string { if m != nil { - return m.Configs + return m.Runtime } - return nil -} - -type SuggestTrialsReply struct { - Trials []*Trial `protobuf:"bytes,1,rep,name=trials" json:"trials,omitempty"` - Completed bool `protobuf:"varint,2,opt,name=completed" json:"completed,omitempty"` + return "" } -func (m *SuggestTrialsReply) Reset() { *m = SuggestTrialsReply{} } -func (m *SuggestTrialsReply) String() string { return proto.CompactTextString(m) } -func (*SuggestTrialsReply) ProtoMessage() {} -func (*SuggestTrialsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } - -func (m *SuggestTrialsReply) GetTrials() []*Trial { +func (m *RunTrialRequest) GetWorkerConfig() *WorkerConfig { if m != nil { - return m.Trials + return m.WorkerConfig } return nil } -func (m *SuggestTrialsReply) GetCompleted() bool { +type RunTrialReply struct { + WorkerId string `protobuf:"bytes,1,opt,name=worker_id,json=workerId" json:"worker_id,omitempty"` +} + +func (m *RunTrialReply) Reset() { *m = RunTrialReply{} } +func (m *RunTrialReply) String() string { return proto.CompactTextString(m) } +func (*RunTrialReply) ProtoMessage() {} +func (*RunTrialReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } + +func (m *RunTrialReply) GetWorkerId() string { if m != nil { - return m.Completed + return m.WorkerId } - return false + return "" } -type CompleteTrialRequest struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - TrialId string `protobuf:"bytes,2,opt,name=trial_id,json=trialId" json:"trial_id,omitempty"` - IsComplete bool `protobuf:"varint,3,opt,name=is_complete,json=isComplete" json:"is_complete,omitempty"` +type StopWorkersRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + WorkerIds []string `protobuf:"bytes,2,rep,name=worker_ids,json=workerIds" json:"worker_ids,omitempty"` + IsComplete bool `protobuf:"varint,3,opt,name=is_complete,json=isComplete" json:"is_complete,omitempty"` } -func (m *CompleteTrialRequest) Reset() { *m = CompleteTrialRequest{} } -func (m *CompleteTrialRequest) String() string { return proto.CompactTextString(m) } -func (*CompleteTrialRequest) ProtoMessage() {} -func (*CompleteTrialRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } +func (m *StopWorkersRequest) Reset() { *m = StopWorkersRequest{} } +func (m *StopWorkersRequest) String() string { return proto.CompactTextString(m) } +func (*StopWorkersRequest) ProtoMessage() {} +func (*StopWorkersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } -func (m *CompleteTrialRequest) GetStudyId() string { +func (m *StopWorkersRequest) GetStudyId() string { if m != nil { return m.StudyId } return "" } -func (m *CompleteTrialRequest) GetTrialId() string { +func (m *StopWorkersRequest) GetWorkerIds() []string { if m != nil { - return m.TrialId + return m.WorkerIds } - return "" + return nil } -func (m *CompleteTrialRequest) GetIsComplete() bool { +func (m *StopWorkersRequest) GetIsComplete() bool { if m != nil { return m.IsComplete } return false } -type CompleteTrialReply struct { +type StopWorkersReply struct { } -func (m *CompleteTrialReply) Reset() { *m = CompleteTrialReply{} } -func (m *CompleteTrialReply) String() string { return proto.CompactTextString(m) } -func (*CompleteTrialReply) ProtoMessage() {} -func (*CompleteTrialReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } +func (m *StopWorkersReply) Reset() { *m = StopWorkersReply{} } +func (m *StopWorkersReply) String() string { return proto.CompactTextString(m) } +func (*StopWorkersReply) ProtoMessage() {} +func (*StopWorkersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } -type EarlyStoppingRequest struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - EarlyStoppingAlgorithm string `protobuf:"bytes,2,opt,name=early_stopping_algorithm,json=earlyStoppingAlgorithm" json:"early_stopping_algorithm,omitempty"` +type GetWorkersRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` } -func (m *EarlyStoppingRequest) Reset() { *m = EarlyStoppingRequest{} } -func (m *EarlyStoppingRequest) String() string { return proto.CompactTextString(m) } -func (*EarlyStoppingRequest) ProtoMessage() {} -func (*EarlyStoppingRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } +func (m *GetWorkersRequest) Reset() { *m = GetWorkersRequest{} } +func (m *GetWorkersRequest) String() string { return proto.CompactTextString(m) } +func (*GetWorkersRequest) ProtoMessage() {} +func (*GetWorkersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } -func (m *EarlyStoppingRequest) GetStudyId() string { +func (m *GetWorkersRequest) GetStudyId() string { if m != nil { return m.StudyId } return "" } -func (m *EarlyStoppingRequest) GetEarlyStoppingAlgorithm() string { +type GetWorkersReply struct { + Workers []*Worker `protobuf:"bytes,1,rep,name=workers" json:"workers,omitempty"` +} + +func (m *GetWorkersReply) Reset() { *m = GetWorkersReply{} } +func (m *GetWorkersReply) String() string { return proto.CompactTextString(m) } +func (*GetWorkersReply) ProtoMessage() {} +func (*GetWorkersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } + +func (m *GetWorkersReply) GetWorkers() []*Worker { if m != nil { - return m.EarlyStoppingAlgorithm + return m.Workers } - return "" + return nil } -type EarlyStoppingReply struct { - Trials []*Trial `protobuf:"bytes,1,rep,name=trials" json:"trials,omitempty"` +type GetSuggestionsRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + SuggestionAlgorithm string `protobuf:"bytes,2,opt,name=suggestion_algorithm,json=suggestionAlgorithm" json:"suggestion_algorithm,omitempty"` + RequestNumber int32 `protobuf:"varint,3,opt,name=request_number,json=requestNumber" json:"request_number,omitempty"` + LogWorkerIds []string `protobuf:"bytes,4,rep,name=log_worker_ids,json=logWorkerIds" json:"log_worker_ids,omitempty"` + ParamId string `protobuf:"bytes,5,opt,name=param_id,json=paramId" json:"param_id,omitempty"` } -func (m *EarlyStoppingReply) Reset() { *m = EarlyStoppingReply{} } -func (m *EarlyStoppingReply) String() string { return proto.CompactTextString(m) } -func (*EarlyStoppingReply) ProtoMessage() {} -func (*EarlyStoppingReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } +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{31} } -func (m *EarlyStoppingReply) GetTrials() []*Trial { +func (m *GetSuggestionsRequest) GetStudyId() string { if m != nil { - return m.Trials + return m.StudyId } - return nil + return "" } -type GetObjectValueRequest struct { - WorkerId string `protobuf:"bytes,1,opt,name=worker_id,json=workerId" json:"worker_id,omitempty"` +func (m *GetSuggestionsRequest) GetSuggestionAlgorithm() string { + if m != nil { + return m.SuggestionAlgorithm + } + return "" +} + +func (m *GetSuggestionsRequest) GetRequestNumber() int32 { + if m != nil { + return m.RequestNumber + } + return 0 } -func (m *GetObjectValueRequest) Reset() { *m = GetObjectValueRequest{} } -func (m *GetObjectValueRequest) String() string { return proto.CompactTextString(m) } -func (*GetObjectValueRequest) ProtoMessage() {} -func (*GetObjectValueRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } +func (m *GetSuggestionsRequest) GetLogWorkerIds() []string { + if m != nil { + return m.LogWorkerIds + } + return nil +} -func (m *GetObjectValueRequest) GetWorkerId() string { +func (m *GetSuggestionsRequest) GetParamId() string { if m != nil { - return m.WorkerId + return m.ParamId } return "" } -type GetObjectValueReply struct { +type GetSuggestionsReply struct { Trials []*Trial `protobuf:"bytes,1,rep,name=trials" json:"trials,omitempty"` } -func (m *GetObjectValueReply) Reset() { *m = GetObjectValueReply{} } -func (m *GetObjectValueReply) String() string { return proto.CompactTextString(m) } -func (*GetObjectValueReply) ProtoMessage() {} -func (*GetObjectValueReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } +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{32} } -func (m *GetObjectValueReply) GetTrials() []*Trial { +func (m *GetSuggestionsReply) GetTrials() []*Trial { if m != nil { return m.Trials } return nil } -type AddMeasurementToTrialsRequest struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - // metrics can be a json string - Metrics string `protobuf:"bytes,2,opt,name=metrics" json:"metrics,omitempty"` +type GetShouldStopWorkersRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + EarlyStoppingAlgorithm string `protobuf:"bytes,2,opt,name=early_stopping_algorithm,json=earlyStoppingAlgorithm" json:"early_stopping_algorithm,omitempty"` + ParamId string `protobuf:"bytes,5,opt,name=param_id,json=paramId" json:"param_id,omitempty"` } -func (m *AddMeasurementToTrialsRequest) Reset() { *m = AddMeasurementToTrialsRequest{} } -func (m *AddMeasurementToTrialsRequest) String() string { return proto.CompactTextString(m) } -func (*AddMeasurementToTrialsRequest) ProtoMessage() {} -func (*AddMeasurementToTrialsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } +func (m *GetShouldStopWorkersRequest) Reset() { *m = GetShouldStopWorkersRequest{} } +func (m *GetShouldStopWorkersRequest) String() string { return proto.CompactTextString(m) } +func (*GetShouldStopWorkersRequest) ProtoMessage() {} +func (*GetShouldStopWorkersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } -func (m *AddMeasurementToTrialsRequest) GetStudyId() string { +func (m *GetShouldStopWorkersRequest) GetStudyId() string { if m != nil { return m.StudyId } return "" } -func (m *AddMeasurementToTrialsRequest) GetMetrics() string { +func (m *GetShouldStopWorkersRequest) GetEarlyStoppingAlgorithm() string { if m != nil { - return m.Metrics + return m.EarlyStoppingAlgorithm } return "" } -type AddMeasurementToTrialsReply struct { +func (m *GetShouldStopWorkersRequest) GetParamId() string { + if m != nil { + return m.ParamId + } + return "" } -func (m *AddMeasurementToTrialsReply) Reset() { *m = AddMeasurementToTrialsReply{} } -func (m *AddMeasurementToTrialsReply) String() string { return proto.CompactTextString(m) } -func (*AddMeasurementToTrialsReply) ProtoMessage() {} -func (*AddMeasurementToTrialsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } - -type StudyOverview struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Owner string `protobuf:"bytes,2,opt,name=owner" json:"owner,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` +type GetShouldStopWorkersReply struct { + ShouldStopWorkerIds []string `protobuf:"bytes,1,rep,name=should_stop_worker_ids,json=shouldStopWorkerIds" json:"should_stop_worker_ids,omitempty"` } -func (m *StudyOverview) Reset() { *m = StudyOverview{} } -func (m *StudyOverview) String() string { return proto.CompactTextString(m) } -func (*StudyOverview) ProtoMessage() {} -func (*StudyOverview) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } +func (m *GetShouldStopWorkersReply) Reset() { *m = GetShouldStopWorkersReply{} } +func (m *GetShouldStopWorkersReply) String() string { return proto.CompactTextString(m) } +func (*GetShouldStopWorkersReply) ProtoMessage() {} +func (*GetShouldStopWorkersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } -func (m *StudyOverview) GetName() string { +func (m *GetShouldStopWorkersReply) GetShouldStopWorkerIds() []string { if m != nil { - return m.Name + return m.ShouldStopWorkerIds } - return "" + return nil } -func (m *StudyOverview) GetOwner() string { +type GetMetricsRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + WorkerIds []string `protobuf:"bytes,2,rep,name=worker_ids,json=workerIds" json:"worker_ids,omitempty"` + MetricsNames []string `protobuf:"bytes,3,rep,name=metrics_names,json=metricsNames" json:"metrics_names,omitempty"` +} + +func (m *GetMetricsRequest) Reset() { *m = GetMetricsRequest{} } +func (m *GetMetricsRequest) String() string { return proto.CompactTextString(m) } +func (*GetMetricsRequest) ProtoMessage() {} +func (*GetMetricsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } + +func (m *GetMetricsRequest) GetStudyId() string { if m != nil { - return m.Owner + return m.StudyId } return "" } -func (m *StudyOverview) GetDescription() string { +func (m *GetMetricsRequest) GetWorkerIds() []string { if m != nil { - return m.Description + return m.WorkerIds } - return "" + return nil +} + +func (m *GetMetricsRequest) GetMetricsNames() []string { + if m != nil { + return m.MetricsNames + } + return nil +} + +type GetMetricsReply struct { + MetricsLogSets []*MetricsLogSet `protobuf:"bytes,1,rep,name=metrics_log_sets,json=metricsLogSets" json:"metrics_log_sets,omitempty"` +} + +func (m *GetMetricsReply) Reset() { *m = GetMetricsReply{} } +func (m *GetMetricsReply) String() string { return proto.CompactTextString(m) } +func (*GetMetricsReply) ProtoMessage() {} +func (*GetMetricsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } + +func (m *GetMetricsReply) GetMetricsLogSets() []*MetricsLogSet { + if m != nil { + return m.MetricsLogSets + } + return nil } type ModelInfo struct { StudyName string `protobuf:"bytes,1,opt,name=study_name,json=studyName" json:"study_name,omitempty"` - TrialId string `protobuf:"bytes,2,opt,name=trial_id,json=trialId" json:"trial_id,omitempty"` + WorkerId string `protobuf:"bytes,2,opt,name=worker_id,json=workerId" json:"worker_id,omitempty"` Parameters []*Parameter `protobuf:"bytes,3,rep,name=parameters" json:"parameters,omitempty"` Metrics []*Metrics `protobuf:"bytes,4,rep,name=metrics" json:"metrics,omitempty"` ModelPath string `protobuf:"bytes,5,opt,name=model_path,json=modelPath" json:"model_path,omitempty"` @@ -1034,7 +1215,7 @@ type ModelInfo struct { func (m *ModelInfo) Reset() { *m = ModelInfo{} } func (m *ModelInfo) String() string { return proto.CompactTextString(m) } func (*ModelInfo) ProtoMessage() {} -func (*ModelInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } +func (*ModelInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } func (m *ModelInfo) GetStudyName() string { if m != nil { @@ -1043,9 +1224,9 @@ func (m *ModelInfo) GetStudyName() string { return "" } -func (m *ModelInfo) GetTrialId() string { +func (m *ModelInfo) GetWorkerId() string { if m != nil { - return m.TrialId + return m.WorkerId } return "" } @@ -1079,7 +1260,7 @@ type DataSetInfo struct { func (m *DataSetInfo) Reset() { *m = DataSetInfo{} } func (m *DataSetInfo) String() string { return proto.CompactTextString(m) } func (*DataSetInfo) ProtoMessage() {} -func (*DataSetInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } +func (*DataSetInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } func (m *DataSetInfo) GetName() string { if m != nil { @@ -1104,7 +1285,7 @@ type SaveStudyRequest struct { func (m *SaveStudyRequest) Reset() { *m = SaveStudyRequest{} } func (m *SaveStudyRequest) String() string { return proto.CompactTextString(m) } func (*SaveStudyRequest) ProtoMessage() {} -func (*SaveStudyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } +func (*SaveStudyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } func (m *SaveStudyRequest) GetStudyName() string { if m != nil { @@ -1133,7 +1314,7 @@ type SaveStudyReply struct { func (m *SaveStudyReply) Reset() { *m = SaveStudyReply{} } func (m *SaveStudyReply) String() string { return proto.CompactTextString(m) } func (*SaveStudyReply) ProtoMessage() {} -func (*SaveStudyReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } +func (*SaveStudyReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } type SaveModelRequest struct { Model *ModelInfo `protobuf:"bytes,1,opt,name=model" json:"model,omitempty"` @@ -1144,7 +1325,7 @@ type SaveModelRequest struct { func (m *SaveModelRequest) Reset() { *m = SaveModelRequest{} } func (m *SaveModelRequest) String() string { return proto.CompactTextString(m) } func (*SaveModelRequest) ProtoMessage() {} -func (*SaveModelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } +func (*SaveModelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } func (m *SaveModelRequest) GetModel() *ModelInfo { if m != nil { @@ -1173,7 +1354,7 @@ type SaveModelReply struct { func (m *SaveModelReply) Reset() { *m = SaveModelReply{} } func (m *SaveModelReply) String() string { return proto.CompactTextString(m) } func (*SaveModelReply) ProtoMessage() {} -func (*SaveModelReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } +func (*SaveModelReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } type GetSavedStudiesRequest struct { } @@ -1181,7 +1362,7 @@ type GetSavedStudiesRequest struct { func (m *GetSavedStudiesRequest) Reset() { *m = GetSavedStudiesRequest{} } func (m *GetSavedStudiesRequest) String() string { return proto.CompactTextString(m) } func (*GetSavedStudiesRequest) ProtoMessage() {} -func (*GetSavedStudiesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } +func (*GetSavedStudiesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } type GetSavedStudiesReply struct { Studies []*StudyOverview `protobuf:"bytes,1,rep,name=studies" json:"studies,omitempty"` @@ -1190,7 +1371,7 @@ type GetSavedStudiesReply struct { func (m *GetSavedStudiesReply) Reset() { *m = GetSavedStudiesReply{} } func (m *GetSavedStudiesReply) String() string { return proto.CompactTextString(m) } func (*GetSavedStudiesReply) ProtoMessage() {} -func (*GetSavedStudiesReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } +func (*GetSavedStudiesReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } func (m *GetSavedStudiesReply) GetStudies() []*StudyOverview { if m != nil { @@ -1206,7 +1387,7 @@ type GetSavedModelsRequest struct { func (m *GetSavedModelsRequest) Reset() { *m = GetSavedModelsRequest{} } func (m *GetSavedModelsRequest) String() string { return proto.CompactTextString(m) } func (*GetSavedModelsRequest) ProtoMessage() {} -func (*GetSavedModelsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } +func (*GetSavedModelsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } func (m *GetSavedModelsRequest) GetStudyName() string { if m != nil { @@ -1222,7 +1403,7 @@ type GetSavedModelsReply struct { func (m *GetSavedModelsReply) Reset() { *m = GetSavedModelsReply{} } func (m *GetSavedModelsReply) String() string { return proto.CompactTextString(m) } func (*GetSavedModelsReply) ProtoMessage() {} -func (*GetSavedModelsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } +func (*GetSavedModelsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} } func (m *GetSavedModelsReply) GetModels() []*ModelInfo { if m != nil { @@ -1233,13 +1414,13 @@ func (m *GetSavedModelsReply) GetModels() []*ModelInfo { type GetSavedModelRequest struct { StudyName string `protobuf:"bytes,1,opt,name=study_name,json=studyName" json:"study_name,omitempty"` - TrialId string `protobuf:"bytes,2,opt,name=trial_id,json=trialId" json:"trial_id,omitempty"` + WorkerId string `protobuf:"bytes,2,opt,name=worker_id,json=workerId" json:"worker_id,omitempty"` } func (m *GetSavedModelRequest) Reset() { *m = GetSavedModelRequest{} } func (m *GetSavedModelRequest) String() string { return proto.CompactTextString(m) } func (*GetSavedModelRequest) ProtoMessage() {} -func (*GetSavedModelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } +func (*GetSavedModelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} } func (m *GetSavedModelRequest) GetStudyName() string { if m != nil { @@ -1248,9 +1429,9 @@ func (m *GetSavedModelRequest) GetStudyName() string { return "" } -func (m *GetSavedModelRequest) GetTrialId() string { +func (m *GetSavedModelRequest) GetWorkerId() string { if m != nil { - return m.TrialId + return m.WorkerId } return "" } @@ -1262,7 +1443,7 @@ type GetSavedModelReply struct { func (m *GetSavedModelReply) Reset() { *m = GetSavedModelReply{} } func (m *GetSavedModelReply) String() string { return proto.CompactTextString(m) } func (*GetSavedModelReply) ProtoMessage() {} -func (*GetSavedModelReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } +func (*GetSavedModelReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} } func (m *GetSavedModelReply) GetModel() *ModelInfo { if m != nil { @@ -1271,160 +1452,94 @@ func (m *GetSavedModelReply) GetModel() *ModelInfo { return nil } -type InitializeSuggestServiceRequest struct { +type SetSuggestionParametersRequest struct { StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - SuggestAlgorithm string `protobuf:"bytes,2,opt,name=suggest_algorithm,json=suggestAlgorithm" json:"suggest_algorithm,omitempty"` - SuggestionParameters []*SuggestionParameter `protobuf:"bytes,3,rep,name=suggestion_parameters,json=suggestionParameters" json:"suggestion_parameters,omitempty"` - Configs *StudyConfig `protobuf:"bytes,4,opt,name=configs" json:"configs,omitempty"` + SuggestionAlgorithm string `protobuf:"bytes,2,opt,name=suggestion_algorithm,json=suggestionAlgorithm" json:"suggestion_algorithm,omitempty"` + ParamId string `protobuf:"bytes,3,opt,name=param_id,json=paramId" json:"param_id,omitempty"` + SuggestionParameters []*SuggestionParameter `protobuf:"bytes,4,rep,name=suggestion_parameters,json=suggestionParameters" json:"suggestion_parameters,omitempty"` } -func (m *InitializeSuggestServiceRequest) Reset() { *m = InitializeSuggestServiceRequest{} } -func (m *InitializeSuggestServiceRequest) String() string { return proto.CompactTextString(m) } -func (*InitializeSuggestServiceRequest) ProtoMessage() {} -func (*InitializeSuggestServiceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{41} -} +func (m *SetSuggestionParametersRequest) Reset() { *m = SetSuggestionParametersRequest{} } +func (m *SetSuggestionParametersRequest) String() string { return proto.CompactTextString(m) } +func (*SetSuggestionParametersRequest) ProtoMessage() {} +func (*SetSuggestionParametersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} } -func (m *InitializeSuggestServiceRequest) GetStudyId() string { +func (m *SetSuggestionParametersRequest) GetStudyId() string { if m != nil { return m.StudyId } return "" } -func (m *InitializeSuggestServiceRequest) GetSuggestAlgorithm() string { +func (m *SetSuggestionParametersRequest) GetSuggestionAlgorithm() string { if m != nil { - return m.SuggestAlgorithm + return m.SuggestionAlgorithm } return "" } -func (m *InitializeSuggestServiceRequest) GetSuggestionParameters() []*SuggestionParameter { +func (m *SetSuggestionParametersRequest) GetParamId() string { if m != nil { - return m.SuggestionParameters + return m.ParamId } - return nil + return "" } -func (m *InitializeSuggestServiceRequest) GetConfigs() *StudyConfig { +func (m *SetSuggestionParametersRequest) GetSuggestionParameters() []*SuggestionParameter { if m != nil { - return m.Configs + return m.SuggestionParameters } return nil } -type InitializeSuggestServiceReply struct { -} - -func (m *InitializeSuggestServiceReply) Reset() { *m = InitializeSuggestServiceReply{} } -func (m *InitializeSuggestServiceReply) String() string { return proto.CompactTextString(m) } -func (*InitializeSuggestServiceReply) ProtoMessage() {} -func (*InitializeSuggestServiceReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } - -type GenerateTrialsRequest struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - Configs *StudyConfig `protobuf:"bytes,2,opt,name=configs" json:"configs,omitempty"` - CompletedTrials []*Trial `protobuf:"bytes,3,rep,name=completed_trials,json=completedTrials" json:"completed_trials,omitempty"` - RunningTrials []*Trial `protobuf:"bytes,4,rep,name=running_trials,json=runningTrials" json:"running_trials,omitempty"` +type SetSuggestionParametersReply struct { + ParamId string `protobuf:"bytes,1,opt,name=param_id,json=paramId" json:"param_id,omitempty"` } -func (m *GenerateTrialsRequest) Reset() { *m = GenerateTrialsRequest{} } -func (m *GenerateTrialsRequest) String() string { return proto.CompactTextString(m) } -func (*GenerateTrialsRequest) ProtoMessage() {} -func (*GenerateTrialsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } +func (m *SetSuggestionParametersReply) Reset() { *m = SetSuggestionParametersReply{} } +func (m *SetSuggestionParametersReply) String() string { return proto.CompactTextString(m) } +func (*SetSuggestionParametersReply) ProtoMessage() {} +func (*SetSuggestionParametersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} } -func (m *GenerateTrialsRequest) GetStudyId() string { +func (m *SetSuggestionParametersReply) GetParamId() string { if m != nil { - return m.StudyId + return m.ParamId } return "" } -func (m *GenerateTrialsRequest) GetConfigs() *StudyConfig { - if m != nil { - return m.Configs - } - return nil -} - -func (m *GenerateTrialsRequest) GetCompletedTrials() []*Trial { - if m != nil { - return m.CompletedTrials - } - return nil +type GetSuggestionParametersRequest struct { + ParamId string `protobuf:"bytes,1,opt,name=param_id,json=paramId" json:"param_id,omitempty"` } -func (m *GenerateTrialsRequest) GetRunningTrials() []*Trial { - if m != nil { - return m.RunningTrials - } - return nil -} - -type GenerateTrialsReply struct { - Trials []*Trial `protobuf:"bytes,1,rep,name=trials" json:"trials,omitempty"` - Completed bool `protobuf:"varint,2,opt,name=completed" json:"completed,omitempty"` -} - -func (m *GenerateTrialsReply) Reset() { *m = GenerateTrialsReply{} } -func (m *GenerateTrialsReply) String() string { return proto.CompactTextString(m) } -func (*GenerateTrialsReply) ProtoMessage() {} -func (*GenerateTrialsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } - -func (m *GenerateTrialsReply) GetTrials() []*Trial { - if m != nil { - return m.Trials - } - return nil -} +func (m *GetSuggestionParametersRequest) Reset() { *m = GetSuggestionParametersRequest{} } +func (m *GetSuggestionParametersRequest) String() string { return proto.CompactTextString(m) } +func (*GetSuggestionParametersRequest) ProtoMessage() {} +func (*GetSuggestionParametersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} } -func (m *GenerateTrialsReply) GetCompleted() bool { +func (m *GetSuggestionParametersRequest) GetParamId() string { if m != nil { - return m.Completed + return m.ParamId } - return false + return "" } -type SetSuggestionParametersRequest struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - SuggestionParameters []*SuggestionParameter `protobuf:"bytes,2,rep,name=suggestion_parameters,json=suggestionParameters" json:"suggestion_parameters,omitempty"` - Configs *StudyConfig `protobuf:"bytes,3,opt,name=configs" json:"configs,omitempty"` +type GetSuggestionParametersReply struct { + SuggestionParameters []*SuggestionParameter `protobuf:"bytes,1,rep,name=suggestion_parameters,json=suggestionParameters" json:"suggestion_parameters,omitempty"` } -func (m *SetSuggestionParametersRequest) Reset() { *m = SetSuggestionParametersRequest{} } -func (m *SetSuggestionParametersRequest) String() string { return proto.CompactTextString(m) } -func (*SetSuggestionParametersRequest) ProtoMessage() {} -func (*SetSuggestionParametersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } - -func (m *SetSuggestionParametersRequest) GetStudyId() string { - if m != nil { - return m.StudyId - } - return "" -} +func (m *GetSuggestionParametersReply) Reset() { *m = GetSuggestionParametersReply{} } +func (m *GetSuggestionParametersReply) String() string { return proto.CompactTextString(m) } +func (*GetSuggestionParametersReply) ProtoMessage() {} +func (*GetSuggestionParametersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} } -func (m *SetSuggestionParametersRequest) GetSuggestionParameters() []*SuggestionParameter { +func (m *GetSuggestionParametersReply) GetSuggestionParameters() []*SuggestionParameter { if m != nil { return m.SuggestionParameters } return nil } -func (m *SetSuggestionParametersRequest) GetConfigs() *StudyConfig { - if m != nil { - return m.Configs - } - return nil -} - -type SetSuggestionParametersReply struct { -} - -func (m *SetSuggestionParametersReply) Reset() { *m = SetSuggestionParametersReply{} } -func (m *SetSuggestionParametersReply) String() string { return proto.CompactTextString(m) } -func (*SetSuggestionParametersReply) ProtoMessage() {} -func (*SetSuggestionParametersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} } - type StopSuggestionRequest struct { StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` } @@ -1432,7 +1547,7 @@ type StopSuggestionRequest struct { func (m *StopSuggestionRequest) Reset() { *m = StopSuggestionRequest{} } func (m *StopSuggestionRequest) String() string { return proto.CompactTextString(m) } func (*StopSuggestionRequest) ProtoMessage() {} -func (*StopSuggestionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} } +func (*StopSuggestionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} } func (m *StopSuggestionRequest) GetStudyId() string { if m != nil { @@ -1447,105 +1562,143 @@ type StopSuggestionReply struct { func (m *StopSuggestionReply) Reset() { *m = StopSuggestionReply{} } func (m *StopSuggestionReply) String() string { return proto.CompactTextString(m) } func (*StopSuggestionReply) ProtoMessage() {} -func (*StopSuggestionReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} } +func (*StopSuggestionReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54} } -type ShouldTrialStopRequest struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` +type SetEarlyStoppingParametersRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + EarlyStoppingAlgorithm string `protobuf:"bytes,2,opt,name=early_stopping_algorithm,json=earlyStoppingAlgorithm" json:"early_stopping_algorithm,omitempty"` + ParamId string `protobuf:"bytes,3,opt,name=param_id,json=paramId" json:"param_id,omitempty"` + EarlyStoppingParameters []*EarlyStoppingParameter `protobuf:"bytes,4,rep,name=early_stopping_parameters,json=earlyStoppingParameters" json:"early_stopping_parameters,omitempty"` } -func (m *ShouldTrialStopRequest) Reset() { *m = ShouldTrialStopRequest{} } -func (m *ShouldTrialStopRequest) String() string { return proto.CompactTextString(m) } -func (*ShouldTrialStopRequest) ProtoMessage() {} -func (*ShouldTrialStopRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} } +func (m *SetEarlyStoppingParametersRequest) Reset() { *m = SetEarlyStoppingParametersRequest{} } +func (m *SetEarlyStoppingParametersRequest) String() string { return proto.CompactTextString(m) } +func (*SetEarlyStoppingParametersRequest) ProtoMessage() {} +func (*SetEarlyStoppingParametersRequest) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{55} +} -func (m *ShouldTrialStopRequest) GetStudyId() string { +func (m *SetEarlyStoppingParametersRequest) GetStudyId() string { if m != nil { return m.StudyId } return "" } -type ShouldTrialStopReply struct { - Trials []*Trial `protobuf:"bytes,1,rep,name=trials" json:"trials,omitempty"` +func (m *SetEarlyStoppingParametersRequest) GetEarlyStoppingAlgorithm() string { + if m != nil { + return m.EarlyStoppingAlgorithm + } + return "" } -func (m *ShouldTrialStopReply) Reset() { *m = ShouldTrialStopReply{} } -func (m *ShouldTrialStopReply) String() string { return proto.CompactTextString(m) } -func (*ShouldTrialStopReply) ProtoMessage() {} -func (*ShouldTrialStopReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} } +func (m *SetEarlyStoppingParametersRequest) GetParamId() string { + if m != nil { + return m.ParamId + } + return "" +} -func (m *ShouldTrialStopReply) GetTrials() []*Trial { +func (m *SetEarlyStoppingParametersRequest) GetEarlyStoppingParameters() []*EarlyStoppingParameter { if m != nil { - return m.Trials + return m.EarlyStoppingParameters } return nil } -type SetEarlyStoppingParameterRequest struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` - EarlyStoppingParameters []*EarlyStoppingParameter `protobuf:"bytes,2,rep,name=early_stopping_parameters,json=earlyStoppingParameters" json:"early_stopping_parameters,omitempty"` +type SetEarlyStoppingParametersReply struct { + ParamId string `protobuf:"bytes,1,opt,name=param_id,json=paramId" json:"param_id,omitempty"` } -func (m *SetEarlyStoppingParameterRequest) Reset() { *m = SetEarlyStoppingParameterRequest{} } -func (m *SetEarlyStoppingParameterRequest) String() string { return proto.CompactTextString(m) } -func (*SetEarlyStoppingParameterRequest) ProtoMessage() {} -func (*SetEarlyStoppingParameterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{51} +func (m *SetEarlyStoppingParametersReply) Reset() { *m = SetEarlyStoppingParametersReply{} } +func (m *SetEarlyStoppingParametersReply) String() string { return proto.CompactTextString(m) } +func (*SetEarlyStoppingParametersReply) ProtoMessage() {} +func (*SetEarlyStoppingParametersReply) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{56} } -func (m *SetEarlyStoppingParameterRequest) GetStudyId() string { +func (m *SetEarlyStoppingParametersReply) GetParamId() string { if m != nil { - return m.StudyId + return m.ParamId } return "" } -func (m *SetEarlyStoppingParameterRequest) GetEarlyStoppingParameters() []*EarlyStoppingParameter { +type GetEarlyStoppingParametersRequest struct { + ParamId string `protobuf:"bytes,1,opt,name=param_id,json=paramId" json:"param_id,omitempty"` +} + +func (m *GetEarlyStoppingParametersRequest) Reset() { *m = GetEarlyStoppingParametersRequest{} } +func (m *GetEarlyStoppingParametersRequest) String() string { return proto.CompactTextString(m) } +func (*GetEarlyStoppingParametersRequest) ProtoMessage() {} +func (*GetEarlyStoppingParametersRequest) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{57} +} + +func (m *GetEarlyStoppingParametersRequest) GetParamId() string { if m != nil { - return m.EarlyStoppingParameters + return m.ParamId } - return nil + return "" } -type SetEarlyStoppingParameterReply struct { +type GetEarlyStoppingParametersReply struct { + EarlyStoppingParameters []*EarlyStoppingParameter `protobuf:"bytes,1,rep,name=early_stopping_parameters,json=earlyStoppingParameters" json:"early_stopping_parameters,omitempty"` } -func (m *SetEarlyStoppingParameterReply) Reset() { *m = SetEarlyStoppingParameterReply{} } -func (m *SetEarlyStoppingParameterReply) String() string { return proto.CompactTextString(m) } -func (*SetEarlyStoppingParameterReply) ProtoMessage() {} -func (*SetEarlyStoppingParameterReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} } +func (m *GetEarlyStoppingParametersReply) Reset() { *m = GetEarlyStoppingParametersReply{} } +func (m *GetEarlyStoppingParametersReply) String() string { return proto.CompactTextString(m) } +func (*GetEarlyStoppingParametersReply) ProtoMessage() {} +func (*GetEarlyStoppingParametersReply) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{58} +} + +func (m *GetEarlyStoppingParametersReply) GetEarlyStoppingParameters() []*EarlyStoppingParameter { + if m != nil { + return m.EarlyStoppingParameters + } + return nil +} func init() { proto.RegisterType((*FeasibleSpace)(nil), "api.FeasibleSpace") proto.RegisterType((*ParameterConfig)(nil), "api.ParameterConfig") proto.RegisterType((*Parameter)(nil), "api.Parameter") + proto.RegisterType((*MetricsLogSet)(nil), "api.MetricsLogSet") proto.RegisterType((*Metrics)(nil), "api.Metrics") - proto.RegisterType((*EvaluationLog)(nil), "api.EvaluationLog") + proto.RegisterType((*MetricsLog)(nil), "api.MetricsLog") proto.RegisterType((*SuggestionParameter)(nil), "api.SuggestionParameter") proto.RegisterType((*EarlyStoppingParameter)(nil), "api.EarlyStoppingParameter") proto.RegisterType((*Tag)(nil), "api.Tag") proto.RegisterType((*MountConf)(nil), "api.MountConf") + proto.RegisterType((*StudyOverview)(nil), "api.StudyOverview") proto.RegisterType((*Trial)(nil), "api.Trial") + proto.RegisterType((*WorkerConfig)(nil), "api.WorkerConfig") + proto.RegisterType((*Worker)(nil), "api.Worker") proto.RegisterType((*StudyConfig)(nil), "api.StudyConfig") proto.RegisterType((*StudyConfig_ParameterConfigs)(nil), "api.StudyConfig.ParameterConfigs") proto.RegisterType((*CreateStudyRequest)(nil), "api.CreateStudyRequest") proto.RegisterType((*CreateStudyReply)(nil), "api.CreateStudyReply") proto.RegisterType((*StopStudyRequest)(nil), "api.StopStudyRequest") proto.RegisterType((*StopStudyReply)(nil), "api.StopStudyReply") - proto.RegisterType((*GetStudiesRequest)(nil), "api.GetStudiesRequest") - proto.RegisterType((*StudyInfo)(nil), "api.StudyInfo") - proto.RegisterType((*GetStudiesReply)(nil), "api.GetStudiesReply") - proto.RegisterType((*SuggestTrialsRequest)(nil), "api.SuggestTrialsRequest") - proto.RegisterType((*SuggestTrialsReply)(nil), "api.SuggestTrialsReply") - proto.RegisterType((*CompleteTrialRequest)(nil), "api.CompleteTrialRequest") - proto.RegisterType((*CompleteTrialReply)(nil), "api.CompleteTrialReply") - proto.RegisterType((*EarlyStoppingRequest)(nil), "api.EarlyStoppingRequest") - proto.RegisterType((*EarlyStoppingReply)(nil), "api.EarlyStoppingReply") - proto.RegisterType((*GetObjectValueRequest)(nil), "api.GetObjectValueRequest") - proto.RegisterType((*GetObjectValueReply)(nil), "api.GetObjectValueReply") - proto.RegisterType((*AddMeasurementToTrialsRequest)(nil), "api.AddMeasurementToTrialsRequest") - proto.RegisterType((*AddMeasurementToTrialsReply)(nil), "api.AddMeasurementToTrialsReply") - proto.RegisterType((*StudyOverview)(nil), "api.StudyOverview") + proto.RegisterType((*GetStudyRequest)(nil), "api.GetStudyRequest") + proto.RegisterType((*GetStudyReply)(nil), "api.GetStudyReply") + proto.RegisterType((*GetStudyListRequest)(nil), "api.GetStudyListRequest") + proto.RegisterType((*GetStudyListReply)(nil), "api.GetStudyListReply") + proto.RegisterType((*GetTrialsRequest)(nil), "api.GetTrialsRequest") + proto.RegisterType((*GetTrialsReply)(nil), "api.GetTrialsReply") + proto.RegisterType((*RunTrialRequest)(nil), "api.RunTrialRequest") + proto.RegisterType((*RunTrialReply)(nil), "api.RunTrialReply") + proto.RegisterType((*StopWorkersRequest)(nil), "api.StopWorkersRequest") + proto.RegisterType((*StopWorkersReply)(nil), "api.StopWorkersReply") + proto.RegisterType((*GetWorkersRequest)(nil), "api.GetWorkersRequest") + proto.RegisterType((*GetWorkersReply)(nil), "api.GetWorkersReply") + proto.RegisterType((*GetSuggestionsRequest)(nil), "api.GetSuggestionsRequest") + proto.RegisterType((*GetSuggestionsReply)(nil), "api.GetSuggestionsReply") + proto.RegisterType((*GetShouldStopWorkersRequest)(nil), "api.GetShouldStopWorkersRequest") + proto.RegisterType((*GetShouldStopWorkersReply)(nil), "api.GetShouldStopWorkersReply") + proto.RegisterType((*GetMetricsRequest)(nil), "api.GetMetricsRequest") + proto.RegisterType((*GetMetricsReply)(nil), "api.GetMetricsReply") proto.RegisterType((*ModelInfo)(nil), "api.ModelInfo") proto.RegisterType((*DataSetInfo)(nil), "api.DataSetInfo") proto.RegisterType((*SaveStudyRequest)(nil), "api.SaveStudyRequest") @@ -1558,21 +1711,19 @@ func init() { proto.RegisterType((*GetSavedModelsReply)(nil), "api.GetSavedModelsReply") proto.RegisterType((*GetSavedModelRequest)(nil), "api.GetSavedModelRequest") proto.RegisterType((*GetSavedModelReply)(nil), "api.GetSavedModelReply") - proto.RegisterType((*InitializeSuggestServiceRequest)(nil), "api.InitializeSuggestServiceRequest") - proto.RegisterType((*InitializeSuggestServiceReply)(nil), "api.InitializeSuggestServiceReply") - proto.RegisterType((*GenerateTrialsRequest)(nil), "api.GenerateTrialsRequest") - proto.RegisterType((*GenerateTrialsReply)(nil), "api.GenerateTrialsReply") proto.RegisterType((*SetSuggestionParametersRequest)(nil), "api.SetSuggestionParametersRequest") proto.RegisterType((*SetSuggestionParametersReply)(nil), "api.SetSuggestionParametersReply") + proto.RegisterType((*GetSuggestionParametersRequest)(nil), "api.GetSuggestionParametersRequest") + proto.RegisterType((*GetSuggestionParametersReply)(nil), "api.GetSuggestionParametersReply") proto.RegisterType((*StopSuggestionRequest)(nil), "api.StopSuggestionRequest") proto.RegisterType((*StopSuggestionReply)(nil), "api.StopSuggestionReply") - proto.RegisterType((*ShouldTrialStopRequest)(nil), "api.ShouldTrialStopRequest") - proto.RegisterType((*ShouldTrialStopReply)(nil), "api.ShouldTrialStopReply") - proto.RegisterType((*SetEarlyStoppingParameterRequest)(nil), "api.SetEarlyStoppingParameterRequest") - proto.RegisterType((*SetEarlyStoppingParameterReply)(nil), "api.SetEarlyStoppingParameterReply") + proto.RegisterType((*SetEarlyStoppingParametersRequest)(nil), "api.SetEarlyStoppingParametersRequest") + proto.RegisterType((*SetEarlyStoppingParametersReply)(nil), "api.SetEarlyStoppingParametersReply") + proto.RegisterType((*GetEarlyStoppingParametersRequest)(nil), "api.GetEarlyStoppingParametersRequest") + proto.RegisterType((*GetEarlyStoppingParametersReply)(nil), "api.GetEarlyStoppingParametersReply") proto.RegisterEnum("api.ParameterType", ParameterType_name, ParameterType_value) proto.RegisterEnum("api.OptimizationType", OptimizationType_name, OptimizationType_value) - proto.RegisterEnum("api.TrialState", TrialState_name, TrialState_value) + proto.RegisterEnum("api.State", State_name, State_value) } // Reference imports to suppress errors if they are not otherwise used. @@ -1588,18 +1739,23 @@ const _ = grpc.SupportPackageIsVersion4 type ManagerClient interface { CreateStudy(ctx context.Context, in *CreateStudyRequest, opts ...grpc.CallOption) (*CreateStudyReply, error) StopStudy(ctx context.Context, in *StopStudyRequest, opts ...grpc.CallOption) (*StopStudyReply, error) - GetStudies(ctx context.Context, in *GetStudiesRequest, opts ...grpc.CallOption) (*GetStudiesReply, error) - SuggestTrials(ctx context.Context, in *SuggestTrialsRequest, opts ...grpc.CallOption) (*SuggestTrialsReply, error) - CompleteTrial(ctx context.Context, in *CompleteTrialRequest, opts ...grpc.CallOption) (*CompleteTrialReply, error) - EarlyStopping(ctx context.Context, in *EarlyStoppingRequest, opts ...grpc.CallOption) (*EarlyStoppingReply, error) - GetObjectValue(ctx context.Context, in *GetObjectValueRequest, opts ...grpc.CallOption) (*GetObjectValueReply, error) - AddMeasurementToTrials(ctx context.Context, in *AddMeasurementToTrialsRequest, opts ...grpc.CallOption) (*AddMeasurementToTrialsReply, error) - InitializeSuggestService(ctx context.Context, in *InitializeSuggestServiceRequest, opts ...grpc.CallOption) (*InitializeSuggestServiceReply, error) + GetStudy(ctx context.Context, in *GetStudyRequest, opts ...grpc.CallOption) (*GetStudyReply, error) + GetStudyList(ctx context.Context, in *GetStudyListRequest, opts ...grpc.CallOption) (*GetStudyListReply, error) + GetTrials(ctx context.Context, in *GetTrialsRequest, opts ...grpc.CallOption) (*GetTrialsReply, error) + RunTrial(ctx context.Context, in *RunTrialRequest, opts ...grpc.CallOption) (*RunTrialReply, error) + StopWorkers(ctx context.Context, in *StopWorkersRequest, opts ...grpc.CallOption) (*StopWorkersReply, error) + GetWorkers(ctx context.Context, in *GetWorkersRequest, opts ...grpc.CallOption) (*GetWorkersReply, error) + GetSuggestions(ctx context.Context, in *GetSuggestionsRequest, opts ...grpc.CallOption) (*GetSuggestionsReply, error) + GetShouldStopWorkers(ctx context.Context, in *GetShouldStopWorkersRequest, opts ...grpc.CallOption) (*GetShouldStopWorkersReply, error) + GetMetrics(ctx context.Context, in *GetMetricsRequest, opts ...grpc.CallOption) (*GetMetricsReply, error) + SetSuggestionParameters(ctx context.Context, in *SetSuggestionParametersRequest, opts ...grpc.CallOption) (*SetSuggestionParametersReply, error) + GetSuggestionParameters(ctx context.Context, in *GetSuggestionParametersRequest, opts ...grpc.CallOption) (*GetSuggestionParametersReply, error) + SetEarlyStoppingParameters(ctx context.Context, in *SetEarlyStoppingParametersRequest, opts ...grpc.CallOption) (*SetEarlyStoppingParametersReply, error) + GetEarlyStoppingParameters(ctx context.Context, in *GetEarlyStoppingParametersRequest, opts ...grpc.CallOption) (*GetEarlyStoppingParametersReply, error) SaveStudy(ctx context.Context, in *SaveStudyRequest, opts ...grpc.CallOption) (*SaveStudyReply, error) SaveModel(ctx context.Context, in *SaveModelRequest, opts ...grpc.CallOption) (*SaveModelReply, error) GetSavedStudies(ctx context.Context, in *GetSavedStudiesRequest, opts ...grpc.CallOption) (*GetSavedStudiesReply, error) GetSavedModels(ctx context.Context, in *GetSavedModelsRequest, opts ...grpc.CallOption) (*GetSavedModelsReply, error) - GetSavedModel(ctx context.Context, in *GetSavedModelRequest, opts ...grpc.CallOption) (*GetSavedModelReply, error) } type managerClient struct { @@ -1628,63 +1784,117 @@ func (c *managerClient) StopStudy(ctx context.Context, in *StopStudyRequest, opt return out, nil } -func (c *managerClient) GetStudies(ctx context.Context, in *GetStudiesRequest, opts ...grpc.CallOption) (*GetStudiesReply, error) { - out := new(GetStudiesReply) - err := grpc.Invoke(ctx, "/api.Manager/GetStudies", in, out, c.cc, opts...) +func (c *managerClient) GetStudy(ctx context.Context, in *GetStudyRequest, opts ...grpc.CallOption) (*GetStudyReply, error) { + out := new(GetStudyReply) + err := grpc.Invoke(ctx, "/api.Manager/GetStudy", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } -func (c *managerClient) SuggestTrials(ctx context.Context, in *SuggestTrialsRequest, opts ...grpc.CallOption) (*SuggestTrialsReply, error) { - out := new(SuggestTrialsReply) - err := grpc.Invoke(ctx, "/api.Manager/SuggestTrials", in, out, c.cc, opts...) +func (c *managerClient) GetStudyList(ctx context.Context, in *GetStudyListRequest, opts ...grpc.CallOption) (*GetStudyListReply, error) { + out := new(GetStudyListReply) + err := grpc.Invoke(ctx, "/api.Manager/GetStudyList", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } -func (c *managerClient) CompleteTrial(ctx context.Context, in *CompleteTrialRequest, opts ...grpc.CallOption) (*CompleteTrialReply, error) { - out := new(CompleteTrialReply) - err := grpc.Invoke(ctx, "/api.Manager/CompleteTrial", in, out, c.cc, opts...) +func (c *managerClient) GetTrials(ctx context.Context, in *GetTrialsRequest, opts ...grpc.CallOption) (*GetTrialsReply, error) { + out := new(GetTrialsReply) + err := grpc.Invoke(ctx, "/api.Manager/GetTrials", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } -func (c *managerClient) EarlyStopping(ctx context.Context, in *EarlyStoppingRequest, opts ...grpc.CallOption) (*EarlyStoppingReply, error) { - out := new(EarlyStoppingReply) - err := grpc.Invoke(ctx, "/api.Manager/EarlyStopping", in, out, c.cc, opts...) +func (c *managerClient) RunTrial(ctx context.Context, in *RunTrialRequest, opts ...grpc.CallOption) (*RunTrialReply, error) { + out := new(RunTrialReply) + err := grpc.Invoke(ctx, "/api.Manager/RunTrial", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } -func (c *managerClient) GetObjectValue(ctx context.Context, in *GetObjectValueRequest, opts ...grpc.CallOption) (*GetObjectValueReply, error) { - out := new(GetObjectValueReply) - err := grpc.Invoke(ctx, "/api.Manager/GetObjectValue", in, out, c.cc, opts...) +func (c *managerClient) StopWorkers(ctx context.Context, in *StopWorkersRequest, opts ...grpc.CallOption) (*StopWorkersReply, error) { + out := new(StopWorkersReply) + err := grpc.Invoke(ctx, "/api.Manager/StopWorkers", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } -func (c *managerClient) AddMeasurementToTrials(ctx context.Context, in *AddMeasurementToTrialsRequest, opts ...grpc.CallOption) (*AddMeasurementToTrialsReply, error) { - out := new(AddMeasurementToTrialsReply) - err := grpc.Invoke(ctx, "/api.Manager/AddMeasurementToTrials", in, out, c.cc, opts...) +func (c *managerClient) GetWorkers(ctx context.Context, in *GetWorkersRequest, opts ...grpc.CallOption) (*GetWorkersReply, error) { + out := new(GetWorkersReply) + err := grpc.Invoke(ctx, "/api.Manager/GetWorkers", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } -func (c *managerClient) InitializeSuggestService(ctx context.Context, in *InitializeSuggestServiceRequest, opts ...grpc.CallOption) (*InitializeSuggestServiceReply, error) { - out := new(InitializeSuggestServiceReply) - err := grpc.Invoke(ctx, "/api.Manager/InitializeSuggestService", in, out, c.cc, opts...) +func (c *managerClient) GetSuggestions(ctx context.Context, in *GetSuggestionsRequest, opts ...grpc.CallOption) (*GetSuggestionsReply, error) { + out := new(GetSuggestionsReply) + err := grpc.Invoke(ctx, "/api.Manager/GetSuggestions", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *managerClient) GetShouldStopWorkers(ctx context.Context, in *GetShouldStopWorkersRequest, opts ...grpc.CallOption) (*GetShouldStopWorkersReply, error) { + out := new(GetShouldStopWorkersReply) + err := grpc.Invoke(ctx, "/api.Manager/GetShouldStopWorkers", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *managerClient) GetMetrics(ctx context.Context, in *GetMetricsRequest, opts ...grpc.CallOption) (*GetMetricsReply, error) { + out := new(GetMetricsReply) + err := grpc.Invoke(ctx, "/api.Manager/GetMetrics", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *managerClient) SetSuggestionParameters(ctx context.Context, in *SetSuggestionParametersRequest, opts ...grpc.CallOption) (*SetSuggestionParametersReply, error) { + out := new(SetSuggestionParametersReply) + err := grpc.Invoke(ctx, "/api.Manager/SetSuggestionParameters", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *managerClient) GetSuggestionParameters(ctx context.Context, in *GetSuggestionParametersRequest, opts ...grpc.CallOption) (*GetSuggestionParametersReply, error) { + out := new(GetSuggestionParametersReply) + err := grpc.Invoke(ctx, "/api.Manager/GetSuggestionParameters", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *managerClient) SetEarlyStoppingParameters(ctx context.Context, in *SetEarlyStoppingParametersRequest, opts ...grpc.CallOption) (*SetEarlyStoppingParametersReply, error) { + out := new(SetEarlyStoppingParametersReply) + err := grpc.Invoke(ctx, "/api.Manager/SetEarlyStoppingParameters", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *managerClient) GetEarlyStoppingParameters(ctx context.Context, in *GetEarlyStoppingParametersRequest, opts ...grpc.CallOption) (*GetEarlyStoppingParametersReply, error) { + out := new(GetEarlyStoppingParametersReply) + err := grpc.Invoke(ctx, "/api.Manager/GetEarlyStoppingParameters", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -1727,32 +1937,28 @@ func (c *managerClient) GetSavedModels(ctx context.Context, in *GetSavedModelsRe return out, nil } -func (c *managerClient) GetSavedModel(ctx context.Context, in *GetSavedModelRequest, opts ...grpc.CallOption) (*GetSavedModelReply, error) { - out := new(GetSavedModelReply) - err := grpc.Invoke(ctx, "/api.Manager/GetSavedModel", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - // Server API for Manager service type ManagerServer interface { CreateStudy(context.Context, *CreateStudyRequest) (*CreateStudyReply, error) StopStudy(context.Context, *StopStudyRequest) (*StopStudyReply, error) - GetStudies(context.Context, *GetStudiesRequest) (*GetStudiesReply, error) - SuggestTrials(context.Context, *SuggestTrialsRequest) (*SuggestTrialsReply, error) - CompleteTrial(context.Context, *CompleteTrialRequest) (*CompleteTrialReply, error) - EarlyStopping(context.Context, *EarlyStoppingRequest) (*EarlyStoppingReply, error) - GetObjectValue(context.Context, *GetObjectValueRequest) (*GetObjectValueReply, error) - AddMeasurementToTrials(context.Context, *AddMeasurementToTrialsRequest) (*AddMeasurementToTrialsReply, error) - InitializeSuggestService(context.Context, *InitializeSuggestServiceRequest) (*InitializeSuggestServiceReply, error) + GetStudy(context.Context, *GetStudyRequest) (*GetStudyReply, error) + GetStudyList(context.Context, *GetStudyListRequest) (*GetStudyListReply, error) + GetTrials(context.Context, *GetTrialsRequest) (*GetTrialsReply, error) + RunTrial(context.Context, *RunTrialRequest) (*RunTrialReply, error) + StopWorkers(context.Context, *StopWorkersRequest) (*StopWorkersReply, error) + GetWorkers(context.Context, *GetWorkersRequest) (*GetWorkersReply, error) + GetSuggestions(context.Context, *GetSuggestionsRequest) (*GetSuggestionsReply, error) + GetShouldStopWorkers(context.Context, *GetShouldStopWorkersRequest) (*GetShouldStopWorkersReply, error) + GetMetrics(context.Context, *GetMetricsRequest) (*GetMetricsReply, error) + SetSuggestionParameters(context.Context, *SetSuggestionParametersRequest) (*SetSuggestionParametersReply, error) + GetSuggestionParameters(context.Context, *GetSuggestionParametersRequest) (*GetSuggestionParametersReply, error) + SetEarlyStoppingParameters(context.Context, *SetEarlyStoppingParametersRequest) (*SetEarlyStoppingParametersReply, error) + GetEarlyStoppingParameters(context.Context, *GetEarlyStoppingParametersRequest) (*GetEarlyStoppingParametersReply, error) SaveStudy(context.Context, *SaveStudyRequest) (*SaveStudyReply, error) SaveModel(context.Context, *SaveModelRequest) (*SaveModelReply, error) GetSavedStudies(context.Context, *GetSavedStudiesRequest) (*GetSavedStudiesReply, error) GetSavedModels(context.Context, *GetSavedModelsRequest) (*GetSavedModelsReply, error) - GetSavedModel(context.Context, *GetSavedModelRequest) (*GetSavedModelReply, error) } func RegisterManagerServer(s *grpc.Server, srv ManagerServer) { @@ -1795,128 +2001,236 @@ func _Manager_StopStudy_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } -func _Manager_GetStudies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetStudiesRequest) +func _Manager_GetStudy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetStudyRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ManagerServer).GetStudies(ctx, in) + return srv.(ManagerServer).GetStudy(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Manager/GetStudies", + FullMethod: "/api.Manager/GetStudy", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetStudies(ctx, req.(*GetStudiesRequest)) + return srv.(ManagerServer).GetStudy(ctx, req.(*GetStudyRequest)) } return interceptor(ctx, in, info, handler) } -func _Manager_SuggestTrials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SuggestTrialsRequest) +func _Manager_GetStudyList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetStudyListRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ManagerServer).SuggestTrials(ctx, in) + return srv.(ManagerServer).GetStudyList(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Manager/SuggestTrials", + FullMethod: "/api.Manager/GetStudyList", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).SuggestTrials(ctx, req.(*SuggestTrialsRequest)) + return srv.(ManagerServer).GetStudyList(ctx, req.(*GetStudyListRequest)) } return interceptor(ctx, in, info, handler) } -func _Manager_CompleteTrial_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CompleteTrialRequest) +func _Manager_GetTrials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTrialsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ManagerServer).CompleteTrial(ctx, in) + return srv.(ManagerServer).GetTrials(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Manager/CompleteTrial", + FullMethod: "/api.Manager/GetTrials", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).CompleteTrial(ctx, req.(*CompleteTrialRequest)) + return srv.(ManagerServer).GetTrials(ctx, req.(*GetTrialsRequest)) } return interceptor(ctx, in, info, handler) } -func _Manager_EarlyStopping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EarlyStoppingRequest) +func _Manager_RunTrial_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RunTrialRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ManagerServer).EarlyStopping(ctx, in) + return srv.(ManagerServer).RunTrial(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Manager/EarlyStopping", + FullMethod: "/api.Manager/RunTrial", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).EarlyStopping(ctx, req.(*EarlyStoppingRequest)) + return srv.(ManagerServer).RunTrial(ctx, req.(*RunTrialRequest)) } return interceptor(ctx, in, info, handler) } -func _Manager_GetObjectValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetObjectValueRequest) +func _Manager_StopWorkers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StopWorkersRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ManagerServer).GetObjectValue(ctx, in) + return srv.(ManagerServer).StopWorkers(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Manager/GetObjectValue", + FullMethod: "/api.Manager/StopWorkers", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetObjectValue(ctx, req.(*GetObjectValueRequest)) + return srv.(ManagerServer).StopWorkers(ctx, req.(*StopWorkersRequest)) } return interceptor(ctx, in, info, handler) } -func _Manager_AddMeasurementToTrials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddMeasurementToTrialsRequest) +func _Manager_GetWorkers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetWorkersRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ManagerServer).AddMeasurementToTrials(ctx, in) + return srv.(ManagerServer).GetWorkers(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Manager/AddMeasurementToTrials", + FullMethod: "/api.Manager/GetWorkers", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).AddMeasurementToTrials(ctx, req.(*AddMeasurementToTrialsRequest)) + return srv.(ManagerServer).GetWorkers(ctx, req.(*GetWorkersRequest)) } return interceptor(ctx, in, info, handler) } -func _Manager_InitializeSuggestService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(InitializeSuggestServiceRequest) +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).InitializeSuggestService(ctx, in) + return srv.(ManagerServer).GetSuggestions(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Manager/InitializeSuggestService", + FullMethod: "/api.Manager/GetSuggestions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).InitializeSuggestService(ctx, req.(*InitializeSuggestServiceRequest)) + return srv.(ManagerServer).GetSuggestions(ctx, req.(*GetSuggestionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Manager_GetShouldStopWorkers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetShouldStopWorkersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServer).GetShouldStopWorkers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Manager/GetShouldStopWorkers", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServer).GetShouldStopWorkers(ctx, req.(*GetShouldStopWorkersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Manager_GetMetrics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMetricsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServer).GetMetrics(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Manager/GetMetrics", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServer).GetMetrics(ctx, req.(*GetMetricsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Manager_SetSuggestionParameters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetSuggestionParametersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServer).SetSuggestionParameters(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Manager/SetSuggestionParameters", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServer).SetSuggestionParameters(ctx, req.(*SetSuggestionParametersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Manager_GetSuggestionParameters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSuggestionParametersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServer).GetSuggestionParameters(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Manager/GetSuggestionParameters", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServer).GetSuggestionParameters(ctx, req.(*GetSuggestionParametersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Manager_SetEarlyStoppingParameters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetEarlyStoppingParametersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServer).SetEarlyStoppingParameters(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Manager/SetEarlyStoppingParameters", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServer).SetEarlyStoppingParameters(ctx, req.(*SetEarlyStoppingParametersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Manager_GetEarlyStoppingParameters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetEarlyStoppingParametersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServer).GetEarlyStoppingParameters(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Manager/GetEarlyStoppingParameters", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServer).GetEarlyStoppingParameters(ctx, req.(*GetEarlyStoppingParametersRequest)) } return interceptor(ctx, in, info, handler) } @@ -1993,24 +2307,6 @@ func _Manager_GetSavedModels_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } -func _Manager_GetSavedModel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetSavedModelRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ManagerServer).GetSavedModel(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.Manager/GetSavedModel", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ManagerServer).GetSavedModel(ctx, req.(*GetSavedModelRequest)) - } - return interceptor(ctx, in, info, handler) -} - var _Manager_serviceDesc = grpc.ServiceDesc{ ServiceName: "api.Manager", HandlerType: (*ManagerServer)(nil), @@ -2024,32 +2320,56 @@ var _Manager_serviceDesc = grpc.ServiceDesc{ Handler: _Manager_StopStudy_Handler, }, { - MethodName: "GetStudies", - Handler: _Manager_GetStudies_Handler, + MethodName: "GetStudy", + Handler: _Manager_GetStudy_Handler, + }, + { + MethodName: "GetStudyList", + Handler: _Manager_GetStudyList_Handler, + }, + { + MethodName: "GetTrials", + Handler: _Manager_GetTrials_Handler, + }, + { + MethodName: "RunTrial", + Handler: _Manager_RunTrial_Handler, + }, + { + MethodName: "StopWorkers", + Handler: _Manager_StopWorkers_Handler, + }, + { + MethodName: "GetWorkers", + Handler: _Manager_GetWorkers_Handler, }, { - MethodName: "SuggestTrials", - Handler: _Manager_SuggestTrials_Handler, + MethodName: "GetSuggestions", + Handler: _Manager_GetSuggestions_Handler, }, { - MethodName: "CompleteTrial", - Handler: _Manager_CompleteTrial_Handler, + MethodName: "GetShouldStopWorkers", + Handler: _Manager_GetShouldStopWorkers_Handler, }, { - MethodName: "EarlyStopping", - Handler: _Manager_EarlyStopping_Handler, + MethodName: "GetMetrics", + Handler: _Manager_GetMetrics_Handler, + }, + { + MethodName: "SetSuggestionParameters", + Handler: _Manager_SetSuggestionParameters_Handler, }, { - MethodName: "GetObjectValue", - Handler: _Manager_GetObjectValue_Handler, + MethodName: "GetSuggestionParameters", + Handler: _Manager_GetSuggestionParameters_Handler, }, { - MethodName: "AddMeasurementToTrials", - Handler: _Manager_AddMeasurementToTrials_Handler, + MethodName: "SetEarlyStoppingParameters", + Handler: _Manager_SetEarlyStoppingParameters_Handler, }, { - MethodName: "InitializeSuggestService", - Handler: _Manager_InitializeSuggestService_Handler, + MethodName: "GetEarlyStoppingParameters", + Handler: _Manager_GetEarlyStoppingParameters_Handler, }, { MethodName: "SaveStudy", @@ -2067,10 +2387,6 @@ var _Manager_serviceDesc = grpc.ServiceDesc{ MethodName: "GetSavedModels", Handler: _Manager_GetSavedModels_Handler, }, - { - MethodName: "GetSavedModel", - Handler: _Manager_GetSavedModel_Handler, - }, }, Streams: []grpc.StreamDesc{}, Metadata: "api.proto", @@ -2079,9 +2395,7 @@ var _Manager_serviceDesc = grpc.ServiceDesc{ // Client API for Suggestion service type SuggestionClient interface { - GenerateTrials(ctx context.Context, in *GenerateTrialsRequest, opts ...grpc.CallOption) (*GenerateTrialsReply, error) - SetSuggestionParameters(ctx context.Context, in *SetSuggestionParametersRequest, opts ...grpc.CallOption) (*SetSuggestionParametersReply, error) - StopSuggestion(ctx context.Context, in *StopSuggestionRequest, opts ...grpc.CallOption) (*StopSuggestionReply, error) + GetSuggestions(ctx context.Context, in *GetSuggestionsRequest, opts ...grpc.CallOption) (*GetSuggestionsReply, error) } type suggestionClient struct { @@ -2092,27 +2406,9 @@ func NewSuggestionClient(cc *grpc.ClientConn) SuggestionClient { return &suggestionClient{cc} } -func (c *suggestionClient) GenerateTrials(ctx context.Context, in *GenerateTrialsRequest, opts ...grpc.CallOption) (*GenerateTrialsReply, error) { - out := new(GenerateTrialsReply) - err := grpc.Invoke(ctx, "/api.Suggestion/GenerateTrials", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *suggestionClient) SetSuggestionParameters(ctx context.Context, in *SetSuggestionParametersRequest, opts ...grpc.CallOption) (*SetSuggestionParametersReply, error) { - out := new(SetSuggestionParametersReply) - err := grpc.Invoke(ctx, "/api.Suggestion/SetSuggestionParameters", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *suggestionClient) StopSuggestion(ctx context.Context, in *StopSuggestionRequest, opts ...grpc.CallOption) (*StopSuggestionReply, error) { - out := new(StopSuggestionReply) - err := grpc.Invoke(ctx, "/api.Suggestion/StopSuggestion", in, out, c.cc, opts...) +func (c *suggestionClient) GetSuggestions(ctx context.Context, in *GetSuggestionsRequest, opts ...grpc.CallOption) (*GetSuggestionsReply, error) { + out := new(GetSuggestionsReply) + err := grpc.Invoke(ctx, "/api.Suggestion/GetSuggestions", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -2122,65 +2418,27 @@ func (c *suggestionClient) StopSuggestion(ctx context.Context, in *StopSuggestio // Server API for Suggestion service type SuggestionServer interface { - GenerateTrials(context.Context, *GenerateTrialsRequest) (*GenerateTrialsReply, error) - SetSuggestionParameters(context.Context, *SetSuggestionParametersRequest) (*SetSuggestionParametersReply, error) - StopSuggestion(context.Context, *StopSuggestionRequest) (*StopSuggestionReply, error) + GetSuggestions(context.Context, *GetSuggestionsRequest) (*GetSuggestionsReply, error) } func RegisterSuggestionServer(s *grpc.Server, srv SuggestionServer) { s.RegisterService(&_Suggestion_serviceDesc, srv) } -func _Suggestion_GenerateTrials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GenerateTrialsRequest) +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).GenerateTrials(ctx, in) + return srv.(SuggestionServer).GetSuggestions(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Suggestion/GenerateTrials", + FullMethod: "/api.Suggestion/GetSuggestions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SuggestionServer).GenerateTrials(ctx, req.(*GenerateTrialsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Suggestion_SetSuggestionParameters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SetSuggestionParametersRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(SuggestionServer).SetSuggestionParameters(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.Suggestion/SetSuggestionParameters", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SuggestionServer).SetSuggestionParameters(ctx, req.(*SetSuggestionParametersRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Suggestion_StopSuggestion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(StopSuggestionRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(SuggestionServer).StopSuggestion(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.Suggestion/StopSuggestion", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SuggestionServer).StopSuggestion(ctx, req.(*StopSuggestionRequest)) + return srv.(SuggestionServer).GetSuggestions(ctx, req.(*GetSuggestionsRequest)) } return interceptor(ctx, in, info, handler) } @@ -2190,16 +2448,8 @@ var _Suggestion_serviceDesc = grpc.ServiceDesc{ HandlerType: (*SuggestionServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "GenerateTrials", - Handler: _Suggestion_GenerateTrials_Handler, - }, - { - MethodName: "SetSuggestionParameters", - Handler: _Suggestion_SetSuggestionParameters_Handler, - }, - { - MethodName: "StopSuggestion", - Handler: _Suggestion_StopSuggestion_Handler, + MethodName: "GetSuggestions", + Handler: _Suggestion_GetSuggestions_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -2209,8 +2459,7 @@ var _Suggestion_serviceDesc = grpc.ServiceDesc{ // Client API for EarlyStopping service type EarlyStoppingClient interface { - ShouldTrialStop(ctx context.Context, in *ShouldTrialStopRequest, opts ...grpc.CallOption) (*ShouldTrialStopReply, error) - SetEarlyStoppingParameter(ctx context.Context, in *SetEarlyStoppingParameterRequest, opts ...grpc.CallOption) (*SetEarlyStoppingParameterReply, error) + GetShouldStopWorkers(ctx context.Context, in *GetShouldStopWorkersRequest, opts ...grpc.CallOption) (*GetShouldStopWorkersReply, error) } type earlyStoppingClient struct { @@ -2221,18 +2470,9 @@ func NewEarlyStoppingClient(cc *grpc.ClientConn) EarlyStoppingClient { return &earlyStoppingClient{cc} } -func (c *earlyStoppingClient) ShouldTrialStop(ctx context.Context, in *ShouldTrialStopRequest, opts ...grpc.CallOption) (*ShouldTrialStopReply, error) { - out := new(ShouldTrialStopReply) - err := grpc.Invoke(ctx, "/api.EarlyStopping/ShouldTrialStop", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *earlyStoppingClient) SetEarlyStoppingParameter(ctx context.Context, in *SetEarlyStoppingParameterRequest, opts ...grpc.CallOption) (*SetEarlyStoppingParameterReply, error) { - out := new(SetEarlyStoppingParameterReply) - err := grpc.Invoke(ctx, "/api.EarlyStopping/SetEarlyStoppingParameter", in, out, c.cc, opts...) +func (c *earlyStoppingClient) GetShouldStopWorkers(ctx context.Context, in *GetShouldStopWorkersRequest, opts ...grpc.CallOption) (*GetShouldStopWorkersReply, error) { + out := new(GetShouldStopWorkersReply) + err := grpc.Invoke(ctx, "/api.EarlyStopping/GetShouldStopWorkers", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -2242,46 +2482,27 @@ func (c *earlyStoppingClient) SetEarlyStoppingParameter(ctx context.Context, in // Server API for EarlyStopping service type EarlyStoppingServer interface { - ShouldTrialStop(context.Context, *ShouldTrialStopRequest) (*ShouldTrialStopReply, error) - SetEarlyStoppingParameter(context.Context, *SetEarlyStoppingParameterRequest) (*SetEarlyStoppingParameterReply, error) + GetShouldStopWorkers(context.Context, *GetShouldStopWorkersRequest) (*GetShouldStopWorkersReply, error) } func RegisterEarlyStoppingServer(s *grpc.Server, srv EarlyStoppingServer) { s.RegisterService(&_EarlyStopping_serviceDesc, srv) } -func _EarlyStopping_ShouldTrialStop_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ShouldTrialStopRequest) +func _EarlyStopping_GetShouldStopWorkers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetShouldStopWorkersRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(EarlyStoppingServer).ShouldTrialStop(ctx, in) + return srv.(EarlyStoppingServer).GetShouldStopWorkers(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.EarlyStopping/ShouldTrialStop", + FullMethod: "/api.EarlyStopping/GetShouldStopWorkers", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(EarlyStoppingServer).ShouldTrialStop(ctx, req.(*ShouldTrialStopRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _EarlyStopping_SetEarlyStoppingParameter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SetEarlyStoppingParameterRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(EarlyStoppingServer).SetEarlyStoppingParameter(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.EarlyStopping/SetEarlyStoppingParameter", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(EarlyStoppingServer).SetEarlyStoppingParameter(ctx, req.(*SetEarlyStoppingParameterRequest)) + return srv.(EarlyStoppingServer).GetShouldStopWorkers(ctx, req.(*GetShouldStopWorkersRequest)) } return interceptor(ctx, in, info, handler) } @@ -2291,12 +2512,8 @@ var _EarlyStopping_serviceDesc = grpc.ServiceDesc{ HandlerType: (*EarlyStoppingServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "ShouldTrialStop", - Handler: _EarlyStopping_ShouldTrialStop_Handler, - }, - { - MethodName: "SetEarlyStoppingParameter", - Handler: _EarlyStopping_SetEarlyStoppingParameter_Handler, + MethodName: "GetShouldStopWorkers", + Handler: _EarlyStopping_GetShouldStopWorkers_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -2306,139 +2523,145 @@ var _EarlyStopping_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("api.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 2142 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xdd, 0x6f, 0x1b, 0xc7, - 0x11, 0xf7, 0x91, 0xa2, 0x48, 0x0e, 0x45, 0xf1, 0xb4, 0xa2, 0xe4, 0x13, 0x6d, 0xc7, 0xf2, 0x25, - 0x75, 0x0c, 0xa7, 0x91, 0x1b, 0xb9, 0x69, 0x13, 0x03, 0x41, 0xa1, 0x0f, 0x46, 0x25, 0x2c, 0x91, - 0xc2, 0x91, 0x8e, 0xfb, 0x01, 0x94, 0x58, 0x93, 0x6b, 0xfa, 0xea, 0xe3, 0xdd, 0xf5, 0xf6, 0x28, - 0x47, 0xf9, 0x0b, 0x8a, 0x3e, 0x15, 0x28, 0xd0, 0xbf, 0xa2, 0x6f, 0x05, 0xfa, 0xd4, 0xb7, 0xbe, - 0xf4, 0x0f, 0xc9, 0xff, 0xd1, 0x62, 0xe7, 0xf6, 0x78, 0x1f, 0x3c, 0x7e, 0x44, 0xf1, 0xdb, 0xed, - 0xec, 0xcc, 0xec, 0xec, 0xcc, 0x6f, 0x3e, 0x96, 0x84, 0x32, 0x75, 0xcd, 0x03, 0xd7, 0x73, 0x7c, - 0x87, 0xe4, 0xa9, 0x6b, 0xea, 0x67, 0x50, 0xfd, 0x9a, 0x51, 0x6e, 0xbe, 0xb2, 0x58, 0xd7, 0xa5, - 0x03, 0x46, 0x54, 0xc8, 0x8f, 0xe9, 0xb7, 0x9a, 0xb2, 0xaf, 0x3c, 0x2a, 0x1b, 0xe2, 0x13, 0x29, - 0xa6, 0xad, 0xe5, 0x24, 0xc5, 0xb4, 0x09, 0x81, 0x35, 0xcb, 0xe4, 0xbe, 0x96, 0xdf, 0xcf, 0x3f, - 0x2a, 0x1b, 0xf8, 0xad, 0xff, 0x55, 0x81, 0xda, 0x25, 0xf5, 0xe8, 0x98, 0xf9, 0xcc, 0x3b, 0x71, - 0xec, 0xd7, 0xe6, 0x48, 0xf0, 0xd9, 0x74, 0xcc, 0xa4, 0x32, 0xfc, 0x26, 0x5f, 0xc2, 0xa6, 0x1b, - 0xb2, 0xf5, 0xfd, 0x6b, 0x97, 0xa1, 0xe2, 0xcd, 0x43, 0x72, 0x20, 0x2c, 0x9b, 0x6a, 0xe8, 0x5d, - 0xbb, 0xcc, 0xa8, 0xba, 0xf1, 0x25, 0x39, 0x80, 0xd2, 0x6b, 0x69, 0xab, 0x96, 0xdf, 0x57, 0x1e, - 0x55, 0xa4, 0x50, 0xe2, 0x02, 0xc6, 0x94, 0x47, 0x77, 0xa1, 0x3c, 0xd5, 0xf7, 0xbe, 0x6d, 0xa9, - 0x43, 0xe1, 0x8a, 0x5a, 0x93, 0xc0, 0x90, 0xb2, 0x11, 0x2c, 0xf4, 0xa7, 0x50, 0xbc, 0x60, 0xbe, - 0x67, 0x0e, 0x78, 0xe6, 0x79, 0x53, 0xa1, 0x5c, 0x5c, 0xe8, 0x39, 0x54, 0x9b, 0xe2, 0x8b, 0xfa, - 0xa6, 0x63, 0x9f, 0x3b, 0xe8, 0x36, 0xdf, 0x8c, 0x44, 0xc5, 0x37, 0x79, 0x08, 0xc5, 0x71, 0xa0, - 0x59, 0xcb, 0xed, 0xe7, 0x1f, 0x55, 0x0e, 0x37, 0xd0, 0x46, 0x79, 0x9a, 0x11, 0x6e, 0xea, 0xbf, - 0x82, 0xed, 0xee, 0x64, 0x34, 0x62, 0x5c, 0x28, 0x5b, 0x7c, 0xfb, 0x6c, 0x6b, 0x8e, 0x61, 0xb7, - 0x49, 0x3d, 0xeb, 0xba, 0xeb, 0x3b, 0xae, 0x6b, 0xda, 0xa3, 0x9b, 0xe8, 0x78, 0x02, 0xf9, 0x1e, - 0x1d, 0xfd, 0x00, 0x81, 0xcf, 0xa0, 0x7c, 0xe1, 0x4c, 0x6c, 0x5f, 0xe0, 0x46, 0xe0, 0xcd, 0xbd, - 0x1a, 0x84, 0x08, 0x74, 0xaf, 0x06, 0x42, 0x91, 0x4b, 0xfd, 0x37, 0x52, 0x06, 0xbf, 0xf5, 0xbf, - 0xe5, 0xa0, 0xd0, 0xf3, 0x4c, 0x6a, 0x91, 0x3d, 0x28, 0xf9, 0xe2, 0xa3, 0x6f, 0x0e, 0xa5, 0x50, - 0x11, 0xd7, 0xad, 0xa1, 0xd8, 0xe2, 0xfe, 0x64, 0x78, 0x2d, 0xb6, 0x02, 0xe1, 0x22, 0xae, 0x5b, - 0x43, 0xf2, 0x14, 0xa2, 0x88, 0xf6, 0x39, 0x0b, 0xc0, 0x5c, 0x39, 0xdc, 0x4c, 0x86, 0xde, 0xd8, - 0x98, 0x32, 0x75, 0x99, 0x4f, 0x3e, 0x86, 0x75, 0xee, 0x53, 0x7f, 0xc2, 0xb5, 0x35, 0x04, 0x4a, - 0x0d, 0xb9, 0xd1, 0x8c, 0xae, 0x4f, 0x7d, 0x66, 0xc8, 0x6d, 0xf2, 0x04, 0xca, 0xec, 0x8a, 0x5a, - 0x7d, 0xcb, 0x19, 0x71, 0xad, 0x80, 0x9a, 0x03, 0x50, 0x25, 0x22, 0x6d, 0x94, 0x04, 0xd3, 0xb9, - 0x33, 0xe2, 0xe4, 0x63, 0xa8, 0x39, 0xaf, 0xfe, 0xc8, 0x06, 0xbe, 0x79, 0xc5, 0xfa, 0x81, 0x87, - 0xd6, 0xd1, 0xe0, 0xcd, 0x29, 0xf9, 0x1b, 0x41, 0x25, 0x77, 0x61, 0xcd, 0xa7, 0x23, 0xae, 0x15, - 0x51, 0x69, 0x29, 0x30, 0x80, 0x8e, 0x0c, 0xa4, 0xea, 0xff, 0x2c, 0x42, 0xa5, 0x2b, 0x6e, 0xb8, - 0x20, 0x03, 0xeb, 0x50, 0x70, 0xde, 0xd9, 0xcc, 0x0b, 0x43, 0x80, 0x0b, 0x72, 0x0c, 0x5b, 0x8e, - 0xeb, 0x9b, 0x63, 0xf3, 0x3b, 0xb4, 0x2e, 0x48, 0x87, 0x3c, 0xde, 0x72, 0x07, 0x0f, 0xe9, 0xc4, - 0x76, 0x31, 0x23, 0x54, 0x27, 0x45, 0x21, 0x9f, 0xa4, 0x74, 0x8c, 0x1c, 0x6a, 0xa1, 0xa7, 0x94, - 0x24, 0xf3, 0x99, 0x43, 0x2d, 0xd2, 0x86, 0xad, 0x28, 0x00, 0x03, 0x34, 0x57, 0xb8, 0x4a, 0xa4, - 0xf5, 0x03, 0x3c, 0x30, 0x76, 0x8f, 0x83, 0x54, 0x65, 0xe1, 0x86, 0xea, 0xa6, 0x28, 0xe4, 0x53, - 0x20, 0x74, 0x30, 0x60, 0x9c, 0xf7, 0x5d, 0xe6, 0x8d, 0x4d, 0xce, 0x4d, 0xc7, 0xe6, 0xda, 0x3a, - 0x96, 0xa8, 0xad, 0x60, 0xe7, 0x32, 0xda, 0x10, 0xb6, 0xf2, 0x20, 0x51, 0xfa, 0xd4, 0x1a, 0x39, - 0x9e, 0xe9, 0xbf, 0x19, 0x6b, 0x45, 0xf4, 0x88, 0x2a, 0x37, 0x8e, 0x42, 0x3a, 0xf9, 0x02, 0x34, - 0x26, 0x92, 0xa2, 0xcf, 0x65, 0x56, 0xc4, 0x64, 0x4a, 0x28, 0xb3, 0xcb, 0xe2, 0x49, 0x13, 0x49, - 0x3e, 0x84, 0x5a, 0x80, 0x40, 0x9f, 0xf2, 0xb7, 0x7d, 0x8c, 0x45, 0x19, 0x05, 0xaa, 0x48, 0xee, - 0x51, 0xfe, 0xb6, 0x2d, 0x82, 0x72, 0x01, 0x3b, 0x7c, 0x9a, 0xb7, 0xfd, 0xe9, 0xe5, 0xb8, 0x06, - 0x18, 0x67, 0x2d, 0xf0, 0xc8, 0x6c, 0x66, 0x1b, 0x75, 0x3e, 0x4b, 0xe4, 0xe4, 0x25, 0xec, 0xa5, - 0x0c, 0x8e, 0xa9, 0xac, 0xa0, 0xca, 0x3b, 0x01, 0x1e, 0x33, 0x73, 0xdd, 0xb8, 0xcd, 0x32, 0xe9, - 0x7c, 0x0a, 0xbf, 0x8d, 0x2c, 0xf8, 0x91, 0x9f, 0x41, 0x3d, 0x85, 0xe2, 0xe0, 0xca, 0x55, 0xbc, - 0x32, 0x49, 0x42, 0x19, 0xef, 0xad, 0x45, 0x75, 0x6d, 0x13, 0x43, 0x15, 0x2e, 0x05, 0x4c, 0xcd, - 0x31, 0x1d, 0x31, 0xad, 0x16, 0xc0, 0x14, 0x17, 0x82, 0x7f, 0xe0, 0x8c, 0xc7, 0xd4, 0x1e, 0x6a, - 0x6a, 0xc0, 0x2f, 0x97, 0xa2, 0x6c, 0x8c, 0xdc, 0x89, 0xb6, 0xb5, 0xaf, 0x3c, 0x2a, 0x18, 0xe2, - 0x93, 0xdc, 0x85, 0x32, 0x1f, 0xbc, 0x61, 0xc3, 0x89, 0xc5, 0x3c, 0x8d, 0xa0, 0x96, 0x88, 0x40, - 0x3e, 0x82, 0xc2, 0x58, 0xd4, 0x1c, 0x6d, 0x1b, 0x31, 0x17, 0x24, 0xfe, 0xb4, 0x0a, 0x19, 0xc1, - 0x26, 0xb9, 0x0f, 0x15, 0x77, 0x62, 0x59, 0x7d, 0xce, 0x06, 0x1e, 0xf3, 0xb5, 0x3a, 0x6a, 0x01, - 0x41, 0xea, 0x22, 0xa5, 0x71, 0x0c, 0x6a, 0x1a, 0x9c, 0xe4, 0x40, 0x18, 0x19, 0x00, 0x5a, 0x41, - 0x3f, 0xd5, 0x93, 0x55, 0x25, 0xe0, 0x33, 0x42, 0x26, 0xbd, 0x05, 0xe4, 0xc4, 0x63, 0xd4, 0x67, - 0x08, 0x79, 0x83, 0xfd, 0x69, 0xc2, 0xb8, 0x4f, 0x9e, 0xc2, 0x46, 0x00, 0x9d, 0x80, 0x0d, 0x73, - 0xb8, 0x72, 0xa8, 0xa6, 0x73, 0xc3, 0xa8, 0xf0, 0x68, 0xa1, 0x7f, 0x0a, 0x6a, 0x42, 0x95, 0x6b, - 0x5d, 0x27, 0xaa, 0xa0, 0x92, 0xa8, 0x82, 0x82, 0x5d, 0x04, 0x39, 0x71, 0xee, 0x02, 0x76, 0x15, - 0x36, 0x63, 0xec, 0xae, 0x75, 0xad, 0x6f, 0xc3, 0xd6, 0x19, 0xf3, 0x05, 0xc1, 0x64, 0x5c, 0x6a, - 0xd0, 0xff, 0xa1, 0x40, 0x19, 0x79, 0x5a, 0xf6, 0x6b, 0x67, 0x81, 0xbe, 0x69, 0x79, 0xca, 0x65, - 0x95, 0xa7, 0x7c, 0xbc, 0x3c, 0x3d, 0x86, 0x2d, 0x6f, 0x62, 0xdb, 0x02, 0xc9, 0x41, 0xb1, 0xb7, - 0x27, 0x63, 0x2c, 0x2d, 0x05, 0xa3, 0x26, 0x37, 0xb0, 0x0c, 0xb7, 0x27, 0x63, 0x72, 0x00, 0xdb, - 0x03, 0x67, 0xec, 0x5a, 0xcc, 0x67, 0xc3, 0x18, 0x77, 0x01, 0xb9, 0xb7, 0xa6, 0x5b, 0x21, 0xbf, - 0x7e, 0x0c, 0xb5, 0xf8, 0x1d, 0x84, 0xcb, 0x9e, 0x40, 0x45, 0xda, 0x6c, 0xbf, 0x76, 0xc2, 0x28, - 0x6e, 0x46, 0xae, 0x17, 0x17, 0x33, 0x80, 0x87, 0x9f, 0x5c, 0xff, 0x8b, 0x02, 0x75, 0x99, 0x9e, - 0xa8, 0x97, 0x2f, 0xf7, 0x66, 0x76, 0x09, 0xca, 0xcd, 0x29, 0x41, 0x8f, 0x23, 0x4c, 0xe5, 0xe7, - 0x00, 0x61, 0x8a, 0xa7, 0x6f, 0x80, 0xa4, 0x6c, 0x11, 0x77, 0xd2, 0x61, 0x1d, 0x9d, 0x11, 0x5e, - 0x07, 0xa2, 0xe6, 0x65, 0xc8, 0x1d, 0x91, 0x32, 0x53, 0xff, 0xa0, 0x29, 0x25, 0x23, 0x22, 0xe8, - 0x63, 0xa8, 0x9f, 0xc8, 0x45, 0x20, 0xb6, 0xfc, 0x8e, 0xf1, 0xe6, 0x9c, 0x4b, 0x36, 0xe7, 0xfb, - 0x50, 0x31, 0x79, 0x3f, 0xd4, 0x8e, 0xb7, 0x2a, 0x19, 0x60, 0xf2, 0xf0, 0x08, 0xbd, 0x0e, 0x24, - 0x75, 0x9c, 0x40, 0xdc, 0x5b, 0xa8, 0x27, 0x8a, 0xd6, 0x0a, 0x46, 0x2c, 0x2a, 0xdf, 0xb9, 0x45, - 0xe5, 0x5b, 0xff, 0x02, 0x48, 0xea, 0xb0, 0x15, 0x3d, 0xa9, 0xff, 0x1c, 0x76, 0xce, 0x98, 0xdf, - 0xc1, 0x8a, 0x87, 0xe5, 0x2e, 0xb4, 0xf3, 0x0e, 0x94, 0xdf, 0x39, 0xde, 0x5b, 0xe6, 0x45, 0x86, - 0x96, 0x02, 0x42, 0x6b, 0xa8, 0x7f, 0x09, 0xdb, 0x69, 0xa9, 0x55, 0x0f, 0xec, 0xc1, 0xbd, 0xa3, - 0xe1, 0xf0, 0x82, 0x51, 0x3e, 0xf1, 0xd8, 0x98, 0xd9, 0x7e, 0xcf, 0x59, 0x19, 0x89, 0x5a, 0x7c, - 0xba, 0x54, 0x62, 0x55, 0x58, 0xbf, 0x07, 0x77, 0xe6, 0x69, 0x15, 0xc1, 0xf8, 0x3d, 0x54, 0x11, - 0x81, 0x9d, 0x2b, 0xe6, 0x5d, 0x99, 0xec, 0xdd, 0x0f, 0x18, 0x38, 0xf6, 0xa1, 0x32, 0x64, 0x7c, - 0xe0, 0x99, 0xae, 0xe8, 0x5d, 0x32, 0xdb, 0xe3, 0x24, 0xfd, 0xdf, 0x8a, 0x18, 0x0b, 0x87, 0xcc, - 0xc2, 0x32, 0x72, 0x0f, 0x82, 0x7c, 0xeb, 0xc7, 0xf4, 0x97, 0x91, 0x82, 0x8d, 0x64, 0x01, 0xd0, - 0x0e, 0x00, 0x62, 0xdd, 0x2f, 0x7b, 0xce, 0x8b, 0x71, 0xc4, 0x67, 0xed, 0xb5, 0x05, 0xb3, 0xb6, - 0xb0, 0x68, 0x2c, 0xcc, 0xeb, 0xe3, 0x70, 0x5a, 0x08, 0x2c, 0x42, 0xca, 0xa5, 0x98, 0x50, 0x3f, - 0x87, 0xca, 0x29, 0xf5, 0x69, 0x97, 0xf9, 0x68, 0x7f, 0x96, 0x67, 0xb2, 0x06, 0x5b, 0x13, 0xd4, - 0x2e, 0xbd, 0x4a, 0xb6, 0x82, 0x25, 0x77, 0xbf, 0xa9, 0x83, 0x45, 0x39, 0x8f, 0x8e, 0x12, 0xf1, - 0xfc, 0xb3, 0x12, 0x9c, 0x8e, 0x6e, 0x0f, 0x4f, 0xc7, 0x4e, 0x39, 0x64, 0x96, 0xec, 0x40, 0x61, - 0xa7, 0x94, 0x81, 0x31, 0x82, 0x4d, 0xf2, 0x09, 0x94, 0x86, 0xd4, 0xa7, 0x38, 0x4b, 0xe7, 0x62, - 0x15, 0x2a, 0xe6, 0x03, 0xa3, 0x38, 0x0c, 0x16, 0xe4, 0x01, 0x6c, 0xf8, 0xcc, 0xe6, 0x8e, 0xd7, - 0x7f, 0xe5, 0x50, 0x6f, 0x28, 0x93, 0xbf, 0x12, 0xd0, 0x8e, 0x05, 0x29, 0x34, 0x4e, 0x5a, 0x22, - 0x8c, 0xd3, 0x60, 0x57, 0xd4, 0x69, 0x7a, 0xc5, 0x86, 0xa9, 0x86, 0x73, 0x0a, 0xf5, 0x99, 0x1d, - 0x91, 0x37, 0x3f, 0x05, 0x84, 0xb8, 0xc9, 0xc2, 0xc4, 0x21, 0x51, 0xd1, 0x0c, 0x21, 0x6b, 0x84, - 0x2c, 0xfa, 0x2f, 0x30, 0x65, 0x51, 0x0b, 0x9e, 0xca, 0x57, 0x73, 0xbf, 0xfe, 0x15, 0x26, 0x6d, - 0x42, 0x4e, 0x1c, 0xfe, 0x10, 0xd6, 0xd1, 0x33, 0xc9, 0xf6, 0x11, 0xf9, 0x4d, 0xee, 0xea, 0x97, - 0x91, 0xf1, 0x09, 0xb7, 0xdf, 0x18, 0xf0, 0xfa, 0x33, 0x20, 0x29, 0x8d, 0xc2, 0x9e, 0x95, 0xc2, - 0xa8, 0x7f, 0xaf, 0xc0, 0xfd, 0x96, 0x6d, 0xfa, 0x26, 0xb5, 0xcc, 0xef, 0x98, 0x6c, 0x23, 0x5d, - 0xe1, 0xaa, 0x01, 0x7b, 0xdf, 0x3d, 0x6d, 0xee, 0xd0, 0x9b, 0xbf, 0xd1, 0xd0, 0x1b, 0x6b, 0x91, - 0x6b, 0xcb, 0x5a, 0xe4, 0x7d, 0xb8, 0x37, 0xff, 0x96, 0x02, 0x6c, 0xff, 0x55, 0x04, 0x1a, 0x6c, - 0xe6, 0x51, 0xd9, 0x7d, 0x56, 0xa9, 0xa3, 0x31, 0x0b, 0x72, 0x4b, 0x2c, 0x20, 0x9f, 0x83, 0x9a, - 0x9a, 0x52, 0xc2, 0x7b, 0xc7, 0xab, 0x7b, 0x2d, 0x39, 0xae, 0x70, 0xf2, 0x19, 0x6c, 0x26, 0x06, - 0xa1, 0xb0, 0x46, 0xc5, 0x85, 0xaa, 0xf1, 0x89, 0x88, 0xeb, 0x2f, 0x05, 0x3e, 0x93, 0x37, 0x79, - 0x3f, 0xf3, 0xc0, 0xbf, 0x14, 0xf8, 0xa0, 0xcb, 0xfc, 0x8c, 0x08, 0xad, 0xe2, 0xac, 0xb9, 0xd1, - 0xcf, 0xfd, 0xd8, 0xe8, 0x2f, 0x1d, 0x90, 0x3e, 0x80, 0xbb, 0x73, 0xed, 0x16, 0xc1, 0x3f, 0x84, - 0x1d, 0x9c, 0x73, 0xa7, 0x0c, 0x2b, 0xcc, 0xc6, 0x3b, 0xb0, 0x9d, 0x96, 0x11, 0xaa, 0x9e, 0xc2, - 0x6e, 0xf7, 0x8d, 0x33, 0xb1, 0x86, 0xf2, 0x57, 0x02, 0xc7, 0x5d, 0x41, 0xd7, 0x33, 0xa8, 0xcf, - 0x08, 0xad, 0x3a, 0x07, 0xfc, 0x5d, 0x81, 0xfd, 0x2e, 0xf3, 0xe7, 0x3c, 0xec, 0x96, 0x87, 0x65, - 0xe1, 0xd3, 0x31, 0x77, 0xf3, 0xa7, 0xa3, 0xbe, 0x8f, 0x60, 0x99, 0x67, 0x97, 0x6b, 0x5d, 0x3f, - 0x7e, 0x01, 0xd5, 0xc4, 0x8f, 0x6e, 0x44, 0x85, 0x8d, 0x17, 0xed, 0xe7, 0xed, 0xce, 0xcb, 0x76, - 0xbf, 0xf7, 0xdb, 0xcb, 0xa6, 0x7a, 0x8b, 0x00, 0xac, 0x9f, 0x76, 0x5e, 0x1c, 0x9f, 0x37, 0x55, - 0x85, 0x14, 0x21, 0xdf, 0x6a, 0xf7, 0xd4, 0x1c, 0xd9, 0x80, 0xd2, 0x69, 0xab, 0x7b, 0x62, 0x34, - 0x7b, 0x4d, 0x35, 0x4f, 0x6a, 0x50, 0x39, 0x39, 0xea, 0x35, 0xcf, 0x3a, 0x46, 0xeb, 0xe4, 0xe8, - 0x5c, 0x5d, 0x7b, 0xfc, 0x6b, 0x50, 0xd3, 0x3f, 0x5e, 0x10, 0x0d, 0xea, 0xa1, 0xe6, 0xce, 0x65, - 0xaf, 0x75, 0xd1, 0xfa, 0xdd, 0x51, 0xaf, 0xd5, 0x69, 0xab, 0xb7, 0x84, 0xb2, 0x8b, 0x56, 0x5b, - 0x50, 0xc4, 0x19, 0x62, 0x75, 0xf4, 0x9b, 0x60, 0x95, 0x7b, 0x7c, 0x0e, 0x10, 0xfd, 0xd8, 0x43, - 0x2a, 0x50, 0xbc, 0x6c, 0xb6, 0x4f, 0x5b, 0xed, 0x33, 0xf5, 0x96, 0x58, 0x18, 0x2f, 0xda, 0x6d, - 0xb1, 0x50, 0x48, 0x15, 0xca, 0x27, 0x9d, 0x8b, 0xcb, 0xf3, 0x66, 0xaf, 0x79, 0xaa, 0xe6, 0x84, - 0xd1, 0xcf, 0x5b, 0xe7, 0xe7, 0xcd, 0x53, 0x35, 0x4f, 0xca, 0x50, 0x68, 0x1a, 0x46, 0xc7, 0x50, - 0xbf, 0x3d, 0xfc, 0xbe, 0x08, 0xc5, 0x0b, 0x6a, 0xd3, 0x11, 0xf3, 0xc8, 0x57, 0x50, 0x89, 0xbd, - 0xdb, 0xc8, 0x6d, 0xf4, 0xf0, 0xec, 0xa3, 0xb0, 0xb1, 0x33, 0xbb, 0x21, 0x80, 0xf1, 0x4b, 0xf1, - 0xe0, 0x92, 0x0f, 0x33, 0xb2, 0x23, 0x81, 0x9f, 0x7c, 0xd7, 0x35, 0xb6, 0xd3, 0x64, 0x21, 0xf8, - 0x0c, 0x20, 0x7a, 0xfb, 0x90, 0x5d, 0x64, 0x99, 0x79, 0xd0, 0x35, 0xea, 0x33, 0x74, 0x21, 0x7b, - 0x02, 0xd5, 0xc4, 0x33, 0x83, 0xec, 0xc5, 0x53, 0x36, 0x51, 0x34, 0x1b, 0xb7, 0xb3, 0xb6, 0xa4, - 0x92, 0xc4, 0x90, 0x2f, 0x95, 0x64, 0xbd, 0x33, 0xa4, 0x92, 0xd9, 0x37, 0x81, 0x50, 0x92, 0xc0, - 0x95, 0x54, 0x92, 0xf5, 0x4e, 0x90, 0x4a, 0x32, 0xa6, 0xfa, 0xaf, 0x61, 0x33, 0x39, 0x7b, 0x93, - 0x46, 0x78, 0xed, 0xd9, 0x31, 0xbe, 0xa1, 0x65, 0xee, 0x09, 0x3d, 0x7f, 0x80, 0xdd, 0xec, 0x91, - 0x99, 0xe8, 0x28, 0xb3, 0x70, 0x4a, 0x6f, 0xec, 0x2f, 0xe4, 0x11, 0xfa, 0x87, 0xa0, 0xcd, 0x6b, - 0x5d, 0xe4, 0x23, 0x94, 0x5e, 0xd2, 0xbf, 0x1b, 0xfa, 0x12, 0xae, 0x10, 0x51, 0xe1, 0x6c, 0x18, - 0x22, 0x2a, 0x35, 0x96, 0x86, 0x88, 0x4a, 0x8c, 0x90, 0xa1, 0x20, 0x0e, 0x16, 0x31, 0xc1, 0xf8, - 0x68, 0x13, 0x13, 0x8c, 0xcd, 0x27, 0xad, 0xe0, 0x19, 0x1e, 0x1b, 0xe2, 0xc8, 0x9d, 0x29, 0xee, - 0x66, 0x87, 0xbe, 0xc6, 0x5e, 0xf6, 0x66, 0x14, 0xca, 0xd8, 0x44, 0x16, 0x85, 0x72, 0x76, 0xbc, - 0x8b, 0x42, 0x39, 0x33, 0xc2, 0x9d, 0x40, 0x35, 0x41, 0x26, 0x7b, 0xb3, 0xac, 0x49, 0x5c, 0xcd, - 0xce, 0x5d, 0x87, 0xff, 0x53, 0x00, 0xa2, 0xae, 0x10, 0xd8, 0x16, 0xef, 0xc6, 0x53, 0xdb, 0x32, - 0x86, 0x8d, 0xa9, 0x6d, 0xb3, 0xed, 0x9b, 0xc2, 0xed, 0x39, 0x3d, 0x8c, 0x7c, 0x18, 0xb8, 0x77, - 0x61, 0x67, 0x6e, 0x3c, 0x58, 0xcc, 0x24, 0xdd, 0x98, 0x6c, 0x69, 0xd2, 0xd4, 0xcc, 0xde, 0x28, - 0x4d, 0xcd, 0xe8, 0x81, 0x87, 0xff, 0x51, 0xd2, 0xf9, 0xd9, 0x82, 0x5a, 0xaa, 0xc1, 0xc9, 0x58, - 0x67, 0xf7, 0x4a, 0x19, 0xeb, 0xcc, 0x9e, 0x38, 0x82, 0xbd, 0xb9, 0x6d, 0x85, 0xfc, 0x24, 0xbc, - 0xe4, 0xc2, 0x76, 0xd8, 0xf8, 0x70, 0x19, 0x9b, 0x6b, 0x5d, 0xbf, 0x5a, 0xc7, 0xbf, 0xcd, 0x9e, - 0xfe, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x37, 0xb0, 0x97, 0x90, 0x43, 0x1b, 0x00, 0x00, + // 2228 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x19, 0x49, 0x73, 0xdb, 0xd6, + 0xd9, 0x20, 0x25, 0x2e, 0x1f, 0x17, 0x41, 0x4f, 0x8b, 0x21, 0x5a, 0xb1, 0x25, 0xc4, 0x71, 0x5d, + 0xc7, 0x51, 0x1b, 0xda, 0x4d, 0xed, 0x24, 0x6e, 0xa3, 0x85, 0x61, 0x39, 0x91, 0x48, 0x0d, 0x48, + 0xd7, 0x69, 0x2f, 0x2c, 0x44, 0x3c, 0xd3, 0x48, 0x40, 0x02, 0xc5, 0x03, 0xe5, 0x28, 0xbf, 0xa0, + 0x97, 0xce, 0xf4, 0xda, 0x1f, 0xd2, 0x6b, 0xff, 0x41, 0xef, 0xbd, 0x74, 0xa6, 0xd3, 0xe9, 0xb1, + 0x3f, 0xa2, 0xf3, 0x16, 0x00, 0x0f, 0xe0, 0x22, 0xc6, 0x89, 0x73, 0xc3, 0xfb, 0xde, 0xf7, 0xbe, + 0x7d, 0x25, 0xa1, 0x68, 0x7a, 0xf6, 0x81, 0xe7, 0xbb, 0x81, 0x8b, 0xb2, 0xa6, 0x67, 0xeb, 0x4d, + 0xa8, 0x7c, 0x8e, 0x4d, 0x62, 0x5f, 0x38, 0xb8, 0xeb, 0x99, 0x03, 0x8c, 0x54, 0xc8, 0x8e, 0xcc, + 0x6f, 0x34, 0x65, 0x4f, 0xb9, 0x5f, 0x34, 0xe8, 0x27, 0x83, 0xd8, 0x63, 0x2d, 0x23, 0x20, 0xf6, + 0x18, 0x21, 0x58, 0x71, 0x6c, 0x12, 0x68, 0xd9, 0xbd, 0xec, 0xfd, 0xa2, 0xc1, 0xbe, 0xf5, 0xbf, + 0x28, 0xb0, 0x76, 0x6e, 0xfa, 0xe6, 0x08, 0x07, 0xd8, 0x3f, 0x76, 0xc7, 0x2f, 0xed, 0x21, 0xc5, + 0x1b, 0x9b, 0x23, 0x2c, 0x88, 0xb1, 0x6f, 0xf4, 0x14, 0xaa, 0x5e, 0x88, 0xd6, 0x0f, 0xae, 0x3c, + 0xcc, 0x08, 0x57, 0xeb, 0xe8, 0x80, 0x4a, 0x16, 0x51, 0xe8, 0x5d, 0x79, 0xd8, 0xa8, 0x78, 0xf2, + 0x11, 0x1d, 0x40, 0xe1, 0xa5, 0x90, 0x55, 0xcb, 0xee, 0x29, 0xf7, 0x4b, 0xe2, 0x51, 0x42, 0x01, + 0x23, 0xc2, 0xd1, 0x3d, 0x28, 0x46, 0xf4, 0x7e, 0x68, 0x59, 0x36, 0x61, 0xf5, 0xd2, 0x74, 0x26, + 0x5c, 0x90, 0xa2, 0xc1, 0x0f, 0xfa, 0x1f, 0xa0, 0x72, 0x86, 0x03, 0xdf, 0x1e, 0x90, 0x53, 0x77, + 0xd8, 0xc5, 0x01, 0xba, 0x05, 0xc5, 0xd7, 0xae, 0xff, 0x35, 0xf6, 0xfb, 0xb6, 0x25, 0x58, 0x17, + 0x38, 0xa0, 0x65, 0xa1, 0x3a, 0x94, 0x47, 0x1c, 0xbb, 0xef, 0xb8, 0x43, 0xa2, 0x65, 0xf6, 0xb2, + 0xf7, 0x4b, 0xf5, 0x35, 0xc6, 0x3c, 0x26, 0x63, 0x94, 0x46, 0xd1, 0x37, 0xd1, 0x1f, 0x41, 0x5e, + 0x5c, 0xcd, 0xd4, 0x28, 0x12, 0x2b, 0x23, 0x8b, 0xf5, 0x04, 0x20, 0xa6, 0x37, 0xf3, 0xdd, 0x36, + 0xe4, 0x18, 0x2a, 0x17, 0xa2, 0x68, 0x88, 0x93, 0xfe, 0x6b, 0xd8, 0xe8, 0x4e, 0x86, 0x43, 0x4c, + 0x02, 0xdb, 0x1d, 0x2f, 0x36, 0xe6, 0x6c, 0xd6, 0x47, 0xb0, 0xdd, 0x30, 0x7d, 0xe7, 0xaa, 0x1b, + 0xb8, 0x9e, 0x67, 0x8f, 0x87, 0x6f, 0x42, 0xe3, 0x67, 0x90, 0xed, 0x99, 0xc3, 0xef, 0xf0, 0xe0, + 0x43, 0x28, 0x9e, 0xb9, 0x93, 0x71, 0x40, 0xc3, 0x90, 0x86, 0xaf, 0x77, 0x39, 0x08, 0x03, 0xda, + 0xbb, 0x1c, 0x50, 0x42, 0x9e, 0x19, 0xbc, 0x12, 0x6f, 0xd8, 0xb7, 0xfe, 0x35, 0x54, 0xba, 0xc1, + 0xc4, 0xba, 0xea, 0x5c, 0x62, 0xff, 0xd2, 0xc6, 0xaf, 0xe7, 0x71, 0x73, 0x5f, 0x8f, 0xb1, 0x1f, + 0x72, 0x63, 0x07, 0x54, 0x85, 0x8c, 0x6d, 0x89, 0x38, 0xc8, 0xd8, 0x16, 0xda, 0x83, 0x92, 0x85, + 0xc9, 0xc0, 0xb7, 0x3d, 0x6a, 0x34, 0x6d, 0x85, 0x5d, 0xc8, 0x20, 0xfd, 0x5f, 0x0a, 0xac, 0xf6, + 0x7c, 0xdb, 0x74, 0xd0, 0x0e, 0x14, 0x02, 0xfa, 0x11, 0x87, 0x47, 0x9e, 0x9d, 0x5b, 0x16, 0xbd, + 0x22, 0x54, 0x22, 0x7a, 0xc5, 0xf9, 0xe5, 0xd9, 0xb9, 0x65, 0xa1, 0x47, 0x10, 0x47, 0x63, 0x9f, + 0x60, 0x9e, 0x88, 0xa5, 0x7a, 0x35, 0x19, 0xb6, 0x46, 0x39, 0x42, 0xa2, 0xa1, 0xa8, 0x43, 0x8e, + 0x04, 0x66, 0x30, 0x21, 0x4c, 0xa2, 0x6a, 0x1d, 0x18, 0x76, 0x37, 0x30, 0x03, 0x6c, 0x88, 0x1b, + 0xf4, 0x13, 0x58, 0x73, 0x2f, 0xbe, 0xc2, 0x83, 0xc0, 0xbe, 0xc4, 0x7d, 0x6e, 0xd8, 0x55, 0xc6, + 0xba, 0x1a, 0x81, 0x7f, 0x4b, 0xa1, 0x68, 0x17, 0x56, 0x02, 0x73, 0x48, 0xb4, 0x02, 0x63, 0x5c, + 0x60, 0xa4, 0x7a, 0xe6, 0xd0, 0x60, 0x50, 0xfd, 0x6f, 0x0a, 0x94, 0x5f, 0xb0, 0x28, 0x17, 0x85, + 0x60, 0x13, 0x56, 0xed, 0x91, 0x39, 0x0c, 0xad, 0xc9, 0x0f, 0x48, 0x83, 0xfc, 0xc0, 0x1d, 0x8d, + 0xcc, 0xb1, 0x25, 0xa2, 0x2e, 0x3c, 0x52, 0x9f, 0x0d, 0xbd, 0x09, 0xb3, 0xe9, 0xaa, 0x41, 0x3f, + 0xd1, 0x2e, 0x14, 0xc9, 0xe0, 0x15, 0xb6, 0x26, 0x0e, 0xf6, 0x85, 0x49, 0x63, 0x00, 0xba, 0x0b, + 0xab, 0x23, 0xea, 0x70, 0x26, 0x6d, 0x68, 0x88, 0x28, 0x04, 0x0c, 0x7e, 0x89, 0xee, 0x40, 0xc9, + 0x9b, 0x38, 0x4e, 0x9f, 0xe0, 0x81, 0x8f, 0x03, 0x2d, 0xc7, 0xa8, 0x00, 0x05, 0x75, 0x19, 0x44, + 0xff, 0x8f, 0x02, 0x39, 0x2e, 0xf7, 0xe2, 0xc4, 0x5d, 0xe0, 0x1a, 0xd9, 0xa1, 0xd9, 0xa4, 0x43, + 0x35, 0xc8, 0xfb, 0x93, 0x71, 0x60, 0x8f, 0xb0, 0x50, 0x20, 0x3c, 0x4a, 0xae, 0x59, 0x9d, 0xeb, + 0x9a, 0x9f, 0x42, 0x6e, 0xc0, 0x8c, 0xc9, 0xe4, 0x2e, 0xd5, 0xd7, 0x19, 0x8e, 0x6c, 0x65, 0x43, + 0x20, 0x44, 0xce, 0xc9, 0xcf, 0x74, 0xce, 0xbf, 0x57, 0xa0, 0xc4, 0x42, 0x7d, 0x41, 0x91, 0x9e, + 0x1d, 0xe8, 0x47, 0xb0, 0xee, 0x7a, 0x81, 0x3d, 0xb2, 0xbf, 0x35, 0x69, 0x18, 0xf3, 0x8a, 0x99, + 0x65, 0x12, 0x6f, 0x31, 0x26, 0x1d, 0xe9, 0x96, 0x15, 0x4d, 0xd5, 0x4d, 0x41, 0xd0, 0xfb, 0x29, + 0x1a, 0x43, 0xd7, 0x74, 0x98, 0x39, 0x94, 0x24, 0x72, 0xd3, 0x35, 0x1d, 0xd4, 0x86, 0xf5, 0x38, + 0xce, 0xb9, 0x72, 0x44, 0xb8, 0x78, 0x5f, 0x98, 0x28, 0xd2, 0xe3, 0x20, 0xd5, 0x7c, 0x88, 0xa1, + 0x7a, 0x29, 0x08, 0xfa, 0x00, 0x90, 0x39, 0x18, 0x60, 0x42, 0xfa, 0x1e, 0xf6, 0x47, 0x36, 0x21, + 0xb6, 0x3b, 0x26, 0x5a, 0x8e, 0xc5, 0xde, 0x3a, 0xbf, 0x39, 0x8f, 0x2f, 0xd0, 0x67, 0xb0, 0x6b, + 0xe1, 0x97, 0xe6, 0xc4, 0x09, 0xfa, 0x24, 0x2a, 0x82, 0x7d, 0xd3, 0x19, 0xba, 0xbe, 0x1d, 0xbc, + 0x1a, 0x69, 0x79, 0x66, 0x9c, 0x9a, 0xc0, 0x89, 0xeb, 0xe4, 0x61, 0x88, 0x81, 0x9a, 0xb0, 0x17, + 0x52, 0xc0, 0xb4, 0x0a, 0xf6, 0x89, 0x28, 0x83, 0x12, 0x95, 0x02, 0xa3, 0xf2, 0x8e, 0xc0, 0x4b, + 0x14, 0xcb, 0x98, 0x50, 0xe8, 0xd2, 0xe2, 0x2c, 0x97, 0xa2, 0x9f, 0xc3, 0x66, 0x2a, 0x6d, 0xfb, + 0xcc, 0xa5, 0xc0, 0x48, 0xa3, 0x64, 0xee, 0xb6, 0xa9, 0x83, 0x35, 0xc8, 0x8b, 0xae, 0xa2, 0x95, + 0x78, 0xea, 0x89, 0x63, 0xed, 0x08, 0xd4, 0xb4, 0x25, 0xd1, 0x01, 0x4d, 0x54, 0x6e, 0x7d, 0x85, + 0x09, 0xb0, 0x99, 0xac, 0x34, 0x22, 0xfe, 0x42, 0x24, 0xbd, 0x05, 0xe8, 0xd8, 0xc7, 0x66, 0x80, + 0x99, 0x7f, 0x0c, 0xfc, 0xc7, 0x09, 0x26, 0x01, 0x7a, 0x04, 0x65, 0x9e, 0x35, 0x22, 0x8e, 0x15, + 0xe6, 0x48, 0x35, 0xed, 0x48, 0xa3, 0x44, 0xe2, 0x83, 0xfe, 0x01, 0xa8, 0x09, 0x52, 0x9e, 0x73, + 0x95, 0x48, 0x3f, 0x25, 0x91, 0x7e, 0x14, 0x9d, 0x1a, 0x2f, 0xc1, 0x77, 0x01, 0xba, 0x0a, 0x55, + 0x09, 0xdd, 0x73, 0xae, 0xf4, 0x87, 0xb0, 0xd6, 0xc4, 0xc1, 0xb2, 0xef, 0x4f, 0xa0, 0x12, 0x63, + 0x53, 0xd1, 0xde, 0x48, 0xc7, 0x2d, 0xd8, 0x08, 0xa9, 0x9c, 0xda, 0x24, 0x10, 0x7c, 0xf5, 0x73, + 0x58, 0x4f, 0x82, 0x29, 0x83, 0x4f, 0x60, 0x8d, 0x33, 0x70, 0x45, 0xa3, 0x0a, 0x5d, 0x82, 0x62, + 0x1e, 0x61, 0x0f, 0x33, 0xaa, 0x44, 0x3e, 0x12, 0x6a, 0x9d, 0x26, 0x0e, 0x58, 0xe7, 0x21, 0x4b, + 0x68, 0xf7, 0x18, 0xaa, 0x12, 0x3a, 0xe5, 0xae, 0x43, 0x8e, 0x55, 0xb3, 0x90, 0x29, 0x2f, 0x54, + 0x0c, 0xc3, 0x10, 0x37, 0xfa, 0x5f, 0x15, 0x58, 0x33, 0x26, 0x63, 0x0e, 0xbc, 0x96, 0x49, 0xa2, + 0x60, 0x66, 0xe6, 0x16, 0xcc, 0x6c, 0xb2, 0x60, 0x7e, 0x04, 0x15, 0x51, 0x9d, 0x85, 0x9d, 0x57, + 0xe6, 0xd5, 0xc4, 0xf2, 0x6b, 0xe9, 0xa4, 0x3f, 0x84, 0x4a, 0x2c, 0x1a, 0x55, 0x68, 0x51, 0x99, + 0xd7, 0x5d, 0x40, 0x34, 0x3a, 0x38, 0xbd, 0x25, 0x0c, 0x86, 0xde, 0x01, 0x88, 0xa8, 0x85, 0x93, + 0x54, 0x31, 0x24, 0x47, 0x68, 0xff, 0xb1, 0x49, 0x7f, 0xe0, 0x8e, 0x3c, 0x07, 0x07, 0x5c, 0xa7, + 0x82, 0x01, 0x36, 0x39, 0x16, 0x10, 0x1d, 0xf1, 0xe8, 0x8d, 0x18, 0xd2, 0x80, 0x3c, 0x60, 0x51, + 0xb0, 0xb4, 0x0c, 0xfa, 0x13, 0x16, 0xc0, 0x32, 0x09, 0xf4, 0x1e, 0xe4, 0xb9, 0x10, 0xa1, 0xdb, + 0x4a, 0x92, 0x9d, 0x8c, 0xf0, 0x4e, 0xff, 0x87, 0x02, 0x5b, 0x34, 0xe0, 0xa2, 0x3a, 0xb6, 0x8c, + 0xca, 0x1f, 0xc2, 0xe6, 0xcc, 0xda, 0xc8, 0x5d, 0xb9, 0x41, 0x66, 0x14, 0xc5, 0xf7, 0xa0, 0xea, + 0x73, 0xc2, 0xfd, 0xf1, 0x64, 0x74, 0x81, 0x7d, 0xd1, 0xe7, 0x2b, 0x02, 0xda, 0x66, 0x40, 0x74, + 0x17, 0xaa, 0x8e, 0x3b, 0xec, 0x4b, 0x06, 0x5d, 0x61, 0x06, 0x2d, 0x3b, 0xee, 0xf0, 0x45, 0x64, + 0xd3, 0x1d, 0x28, 0xb0, 0x32, 0x4f, 0x45, 0xe3, 0xa3, 0x4a, 0x9e, 0x9d, 0x5b, 0x96, 0xfe, 0x94, + 0xa7, 0x95, 0xac, 0xce, 0xb2, 0x31, 0xfc, 0x67, 0x05, 0x6e, 0xd1, 0xb7, 0xaf, 0xdc, 0x89, 0x63, + 0x7d, 0xb7, 0x18, 0x78, 0x02, 0xda, 0xdc, 0x52, 0xcf, 0x8d, 0xb2, 0x8d, 0x67, 0xd7, 0xf8, 0x05, + 0xaa, 0x9c, 0xc3, 0xce, 0x6c, 0x71, 0x78, 0xcd, 0xd9, 0x26, 0xec, 0x86, 0xb1, 0x94, 0x0d, 0xa6, + 0x30, 0x83, 0x6d, 0x90, 0xd4, 0xbb, 0x96, 0x45, 0x74, 0x9f, 0x85, 0x95, 0xd8, 0x0a, 0xbe, 0x7f, + 0x68, 0xbf, 0x0b, 0x95, 0x70, 0x95, 0xa1, 0x9d, 0x87, 0x88, 0xd5, 0x30, 0xdc, 0x6f, 0x68, 0xcf, + 0x21, 0x7a, 0x87, 0x85, 0x66, 0xc4, 0x93, 0xca, 0xfe, 0x29, 0xa8, 0xd2, 0x0a, 0x44, 0x67, 0xd9, + 0x64, 0x3d, 0x4b, 0x6c, 0x53, 0x46, 0x75, 0x24, 0x1f, 0x89, 0xfe, 0x77, 0x85, 0x0e, 0xfa, 0x16, + 0x76, 0x5a, 0xe3, 0x97, 0x2e, 0x15, 0x91, 0x4b, 0x2f, 0x8d, 0x33, 0x45, 0x06, 0x61, 0x2d, 0x2f, + 0x91, 0xea, 0x99, 0xd4, 0x44, 0x77, 0x00, 0x10, 0x4d, 0x0b, 0x64, 0xce, 0x38, 0x2d, 0x61, 0xa0, + 0x7b, 0x71, 0xff, 0x5c, 0x61, 0xc8, 0x65, 0x59, 0xdc, 0xa8, 0x9b, 0x52, 0x99, 0x46, 0x54, 0xc0, + 0x3e, 0x5b, 0x38, 0xb8, 0x57, 0x8b, 0x0c, 0x72, 0x4e, 0xb7, 0x8e, 0x5f, 0x40, 0xe9, 0xc4, 0x0c, + 0xcc, 0x2e, 0x0e, 0x98, 0x06, 0xb3, 0x46, 0xb1, 0x59, 0xcb, 0x8a, 0x0d, 0x6a, 0xd7, 0xbc, 0x4c, + 0x76, 0xd7, 0x6b, 0xb4, 0x9f, 0x3d, 0xd1, 0xa5, 0x56, 0x95, 0xec, 0xf4, 0xaa, 0x42, 0x3b, 0x64, + 0xcc, 0x8a, 0x16, 0xa4, 0x3f, 0x29, 0x9c, 0x3b, 0x33, 0x7c, 0xc8, 0x9d, 0x0d, 0xe0, 0x16, 0x76, + 0x44, 0xc3, 0x0b, 0x07, 0x70, 0xe1, 0x1a, 0x83, 0x5f, 0xa2, 0xf7, 0xa1, 0x60, 0x99, 0x81, 0xc9, + 0x56, 0x96, 0x8c, 0xd4, 0x19, 0x25, 0x1b, 0x18, 0x79, 0x8b, 0x1f, 0xd0, 0x3e, 0x94, 0x03, 0x3c, + 0x26, 0xae, 0xdf, 0xbf, 0x70, 0x4d, 0xdf, 0x12, 0xe5, 0xb2, 0xc4, 0x61, 0x47, 0x14, 0x14, 0x0a, + 0x27, 0x24, 0xa1, 0xc2, 0x69, 0xb0, 0x4d, 0x13, 0xc5, 0xbc, 0xc4, 0x16, 0x15, 0xd9, 0xc6, 0x61, + 0x6c, 0xeb, 0x27, 0xb0, 0x39, 0x75, 0x43, 0x23, 0xf0, 0x21, 0xb0, 0x18, 0xb7, 0xf1, 0xa2, 0x46, + 0x1a, 0xa2, 0xe8, 0x1f, 0xf1, 0x12, 0x49, 0xa9, 0x30, 0xae, 0x64, 0x39, 0xf3, 0xeb, 0xcf, 0x78, + 0x2d, 0x92, 0xdf, 0x51, 0xe6, 0xf7, 0x20, 0xc7, 0x2c, 0x13, 0xf2, 0x4e, 0xdb, 0x4d, 0xdc, 0xea, + 0x46, 0x2c, 0x7c, 0xc2, 0xec, 0xdf, 0x23, 0xe4, 0xf5, 0x8f, 0x01, 0xa5, 0x68, 0x52, 0x89, 0x96, + 0x72, 0xa4, 0xfe, 0x4f, 0x05, 0x6e, 0x77, 0xe5, 0xda, 0x1a, 0x65, 0xc9, 0x5b, 0xea, 0x19, 0x72, + 0x6d, 0xcc, 0x26, 0x6a, 0x23, 0x3a, 0x83, 0x2d, 0x89, 0x9a, 0x94, 0xc5, 0x3c, 0x31, 0x35, 0xee, + 0xce, 0x69, 0x49, 0x0d, 0x49, 0x88, 0x58, 0x7c, 0xfd, 0x29, 0xec, 0xce, 0xd5, 0x4c, 0x0c, 0x9f, + 0x91, 0x24, 0x4a, 0xb2, 0x4a, 0x7f, 0x02, 0xb7, 0x9b, 0xd7, 0x1a, 0x65, 0xde, 0xe3, 0x11, 0xec, + 0x36, 0x17, 0xf1, 0x9d, 0xab, 0xa6, 0xf2, 0x46, 0x6a, 0xd6, 0x61, 0x8b, 0x4d, 0xbe, 0xd1, 0xdd, + 0x12, 0xa3, 0xc5, 0x16, 0x6c, 0xa4, 0xdf, 0xd0, 0x9c, 0xfb, 0x9f, 0x02, 0xfb, 0x5d, 0x1c, 0xcc, + 0xfe, 0x99, 0xe7, 0xc7, 0x6b, 0x99, 0xa9, 0xb0, 0x78, 0x01, 0x3b, 0x29, 0xa2, 0x53, 0xa1, 0x71, + 0x8b, 0xd9, 0x6c, 0xb6, 0xdc, 0xc6, 0x4d, 0x3c, 0x5b, 0x1f, 0xfd, 0x53, 0xb8, 0xb3, 0x48, 0xdb, + 0x6b, 0x62, 0xe4, 0x57, 0xb0, 0xdf, 0x5c, 0xc6, 0x56, 0xf3, 0xde, 0x7f, 0x0b, 0x77, 0x9a, 0xd7, + 0x70, 0x5f, 0xa8, 0xb9, 0xf2, 0xe6, 0x9a, 0x3f, 0x78, 0x0e, 0x95, 0xc4, 0x6f, 0xa2, 0x48, 0x85, + 0xf2, 0xf3, 0xf6, 0x17, 0xed, 0xce, 0x8b, 0x76, 0xbf, 0xf7, 0xbb, 0xf3, 0x86, 0x7a, 0x03, 0x01, + 0xe4, 0x4e, 0x3a, 0xcf, 0x8f, 0x4e, 0x1b, 0xaa, 0x82, 0xf2, 0x90, 0x6d, 0xb5, 0x7b, 0x6a, 0x06, + 0x95, 0xa1, 0x70, 0xd2, 0xea, 0x1e, 0x1b, 0x8d, 0x5e, 0x43, 0xcd, 0xa2, 0x35, 0x28, 0x1d, 0x1f, + 0xf6, 0x1a, 0xcd, 0x8e, 0xd1, 0x3a, 0x3e, 0x3c, 0x55, 0x57, 0x1e, 0xfc, 0x06, 0xd4, 0xf4, 0x0f, + 0x07, 0x48, 0x83, 0xcd, 0x90, 0x72, 0xe7, 0xbc, 0xd7, 0x3a, 0x6b, 0xfd, 0xfe, 0xb0, 0xd7, 0xea, + 0xb4, 0xd5, 0x1b, 0x94, 0xd8, 0x59, 0xab, 0x4d, 0x21, 0x94, 0x07, 0x3d, 0x1d, 0x7e, 0xc9, 0x4f, + 0x99, 0x07, 0x4d, 0x58, 0x65, 0x3f, 0x9a, 0xa0, 0x12, 0xe4, 0xcf, 0x1b, 0xed, 0x93, 0x56, 0xbb, + 0xa9, 0xde, 0xa0, 0x07, 0xe3, 0x79, 0xbb, 0x4d, 0x0f, 0x0a, 0xaa, 0x40, 0xf1, 0xb8, 0x73, 0x76, + 0x7e, 0xda, 0xe8, 0x35, 0x4e, 0xd4, 0x0c, 0x95, 0xf7, 0x8b, 0xd6, 0xe9, 0x69, 0xe3, 0x44, 0xcd, + 0xa2, 0x22, 0xac, 0x36, 0x0c, 0xa3, 0x63, 0xa8, 0xdf, 0xd4, 0xff, 0x0b, 0x90, 0x3f, 0x33, 0xc7, + 0xe6, 0x10, 0xfb, 0xe8, 0x19, 0x94, 0xa4, 0x0d, 0x14, 0xdd, 0x64, 0xa6, 0x9b, 0x5e, 0x6f, 0x6b, + 0x5b, 0xd3, 0x17, 0xd4, 0x1b, 0xbf, 0x84, 0x62, 0xb4, 0x62, 0xa2, 0x2d, 0xd1, 0x5b, 0x92, 0x1b, + 0x6a, 0x6d, 0x23, 0x0d, 0xa6, 0x0f, 0x1f, 0x43, 0x21, 0x5c, 0xff, 0x10, 0xdf, 0xb7, 0x53, 0x8b, + 0x69, 0x0d, 0xa5, 0xa0, 0xf4, 0xd5, 0x67, 0x50, 0x96, 0x97, 0x46, 0xa4, 0x25, 0x70, 0xa4, 0xf5, + 0xb2, 0xb6, 0x3d, 0xe3, 0x46, 0x08, 0x1c, 0x6d, 0x7d, 0x42, 0xe0, 0xf4, 0xd2, 0x28, 0x04, 0x4e, + 0x2d, 0x87, 0x8f, 0xa1, 0x10, 0x2e, 0x57, 0x42, 0xe0, 0xd4, 0x1a, 0x28, 0x04, 0x4e, 0x6e, 0x60, + 0xcf, 0xa0, 0x24, 0x4d, 0xb4, 0xc2, 0xbc, 0xd3, 0x23, 0x77, 0x6d, 0x6b, 0xfa, 0x82, 0x3e, 0xff, + 0x18, 0x20, 0x5e, 0x77, 0x50, 0xa4, 0x53, 0xea, 0xf1, 0xe6, 0x14, 0x9c, 0xbe, 0xfd, 0x9c, 0xed, + 0xb7, 0xd2, 0x82, 0x80, 0x6a, 0x91, 0x4d, 0xa6, 0x96, 0xa0, 0x9a, 0x36, 0xf3, 0x8e, 0xd2, 0xf9, + 0x92, 0x77, 0xe7, 0xf4, 0x74, 0x8e, 0xf6, 0xa2, 0x17, 0x73, 0xf6, 0x88, 0xda, 0xed, 0x05, 0x18, + 0xb1, 0x76, 0xe1, 0x0f, 0xfe, 0x91, 0x76, 0xc9, 0xb1, 0x3d, 0xd6, 0x2e, 0x31, 0x5a, 0x9b, 0x70, + 0x73, 0x4e, 0x23, 0x43, 0xef, 0x72, 0x5b, 0x2e, 0xec, 0x55, 0xb5, 0xfd, 0xc5, 0x48, 0x82, 0x45, + 0x73, 0x21, 0x8b, 0xe6, 0x32, 0x2c, 0x16, 0xb6, 0xbd, 0xaf, 0xa0, 0x36, 0xbf, 0xda, 0xa2, 0x7b, + 0xa1, 0x8c, 0x8b, 0x0b, 0x6a, 0xed, 0xee, 0xb5, 0x78, 0x82, 0x57, 0xf3, 0x3a, 0x5e, 0xcd, 0x25, + 0x79, 0x5d, 0x57, 0xa4, 0x69, 0x59, 0x08, 0xe7, 0xea, 0xb0, 0x2c, 0xa4, 0x46, 0xfa, 0xb0, 0x2c, + 0x24, 0xc6, 0xef, 0xf0, 0x21, 0x1b, 0xc9, 0xa4, 0x87, 0xf2, 0x58, 0x28, 0x3d, 0x94, 0x26, 0xbb, + 0x16, 0xff, 0x65, 0x4b, 0x1a, 0x80, 0xd1, 0xad, 0xc8, 0xfe, 0xd3, 0x03, 0x73, 0x6d, 0x67, 0xf6, + 0xa5, 0x94, 0x38, 0xf1, 0x34, 0x2b, 0x25, 0xce, 0xd4, 0x68, 0x2c, 0x25, 0x4e, 0x6a, 0xfc, 0xad, + 0xf7, 0x00, 0x62, 0xcf, 0xff, 0x50, 0xe9, 0x58, 0xb7, 0xa1, 0x92, 0x30, 0xfd, 0xdb, 0xcb, 0xcf, + 0x8b, 0x1c, 0xfb, 0x27, 0xf5, 0xd1, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x5a, 0x15, 0x33, 0x11, + 0x56, 0x1d, 0x00, 0x00, } diff --git a/pkg/api/api.proto b/pkg/api/api.proto index a677f4e1117..a57c81d0892 100644 --- a/pkg/api/api.proto +++ b/pkg/api/api.proto @@ -5,29 +5,31 @@ package api; service Manager { rpc CreateStudy(CreateStudyRequest) returns (CreateStudyReply); rpc StopStudy(StopStudyRequest) returns (StopStudyReply); - rpc GetStudies(GetStudiesRequest) returns (GetStudiesReply); - rpc SuggestTrials(SuggestTrialsRequest) returns (SuggestTrialsReply); - rpc CompleteTrial(CompleteTrialRequest) returns (CompleteTrialReply); - rpc EarlyStopping(EarlyStoppingRequest) returns (EarlyStoppingReply); - rpc GetObjectValue(GetObjectValueRequest) returns (GetObjectValueReply); - rpc AddMeasurementToTrials(AddMeasurementToTrialsRequest) returns (AddMeasurementToTrialsReply); - rpc InitializeSuggestService(InitializeSuggestServiceRequest) returns(InitializeSuggestServiceReply); + rpc GetStudy(GetStudyRequest) returns (GetStudyReply); + rpc GetStudyList(GetStudyListRequest) returns (GetStudyListReply); + rpc GetTrials(GetTrialsRequest) returns (GetTrialsReply); + rpc RunTrial(RunTrialRequest) returns (RunTrialReply); + rpc StopWorkers(StopWorkersRequest) returns (StopWorkersReply); + rpc GetWorkers(GetWorkersRequest) returns (GetWorkersReply); + rpc GetSuggestions(GetSuggestionsRequest) returns (GetSuggestionsReply); + rpc GetShouldStopWorkers(GetShouldStopWorkersRequest) returns (GetShouldStopWorkersReply); + rpc GetMetrics(GetMetricsRequest) returns (GetMetricsReply); + rpc SetSuggestionParameters(SetSuggestionParametersRequest) returns (SetSuggestionParametersReply); + rpc GetSuggestionParameters(GetSuggestionParametersRequest) returns (GetSuggestionParametersReply); + rpc SetEarlyStoppingParameters(SetEarlyStoppingParametersRequest) returns (SetEarlyStoppingParametersReply); + rpc GetEarlyStoppingParameters(GetEarlyStoppingParametersRequest) returns (GetEarlyStoppingParametersReply); rpc SaveStudy(SaveStudyRequest) returns(SaveStudyReply); rpc SaveModel(SaveModelRequest) returns(SaveModelReply); rpc GetSavedStudies(GetSavedStudiesRequest) returns(GetSavedStudiesReply); rpc GetSavedModels(GetSavedModelsRequest) returns(GetSavedModelsReply); - rpc GetSavedModel(GetSavedModelRequest) returns(GetSavedModelReply); } service Suggestion { - rpc GenerateTrials(GenerateTrialsRequest) returns (GenerateTrialsReply); - rpc SetSuggestionParameters(SetSuggestionParametersRequest) returns (SetSuggestionParametersReply); - rpc StopSuggestion(StopSuggestionRequest) returns (StopSuggestionReply); + rpc GetSuggestions(GetSuggestionsRequest) returns (GetSuggestionsReply); } service EarlyStopping { - rpc ShouldTrialStop(ShouldTrialStopRequest) returns (ShouldTrialStopReply); - rpc SetEarlyStoppingParameter(SetEarlyStoppingParameterRequest) returns (SetEarlyStoppingParameterReply); + rpc GetShouldStopWorkers(GetShouldStopWorkersRequest) returns (GetShouldStopWorkersReply); } enum ParameterType { @@ -68,7 +70,7 @@ message Parameter { } // This value is stored as TINYINT in MySQL. -enum TrialState { +enum State { PENDING = 0; RUNNING = 1; COMPLETED = 2; @@ -76,14 +78,19 @@ enum TrialState { ERROR = 120; } +message MetricsLogSet { + string worker_id = 1; + repeated MetricsLog metrics_logs= 2; +} + message Metrics { string name = 1; string value = 2; } -message EvaluationLog { - string time = 1; - repeated Metrics metrics = 2; +message MetricsLog { + string name = 1; + repeated string values = 2; } message SuggestionParameter { @@ -106,13 +113,38 @@ message MountConf { string path = 2; } +message StudyOverview { + string name = 1; + string owner = 2; + string id = 3; + string description = 4; +} + message Trial { string trial_id = 1; string study_id = 2; repeated Parameter parameter_set = 3; - TrialState status = 4; - repeated EvaluationLog eval_logs = 5; - string objective_value = 6; + State status = 4; + string objective_value = 5; + repeated Tag tags = 8; +} + +message WorkerConfig { + string image = 1; + repeated string command = 2; + int32 gpu = 3; + string scheduler = 4; + MountConf mount = 5; + string pull_secret = 6; +} + +message Worker { + string worker_id = 1; + string study_id = 2; + string trial_id = 3; + string runtime = 4; + State status = 5; + WorkerConfig config = 6; repeated Tag tags = 7; } @@ -126,21 +158,11 @@ message StudyConfig { double optimization_goal = 4; ParameterConfigs parameter_configs = 5; repeated string access_permissions = 6; - string suggest_algorithm = 7; - string early_stopping_algorithm = 8; - string study_task_name = 9; - repeated SuggestionParameter suggestion_parameters = 10; - repeated EarlyStoppingParameter early_stopping_parameters= 11; - repeated Tag tags = 12; - string objective_value_name = 13; - repeated string metrics = 14; - string image = 15; - repeated string command = 16; - int32 gpu = 17; - string scheduler = 18; - MountConf mount = 19; - string pull_secret = 20; - //string log_collector = 10; // XXX + string default_suggestion_algorithm = 7; + string default_early_stopping_algorithm = 8; + repeated Tag tags = 9; + string objective_value_name = 10; + repeated string metrics = 11; } message CreateStudyRequest { @@ -158,76 +180,92 @@ message StopStudyRequest { message StopStudyReply { } -message GetStudiesRequest { +message GetStudyRequest { + string study_id = 1; } -message StudyInfo { - string study_id = 1; - string name = 2; - string owner = 3; - int32 running_trial_num = 4; - int32 completed_trial_num = 5; +message GetStudyReply { + StudyConfig study_config= 1; } -message GetStudiesReply { - repeated StudyInfo study_infos= 1; +message GetStudyListRequest { } -message SuggestTrialsRequest { - string study_id = 1; - string suggest_algorithm = 2; - StudyConfig configs = 3; +message GetStudyListReply { + repeated StudyOverview study_overviews = 1; } -message SuggestTrialsReply { - repeated Trial trials = 1; - bool completed = 2; +message GetTrialsRequest { + string study_id = 1; } -message CompleteTrialRequest { - string study_id = 1; - string trial_id = 2; - bool is_complete = 3; +message GetTrialsReply { + repeated Trial trials = 1; } -message CompleteTrialReply { +message RunTrialRequest { + string study_id = 1; + string trial_id = 2; + string runtime = 3; + WorkerConfig worker_config = 4; } -message EarlyStoppingRequest { - string study_id = 1; - string early_stopping_algorithm = 2; +message RunTrialReply { + string worker_id = 1; } -message EarlyStoppingReply { - repeated Trial trials = 1; +message StopWorkersRequest { + string study_id = 1; + repeated string worker_ids = 2; + bool is_complete = 3; } -message GetObjectValueRequest { - string worker_id = 1; +message StopWorkersReply { } -message GetObjectValueReply { - repeated Trial trials = 1; +message GetWorkersRequest { + string study_id = 1; } -message AddMeasurementToTrialsRequest { - string study_id = 1; - // metrics can be a json string - string metrics = 2; +message GetWorkersReply { + repeated Worker workers = 1; } -message AddMeasurementToTrialsReply { +message GetSuggestionsRequest { + string study_id = 1; + string suggestion_algorithm = 2; + int32 request_number = 3; + repeated string log_worker_ids = 4; + string param_id = 5; } -message StudyOverview { - string name = 1; - string owner = 2; - string description = 3; +message GetSuggestionsReply { + repeated Trial trials = 1; +} + +message GetShouldStopWorkersRequest { + string study_id = 1; + string early_stopping_algorithm = 2; + string param_id = 5; +} + +message GetShouldStopWorkersReply { + repeated string should_stop_worker_ids = 1; +} + +message GetMetricsRequest { + string study_id = 1; + repeated string worker_ids = 2; + repeated string metrics_names = 3; +} + +message GetMetricsReply { + repeated MetricsLogSet metrics_log_sets = 1; } message ModelInfo { string study_name = 1; - string trial_id = 2; + string worker_id = 2; repeated Parameter parameters = 3; repeated Metrics metrics = 4; string model_path = 5; @@ -273,42 +311,30 @@ message GetSavedModelsReply { message GetSavedModelRequest { string study_name = 1; - string trial_id = 2; + string worker_id = 2; } message GetSavedModelReply { ModelInfo model = 1; } -message InitializeSuggestServiceRequest { - string study_id = 1; - string suggest_algorithm = 2; - repeated SuggestionParameter suggestion_parameters = 3; - StudyConfig configs = 4; -} - -message InitializeSuggestServiceReply { -} - -message GenerateTrialsRequest { +message SetSuggestionParametersRequest { string study_id = 1; - StudyConfig configs = 2; - repeated Trial completed_trials = 3; - repeated Trial running_trials = 4; + string suggestion_algorithm = 2; + string param_id = 3; + repeated SuggestionParameter suggestion_parameters = 4; } -message GenerateTrialsReply { - repeated Trial trials = 1; - bool completed = 2; +message SetSuggestionParametersReply { + string param_id = 1; } -message SetSuggestionParametersRequest { - string study_id = 1; - repeated SuggestionParameter suggestion_parameters =2; - StudyConfig configs = 3; +message GetSuggestionParametersRequest { + string param_id = 1; } -message SetSuggestionParametersReply { +message GetSuggestionParametersReply { + repeated SuggestionParameter suggestion_parameters = 1; } message StopSuggestionRequest { @@ -318,18 +344,21 @@ message StopSuggestionRequest { message StopSuggestionReply { } -message ShouldTrialStopRequest { +message SetEarlyStoppingParametersRequest { string study_id = 1; + string early_stopping_algorithm = 2; + string param_id = 3; + repeated EarlyStoppingParameter early_stopping_parameters = 4; } -message ShouldTrialStopReply { - repeated Trial trials = 1; +message SetEarlyStoppingParametersReply { + string param_id = 1; } -message SetEarlyStoppingParameterRequest { - string study_id = 1; - repeated EarlyStoppingParameter early_stopping_parameters =2; +message GetEarlyStoppingParametersRequest { + string param_id = 1; } -message SetEarlyStoppingParameterReply { +message GetEarlyStoppingParametersReply { + repeated EarlyStoppingParameter early_stopping_parameters = 1; } diff --git a/pkg/db/db_init.go b/pkg/db/db_init.go index 47d6bb2c975..f92812f8286 100644 --- a/pkg/db/db_init.go +++ b/pkg/db/db_init.go @@ -15,18 +15,9 @@ func (d *db_conn) DB_Init() { "parameter_configs TEXT, " + "suggest_algo VARCHAR(255), " + "early_stop_algo VARCHAR(255), " + - "study_task_name VARCHAR(255), " + - "suggestion_parameters TEXT, " + - "early_stopping_parameters TEXT, " + "tags TEXT, " + "objective_value_name VARCHAR(255), " + - "metrics TEXT, " + - "image VARCHAR(255), " + - "command TEXT, " + - "gpu INT, " + - "scheduler VARCHAR(255), " + - "mount TEXT, " + - "pull_secret TEXT)") + "metrics TEXT)") if err != nil { log.Fatalf("Error creating studies table: %v", err) } @@ -51,31 +42,53 @@ func (d *db_conn) DB_Init() { log.Fatalf("Error creating trials table: %v", err) } - _, err = db.Exec("CREATE TABLE IF NOT EXISTS trial_metrics" + - "(trial_id CHAR(16) NOT NULL, " + + _, err = db.Exec("CREATE TABLE IF NOT EXISTS workers" + + "(id CHAR(16) PRIMARY KEY, " + + "study_id CHAR(16), " + + "trial_id CHAR(16), " + + "runtime VARCHAR(255), " + + "status TINYINT, " + + "config TEXT, " + + "tags TEXT, " + + "FOREIGN KEY(study_id) REFERENCES studies(id))") + if err != nil { + log.Fatalf("Error creating workers table: %v", err) + } + + _, err = db.Exec("CREATE TABLE IF NOT EXISTS worker_metrics" + + "(worker_id CHAR(16) NOT NULL, " + "id INT AUTO_INCREMENT PRIMARY KEY, " + "time DATETIME(6), " + "name VARCHAR(255), " + "value TEXT, " + "is_objective TINYINT)") if err != nil { - log.Fatalf("Error creating trial_metrics table: %v", err) + log.Fatalf("Error creating worker_metrics table: %v", err) } - _, err = db.Exec("CREATE TABLE IF NOT EXISTS trial_lastlogs" + - "(trial_id CHAR(16) PRIMARY KEY, " + + _, err = db.Exec("CREATE TABLE IF NOT EXISTS worker_lastlogs" + + "(worker_id CHAR(16) PRIMARY KEY, " + "time DATETIME(6), " + "value TEXT)") if err != nil { - log.Fatalf("Error creating trial_lastlogs table: %v", err) + log.Fatalf("Error creating worker_lastlogs table: %v", err) } - _, err = db.Exec("CREATE TABLE IF NOT EXISTS workers" + + _, err = db.Exec("CREATE TABLE IF NOT EXISTS suggestion_param" + + "(id CHAR(16) PRIMARY KEY," + + "suggestion_algo TEXT, " + + "study_id CHAR(16), " + + "parameters TEXT)") + if err != nil { + log.Fatalf("Error creating suggestion_param table: %v", err) + } + + _, err = db.Exec("CREATE TABLE IF NOT EXISTS earlystop_param" + "(id CHAR(16) PRIMARY KEY, " + - "trial_id CHAR(16), " + - "status TINYINT, " + - "FOREIGN KEY(trial_id) REFERENCES trials(id))") + "earlystop_argo TEXT, " + + "study_id CHAR(16), " + + "parameters TEXT)") if err != nil { - log.Fatalf("Error creating workers table: %v", err) + log.Fatalf("Error creating earlystop_param table: %v", err) } } diff --git a/pkg/db/interface.go b/pkg/db/interface.go index 346426cb452..89bb1fcf156 100644 --- a/pkg/db/interface.go +++ b/pkg/db/interface.go @@ -23,7 +23,7 @@ const ( mysql_time_fmt = "2006-01-02 15:04:05.999999" ) -type GetTrialLogOpts struct { +type GetWorkerLogOpts struct { Name string SinceTime *time.Time Descending bool @@ -31,7 +31,7 @@ type GetTrialLogOpts struct { Objective bool } -type TrialLog struct { +type WorkerLog struct { Time time.Time Name string Value string @@ -45,14 +45,28 @@ type VizierDBInterface interface { DeleteStudy(string) error GetTrial(string) (*api.Trial, error) - GetTrialStatus(string) (api.TrialState, error) + GetTrialStatus(string) (api.State, error) GetTrialList(string) ([]*api.Trial, error) CreateTrial(*api.Trial) error - UpdateTrial(string, api.TrialState) error - GetTrialLogs(string, *GetTrialLogOpts) ([]*TrialLog, error) - GetTrialTimestamp(string) (*time.Time, error) - StoreTrialLogs(string, []string) error + UpdateTrial(string, api.State) error DeleteTrial(string) error + + GetWorker(string) (*api.Worker, error) + GetWorkerStatus(string) (*api.State, error) + GetWorkerList(string) ([]*api.Worker, error) + GetWorkerLogs(string, *GetWorkerLogOpts) ([]*WorkerLog, error) + GetWorkerTimestamp(string) (*time.Time, error) + StoreWorkerLogs(string, []string) error + CreateWorker(*api.Worker) (string, error) + UpdateWorker(string, api.State) error + DeleteWorker(string) error + + SetSuggestionParam(string, string, []*api.SuggestionParameter) (string, error) + UpdateSuggestionParam(string, []*api.SuggestionParameter) error + GetSuggestionParam(string) ([]*api.SuggestionParameter, error) + SetEarlyStopParam(string, string, []*api.EarlyStoppingParameter) (string, error) + UpdateEarlyStopParam(string, []*api.EarlyStoppingParameter) error + GetEarlyStopParam(string) ([]*api.EarlyStoppingParameter, error) } type db_conn struct { @@ -98,27 +112,18 @@ func (d *db_conn) GetStudyConfig(id string) (*api.StudyConfig, error) { row := d.db.QueryRow("SELECT * FROM studies WHERE id = ?", id) study := new(api.StudyConfig) - var dummy_id, configs, suggestion_parameters, early_stopping_parameters, tags, metrics, command, mconf string + var dummy_id, configs, tags, metrics string err := row.Scan(&dummy_id, &study.Name, &study.Owner, &study.OptimizationType, &study.OptimizationGoal, &configs, - &study.SuggestAlgorithm, - &study.EarlyStoppingAlgorithm, - &study.StudyTaskName, - &suggestion_parameters, - &early_stopping_parameters, + &study.DefaultSuggestionAlgorithm, + &study.DefaultEarlyStoppingAlgorithm, &tags, &study.ObjectiveValueName, &metrics, - &study.Image, - &command, - &study.Gpu, - &study.Scheduler, - &mconf, - &study.PullSecret, ) if err != nil { return nil, err @@ -129,21 +134,6 @@ func (d *db_conn) GetStudyConfig(id string) (*api.StudyConfig, error) { return nil, err } - var sp_array []string - if len(suggestion_parameters) > 0 { - sp_array = strings.Split(suggestion_parameters, ",\n") - } - study.SuggestionParameters = make([]*api.SuggestionParameter, len(sp_array)) - for i, j := range sp_array { - sp := new(api.SuggestionParameter) - err = jsonpb.UnmarshalString(j, sp) - if err != nil { - log.Printf("err unmarshal %s", j) - return nil, err - } - study.SuggestionParameters[i] = sp - } - var tags_array []string if len(tags) > 0 { tags_array = strings.Split(tags, ",\n") @@ -158,17 +148,7 @@ func (d *db_conn) GetStudyConfig(id string) (*api.StudyConfig, error) { } study.Tags[i] = tag } - - study.Mount = new(api.MountConf) - if mconf != "" { - err = jsonpb.UnmarshalString(mconf, study.Mount) - if err != nil { - return nil, err - } - } - study.Metrics = strings.Split(metrics, ",\n") - study.Command = strings.Split(command, ",\n") return study, nil } @@ -193,33 +173,15 @@ func (d *db_conn) GetStudyList() ([]string, error) { } func (d *db_conn) CreateStudy(in *api.StudyConfig) (string, error) { + if in.ParameterConfigs == nil { + return "", errors.New("ParameterConfigs must be set") + + } configs, err := (&jsonpb.Marshaler{}).MarshalToString(in.ParameterConfigs) if err != nil { log.Fatalf("Error marshaling configs: %v", err) } - suggestion_parameters := make([]string, len(in.SuggestionParameters)) - for i, elem := range in.SuggestionParameters { - suggestion_parameters[i], err = (&jsonpb.Marshaler{}).MarshalToString(elem) - if err != nil { - log.Printf("Error marshalling %v: %v", elem, err) - } - } - earlystopping_parameters := make([]string, len(in.EarlyStoppingParameters)) - for i, elem := range in.EarlyStoppingParameters { - earlystopping_parameters[i], err = (&jsonpb.Marshaler{}).MarshalToString(elem) - if err != nil { - log.Printf("Error marshalling %v: %v", elem, err) - } - } - var mconf string = "" - if in.Mount != nil { - mconf, err = (&jsonpb.Marshaler{}).MarshalToString(in.Mount) - if err != nil { - log.Fatalf("Error marshaling mount configs: %v", err) - } - } - tags := make([]string, len(in.Tags)) for i, elem := range in.Tags { tags[i], err = (&jsonpb.Marshaler{}).MarshalToString(elem) @@ -244,27 +206,18 @@ func (d *db_conn) CreateStudy(in *api.StudyConfig) (string, error) { for true { study_id = generate_randid() _, err := d.db.Exec( - "INSERT INTO studies VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + "INSERT INTO studies VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", study_id, in.Name, in.Owner, in.OptimizationType, in.OptimizationGoal, configs, - in.SuggestAlgorithm, - in.EarlyStoppingAlgorithm, - in.StudyTaskName, - strings.Join(suggestion_parameters, ",\n"), - strings.Join(earlystopping_parameters, ",\n"), + in.DefaultSuggestionAlgorithm, + in.DefaultEarlyStoppingAlgorithm, strings.Join(tags, ",\n"), in.ObjectiveValueName, strings.Join(in.Metrics, ",\n"), - in.Image, - strings.Join(in.Command, ",\n"), - in.Gpu, - in.Scheduler, - mconf, - in.PullSecret, ) if err == nil { break @@ -345,10 +298,10 @@ func (d *db_conn) getTrials(trial_id string, study_id string) ([]*api.Trial, err taglist := strings.Split(tags, ",\n") t := make([]*api.Tag, len(taglist)) for i, tstr := range taglist { + t[i] = &api.Tag{} if tstr == "" { continue } - t[i] = &api.Tag{} err := jsonpb.UnmarshalString(tstr, t[i]) if err != nil { return nil, err @@ -376,8 +329,8 @@ func (d *db_conn) GetTrial(id string) (*api.Trial, error) { return trials[0], nil } -func (d *db_conn) GetTrialStatus(id string) (api.TrialState, error) { - status := api.TrialState_ERROR +func (d *db_conn) GetTrialStatus(id string) (api.State, error) { + status := api.State_ERROR row := d.db.QueryRow("SELECT status FROM trials WHERE id = ?", id) err := row.Scan(&status) @@ -441,12 +394,17 @@ func (d *db_conn) CreateTrial(trial *api.Trial) error { return lastErr } -func (d *db_conn) UpdateTrial(id string, newstatus api.TrialState) error { +func (d *db_conn) UpdateTrial(id string, newstatus api.State) error { _, err := d.db.Exec("UPDATE trials SET status = ? WHERE id = ?", newstatus, id) return err } -func (d *db_conn) GetTrialLogs(id string, opts *GetTrialLogOpts) ([]*TrialLog, error) { +func (d *db_conn) DeleteTrial(id string) error { + _, err := d.db.Exec("DELETE FROM trials WHERE id = ?", id) + return err +} + +func (d *db_conn) GetWorkerLogs(id string, opts *GetWorkerLogOpts) ([]*WorkerLog, error) { qstr := "" qfield := []interface{}{id} order := "" @@ -470,15 +428,15 @@ func (d *db_conn) GetTrialLogs(id string, opts *GetTrialLogOpts) ([]*TrialLog, e } } - rows, err := d.db.Query("SELECT time, name, value FROM trial_metrics WHERE trial_id = ?"+ + rows, err := d.db.Query("SELECT time, name, value FROM worker_metrics WHERE worker_id = ?"+ qstr+" ORDER BY time"+order, qfield...) if err != nil { return nil, err } - var result []*TrialLog + var result []*WorkerLog for rows.Next() { - log1 := new(TrialLog) + log1 := new(WorkerLog) var time_str string err := rows.Scan(&time_str, &((*log1).Name), &((*log1).Value)) @@ -496,15 +454,15 @@ func (d *db_conn) GetTrialLogs(id string, opts *GetTrialLogOpts) ([]*TrialLog, e return result, nil } -func (d *db_conn) getTrialLastlog(id string, value *string) (*time.Time, error) { +func (d *db_conn) getWorkerLastlog(id string, value *string) (*time.Time, error) { var last_timestamp string var err error if value != nil { - row := d.db.QueryRow("SELECT time, value FROM trial_lastlogs WHERE trial_id = ?", id) + row := d.db.QueryRow("SELECT time, value FROM worker_lastlogs WHERE worker_id = ?", id) err = row.Scan(&last_timestamp, value) } else { - row := d.db.QueryRow("SELECT time FROM trial_lastlogs WHERE trial_id = ?", id) + row := d.db.QueryRow("SELECT time FROM worker_lastlogs WHERE worker_id = ?", id) err = row.Scan(&last_timestamp) } @@ -524,11 +482,11 @@ func (d *db_conn) getTrialLastlog(id string, value *string) (*time.Time, error) } } -func (d *db_conn) GetTrialTimestamp(id string) (*time.Time, error) { - return d.getTrialLastlog(id, nil) +func (d *db_conn) GetWorkerTimestamp(id string) (*time.Time, error) { + return d.getWorkerLastlog(id, nil) } -func (d *db_conn) storeTrialLog(trial_id string, time string, line string, +func (d *db_conn) storeWorkerLog(worker_id string, time string, line string, objective_value_name string, metrics []string) error { kvpairs := strings.Fields(line) for _, kv := range kvpairs { @@ -552,8 +510,8 @@ func (d *db_conn) storeTrialLog(trial_id string, time string, line string, } continue } - _, err := d.db.Exec("INSERT INTO trial_metrics (trial_id, time, name, value, is_objective) VALUES (?, ?, ?, ?, ?)", - trial_id, time, v[0], v[1], is_objective) + _, err := d.db.Exec("INSERT INTO worker_metrics (worker_id, time, name, value, is_objective) VALUES (?, ?, ?, ?, ?)", + worker_id, time, v[0], v[1], is_objective) if err != nil { return err } @@ -561,19 +519,19 @@ func (d *db_conn) storeTrialLog(trial_id string, time string, line string, return nil } -func (d *db_conn) StoreTrialLogs(trial_id string, logs []string) error { +func (d *db_conn) StoreWorkerLogs(worker_id string, logs []string) error { var lasterr error var last_value string var stored_logs []*string - db_t, err := d.getTrialLastlog(trial_id, &last_value) + db_t, err := d.getWorkerLastlog(worker_id, &last_value) if err != nil { log.Printf("Error getting last log timestamp: %v", err) } - row := d.db.QueryRow("SELECT objective_value_name, metrics FROM trials "+ - "JOIN (studies) ON (trials.study_id = studies.id) WHERE "+ - "trials.id = ?", trial_id) + row := d.db.QueryRow("SELECT objective_value_name, metrics FROM workers "+ + "JOIN (studies) ON (workers.study_id = studies.id) WHERE "+ + "workers.id = ?", worker_id) var objective_value_name, metrics_str string err = row.Scan(&objective_value_name, &metrics_str) if err != nil { @@ -600,7 +558,7 @@ func (d *db_conn) StoreTrialLogs(trial_id string, logs []string) error { lasterr = err continue } - if db_t != nil && t.Before(*db_t) { + if db_t != nil && !t.After(*db_t) { // db_t is from mysql and has microsec precision. // This code assumes nanosec fractions are rounded down. continue @@ -624,7 +582,7 @@ func (d *db_conn) StoreTrialLogs(trial_id string, logs []string) error { } // (reparsed_time > *db_t) can be assumed for _, value := range stored_logs { - err = d.storeTrialLog(trial_id, + err = d.storeWorkerLog(worker_id, db_t.UTC().Format(mysql_time_fmt), *value, objective_value_name, metrics) if err != nil { @@ -635,7 +593,7 @@ func (d *db_conn) StoreTrialLogs(trial_id string, logs []string) error { db_t = nil } - err = d.storeTrialLog(trial_id, + err = d.storeWorkerLog(worker_id, formatted_time, ls[1], objective_value_name, metrics) if err != nil { @@ -646,7 +604,7 @@ func (d *db_conn) StoreTrialLogs(trial_id string, logs []string) error { if db_t != nil && len(stored_logs) > 0 { // No duplicate log found. So they are valid. for _, value := range stored_logs { - err = d.storeTrialLog(trial_id, + err = d.storeWorkerLog(worker_id, db_t.UTC().Format(mysql_time_fmt), *value, objective_value_name, metrics) if err != nil { @@ -662,12 +620,278 @@ func (d *db_conn) StoreTrialLogs(trial_id string, logs []string) error { } if len(ls) == 2 { _, err = d.db.Exec("REPLACE INTO trial_lastlogs VALUES (?, ?, ?)", - trial_id, formatted_time, ls[1]) + worker_id, formatted_time, ls[1]) } return err } -func (d *db_conn) DeleteTrial(id string) error { - _, err := d.db.Exec("DELETE FROM trials WHERE id = ?", id) +func (d *db_conn) getWorkers(worker_id string, trial_id string, study_id string) ([]*api.Worker, error) { + var rows *sql.Rows + var err error + + if worker_id != "" { + rows, err = d.db.Query("SELECT * FROM workers WHERE id = ?", worker_id) + } else if trial_id != "" { + rows, err = d.db.Query("SELECT * FROM workers WHERE trial_id = ?", trial_id) + } else if study_id != "" { + rows, err = d.db.Query("SELECT * FROM workers WHERE study_id = ?", study_id) + } else { + return nil, errors.New("worker_id, trial_id or study_id must be set") + } + + if err != nil { + return nil, err + } + + var result []*api.Worker + for rows.Next() { + worker := new(api.Worker) + + var config, tags string + err := rows.Scan( + &worker.WorkerId, + &worker.StudyId, + &worker.TrialId, + &worker.Runtime, + &worker.Status, + &config, + &tags, + ) + if err != nil { + return nil, err + } + worker.Config = new(api.WorkerConfig) + err = jsonpb.UnmarshalString(config, worker.Config) + if err != nil { + return nil, err + } + + taglist := strings.Split(tags, ",\n") + t := make([]*api.Tag, len(taglist)) + for i, tstr := range taglist { + t[i] = &api.Tag{} + if tstr == "" { + continue + } + err := jsonpb.UnmarshalString(tstr, t[i]) + if err != nil { + return nil, err + } + } + worker.Tags = t + result = append(result, worker) + } + return result, nil +} + +func (d *db_conn) GetWorker(id string) (*api.Worker, error) { + workers, err := d.getWorkers(id, "", "") + if err != nil { + return nil, err + } + if len(workers) > 1 { + return nil, errors.New("multiple workers found") + } else if len(workers) == 0 { + return nil, errors.New("worker not found") + } + + return workers[0], nil + +} + +func (d *db_conn) GetWorkerStatus(id string) (*api.State, error) { + status := api.State_ERROR + row := d.db.QueryRow("SELECT status FROM workers WHERE id = ?", id) + err := row.Scan(&status) + if err != nil { + return &status, err + } + return &status, nil +} + +func (d *db_conn) GetWorkerList(id string) ([]*api.Worker, error) { + workers, err := d.getWorkers("", "", id) + return workers, err +} + +func (d *db_conn) CreateWorker(worker *api.Worker) (string, error) { + // Users should not overwrite worker.id + var err, lastErr error + config, err := (&jsonpb.Marshaler{}).MarshalToString(worker.Config) + if err != nil { + log.Fatalf("Error marshaling configs: %v", err) + lastErr = err + } + + tags := make([]string, len(worker.Tags)) + for i := range tags { + tags[i], err = (&jsonpb.Marshaler{}).MarshalToString(worker.Tags[i]) + if err != nil { + log.Printf("Error marshalling worker.Tags %v: %v", + worker.Tags[i], err) + lastErr = err + } + } + + var worker_id string + i := 3 + for true { + worker_id = generate_randid() + _, err = d.db.Exec("INSERT INTO workers VALUES (?, ?, ?, ?, ?, ?, ?)", + worker_id, worker.StudyId, worker.TrialId, worker.Runtime, + api.State_PENDING, config, strings.Join(tags, ",\n")) + if err == nil { + worker.WorkerId = worker_id + break + } else { + errmsg := strings.ToLower(err.Error()) + if strings.Contains(errmsg, "unique") || strings.Contains(errmsg, "duplicate") { + i-- + if i > 0 { + continue + } + } + } + return "", err + } + return worker.WorkerId, lastErr + +} + +func (d *db_conn) UpdateWorker(id string, newstatus api.State) error { + _, err := d.db.Exec("UPDATE workers SET status = ? WHERE id = ?", newstatus, id) + return err +} + +func (d *db_conn) DeleteWorker(id string) error { + _, err := d.db.Exec("DELETE FROM workers WHERE id = ?", id) + return err +} + +func (d *db_conn) SetSuggestionParam(algorithm string, studyId string, params []*api.SuggestionParameter) (string, error) { + var err error + ps := make([]string, len(params)) + for i, elem := range params { + ps[i], err = (&jsonpb.Marshaler{}).MarshalToString(elem) + if err != nil { + log.Printf("Error marshalling %v: %v", elem, err) + return "", err + } + } + var paramId string + for true { + paramId := generate_randid() + _, err = d.db.Exec("INSERT INTO suggestion_param VALUES (?, ?, ?, ?)", + paramId, algorithm, studyId, strings.Join(ps, ",\n")) + if err == nil { + break + } + } + return paramId, err +} + +func (d *db_conn) UpdateSuggestionParam(paramId string, params []*api.SuggestionParameter) error { + var err error + ps := make([]string, len(params)) + for i, elem := range params { + ps[i], err = (&jsonpb.Marshaler{}).MarshalToString(elem) + if err != nil { + log.Printf("Error marshalling %v: %v", elem, err) + return err + } + } + _, err = d.db.Exec("UPDATE suggestion_param SET parameters = ? WHERE id = ?", + strings.Join(ps, ",\n"), paramId) return err } + +func (d *db_conn) GetSuggestionParam(paramId string) ([]*api.SuggestionParameter, error) { + var params string + row := d.db.QueryRow("SELECT parameters FROM suggestion_param WHERE id = ?", paramId) + err := row.Scan(¶ms) + if err != nil { + return nil, err + } + var p_array []string + if len(params) > 0 { + p_array = strings.Split(params, ",\n") + } else { + return nil, nil + } + ret := make([]*api.SuggestionParameter, len(p_array)) + for i, j := range p_array { + p := new(api.SuggestionParameter) + err = jsonpb.UnmarshalString(j, p) + if err != nil { + log.Printf("err unmarshal %s", j) + return nil, err + } + ret[i] = p + } + return ret, nil +} + +func (d *db_conn) SetEarlyStopParam(algorithm string, studyId string, params []*api.EarlyStoppingParameter) (string, error) { + ps := make([]string, len(params)) + var err error + for i, elem := range params { + ps[i], err = (&jsonpb.Marshaler{}).MarshalToString(elem) + if err != nil { + log.Printf("Error marshalling %v: %v", elem, err) + return "", err + } + } + var paramId string + for true { + paramId := generate_randid() + _, err = d.db.Exec("INSERT INTO earlystopping_param VALUES (?,?, ?, ?)", + paramId, algorithm, studyId, strings.Join(ps, ",\n")) + if err == nil { + break + } + } + return paramId, nil +} + +func (d *db_conn) UpdateEarlyStopParam(paramId string, params []*api.EarlyStoppingParameter) error { + ps := make([]string, len(params)) + var err error + for i, elem := range params { + ps[i], err = (&jsonpb.Marshaler{}).MarshalToString(elem) + if err != nil { + log.Printf("Error marshalling %v: %v", elem, err) + return err + } + } + _, err = d.db.Exec("UPDATE earlystopping_param SET parameters = ? WHERE id = ?", + strings.Join(ps, ",\n"), paramId) + return err +} + +func (d *db_conn) GetEarlyStopParam(paramId string) ([]*api.EarlyStoppingParameter, error) { + var params string + row := d.db.QueryRow("SELECT parameters FROM earlystopping_param WHERE id = ?", paramId) + err := row.Scan(¶ms) + if err != nil { + return nil, err + } + var p_array []string + if len(params) > 0 { + p_array = strings.Split(params, ",\n") + } else { + return nil, nil + } + ret := make([]*api.EarlyStoppingParameter, len(p_array)) + for i, j := range p_array { + p := new(api.EarlyStoppingParameter) + err = jsonpb.UnmarshalString(j, p) + if err != nil { + log.Printf("err unmarshal %s", j) + return nil, err + } + ret[i] = p + } + + return ret, nil + +} diff --git a/pkg/db/interface_test.go b/pkg/db/interface_test.go index 93ccf6b5091..5aa0617f69f 100644 --- a/pkg/db/interface_test.go +++ b/pkg/db/interface_test.go @@ -33,8 +33,8 @@ func TestMain(m *testing.M) { mock.ExpectExec("CREATE TABLE IF NOT EXISTS studies").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec("CREATE TABLE IF NOT EXISTS study_permissions").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 trial_metrics").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec("CREATE TABLE IF NOT EXISTS trial_lastlogs").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectExec("CREATE TABLE IF NOT EXISTS worker_metrics").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectExec("CREATE TABLE IF NOT EXISTS worker_lastlogs").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec("CREATE TABLE IF NOT EXISTS workers").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) db_interface.DB_Init() @@ -57,7 +57,8 @@ func TestGetStudyConfig(t *testing.T) { } // mock.ExpectExec("SELECT * FROM studies WHERE id").WithArgs(id).WillReturnRows(sqlmock.NewRows()) mock.ExpectQuery("SELECT").WillReturnRows( - sqlmock.NewRows([]string{"id", + sqlmock.NewRows([]string{ + "id", "name", "owner", "optimization_type", @@ -65,20 +66,11 @@ func TestGetStudyConfig(t *testing.T) { "parameter_configs", "suggest_algo", "early_stop_algo", - "study_task_name", - "suggestion_parameters", - "early_stopping_parameters", "tags", "objective_value_name", "metrics", - "image", - "command", - "gpu", - "scheduler", - "mount", - "pull_secret", }). - AddRow("abc", "test", "admin", 1, 0.99, "{}", "random", "test", "", "", "", "", "", "", "", "", 1, "", "", "")) + AddRow("abc", "test", "admin", 1, 0.99, "{}", "random", "test", "", "", "", "")) study, err := db_interface.GetStudyConfig(id) if err != nil { t.Errorf("GetStudyConfig failed: %v", err) diff --git a/pkg/earlystopping/medianstopping.go b/pkg/earlystopping/medianstopping.go index 41d116c94be..c119fb1aecd 100644 --- a/pkg/earlystopping/medianstopping.go +++ b/pkg/earlystopping/medianstopping.go @@ -24,24 +24,18 @@ type MedianStoppingParam struct { } type MedianStoppingRule struct { - confList map[string]*MedianStoppingParam - dbIf vdb.VizierDBInterface + dbIf vdb.VizierDBInterface } func NewMedianStoppingRule() *MedianStoppingRule { m := &MedianStoppingRule{} - m.confList = make(map[string]*MedianStoppingParam) m.dbIf = vdb.New() return m } -func (m *MedianStoppingRule) SetEarlyStoppingParameter(ctx context.Context, in *api.SetEarlyStoppingParameterRequest) (*api.SetEarlyStoppingParameterReply, error) { - sc, err := m.dbIf.GetStudyConfig(in.StudyId) - if err != nil { - return &api.SetEarlyStoppingParameterReply{}, err - } +func (m *MedianStoppingRule) purseEarlyStoppingParameters(sc *api.StudyConfig, eps []*api.EarlyStoppingParameter) (*MedianStoppingParam, error) { p := &MedianStoppingParam{LeastStep: defaultLeastStep, Margin: defaultMargin, EvalMetric: sc.ObjectiveValueName, BurnIn: defaultBurnIn} - for _, ep := range in.EarlyStoppingParameters { + for _, ep := range eps { switch ep.Name { case "LeastStep": l, err := strconv.Atoi(ep.Value) @@ -70,27 +64,26 @@ func (m *MedianStoppingRule) SetEarlyStoppingParameter(ctx context.Context, in * log.Printf("Unknown EarlyStopping Parameter %v", ep.Name) } } - m.confList[in.StudyId] = p - log.Printf("Parameter for Study %s : LeastStep %d, Margin %v, EvalMetric %s, BurnInPeriod %d", in.StudyId, p.LeastStep, p.Margin, p.EvalMetric, p.BurnIn) - return &api.SetEarlyStoppingParameterReply{}, nil + log.Printf("Parameter: LeastStep %d, Margin %v, EvalMetric %s, BurnInPeriod %d", p.LeastStep, p.Margin, p.EvalMetric, p.BurnIn) + return p, nil } -func (m *MedianStoppingRule) getMedianRunningAverage(completedTrialslogs [][]*vdb.TrialLog, step int, burnin int) float64 { +func (m *MedianStoppingRule) getMedianRunningAverage(completedWorkerslogs [][]*vdb.WorkerLog, step int, burnin int) float64 { r := []float64{} var ra float64 - for _, ctl := range completedTrialslogs { + for _, cwl := range completedWorkerslogs { ra = 0 var st int var errParce bool = false - if step > len(ctl) { - st = len(ctl) + if step > len(cwl) { + st = len(cwl) } else { st = step } for s := burnin; s < st; s++ { - v, err := strconv.ParseFloat(ctl[s].Value, 64) + v, err := strconv.ParseFloat(cwl[s].Value, 64) if err != nil { - log.Printf("Fail to Parse %s : %s", ctl[s].Name, ctl[s].Value) + log.Printf("Fail to Parse %s : %s", cwl[s].Name, cwl[s].Value) errParce = true break } @@ -110,7 +103,7 @@ func (m *MedianStoppingRule) getMedianRunningAverage(completedTrialslogs [][]*vd } } -func (m *MedianStoppingRule) getBestValue(sid string, sc *api.StudyConfig, logs []*vdb.TrialLog) (float64, error) { +func (m *MedianStoppingRule) getBestValue(sid string, sc *api.StudyConfig, logs []*vdb.WorkerLog) (float64, error) { if len(logs) == 0 { return 0, errors.New("Evaluation Log is missing") } @@ -139,60 +132,66 @@ func (m *MedianStoppingRule) getBestValue(sid string, sc *api.StudyConfig, logs } return ret, nil } -func (m *MedianStoppingRule) ShouldTrialStop(ctx context.Context, in *api.ShouldTrialStopRequest) (*api.ShouldTrialStopReply, error) { - if _, ok := m.confList[in.StudyId]; !ok { - return &api.ShouldTrialStopReply{}, errors.New("EarlyStopping config is not set.") - } - tl, err := m.dbIf.GetTrialList(in.StudyId) +func (m *MedianStoppingRule) GetShouldStopWorkers(ctx context.Context, in *api.GetShouldStopWorkersRequest) (*api.GetShouldStopWorkersReply, error) { + wl, err := m.dbIf.GetWorkerList(in.StudyId) if err != nil { - return &api.ShouldTrialStopReply{}, err + return &api.GetShouldStopWorkersReply{}, err } sc, err := m.dbIf.GetStudyConfig(in.StudyId) if err != nil { - return &api.ShouldTrialStopReply{}, err + return &api.GetShouldStopWorkersReply{}, err } - rtl := []*api.Trial{} - ctl := make([][]*vdb.TrialLog, 0, len(tl)) - s_t := []*api.Trial{} - for _, t := range tl { - switch t.Status { - case api.TrialState_RUNNING: - rtl = append(rtl, t) - case api.TrialState_COMPLETED: - tl, err := m.dbIf.GetTrialLogs(t.TrialId, &vdb.GetTrialLogOpts{Name: m.confList[in.StudyId].EvalMetric}) + eparam, err := m.dbIf.GetEarlyStopParam(in.ParamId) + if err != nil { + return &api.GetShouldStopWorkersReply{}, err + } + p, err := m.purseEarlyStoppingParameters(sc, eparam) + if err != nil { + return &api.GetShouldStopWorkersReply{}, err + } + + rwids := []string{} + cwl := make([][]*vdb.WorkerLog, 0, len(wl)) + s_w := []string{} + for _, w := range wl { + switch w.Status { + case api.State_RUNNING: + rwids = append(rwids, w.WorkerId) + case api.State_COMPLETED: + wl, err := m.dbIf.GetWorkerLogs(w.WorkerId, &vdb.GetWorkerLogOpts{Name: p.EvalMetric}) if err != nil { - log.Printf("Fail to get trial %v logs", t.TrialId) + log.Printf("Fail to get worker %v logs", w.WorkerId) continue } - if len(tl) > m.confList[in.StudyId].BurnIn { - ctl = append(ctl, tl) + if len(wl) > p.BurnIn { + cwl = append(cwl, wl) } default: } } - if len(ctl) == 0 { - return &api.ShouldTrialStopReply{}, nil + if len(cwl) == 0 { + return &api.GetShouldStopWorkersReply{}, err } - for _, t := range rtl { - tl, err := m.dbIf.GetTrialLogs(t.TrialId, &vdb.GetTrialLogOpts{Name: m.confList[in.StudyId].EvalMetric}) + for _, w := range rwids { + wl, err := m.dbIf.GetWorkerLogs(w, &vdb.GetWorkerLogOpts{Name: p.EvalMetric}) if err != nil { - log.Printf("Fail to get trial %v logs", t.TrialId) + log.Printf("Fail to get worker %v logs", w) continue } - if len(tl) < m.confList[in.StudyId].LeastStep || len(tl) <= m.confList[in.StudyId].BurnIn { + if len(wl) < p.LeastStep || len(wl) <= p.BurnIn { continue } - v, err := m.getBestValue(in.StudyId, sc, tl) + v, err := m.getBestValue(in.StudyId, sc, wl) if err != nil { - log.Printf("Fail to Get Best Value at %s: %v Log:%v", t.TrialId, err, tl) + log.Printf("Fail to Get Best Value at %s: %v Log:%v", w, err, wl) continue } - om := m.getMedianRunningAverage(ctl, len(tl), m.confList[in.StudyId].BurnIn) - log.Printf("Trial %s, In step %d Current value: %v Median value: %v\n", t.TrialId, len(tl), v, om) - if (v < (om-m.confList[in.StudyId].Margin) && sc.OptimizationType == api.OptimizationType_MAXIMIZE) || v > (om+m.confList[in.StudyId].Margin) && sc.OptimizationType == api.OptimizationType_MINIMIZE { - log.Printf("Trial %s shuold be stopped", t.TrialId) - s_t = append(s_t, t) + om := m.getMedianRunningAverage(cwl, len(wl), p.BurnIn) + log.Printf("Worker %s, In step %d Current value: %v Median value: %v\n", w, len(wl), v, om) + if (v < (om-p.Margin) && sc.OptimizationType == api.OptimizationType_MAXIMIZE) || v > (om+p.Margin) && sc.OptimizationType == api.OptimizationType_MINIMIZE { + log.Printf("Worker %s shuold be stopped", w) + s_w = append(s_w, w) } } - return &api.ShouldTrialStopReply{Trials: s_t}, nil + return &api.GetShouldStopWorkersReply{ShouldStopWorkerIds: s_w}, nil } diff --git a/pkg/earlystopping/types.go b/pkg/earlystopping/types.go index d48d8225240..0e8d4e1fdad 100644 --- a/pkg/earlystopping/types.go +++ b/pkg/earlystopping/types.go @@ -13,6 +13,5 @@ const ( // EarlyStoppingService is the interface for earlystopping service. type EarlyStoppingService interface { - ShouldTrialStop(ctx context.Context, in *api.ShouldTrialStopRequest) (*api.ShouldTrialStopReply, error) - SetEarlyStoppingParameter(ctx context.Context, in *api.SetEarlyStoppingParameterRequest) (*api.SetEarlyStoppingParameterReply, error) + GetEarlyStoppingParameters(ctx context.Context, in *api.GetEarlyStoppingParametersRequest) (api.GetEarlyStoppingParametersReply, error) } diff --git a/pkg/manager/modelstore/modeldb.go b/pkg/manager/modelstore/modeldb.go index 9240ce090fb..fabc1f4f968 100644 --- a/pkg/manager/modelstore/modeldb.go +++ b/pkg/manager/modelstore/modeldb.go @@ -66,8 +66,8 @@ func (m *ModelDB) SaveModel(in *api.SaveModelRequest) error { var mid int32 = -1 var msid int32 = -1 for _, md := range pml { - if md.Specification.Tag == in.Model.StudyName+":"+in.Model.TrialId { - log.Printf("Study %s: Trial %s is already exist. Metrics will be updated.\n", in.Model.StudyName, in.Model.TrialId) + if md.Specification.Tag == in.Model.StudyName+":"+in.Model.WorkerId { + log.Printf("Study %s: Trial %s is already exist. Metrics will be updated.\n", in.Model.StudyName, in.Model.WorkerId) did = md.TrainingDataFrame.ID mid = md.ID msid = md.Specification.ID @@ -117,7 +117,7 @@ func (m *ModelDB) SaveModel(in *api.SaveModelRequest) error { ID: msid, TransformerType: "NN", Hyperparameters: hs, - Tag: in.Model.StudyName + ":" + in.Model.TrialId, + Tag: in.Model.StudyName + ":" + in.Model.WorkerId, }, ExperimentRunId: exrId, FeatureColumns: []string{}, @@ -207,7 +207,7 @@ func (m *ModelDB) convertmdModelToModelInfo(mdm *modeldb.ModelResponse) *api.Mod } return &api.ModelInfo{ StudyName: sn, - TrialId: mn, + WorkerId: mn, Parameters: param, Metrics: met, ModelPath: *mdm.Metadata, @@ -277,7 +277,7 @@ func (m *ModelDB) GetSavedModel(in *api.GetSavedModelRequest) (*api.ModelInfo, e return nil, err } for _, md := range pml { - if md.Specification.Tag == in.StudyName+":"+in.TrialId { + if md.Specification.Tag == in.StudyName+":"+in.WorkerId { return m.convertmdModelToModelInfo(md), nil } } diff --git a/pkg/manager/worker/dlk/dlk.go b/pkg/manager/worker/dlk/dlk.go deleted file mode 100644 index 04639e17462..00000000000 --- a/pkg/manager/worker/dlk/dlk.go +++ /dev/null @@ -1,301 +0,0 @@ -package dlk - -import ( - "bytes" - "encoding/json" - "fmt" - "github.com/kubeflow/katib/pkg/api" - "github.com/kubeflow/katib/pkg/db" - dlkapi "github.com/kubeflow/katib/dlk/dlkmanager/api" - "github.com/kubeflow/katib/dlk/dlkmanager/datastore" - wIF "github.com/kubeflow/katib/pkg/manager/worker" - "io/ioutil" - "log" - "net/http" - "net/url" - "strings" - "sync" -) - -type DlkWorkerInterface struct { - RunningTrialList map[string][]*api.Trial - CompletedTrialList map[string][]*api.Trial - dlkmanager string - namespace string - mux *sync.Mutex - dbIf db.VizierDBInterface -} - -func NewDlkWorkerInterface(s string, n string) *DlkWorkerInterface { - return &DlkWorkerInterface{ - RunningTrialList: make(map[string][]*api.Trial), - CompletedTrialList: make(map[string][]*api.Trial), - dlkmanager: s, - namespace: n, - mux: new(sync.Mutex), - dbIf: db.New(), - } -} - -func (d *DlkWorkerInterface) getLt(tID string) (*datastore.LearningTaskInfo, error) { - url := d.dlkmanager + "/learningTask/" + d.namespace + "/" + tID - resp, err := http.Get(url) - if err != nil { - return nil, err - } - defer resp.Body.Close() - rs := &datastore.LearningTaskInfo{} - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - err = json.Unmarshal(body, rs) - if err != nil { - return nil, err - } - return rs, nil -} -func (d *DlkWorkerInterface) getLtLogs(tID string, stime string) (*datastore.LtLogInfo, error) { - str := d.dlkmanager + "/learningTasks/logs/" + d.namespace + "/" + tID + "/worker" - reqURL, err := url.Parse(str) - if stime != "" { - parameters := url.Values{} - parameters.Add("sinceTime", stime) - reqURL.RawQuery = parameters.Encode() - - } - resp, err := http.Get(reqURL.String()) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - // get and decode response(json) - rs := &datastore.LtLogInfo{} - body, err := ioutil.ReadAll(resp.Body) - err = json.Unmarshal(body, rs) - if err != nil { - return nil, err - } - return rs, nil -} - -func (d *DlkWorkerInterface) IsTrialComplete(studyId string, tID string) (bool, error) { - lt, err := d.getLt(tID) - if err != nil { - return false, err - } else if lt == nil { - return false, nil - } else if lt.State == "completed" { - return true, nil - } - return false, nil -} - -func (d *DlkWorkerInterface) storeTrialLog(tID string) error { - var unformatted_logs []string - ltlogs, _ := d.getLtLogs(tID, "") - for _, pl := range ltlogs.PodLogs { - for _, l := range pl.Logs { - unformatted_logs = append(unformatted_logs, - l.Time+" "+l.Value) - } - } - err := d.dbIf.StoreTrialLogs(tID, unformatted_logs) - return err -} - -func (d *DlkWorkerInterface) GetTrialObjValue(studyId string, tID string, objname string) (string, error) { - return wIF.GetTrialObjValue(d.dbIf, studyId, tID, objname) -} - -func (d *DlkWorkerInterface) GetTrialEvLogs(studyId string, tID string, metrics []string, sinceTime string) ([]*api.EvaluationLog, error) { - return wIF.GetTrialEvLogs(d.dbIf, studyId, tID, metrics, sinceTime) -} - -func (d *DlkWorkerInterface) CheckRunningTrials(studyId string, objname string) error { - d.mux.Lock() - defer d.mux.Unlock() - if len(d.RunningTrialList[studyId]) == 0 { - return nil - } - sc, _ := d.dbIf.GetStudyConfig(studyId) - metrics := sc.Metrics - for _, t := range d.RunningTrialList[studyId] { - status, err := d.dbIf.GetTrialStatus(t.TrialId) - if err != nil { - log.Printf("Error getting status of %s: %v", t.TrialId, err) - continue - } - if status == api.TrialState_RUNNING { - c, _ := d.IsTrialComplete(studyId, t.TrialId) - err = d.storeTrialLog(t.TrialId) - if err != nil { - log.Printf("Error storing trial log of %s: %v", t.TrialId, err) - } - var es []*api.EvaluationLog - if len(t.EvalLogs) == 0 { - es, err = d.GetTrialEvLogs(studyId, t.TrialId, metrics, "") - } else { - es, err = d.GetTrialEvLogs(studyId, t.TrialId, metrics, t.EvalLogs[len(t.EvalLogs)-1].Time) - } - if err != nil { - log.Printf("GetTrialEvLogs Err %v", err) - return err - } - if len(es) > 0 { - t.EvalLogs = append(t.EvalLogs, es...) - } - if c { - o, _ := d.GetTrialObjValue(studyId, t.TrialId, objname) - t.ObjectiveValue = o - t.Status = api.TrialState_COMPLETED - d.dbIf.UpdateTrial(t.TrialId, api.TrialState_COMPLETED) - log.Printf("Trial %v is completed.", t.TrialId) - log.Printf("Objective Value: %v", t.ObjectiveValue) - d.CompletedTrialList[studyId] = append(d.CompletedTrialList[studyId], t) - if len(d.RunningTrialList[studyId]) <= 1 { - d.RunningTrialList[studyId] = []*api.Trial{} - } else { - tn := t.TrialId - for j, tt := range d.RunningTrialList[studyId] { - if tt.TrialId == tn { - d.RunningTrialList[studyId] = append(d.RunningTrialList[studyId][:j], d.RunningTrialList[studyId][j+1:]...) - break - } - } - } - } - } - } - return nil -} -func (d *DlkWorkerInterface) convertTrialToManifest(trials []*api.Trial, studyId string) []*dlkapi.LTConfig { - sc, _ := d.dbIf.GetStudyConfig(studyId) - ret := make([]*dlkapi.LTConfig, len(trials)) - command := strings.Join(sc.Command, " ") - d.mux.Lock() - defer d.mux.Unlock() - for i, t := range trials { - d.RunningTrialList[studyId] = append(d.RunningTrialList[studyId], t) - var param string - for _, v := range t.ParameterSet { - param += " " + v.Name + "=" + v.Value - } - e := []dlkapi.EnvConf{ - dlkapi.EnvConf{Name: "STUDY_ID", Value: studyId}, - dlkapi.EnvConf{Name: "TRIAL_ID", Value: t.TrialId}, - } - c := strings.Replace(strings.Replace(command, "{{STUDY_ID}}", studyId, -1), "{{TRIAL_ID}}", t.TrialId, -1) - var sched = "default-scheduler" - if sc.Scheduler != "" { - sched = sc.Scheduler - } - j := &dlkapi.LTConfig{ - Ns: d.namespace, - Scheduler: sched, - Name: t.TrialId, - NrPS: 0, - NrWorker: 1, - PsImage: sc.Image, - WorkerImage: sc.Image, - Gpu: int(sc.Gpu), - DryRun: false, - EntryPoint: c + param, - Parameters: "", - Timeout: 0, - Pvc: sc.Mount.Pvc, - MountPath: sc.Mount.Path, - Priority: 0, - User: sc.Owner, - Envs: e, - PullSecret: sc.PullSecret, - } - ret[i] = j - } - return ret -} -func (d *DlkWorkerInterface) SpawnWorkers(trials []*api.Trial, studyId string) error { - runp := d.convertTrialToManifest(trials, studyId) - url := fmt.Sprintf("%s/learningTask", d.dlkmanager) - for _, j := range runp { - //encode json - b, err := json.Marshal(*j) - if err != nil { - return err - } - //send REST API Request - resp, err := http.Post(url, "application/json", bytes.NewReader(b)) - if err != nil { - return err - } - d.dbIf.UpdateTrial(j.Name, api.TrialState_RUNNING) - resp.Body.Close() - log.Printf("Created Lt %v.", j.Name) - } - return nil -} -func (d *DlkWorkerInterface) GetRunningTrials(studyId string) []*api.Trial { - d.mux.Lock() - defer d.mux.Unlock() - return d.RunningTrialList[studyId] -} -func (d *DlkWorkerInterface) GetCompletedTrials(studyId string) []*api.Trial { - d.mux.Lock() - defer d.mux.Unlock() - return d.CompletedTrialList[studyId] -} -func (d *DlkWorkerInterface) CleanWorkers(studyId string) error { - url := fmt.Sprintf("%s/learningTasks/%s/", d.dlkmanager, d.namespace) - d.mux.Lock() - defer d.mux.Unlock() - for _, t := range d.RunningTrialList[studyId] { - req, err := http.NewRequest("DELETE", url+t.TrialId, nil) - if err != nil { - log.Printf("failed to create DELETE request: %s\n", err) - return err - } - //send REST API Request - _, err = http.DefaultClient.Do(req) - if err != nil { - fmt.Println(err.Error()) - return err - } - } - return nil -} -func (d *DlkWorkerInterface) CompleteTrial(studyId string, tID string, iscomplete bool) error { - url := fmt.Sprintf("%s/learningTasks/%s/", d.dlkmanager, d.namespace) - d.mux.Lock() - defer d.mux.Unlock() - if iscomplete { - log.Printf("Trial %s completed", tID) - } else { - log.Printf("Trial %s has been killed", tID) - } - req, err := http.NewRequest("DELETE", url+tID, nil) - if err != nil { - log.Printf("failed to create DELETE request: %s\n", err) - return err - } - //send REST API Request - _, err = http.DefaultClient.Do(req) - if err != nil { - fmt.Println(err.Error()) - return err - } - for i, t := range d.RunningTrialList[studyId] { - if t.TrialId == tID { - d.RunningTrialList[studyId] = append(d.RunningTrialList[studyId][:i], d.RunningTrialList[studyId][i+1:]...) - if iscomplete { - t.Status = api.TrialState_COMPLETED - d.dbIf.UpdateTrial(t.TrialId, api.TrialState_COMPLETED) - } else { - t.Status = api.TrialState_KILLED - d.dbIf.UpdateTrial(t.TrialId, api.TrialState_KILLED) - } - d.CompletedTrialList[studyId] = append(d.CompletedTrialList[studyId], t) - } - } - return nil -} diff --git a/pkg/manager/worker/interface.go b/pkg/manager/worker/interface.go index 46dcf444fcf..fe5a84b989a 100644 --- a/pkg/manager/worker/interface.go +++ b/pkg/manager/worker/interface.go @@ -1,74 +1,14 @@ package worker import ( - "errors" - "fmt" - "time" - "github.com/kubeflow/katib/pkg/api" - "github.com/kubeflow/katib/pkg/db" ) type Interface interface { - IsTrialComplete(studyId string, tID string) (bool, error) - GetTrialObjValue(studyId string, tID string, objname string) (string, error) - GetTrialEvLogs(studyId string, tID string, metrics []string, sinceTime string) ([]*api.EvaluationLog, error) - CheckRunningTrials(studyId string, objname string) error - SpawnWorkers(trials []*api.Trial, studyId string) error - GetRunningTrials(studyId string) []*api.Trial - GetCompletedTrials(studyId string) []*api.Trial + SpawnWorker(wid string, workerConf *api.WorkerConfig) error + StoreWorkerLog(wID string) error + IsWorkerComplete(wID string) (bool, error) + UpdateWorkerStatus(studyId string) error + StopWorkers(studyId string, wIDs []string, iscomplete bool) error CleanWorkers(studyId string) error - CompleteTrial(studyId string, tID string, iscomplete bool) error -} - -// Those functions can go after EvalLog transition to DB is complete. -func GetTrialObjValue(d db.VizierDBInterface, studyId string, tID string, objname string) (string, error) { - - log, err := d.GetTrialLogs(tID, - &db.GetTrialLogOpts{Name: objname, Descending: true, Limit: 1}) - if err != nil { - return "", err - } - if len(log) == 0 { - return "", errors.New(fmt.Sprintf("No Objective Value Name %v is found in log", objname)) - } - return log[0].Value, nil -} - -func GetTrialEvLogs(d db.VizierDBInterface, studyId string, tID string, metrics []string, sinceTime string) ([]*api.EvaluationLog, error) { - var ret []*api.EvaluationLog - logopts := db.GetTrialLogOpts{} - if sinceTime != "" { - t, err := time.Parse(time.RFC3339, sinceTime) - if err != nil { - return nil, err - } - logopts.SinceTime = &t - } - log, err := d.GetTrialLogs(tID, &logopts) - if err != nil { - return nil, err - } - for _, ls := range log { - match := false - for _, m := range metrics { - if ls.Name == m { - match = true - break - } - } - if !match { - continue - } - time_str := ls.Time.Format(time.RFC3339Nano) - metric := api.Metrics{Name: ls.Name, Value: ls.Value} - if len(ret) > 0 && ret[len(ret)-1].Time == time_str { - ret[len(ret)-1].Metrics = append( - ret[len(ret)-1].Metrics, &metric) - continue - } - ret = append(ret, &api.EvaluationLog{ - Time: time_str, Metrics: []*api.Metrics{&metric}}) - } - return ret, nil } diff --git a/pkg/manager/worker/kubernetes/kubernetes.go b/pkg/manager/worker/kubernetes/kubernetes.go index 8d96c79c9a0..7ce696ad3a4 100644 --- a/pkg/manager/worker/kubernetes/kubernetes.go +++ b/pkg/manager/worker/kubernetes/kubernetes.go @@ -1,72 +1,131 @@ package kubernetes import ( - "bytes" "errors" "fmt" - "io/ioutil" "log" + "strconv" "strings" - "sync" - "time" batchv1 "k8s.io/api/batch/v1" apiv1 "k8s.io/api/core/v1" + resource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - k8syaml "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" "github.com/kubeflow/katib/pkg/api" "github.com/kubeflow/katib/pkg/db" - "github.com/kubeflow/katib/pkg/earlystopping" - wIF "github.com/kubeflow/katib/pkg/manager/worker" +) + +const ( + kubeNamespace = "katib" ) type KubernetesWorkerInterface struct { - //Support MultiStudy - RunningTrialList map[string][]*api.Trial - CompletedTrialList map[string][]*api.Trial - clientset *kubernetes.Clientset - mux *sync.Mutex - db db.VizierDBInterface + clientset *kubernetes.Clientset + db db.VizierDBInterface } -func NewKubernetesWorkerInterface(cs *kubernetes.Clientset, db db.VizierDBInterface) *KubernetesWorkerInterface { - return &KubernetesWorkerInterface{ - RunningTrialList: make(map[string][]*api.Trial), - CompletedTrialList: make(map[string][]*api.Trial), - clientset: cs, - mux: new(sync.Mutex), - db: db, +func NewKubernetesWorkerInterface(db db.VizierDBInterface) (*KubernetesWorkerInterface, error) { + config, err := restclient.InClusterConfig() + if err != nil { + return nil, err } + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + return nil, err + } + return &KubernetesWorkerInterface{ + clientset: clientset, + db: db, + }, nil } -func (d *KubernetesWorkerInterface) convertTrialToManifest(trials []*api.Trial, tFile []byte, studyId string) []batchv1.Job { - ret := make([]batchv1.Job, len(trials)) - BUFSIZE := 1024 - d.mux.Lock() - defer d.mux.Unlock() - for i, t := range trials { - d.RunningTrialList[studyId] = append(d.RunningTrialList[studyId], t) - k8syaml.NewYAMLOrJSONDecoder(bytes.NewReader(tFile), BUFSIZE).Decode(&ret[i]) - var args = []string{} - for _, v := range t.ParameterSet { - args = append(args, v.Name+"="+v.Value) +// Generate Job Template +func (d *KubernetesWorkerInterface) genJobManifest(wid string, conf *api.WorkerConfig) (*batchv1.Job, error) { + //construct entry point nad parameter + template := &batchv1.Job{ + TypeMeta: metav1.TypeMeta{ + Kind: "Job", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: wid, + Labels: map[string]string{ + "katib-version": "alpha-0.2.0", + "worker-id": wid, + }, + }, + Spec: batchv1.JobSpec{ + Template: apiv1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "katib-version": "alpha-0.2.0", + "worker-id": wid, + }, + }, + Spec: apiv1.PodSpec{ + SchedulerName: conf.Scheduler, + Containers: []apiv1.Container{ + { + Image: conf.Image, + Name: wid, + Command: conf.Command, + ImagePullPolicy: apiv1.PullAlways, + }, + }, + RestartPolicy: apiv1.RestartPolicyOnFailure, + ImagePullSecrets: []apiv1.LocalObjectReference{ + apiv1.LocalObjectReference{ + Name: conf.PullSecret, + }, + }, + }, + }, + }, + } + + // Specified pvc is mounted to both PS and Worker Pods + if conf.Mount != nil { + if conf.Mount.Pvc != "" && conf.Mount.Path != "" { + template.Spec.Template.Spec.Volumes = []apiv1.Volume{ + apiv1.Volume{ + Name: "pvc-mount-point", + VolumeSource: apiv1.VolumeSource{ + PersistentVolumeClaim: &apiv1.PersistentVolumeClaimVolumeSource{ + ClaimName: conf.Mount.Pvc, + }, + }, + }, + } + template.Spec.Template.Spec.Containers[0].VolumeMounts = []apiv1.VolumeMount{ + apiv1.VolumeMount{ + Name: "pvc-mount-point", + MountPath: conf.Mount.Path, + }, + } + } + } + if conf.Gpu > 0 { + gpuReq, err := resource.ParseQuantity(strconv.Itoa(int(conf.Gpu))) + if err != nil { + return nil, err } - ret[i].ObjectMeta.Name = t.TrialId - ret[i].Spec.Template.Spec.Containers[0].Name = t.TrialId + "-worker" - ret[i].Spec.Template.Spec.Containers[0].Args = args + template.Spec.Template.Spec.Containers[0].Resources = + apiv1.ResourceRequirements{ + Limits: apiv1.ResourceList{"nvidia.com/gpu": gpuReq}, + } } - return ret + return template, nil } -func (d *KubernetesWorkerInterface) storeTrialLog(tID string) error { - pl, _ := d.clientset.CoreV1().Pods("").List(metav1.ListOptions{LabelSelector: "job-name=" + tID}) +func (d *KubernetesWorkerInterface) StoreWorkerLog(wID string) error { + pl, _ := d.clientset.CoreV1().Pods(kubeNamespace).List(metav1.ListOptions{LabelSelector: "job-name=" + wID}) if len(pl.Items) == 0 { - return errors.New(fmt.Sprintf("No Pods are found in Job %v", tID)) + return errors.New(fmt.Sprintf("No Pods are found in Job %v", wID)) } - mt, err := d.db.GetTrialTimestamp(tID) + mt, err := d.db.GetWorkerTimestamp(wID) if err != nil { return err } @@ -75,71 +134,29 @@ func (d *KubernetesWorkerInterface) storeTrialLog(tID string) error { logopt.SinceTime = &metav1.Time{Time: *mt} } - logs, err := d.clientset.CoreV1().Pods(apiv1.NamespaceDefault).GetLogs(pl.Items[0].ObjectMeta.Name, &logopt).Do().Raw() + logs, err := d.clientset.CoreV1().Pods(kubeNamespace).GetLogs(pl.Items[0].ObjectMeta.Name, &logopt).Do().Raw() if err != nil { return err } if len(logs) == 0 { return nil } - err = d.db.StoreTrialLogs(tID, strings.Split(string(logs), "\n")) + err = d.db.StoreWorkerLogs(wID, strings.Split(string(logs), "\n")) return err } -func (d *KubernetesWorkerInterface) GetTrialObjValue(studyId string, tID string, objname string) (string, error) { - return wIF.GetTrialObjValue(d.db, studyId, tID, objname) -} - -func (d *KubernetesWorkerInterface) GetTrialEvLogs(studyId string, tID string, metrics []string, sinceTime string) ([]*api.EvaluationLog, error) { - return wIF.GetTrialEvLogs(d.db, studyId, tID, metrics, sinceTime) -} - -func (d *KubernetesWorkerInterface) PollingShouldStop(ess earlystopping.EarlyStoppingService, studyId string) chan bool { - stop := make(chan bool) - go func() { - defer close(stop) - tm := time.NewTimer(60 * time.Second) - for { - select { - case <-tm.C: - tm.Reset(60 * time.Second) - // d.mux.Lock() - // st := ess.ShouldTrialStop(d.RunningTrialList[studyId], d.CompletedTrialList[studyId], 10) - // jcl := d.clientset.BatchV1().Jobs(apiv1.NamespaceDefault) - // pcl := d.clientset.CoreV1().Pods(apiv1.NamespaceDefault) - // for _, t := range st { - // jcl.Delete(t.TrialId, &metav1.DeleteOptions{}) - // pl, _ := pcl.List(metav1.ListOptions{LabelSelector: "job-name=" + t.TrialId}) - // pcl.Delete(pl.Items[0].ObjectMeta.Name, &metav1.DeleteOptions{}) - // log.Printf("Trial %v is Killed.", t.TrialId) - // for i := range d.RunningTrialList[studyId] { - // if d.RunningTrialList[studyId][i].TrialId == t.TrialId { - // d.RunningTrialList[studyId][i].Status = api.TrialState_KILLED - // break - // } - // } - // } - // d.mux.Unlock() - case <-stop: - return - } - } - }() - return stop -} - -func (d *KubernetesWorkerInterface) IsTrialComplete(studyId string, tID string) (bool, error) { - jcl := d.clientset.BatchV1().Jobs(apiv1.NamespaceDefault) - ji, err := jcl.Get(tID, metav1.GetOptions{}) +func (d *KubernetesWorkerInterface) IsWorkerComplete(wID string) (bool, error) { + jcl := d.clientset.BatchV1().Jobs(kubeNamespace) + ji, err := jcl.Get(wID, metav1.GetOptions{}) if err != nil { return false, err } if ji.Status.Succeeded == 0 { return false, nil } - pl, _ := d.clientset.CoreV1().Pods("").List(metav1.ListOptions{LabelSelector: "job-name=" + tID}) + pl, _ := d.clientset.CoreV1().Pods(kubeNamespace).List(metav1.ListOptions{LabelSelector: "job-name=" + wID}) if len(pl.Items) == 0 { - return false, errors.New(fmt.Sprintf("No Pods are found in Job %v", tID)) + return false, errors.New(fmt.Sprintf("No Pods are found in Job %v", wID)) } if pl.Items[0].Status.Phase == "Succeeded" { return true, nil @@ -147,119 +164,100 @@ func (d *KubernetesWorkerInterface) IsTrialComplete(studyId string, tID string) return false, nil } -func (d *KubernetesWorkerInterface) CheckRunningTrials(studyId string, objname string) error { - allcomp := true - d.mux.Lock() - sc, _ := d.db.GetStudyConfig(studyId) - metrics := sc.Metrics - defer d.mux.Unlock() - if len(d.RunningTrialList[studyId]) == 0 { - return nil +func (d *KubernetesWorkerInterface) UpdateWorkerStatus(studyId string) error { + ws, err := d.db.GetWorkerList(studyId) + if err != nil { + return err } - for i, t := range d.RunningTrialList[studyId] { - status, err := d.db.GetTrialStatus(t.TrialId) - if err != nil { - log.Printf("Error getting status of %s: %v", t.TrialId, err) - continue - } - if status == api.TrialState_RUNNING { - c, err := d.IsTrialComplete(studyId, t.TrialId) - if err != nil { - log.Printf("IsTrialComplete: %v", err) - } - err = d.storeTrialLog(t.TrialId) + for _, w := range ws { + if w.Status == api.State_RUNNING { + d.StoreWorkerLog(w.WorkerId) + c, err := d.IsWorkerComplete(w.WorkerId) if err != nil { - log.Printf("Error storing trial log of %s: %v", t.TrialId, err) + return err } - // TODO: remove the following code block after - // suggestions and earlystopping switch to - // read those values from DB if c { - o, _ := d.GetTrialObjValue(studyId, t.TrialId, objname) - d.RunningTrialList[studyId][i].ObjectiveValue = o - d.RunningTrialList[studyId][i].Status = api.TrialState_COMPLETED - } else { - allcomp = false - var es []*api.EvaluationLog - if len(d.RunningTrialList[studyId][i].EvalLogs) == 0 { - es, _ = d.GetTrialEvLogs(studyId, t.TrialId, metrics, "") - } else { - es, _ = d.GetTrialEvLogs(studyId, t.TrialId, metrics, d.RunningTrialList[studyId][i].EvalLogs[len(d.RunningTrialList[studyId][i].EvalLogs)-1].Time) - } - if len(es) > 0 { - d.RunningTrialList[studyId][i].EvalLogs = append(d.RunningTrialList[studyId][i].EvalLogs, es...) + err := d.db.UpdateWorker(w.WorkerId, api.State_COMPLETED) + if err != nil { + return err } + jcl := d.clientset.BatchV1().Jobs(kubeNamespace) + pcl := d.clientset.CoreV1().Pods(kubeNamespace) + jcl.Delete(w.WorkerId, &metav1.DeleteOptions{}) + pl, _ := pcl.List(metav1.ListOptions{LabelSelector: "job-name=" + w.WorkerId}) + pcl.Delete(pl.Items[0].ObjectMeta.Name, &metav1.DeleteOptions{}) } - } else if status == api.TrialState_PENDING { - allcomp = false - } - } - if allcomp { - for i, t := range d.RunningTrialList[studyId] { - log.Printf("%v is completed.", t.TrialId) - log.Printf("Objective Value: %v", d.RunningTrialList[studyId][i].ObjectiveValue) - log.Printf("Tags: %v", t.Tags) - // for _, l := range t.EvalLogs { - // log.Printf("\tEval Logs %v %v\n", l.Time, l.Value) - // } } - d.CompletedTrialList[studyId] = append(d.CompletedTrialList[studyId], d.RunningTrialList[studyId]...) - d.RunningTrialList[studyId] = []*api.Trial{} - return nil } return nil } -func (d *KubernetesWorkerInterface) SpawnWorkers(trials []*api.Trial, studyId string) error { - // Notice: Missing in the repo. - tFile, _ := ioutil.ReadFile("/conf/template.yml") - jobs := d.convertTrialToManifest(trials, tFile, studyId) - jcl := d.clientset.BatchV1().Jobs(apiv1.NamespaceDefault) - for _, j := range jobs { - result, err := jcl.Create(&j) - if err != nil { - return err - } - err = d.db.UpdateTrial(j.ObjectMeta.Name, api.TrialState_RUNNING) - if err != nil { - log.Printf("Error updating status for %s: %v", j.ObjectMeta.Name, err) - } - - log.Printf("Created Job %q.", result.GetObjectMeta().GetName()) +func (d *KubernetesWorkerInterface) SpawnWorker(wid string, workerConf *api.WorkerConfig) error { + job, err := d.genJobManifest(wid, workerConf) + if err != nil { + return err } + jcl := d.clientset.BatchV1().Jobs(kubeNamespace) + result, err := jcl.Create(job) + if err != nil { + return err + } + err = d.db.UpdateWorker(wid, api.State_RUNNING) + if err != nil { + log.Printf("Error updating status for %s: %v", job.ObjectMeta.Name, err) + return err + } + log.Printf("Created Job %q.", result.GetObjectMeta().GetName()) return nil } -func (d *KubernetesWorkerInterface) GetRunningTrials(studyId string) []*api.Trial { - return d.RunningTrialList[studyId] -} - -func (d *KubernetesWorkerInterface) GetCompletedTrials(studyId string) []*api.Trial { - return d.CompletedTrialList[studyId] -} - func (d *KubernetesWorkerInterface) CleanWorkers(studyId string) error { - jcl := d.clientset.BatchV1().Jobs(apiv1.NamespaceDefault) - pcl := d.clientset.CoreV1().Pods(apiv1.NamespaceDefault) - for _, t := range d.RunningTrialList[studyId] { - jcl.Delete(t.TrialId, &metav1.DeleteOptions{}) - pl, _ := pcl.List(metav1.ListOptions{LabelSelector: "job-name=" + t.TrialId}) - pcl.Delete(pl.Items[0].ObjectMeta.Name, &metav1.DeleteOptions{}) + jcl := d.clientset.BatchV1().Jobs(kubeNamespace) + pcl := d.clientset.CoreV1().Pods(kubeNamespace) + ws, err := d.db.GetWorkerList(studyId) + if err != nil { + return err } - for _, t := range d.CompletedTrialList[studyId] { - jcl.Delete(t.TrialId, &metav1.DeleteOptions{}) - pl, _ := pcl.List(metav1.ListOptions{LabelSelector: "job-name=" + t.TrialId}) - pcl.Delete(pl.Items[0].ObjectMeta.Name, &metav1.DeleteOptions{}) + for _, w := range ws { + if w.Status == api.State_RUNNING { + jcl.Delete(w.WorkerId, &metav1.DeleteOptions{}) + pl, _ := pcl.List(metav1.ListOptions{LabelSelector: "job-name=" + w.WorkerId}) + pcl.Delete(pl.Items[0].ObjectMeta.Name, &metav1.DeleteOptions{}) + err := d.db.UpdateWorker(w.WorkerId, api.State_KILLED) + if err != nil { + return err + } + } } - delete(d.RunningTrialList, studyId) - delete(d.CompletedTrialList, studyId) return nil } -func (d *KubernetesWorkerInterface) CompleteTrial(studyId string, tID string, iscomplete bool) error { - jcl := d.clientset.BatchV1().Jobs(apiv1.NamespaceDefault) - pcl := d.clientset.CoreV1().Pods(apiv1.NamespaceDefault) - jcl.Delete(tID, &metav1.DeleteOptions{}) - pl, _ := pcl.List(metav1.ListOptions{LabelSelector: "job-name=" + tID}) - pcl.Delete(pl.Items[0].ObjectMeta.Name, &metav1.DeleteOptions{}) + +func (d *KubernetesWorkerInterface) StopWorkers(studyId string, wIDs []string, iscomplete bool) error { + ws, err := d.db.GetWorkerList(studyId) + if err != nil { + return err + } + jcl := d.clientset.BatchV1().Jobs(kubeNamespace) + pcl := d.clientset.CoreV1().Pods(kubeNamespace) + for _, w := range ws { + for _, wid := range wIDs { + if w.Status == api.State_RUNNING && w.WorkerId == wid { + jcl.Delete(wid, &metav1.DeleteOptions{}) + pl, err := pcl.List(metav1.ListOptions{LabelSelector: "job-name=" + wid}) + if err != nil { + return err + } + pcl.Delete(pl.Items[0].ObjectMeta.Name, &metav1.DeleteOptions{}) + if iscomplete { + err = d.db.UpdateWorker(wid, api.State_COMPLETED) + } else { + err = d.db.UpdateWorker(wid, api.State_KILLED) + } + if err != nil { + return err + } + } + } + } return nil } diff --git a/pkg/manager/worker/nvdocker/nvidia-docker.go b/pkg/manager/worker/nvdocker/nvidia-docker.go deleted file mode 100644 index 0a40b4bfe9c..00000000000 --- a/pkg/manager/worker/nvdocker/nvidia-docker.go +++ /dev/null @@ -1,455 +0,0 @@ -package nvdocker - -import ( - "bytes" - "context" - "errors" - "fmt" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" - dclient "github.com/docker/docker/client" - "github.com/kubeflow/katib/pkg/api" - "github.com/kubeflow/katib/pkg/db" - wIF "github.com/kubeflow/katib/pkg/manager/worker" - "io" - "io/ioutil" - "log" - "os" - "path" - "regexp" - "strconv" - "strings" - "sync" - "time" -) - -const ( - nvCtlDevice string = "/dev/nvidiactl" - nvUVMDevice string = "/dev/nvidia-uvm" - nvUVMToolsDevice string = "/dev/nvidia-uvm-tools" - devDirectory = "/dev" -) - -var ( - nvidiaDeviceRE = regexp.MustCompile(`^nvidia[0-9]*$`) - nvidiaFullpathRE = regexp.MustCompile(`^/dev/nvidia[0-9]*$`) -) - -type nvGPUManager struct { - mux sync.Mutex - // All gpus available on the Node - allGPUs []string - gPUAllocedContainer map[string]string -} - -func NewNvGPUManager() (*nvGPUManager, error) { - n := &nvGPUManager{ - allGPUs: []string{}, - gPUAllocedContainer: map[string]string{}, - } - err := n.discoverGPUs() - return n, err -} - -func (ngm *nvGPUManager) discoverGPUs() error { - files, err := ioutil.ReadDir(devDirectory) - if err != nil { - return err - } - for _, f := range files { - if f.IsDir() { - continue - } - if nvidiaDeviceRE.MatchString(f.Name()) { - fmt.Printf("Found Nvidia GPU %v\n", f.Name()) - gn := path.Join(devDirectory, f.Name()) - ngm.allGPUs = append(ngm.allGPUs, gn) - ngm.gPUAllocedContainer[gn] = "" - } - } - return nil -} - -func (ngm *nvGPUManager) AllocGPU(num int, cid string) (bool, []string, error) { - ngm.mux.Lock() - defer ngm.mux.Unlock() - fGpusId := []int{} - for i, g := range ngm.allGPUs { - if ngm.gPUAllocedContainer[g] == "" { - fGpusId = append(fGpusId, i) - } - } - if len(fGpusId) < num { - return false, nil, nil - } - fGpusId = fGpusId[:num] - retid := make([]string, num) - for j, i := range fGpusId { - ngm.gPUAllocedContainer[ngm.allGPUs[i]] = cid - retid[j] = strconv.Itoa(i) - } - log.Printf("%v GPU Alloced. ID %v", num, retid) - return true, retid, nil -} - -func (ngm *nvGPUManager) ReleaseGPU(cid string) error { - ngm.mux.Lock() - defer ngm.mux.Unlock() - for _, g := range ngm.allGPUs { - if ngm.gPUAllocedContainer[g] == cid { - log.Printf("GPU ID %v Releaseced.", g) - ngm.gPUAllocedContainer[g] = "" - } - } - return nil -} - -func (ngm *nvGPUManager) GetAllGPU() []string { - return ngm.allGPUs -} - -type spawnReq struct { - StudyID string - Trials []*api.Trial - CConf []*container.Config -} - -type NvDockerWorkerInterface struct { - PendingTrialList map[string][]*api.Trial - RunningTrialList map[string][]*api.Trial - CompletedTrialList map[string][]*api.Trial - dcli *dclient.Client - mux *sync.Mutex - dbIf db.VizierDBInterface - tidToCid map[string]string - ngm *nvGPUManager - addTrialQueCh chan spawnReq - deleteTrialQueCh chan string - stopSchedule chan bool -} - -func NewNvDockerWorkerInterface() *NvDockerWorkerInterface { - dc, err := dclient.NewEnvClient() - if err != nil { - log.Printf("docker client err %v", err) - return nil - } - ngm, err := NewNvGPUManager() - if err != nil { - log.Printf("GPU device detect err %v", err) - return nil - } - n := &NvDockerWorkerInterface{ - PendingTrialList: make(map[string][]*api.Trial), - RunningTrialList: make(map[string][]*api.Trial), - CompletedTrialList: make(map[string][]*api.Trial), - dcli: dc, - mux: new(sync.Mutex), - dbIf: db.New(), - ngm: ngm, - tidToCid: make(map[string]string), - addTrialQueCh: make(chan spawnReq), - deleteTrialQueCh: make(chan string), - stopSchedule: make(chan bool), - } - go n.schedulingLoop() - return n -} - -func (n *NvDockerWorkerInterface) getcid(tID string) (string, error) { - cid, ok := n.tidToCid[tID] - if !ok { - return "", errors.New(fmt.Sprintf("No container TID %v", tID)) - } - return cid, nil -} - -func (n *NvDockerWorkerInterface) getCon(tID string) (types.ContainerJSON, error) { - cid, err := n.getcid(tID) - if err != nil { - return types.ContainerJSON{}, err - } - return n.dcli.ContainerInspect(context.Background(), cid) -} - -func (n *NvDockerWorkerInterface) getConLog(tID string, since string) ([]string, error) { - cid, err := n.getcid(tID) - if err != nil { - log.Printf("getcid err %v", err) - return nil, err - } - out, err := n.dcli.ContainerLogs(context.Background(), cid, types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Since: since, Timestamps: true}) - if err != nil { - log.Printf("get log err %v", err) - return nil, err - } - defer out.Close() - buf := new(bytes.Buffer) - buf.ReadFrom(out) - return strings.Split(buf.String(), "\n"), nil -} - -func (n *NvDockerWorkerInterface) IsTrialComplete(studyId string, tID string) (bool, error) { - c, err := n.getCon(tID) - if err != nil { - return false, err - } - if !c.State.Running && !c.State.Dead && !c.State.OOMKilled { - return true, nil - } - return false, nil -} - -func (n *NvDockerWorkerInterface) storeTrialLog(tID string) error { - mt, err := n.dbIf.GetTrialTimestamp(tID) - if err != nil { - return err - } - sincetime := "" - if mt != nil { - sincetime = mt.Format(time.RFC3339Nano) - } - cl, err := n.getConLog(tID, sincetime) - if err != nil { - return err - } - err = n.dbIf.StoreTrialLogs(tID, cl) - return err -} - -func (n *NvDockerWorkerInterface) GetTrialObjValue(studyId string, tID string, objname string) (string, error) { - return wIF.GetTrialObjValue(n.dbIf, studyId, tID, objname) -} - -func (n *NvDockerWorkerInterface) GetTrialEvLogs(studyId string, tID string, metrics []string, sinceTime string) ([]*api.EvaluationLog, error) { - return wIF.GetTrialEvLogs(n.dbIf, studyId, tID, metrics, sinceTime) -} - -func (n *NvDockerWorkerInterface) CheckRunningTrials(studyId string, objname string) error { - n.mux.Lock() - defer n.mux.Unlock() - if len(n.RunningTrialList[studyId]) == 0 { - return nil - } - sc, _ := n.dbIf.GetStudyConfig(studyId) - metrics := sc.Metrics - for _, t := range n.RunningTrialList[studyId] { - status, err := n.dbIf.GetTrialStatus(t.TrialId) - if err != nil { - log.Printf("Error getting status of %s: %v", t.TrialId, err) - continue - } - if status == api.TrialState_RUNNING { - c, _ := n.IsTrialComplete(studyId, t.TrialId) - err = n.storeTrialLog(t.TrialId) - if err != nil { - log.Printf("Error storing trial log of %s: %v", t.TrialId, err) - } - var es []*api.EvaluationLog - if len(t.EvalLogs) == 0 { - es, err = n.GetTrialEvLogs(studyId, t.TrialId, metrics, "") - } else { - es, err = n.GetTrialEvLogs(studyId, t.TrialId, metrics, t.EvalLogs[len(t.EvalLogs)-1].Time) - } - if err != nil { - log.Printf("GetTrialEvLogs Err %v", err) - return err - } - if len(es) > 0 { - t.EvalLogs = append(t.EvalLogs, es...) - } - if c { - o, _ := n.GetTrialObjValue(studyId, t.TrialId, objname) - t.ObjectiveValue = o - t.Status = api.TrialState_COMPLETED - log.Printf("Trial %v is completed.", t.TrialId) - log.Printf("Objective Value: %v", t.ObjectiveValue) - n.CompletedTrialList[studyId] = append(n.CompletedTrialList[studyId], t) - n.ngm.ReleaseGPU(t.TrialId) - cid := n.tidToCid[t.TrialId] - err = n.dcli.ContainerRemove(context.Background(), cid, types.ContainerRemoveOptions{Force: true}) - if err != nil { - log.Printf("Container delete err %v", err) - } - delete(n.tidToCid, t.TrialId) - if len(n.RunningTrialList[studyId]) <= 1 { - n.RunningTrialList[studyId] = []*api.Trial{} - } else { - tn := t.TrialId - for j, tt := range n.RunningTrialList[studyId] { - if tt.TrialId == tn { - n.RunningTrialList[studyId] = append(n.RunningTrialList[studyId][:j], n.RunningTrialList[studyId][j+1:]...) - break - } - } - } - } - } - } - return nil -} - -func (n *NvDockerWorkerInterface) convertTrialToContainer(trials []*api.Trial, studyId string) []*container.Config { - sc, _ := n.dbIf.GetStudyConfig(studyId) - ret := make([]*container.Config, len(trials)) - n.mux.Lock() - defer n.mux.Unlock() - for i, t := range trials { - n.PendingTrialList[studyId] = append(n.PendingTrialList[studyId], t) - command := sc.Command - for _, v := range t.ParameterSet { - command = append(command, v.Name+"="+v.Value) - } - j := &container.Config{ - Image: sc.Image, - Cmd: command, - } - ret[i] = j - } - return ret -} - -type trialQueueObj struct { - StudyID string - Trial *api.Trial - CConf *container.Config -} - -func (n *NvDockerWorkerInterface) schedulingLoop() error { - tq := []*trialQueueObj{} - t := time.NewTicker(3 * time.Second) - for { - select { - case <-n.stopSchedule: - return nil - case sr := <-n.addTrialQueCh: - log.Printf("%v Trial set to trial queue", len(sr.Trials)) - for i, t := range sr.Trials { - tq = append(tq, &trialQueueObj{ - StudyID: sr.StudyID, - Trial: t, - CConf: sr.CConf[i], - }) - } - case <-t.C: - for i, t := range tq { - sc, _ := n.dbIf.GetStudyConfig(t.StudyID) - chc := &container.HostConfig{} - if sc.Mount.Pvc != "" { - chc.Binds = []string{sc.Mount.Pvc + ":" + sc.Mount.Path} - } - if sc.Gpu > 0 { - ok, gid, err := n.ngm.AllocGPU(int(sc.Gpu), t.Trial.TrialId) - if err != nil { - log.Printf("AllocGPU error %v", err) - break - } - if !ok { - break - } - t.CConf.Env = []string{"NVIDIA_VISIBLE_DEVICES=" + strings.Join(gid, ",")} - chc.Runtime = "nvidia" - } - resp, err := n.dcli.ContainerCreate(context.Background(), t.CConf, chc, nil, t.Trial.TrialId) - if err != nil { - log.Printf("Container create err %v", err) - r, err := n.dcli.ImagePull(context.Background(), t.CConf.Image, types.ImagePullOptions{}) - if err != nil { - log.Printf("Container create err %v", err) - if sc.Gpu > 0 { - n.ngm.ReleaseGPU(t.Trial.TrialId) - } - break - } - log.Printf("Image %v start to pull", t.CConf.Image) - io.Copy(os.Stdout, r) - resp, err = n.dcli.ContainerCreate(context.Background(), t.CConf, chc, nil, t.Trial.TrialId) - if err != nil { - log.Printf("Container create err %v", err) - break - } - } - if err := n.dcli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil { - if sc.Gpu > 0 { - n.ngm.ReleaseGPU(t.Trial.TrialId) - } - break - } - n.mux.Lock() - n.tidToCid[t.Trial.TrialId] = resp.ID - for i, pt := range n.PendingTrialList[t.StudyID] { - if pt.TrialId == t.Trial.TrialId { - if len(n.PendingTrialList[t.StudyID]) <= 1 { - n.PendingTrialList[t.StudyID] = []*api.Trial{} - } else { - n.PendingTrialList[t.StudyID] = append(n.PendingTrialList[t.StudyID][:i], n.PendingTrialList[t.StudyID][i+1:]...) - } - n.dbIf.UpdateTrial(t.Trial.TrialId, api.TrialState_RUNNING) - n.RunningTrialList[t.StudyID] = append(n.RunningTrialList[t.StudyID], pt) - break - } - } - n.mux.Unlock() - if len(tq) <= 1 { - tq = []*trialQueueObj{} - } else { - tq = append(tq[:i], tq[i+1:]...) - } - log.Printf("Trial %v spawned. container ID %v", t.Trial.TrialId, resp.ID) - } - case ds := <-n.deleteTrialQueCh: - ntq := []*trialQueueObj{} - for _, t := range tq { - if ds != t.StudyID { - ntq = append(ntq, t) - } - } - tq = ntq - } - } -} - -func (n *NvDockerWorkerInterface) SpawnWorkers(trials []*api.Trial, studyId string) error { - n.addTrialQueCh <- spawnReq{StudyID: studyId, Trials: trials, CConf: n.convertTrialToContainer(trials, studyId)} - return nil -} - -func (n *NvDockerWorkerInterface) GetRunningTrials(studyId string) []*api.Trial { - n.mux.Lock() - defer n.mux.Unlock() - return append(n.PendingTrialList[studyId], n.RunningTrialList[studyId]...) -} - -func (n *NvDockerWorkerInterface) GetCompletedTrials(studyId string) []*api.Trial { - n.mux.Lock() - defer n.mux.Unlock() - return n.CompletedTrialList[studyId] -} - -func (n *NvDockerWorkerInterface) CleanWorkers(studyId string) error { - n.mux.Lock() - defer n.mux.Unlock() - n.deleteTrialQueCh <- studyId - for _, t := range n.RunningTrialList[studyId] { - cid := n.tidToCid[t.TrialId] - err := n.dcli.ContainerRemove(context.Background(), cid, types.ContainerRemoveOptions{Force: true}) - if err != nil { - log.Printf("Container delete err %v", err) - } - delete(n.tidToCid, t.TrialId) - n.ngm.ReleaseGPU(t.TrialId) - } - delete(n.PendingTrialList, studyId) - delete(n.RunningTrialList, studyId) - return nil -} -func (n *NvDockerWorkerInterface) CompleteTrial(studyId string, tID string, iscomplete bool) error { - cid := n.tidToCid[tID] - err := n.dcli.ContainerRemove(context.Background(), cid, types.ContainerRemoveOptions{Force: true}) - if err != nil { - return err - } - delete(n.tidToCid, tID) - n.ngm.ReleaseGPU(tID) - return nil -} diff --git a/pkg/suggestion/grid_service.go b/pkg/suggestion/grid_service.go index 73a1b30bc8c..3a1aa181d2e 100644 --- a/pkg/suggestion/grid_service.go +++ b/pkg/suggestion/grid_service.go @@ -7,6 +7,7 @@ import ( "strconv" "github.com/kubeflow/katib/pkg/api" + "google.golang.org/grpc" ) type GridSuggestParameters struct { @@ -16,29 +17,10 @@ type GridSuggestParameters struct { } type GridSuggestService struct { - parameters map[string]*GridSuggestParameters - grids map[string][][]*api.Parameter - gridPointer map[string]int } func NewGridSuggestService() *GridSuggestService { - return &GridSuggestService{parameters: make(map[string]*GridSuggestParameters), grids: make(map[string][][]*api.Parameter), gridPointer: make(map[string]int)} -} - -func (s *GridSuggestService) SetSuggestionParameters(ctx context.Context, in *api.SetSuggestionParametersRequest) (*api.SetSuggestionParametersReply, error) { - p := &GridSuggestParameters{gridConfig: make(map[string]int)} - for _, sp := range in.SuggestionParameters { - switch sp.Name { - case "DefaultGrid": - p.defaultGridNum, _ = strconv.Atoi(sp.Value) - case "MaxParallel": - p.MaxParallel, _ = strconv.Atoi(sp.Value) - default: - p.gridConfig[sp.Name], _ = strconv.Atoi(sp.Value) - } - } - s.parameters[in.StudyId] = p - return &api.SetSuggestionParametersReply{}, nil + return &GridSuggestService{} } func (s *GridSuggestService) allocInt(min int, max int, reqnum int) []string { @@ -104,14 +86,30 @@ func (s *GridSuggestService) setP(gci int, p [][]*api.Parameter, pg [][]string, } } -func (s *GridSuggestService) genGrids(studyId string, pcs []*api.ParameterConfig) [][]*api.Parameter { +func (s *GridSuggestService) purseSuggestParam(suggestParam []*api.SuggestionParameter) (int, map[string]int) { + ret := make(map[string]int) + defaultGrid := 0 + for _, sp := range suggestParam { + switch sp.Name { + case "DefaultGrid": + defaultGrid, _ = strconv.Atoi(sp.Value) + default: + ret[sp.Name], _ = strconv.Atoi(sp.Value) + } + } + if defaultGrid == 0 { + defaultGrid = 1 + } + return defaultGrid, ret +} +func (s *GridSuggestService) genGrids(studyId string, pcs []*api.ParameterConfig, df int, glist map[string]int) [][]*api.Parameter { var pg [][]string var holenum = 1 gcl := make([]int, len(pcs)) for i, pc := range pcs { - gc, ok := s.parameters[studyId].gridConfig[pc.Name] + gc, ok := glist[pc.Name] if !ok { - gc = s.parameters[studyId].defaultGridNum + gc = df } holenum *= gc gcl[i] = gc @@ -134,41 +132,41 @@ func (s *GridSuggestService) genGrids(studyId string, pcs []*api.ParameterConfig return ret } -func (s *GridSuggestService) GenerateTrials(ctx context.Context, in *api.GenerateTrialsRequest) (*api.GenerateTrialsReply, error) { - if _, ok := s.grids[in.StudyId]; !ok { - s.grids[in.StudyId] = s.genGrids(in.StudyId, in.Configs.ParameterConfigs.Configs) - s.gridPointer[in.StudyId] = 0 +func (s *GridSuggestService) GetSuggestions(ctx context.Context, in *api.GetSuggestionsRequest) (*api.GetSuggestionsReply, error) { + conn, err := grpc.Dial(manager, grpc.WithInsecure()) + if err != nil { + log.Fatalf("could not connect: %v", err) + return &api.GetSuggestionsReply{}, err } - if s.gridPointer[in.StudyId] >= len(s.grids[in.StudyId]) { - if len(in.RunningTrials) == 0 { - s.StopSuggestion(ctx, &api.StopSuggestionRequest{StudyId: in.StudyId}) - return &api.GenerateTrialsReply{Completed: true}, nil - } else { - return &api.GenerateTrialsReply{Completed: false}, nil - } + defer conn.Close() + c := api.NewManagerClient(conn) + screq := &api.GetStudyRequest{ + StudyId: in.StudyId, } - var reqnum = 0 - if s.parameters[in.StudyId].MaxParallel <= 0 { - reqnum = len(s.grids[in.StudyId]) - } else if len(s.grids[in.StudyId])-s.gridPointer[in.StudyId] < s.parameters[in.StudyId].MaxParallel-len(in.RunningTrials) { - reqnum = len(s.grids[in.StudyId]) - s.gridPointer[in.StudyId] - } else if len(in.RunningTrials) < s.parameters[in.StudyId].MaxParallel { - reqnum = s.parameters[in.StudyId].MaxParallel - len(in.RunningTrials) + scr, err := c.GetStudy(ctx, screq) + if err != nil { + log.Fatalf("GetStudyConf failed: %v", err) + return &api.GetSuggestionsReply{}, err + } + spreq := &api.GetSuggestionParametersRequest{ + ParamId: in.ParamId, + } + spr, err := c.GetSuggestionParameters(ctx, spreq) + if err != nil { + log.Fatalf("GetParameter failed: %v", err) + return &api.GetSuggestionsReply{}, err + } + df, glist := s.purseSuggestParam(spr.SuggestionParameters) + grids := s.genGrids(in.StudyId, scr.StudyConfig.ParameterConfigs.Configs, df, glist) + var reqnum = int(in.RequestNumber) + if reqnum == 0 { + reqnum = len(grids) } trials := make([]*api.Trial, reqnum) for i := 0; i < int(reqnum); i++ { trials[i] = &api.Trial{} - trials[i].Status = api.TrialState_PENDING - trials[i].EvalLogs = make([]*api.EvaluationLog, 0) - trials[i].ParameterSet = s.grids[in.StudyId][s.gridPointer[in.StudyId]+i] + trials[i].Status = api.State_PENDING + trials[i].ParameterSet = grids[i] } - s.gridPointer[in.StudyId] += reqnum - return &api.GenerateTrialsReply{Trials: trials, Completed: false}, nil -} - -func (s *GridSuggestService) StopSuggestion(ctx context.Context, in *api.StopSuggestionRequest) (*api.StopSuggestionReply, error) { - delete(s.gridPointer, in.StudyId) - delete(s.grids, in.StudyId) - delete(s.parameters, in.StudyId) - return &api.StopSuggestionReply{}, nil + return &api.GetSuggestionsReply{Trials: trials}, nil } diff --git a/pkg/suggestion/hyperband_service.go b/pkg/suggestion/hyperband_service.go index fa90c86bded..682cf0bbbee 100644 --- a/pkg/suggestion/hyperband_service.go +++ b/pkg/suggestion/hyperband_service.go @@ -2,232 +2,326 @@ package suggestion import ( "context" - "crypto/rand" - "fmt" - "github.com/kubeflow/katib/pkg/db" - "log" - "math" - "sort" - "strconv" + // "crypto/rand" + // "fmt" + // "github.com/kubeflow/katib/pkg/db" + // "log" + // "math" + // "sort" + // "strconv" "github.com/kubeflow/katib/pkg/api" ) -type Bracket []*api.Trial - -func (b Bracket) Len() int { - return len(b) -} - -func (b Bracket) Swap(i, j int) { - b[i], b[j] = b[j], b[i] -} - -func (b Bracket) Less(i, j int) bool { - vi, _ := strconv.ParseFloat(b[i].ObjectiveValue, 64) - vj, _ := strconv.ParseFloat(b[j].ObjectiveValue, 64) - return vi > vj -} - +//type Evals struct { +// id string +// value float64 +//} +//type Bracket []Evals +// +//func (b Bracket) Len() int { +// return len(b) +//} +// +//func (b Bracket) Swap(i, j int) { +// b[i], b[j] = b[j], b[i] +//} +// +//func (b Bracket) Less(i, j int) bool { +// return b[i].value > b[j].value +//} +// type HyperBandParameters struct { - eta float64 - sMax int - b_l float64 - r_l float64 - r float64 - n int - shloopitr int - currentS int - MasterBracket Bracket - ResourceName string + eta float64 + sMax int + b_l float64 + r_l float64 + r float64 + n int + shloopitr int + currentS int + ResourceName string } + type HyperBandSuggestService struct { RandomSuggestService - parameters map[string]*HyperBandParameters - dbIf db.VizierDBInterface + parameters HyperBandParameters } func NewHyperBandSuggestService() *HyperBandSuggestService { - return &HyperBandSuggestService{parameters: make(map[string]*HyperBandParameters), dbIf: db.New()} -} - -func (h *HyperBandSuggestService) generate_randid() string { - // UUID isn't quite handy in the Go world - id_ := make([]byte, 8) - _, err := rand.Read(id_) - if err != nil { - log.Fatalf("Error reading random: %v", err) - } - return fmt.Sprintf("%016x", id_) + return &HyperBandSuggestService{} } -func (h *HyperBandSuggestService) makeMasterBracket(sconf *api.StudyConfig, n int) Bracket { - log.Printf("Make MasterBracket %v Trials", n) - s_t := make([]*api.Trial, n) - for i := 0; i < n; i++ { - s_t[i] = &api.Trial{} - s_t[i].ParameterSet = make([]*api.Parameter, len(sconf.ParameterConfigs.Configs)) - for j, pc := range sconf.ParameterConfigs.Configs { - s_t[i].ParameterSet[j] = &api.Parameter{Name: pc.Name} - s_t[i].ParameterSet[j].ParameterType = pc.ParameterType - switch pc.ParameterType { - case api.ParameterType_INT: - imin, _ := strconv.Atoi(pc.Feasible.Min) - imax, _ := strconv.Atoi(pc.Feasible.Max) - s_t[i].ParameterSet[j].Value = strconv.Itoa(h.IntRandom(imin, imax)) - case api.ParameterType_DOUBLE: - dmin, _ := strconv.ParseFloat(pc.Feasible.Min, 64) - dmax, _ := strconv.ParseFloat(pc.Feasible.Max, 64) - s_t[i].ParameterSet[j].Value = strconv.FormatFloat(h.DoubelRandom(dmin, dmax), 'f', 4, 64) - case api.ParameterType_CATEGORICAL: - s_t[i].ParameterSet[j].Value = pc.Feasible.List[h.IntRandom(0, len(pc.Feasible.List)-1)] - } - } - s_t[i].Tags = append(s_t[i].Tags, &api.Tag{Name: "HyperBand_BracketID", Value: h.generate_randid()}) - } - return Bracket(s_t) -} - -func (h *HyperBandSuggestService) SetSuggestionParameters(ctx context.Context, in *api.SetSuggestionParametersRequest) (*api.SetSuggestionParametersReply, error) { - p := &HyperBandParameters{} - for _, sp := range in.SuggestionParameters { - switch sp.Name { - case "Eta": - p.eta, _ = strconv.ParseFloat(sp.Value, 64) - case "R": - p.r_l, _ = strconv.ParseFloat(sp.Value, 64) - case "ResourceName": - p.ResourceName = sp.Value - default: - log.Printf("Unknown Suggestion Parameter %v", sp.Name) - } - } - if p.eta == 0 || p.r_l == 0 || p.ResourceName == "" { - log.Printf("Failed to Suggestion Parameter set.") - return &api.SetSuggestionParametersReply{}, fmt.Errorf("Suggestion Parameter set Error") - } - p.sMax = int(math.Log(p.r_l) / math.Log(p.eta)) - p.b_l = float64((p.sMax + 1.0)) * p.r_l - p.n = int((p.b_l/p.r_l)*(math.Pow(p.eta, float64(p.sMax))/float64(p.sMax+1))) + 1 - p.currentS = p.sMax + 1 - p.shloopitr = p.currentS + 1 - p.r = p.r_l * math.Pow(p.eta, float64(-p.sMax)) - p.MasterBracket = h.makeMasterBracket(in.Configs, p.n) - h.parameters[in.StudyId] = p - log.Printf("Smax = %v", p.sMax) - return &api.SetSuggestionParametersReply{}, nil -} - -func (h *HyperBandSuggestService) getHyperParameter(studyId string, sconf *api.StudyConfig, n int) Bracket { - s_t := make([]*api.Trial, n) - for i := 0; i < n; i++ { - s_t[i] = &api.Trial{} - s_t[i].ParameterSet = make([]*api.Parameter, len(sconf.ParameterConfigs.Configs)) - s_t[i].Status = api.TrialState_PENDING - s_t[i].EvalLogs = make([]*api.EvaluationLog, 0) - var j int - if sconf.OptimizationType == api.OptimizationType_MAXIMIZE { - j = i - } else if sconf.OptimizationType == api.OptimizationType_MINIMIZE { - j = len(h.parameters[studyId].MasterBracket) - 1 - i - } - for k, v := range h.parameters[studyId].MasterBracket[j].ParameterSet { - s_t[i].ParameterSet[k] = v - } - for _, t := range h.parameters[studyId].MasterBracket[j].Tags { - s_t[i].Tags = append(s_t[i].Tags, t) - } - } - return Bracket(s_t) -} -func (h *HyperBandSuggestService) hbLoopParamUpdate(studyId string) { - log.Printf("HB loop s = %v", h.parameters[studyId].currentS) - h.parameters[studyId].shloopitr = 0 - h.parameters[studyId].n = int((h.parameters[studyId].b_l/h.parameters[studyId].r_l)*(math.Pow(h.parameters[studyId].eta, float64(h.parameters[studyId].currentS))/float64(h.parameters[studyId].currentS+1))) + 1 - h.parameters[studyId].r = h.parameters[studyId].r_l * math.Pow(h.parameters[studyId].eta, float64(-h.parameters[studyId].currentS)) -} - -func (h *HyperBandSuggestService) shLoopParamUpdate(studyId string) (int, int) { - log.Printf("SH loop i = %v", h.parameters[studyId].shloopitr) - pn_i := int(float64(h.parameters[studyId].n) * math.Pow(h.parameters[studyId].eta, float64(-h.parameters[studyId].shloopitr+1)) / h.parameters[studyId].eta) - r_i := int(h.parameters[studyId].r * math.Pow(h.parameters[studyId].eta, float64(h.parameters[studyId].shloopitr))) - return pn_i, r_i -} - -func (h *HyperBandSuggestService) GenerateTrials(ctx context.Context, in *api.GenerateTrialsRequest) (*api.GenerateTrialsReply, error) { - if h.parameters[in.StudyId].currentS <= 0 { - h.StopSuggestion(ctx, &api.StopSuggestionRequest{StudyId: in.StudyId}) - return &api.GenerateTrialsReply{Completed: true}, nil - } - if len(in.RunningTrials) > 0 { - return &api.GenerateTrialsReply{Completed: false}, nil - } - if len(in.CompletedTrials) > 0 { - var schec int - var bid string - for _, c := range in.CompletedTrials { - schec = 0 - value, _ := h.dbIf.GetTrialLogs(c.TrialId, - &db.GetTrialLogOpts{Objective: true, Descending: true, Limit: 1}) - if len(value) != 1 { - log.Printf("objective value for %s not found", - c.TrialId) - continue - } - c.ObjectiveValue = value[0].Value - for _, t := range c.Tags { - if t.Name == "HyperBand_shi" && t.Value == strconv.Itoa(h.parameters[in.StudyId].shloopitr) { - schec++ - } - if t.Name == "HyperBand_s" && t.Value == strconv.Itoa(h.parameters[in.StudyId].currentS) { - schec++ - } - if t.Name == "HyperBand_BracketID" { - bid = t.Value - } - } - if schec == 2 { - for _, b := range h.parameters[in.StudyId].MasterBracket { - for _, t := range b.Tags { - if t.Name == "HyperBand_BracketID" && t.Value == bid { - b.ObjectiveValue = c.ObjectiveValue - } - } - } - } - } - sort.Sort(h.parameters[in.StudyId].MasterBracket) - } - var evalT []*api.Trial - var r_i int - if h.parameters[in.StudyId].shloopitr > h.parameters[in.StudyId].currentS { - h.parameters[in.StudyId].currentS-- - h.hbLoopParamUpdate(in.StudyId) - _, r_i = h.shLoopParamUpdate(in.StudyId) - h.parameters[in.StudyId].MasterBracket = h.makeMasterBracket(in.Configs, h.parameters[in.StudyId].n) - evalT = h.getHyperParameter(in.StudyId, in.Configs, h.parameters[in.StudyId].n) - h.parameters[in.StudyId].shloopitr++ - } else { - var pn_i int - pn_i, r_i = h.shLoopParamUpdate(in.StudyId) - evalT = h.getHyperParameter(in.StudyId, in.Configs, pn_i) - h.parameters[in.StudyId].shloopitr++ - } - for i := range evalT { - for j := range evalT[i].ParameterSet { - if evalT[i].ParameterSet[j].Name == h.parameters[in.StudyId].ResourceName { - evalT[i].ParameterSet[j].Value = strconv.Itoa(r_i) - } - } - evalT[i].Tags = append(evalT[i].Tags, &api.Tag{Name: "HyperBand_s", Value: strconv.Itoa(h.parameters[in.StudyId].currentS)}) - evalT[i].Tags = append(evalT[i].Tags, &api.Tag{Name: "HyperBand_r", Value: strconv.Itoa(r_i)}) - evalT[i].Tags = append(evalT[i].Tags, &api.Tag{Name: "HyperBand_shi", Value: strconv.Itoa(h.parameters[in.StudyId].shloopitr)}) - log.Printf("Gen Trial %v", evalT[i].Tags) - } - return &api.GenerateTrialsReply{Trials: evalT, Completed: false}, nil -} +// +//func (h *HyperBandSuggestService) generate_randid() string { +// // UUID isn't quite handy in the Go world +// id_ := make([]byte, 8) +// _, err := rand.Read(id_) +// if err != nil { +// log.Fatalf("Error reading random: %v", err) +// } +// return fmt.Sprintf("%016x", id_) +//} +// +//func (h *HyperBandSuggestService) makeMasterBracket(sconf *api.StudyConfig, n int) Bracket { +// log.Printf("Make MasterBracket %v Trials", n) +// s_t := make([]*api.Trial, n) +// for i := 0; i < n; i++ { +// s_t[i] = &api.Trial{} +// s_t[i].ParameterSet = make([]*api.Parameter, len(sconf.ParameterConfigs.Configs)) +// for j, pc := range sconf.ParameterConfigs.Configs { +// s_t[i].ParameterSet[j] = &api.Parameter{Name: pc.Name} +// s_t[i].ParameterSet[j].ParameterType = pc.ParameterType +// switch pc.ParameterType { +// case api.ParameterType_INT: +// imin, _ := strconv.Atoi(pc.Feasible.Min) +// imax, _ := strconv.Atoi(pc.Feasible.Max) +// s_t[i].ParameterSet[j].Value = strconv.Itoa(h.IntRandom(imin, imax)) +// case api.ParameterType_DOUBLE: +// dmin, _ := strconv.ParseFloat(pc.Feasible.Min, 64) +// dmax, _ := strconv.ParseFloat(pc.Feasible.Max, 64) +// s_t[i].ParameterSet[j].Value = strconv.FormatFloat(h.DoubelRandom(dmin, dmax), 'f', 4, 64) +// case api.ParameterType_CATEGORICAL: +// s_t[i].ParameterSet[j].Value = pc.Feasible.List[h.IntRandom(0, len(pc.Feasible.List)-1)] +// } +// } +// s_t[i].Tags = append(s_t[i].Tags, &api.Tag{Name: "HyperBand_BracketID", Value: h.generate_randid()}) +// } +// return Bracket(s_t) +//} +// +//func (h *HyperBandSuggestService) purseSuggestionParameters(sparam []*api.SuggestionParameters) (HyperBandParameters, error) { +// p := &HyperBandParameters{ +// eta: -1, +// sMax: -1, +// b_l: -1, +// r_l: -1, +// r: -1, +// n: -1, +// shloopitr: -1, +// currentS: -1, +// ResourceName: -1, +// } +// for _, sp := range sparam { +// switch sp.Name { +// case "Eta": +// p.eta, _ = strconv.ParseFloat(sp.Value, 64) +// case "R": +// p.r_l, _ = strconv.ParseFloat(sp.Value, 64) +// case "ResourceName": +// p.ResourceName = sp.Value +// case "b_l": +// p.b_l, _ = strconv.ParseFloat(sp.Value, 64) +// case "sMax": +// p.sMax, _ = strconv.AtoI(sp.Value) +// case "r_s": +// p.r, _ = strconv.ParseFloat(sp.Value, 64) +// case "n_s": +// p.n, _ = strconv.AtoI(sp.Value) +// case "shloopitr": +// p.shloopitr, _ = strconv.AtoI(sp.Value) +// case "currentS": +// p.currentS, _ = strconv.AtoI(sp.Value) +// default: +// log.Printf("Unknown Suggestion Parameter %v", sp.Name) +// } +// } +// if p.eta == 0 || p.r_l == 0 || p.ResourceName == "" { +// log.Printf("Failed to Suggestion Parameter set.") +// return &api.SetSuggestionParametersReply{}, fmt.Errorf("Suggestion Parameter set Error") +// } +// if p.sMax == -1 { +// p.sMax = int(math.Log(p.r_l) / math.Log(p.eta)) +// } +// if p.b_l == -1 { +// p.b_l = float64((p.sMax + 1.0)) * p.r_l +// } +// if p.n == -1 { +// p.n = int((p.b_l/p.r_l)*(math.Pow(p.eta, float64(p.sMax))/float64(p.sMax+1))) + 1 +// } +// if p.currentS == -1 { +// p.currentS = p.sMax + 1 +// } +// if p.shloopit == -1 { +// p.shloopitr = p.currentS + 1 +// } +// if p.r == -1 { +// p.r = p.r_l * math.Pow(p.eta, float64(-p.sMax)) +// } +// p.MasterBracket = h.makeMasterBracket(in.Configs, p.n) +// h.parameters[in.StudyId] = p +// log.Printf("Smax = %v", p.sMax) +// return &api.SetSuggestionParametersReply{}, nil +//} +// +//func (h *HyperBandSuggestService) getHyperParameter(studyId string, sconf *api.StudyConfig, n int) Bracket { +// s_t := make([]*api.Trial, n) +// for i := 0; i < n; i++ { +// s_t[i] = &api.Trial{} +// s_t[i].ParameterSet = make([]*api.Parameter, len(sconf.ParameterConfigs.Configs)) +// s_t[i].Status = api.TrialState_PENDING +// s_t[i].EvalLogs = make([]*api.EvaluationLog, 0) +// var j int +// if sconf.OptimizationType == api.OptimizationType_MAXIMIZE { +// j = i +// } else if sconf.OptimizationType == api.OptimizationType_MINIMIZE { +// j = len(h.parameters[studyId].MasterBracket) - 1 - i +// } +// for k, v := range h.parameters[studyId].MasterBracket[j].ParameterSet { +// s_t[i].ParameterSet[k] = v +// } +// for _, t := range h.parameters[studyId].MasterBracket[j].Tags { +// s_t[i].Tags = append(s_t[i].Tags, t) +// } +// } +// return Bracket(s_t) +//} +// +//func (h *HyperBandSuggestService) hbLoopParamUpdate(studyId string) { +// log.Printf("HB loop s = %v", h.parameters[studyId].currentS) +// h.parameters[studyId].shloopitr = 0 +// h.parameters[studyId].n = int((h.parameters[studyId].b_l/h.parameters[studyId].r_l)*(math.Pow(h.parameters[studyId].eta, float64(h.parameters[studyId].currentS))/float64(h.parameters[studyId].currentS+1))) + 1 +// h.parameters[studyId].r = h.parameters[studyId].r_l * math.Pow(h.parameters[studyId].eta, float64(-h.parameters[studyId].currentS)) +//} +// +//func (h *HyperBandSuggestService) shLoopParamUpdate(studyId string) (int, int) { +// log.Printf("SH loop i = %v", h.parameters[studyId].shloopitr) +// pn_i := int(float64(h.parameters[studyId].n) * math.Pow(h.parameters[studyId].eta, float64(-h.parameters[studyId].shloopitr+1)) / h.parameters[studyId].eta) +// r_i := int(h.parameters[studyId].r * math.Pow(h.parameters[studyId].eta, float64(h.parameters[studyId].shloopitr))) +// return pn_i, r_i +//} +// +//func (h *HyperBandSuggestService) makeBracker(ctx context.Context, cl *api.ManagerClient, sid string, logs []string) (Bracket, error) { +// req := &api.GetWorkersRequest{StudyId: sid} +// r, err := api.GetWorkers(ctx, req) +// if err != nil { +// return nil, err +// } +// mreq := &api.GetMetrics{ +// StudyId: sid, +// WorkerId: logs, +// MetricsNames: []string{h.ResourceName}, +// } +// mr, err := api.GetMetrics(ctx, mreq) +// if err != nil { +// return nil, err +// } +// e_l := make([]Evals, len(logs)) +// for i, l := range logs { +// for _, m := range mr.MetricsLogs { +// if m.WorkerId == l { +// if len(m.MetricsLogs) == 0 { +// break +// } +// e_l[i].Value = strconv.ParseFloat(m.MetricsLogs[len(m.MetricsLogs)-1].Value, 64) +// } +// } +// for _, w := range r.Workers { +// if w.WorkerId == l { +// e_l[i].Id = w.TrialId +// } +// } +// } +// return Bracket(e_l) +//} -func (h *HyperBandSuggestService) StopSuggestion(ctx context.Context, in *api.StopSuggestionRequest) (*api.StopSuggestionReply, error) { - delete(h.parameters, in.StudyId) - return &api.StopSuggestionReply{}, nil +func (h *HyperBandSuggestService) GetSuggestions(ctx context.Context, in *api.GetSuggestionsRequest) (*api.GetSuggestionsReply, error) { + return &api.GetSuggestionsReply{}, nil + // conn, err := grpc.Dial(manager, grpc.WithInsecure()) + // if err != nil { + // log.Fatalf("could not connect: %v", err) + // return + // } + // defer conn.Close() + // c := api.NewManagerClient(conn) + // screq := &api.GetStudyRequest{ + // StudyId: in.StudyId, + // } + // scr, err := GetStudy(ctx, screq) + // if err != nil { + // log.Fatalf("GetStudyConf failed: %v", err) + // return &api.GetSuggestionsReply{}, err + // } + // spreq := &api.GetSuggestionParametersRequest{ + // StudyId: in.StudyId, + // SuggestionAlgorithm: in.SuggestionAlgorithm, + // } + // spr, err := c.GetSuggestionParameters(ctx, spreq) + // if err != nil { + // log.Fatalf("GetParameter failed: %v", err) + // return &api.GetSuggestionsReply{}, err + // } + // hp, err := h.purseSuggestionParameters(spr.SuggestionParameters) + // if err != nil { + // return &api.GetSuggestionsReply{}, err + // } + // + // if hp.currentS <= 0 { + // return &api.GetSuggestionsReply{}, nil + // } + // + // if len(in.LogWorkerIds) > 0 { + // + // var schec int + // var bid string + // for _, c := range in.CompletedTrials { + // schec = 0 + // value, _ := h.dbIf.GetTrialLogs(c.TrialId, + // &db.GetTrialLogOpts{Objective: true, Descending: true, Limit: 1}) + // if len(value) != 1 { + // log.Printf("objective value for %s not found", + // c.TrialId) + // continue + // } + // c.ObjectiveValue = value[0].Value + // for _, t := range c.Tags { + // if t.Name == "HyperBand_shi" && t.Value == strconv.Itoa(h.parameters[in.StudyId].shloopitr) { + // schec++ + // } + // if t.Name == "HyperBand_s" && t.Value == strconv.Itoa(h.parameters[in.StudyId].currentS) { + // schec++ + // } + // if t.Name == "HyperBand_BracketID" { + // bid = t.Value + // } + // } + // if schec == 2 { + // for _, b := range h.parameters[in.StudyId].MasterBracket { + // for _, t := range b.Tags { + // if t.Name == "HyperBand_BracketID" && t.Value == bid { + // b.ObjectiveValue = c.ObjectiveValue + // } + // } + // } + // } + // } + // sort.Sort(h.parameters[in.StudyId].MasterBracket) + // } + // var evalT []*api.Trial + // var r_i int + // if h.parameters.shloopitr > h.parameters.currentS { + // h.parameters.currentS-- + // h.hbLoopParamUpdate(in.StudyId) + // _, r_i = h.shLoopParamUpdate(in.StudyId) + // h.parameters.MasterBracket = h.makeMasterBracket(in.Configs, h.parameters.n) + // evalT = h.getHyperParameter(in.StudyId, in.Configs, h.parameters.n) + // h.parameters.shloopitr++ + // } else { + // var pn_i int + // pn_i, r_i = h.shLoopParamUpdate(in.StudyId) + // evalT = h.getHyperParameter(in.StudyId, in.Configs, pn_i) + // h.parameters.shloopitr++ + // } + // for i := range evalT { + // for j := range evalT[i].ParameterSet { + // if evalT[i].ParameterSet[j].Name == h.parameters.ResourceName { + // evalT[i].ParameterSet[j].Value = strconv.Itoa(r_i) + // } + // } + // evalT[i].Tags = append(evalT[i].Tags, &api.Tag{Name: "HyperBand_s", Value: strconv.Itoa(h.parameters.currentS)}) + // evalT[i].Tags = append(evalT[i].Tags, &api.Tag{Name: "HyperBand_r", Value: strconv.Itoa(r_i)}) + // evalT[i].Tags = append(evalT[i].Tags, &api.Tag{Name: "HyperBand_shi", Value: strconv.Itoa(h.parameters.shloopitr)}) + // log.Printf("Gen Trial %v", evalT[i].Tags) + // } + // return &api.GenerateTrialsReply{Trials: evalT, Completed: false}, nil } diff --git a/pkg/suggestion/random_service.go b/pkg/suggestion/random_service.go index e4096da5022..b0ac9f5733c 100644 --- a/pkg/suggestion/random_service.go +++ b/pkg/suggestion/random_service.go @@ -8,19 +8,14 @@ import ( "time" "github.com/kubeflow/katib/pkg/api" + "google.golang.org/grpc" ) -type RandomSuggestParameters struct { - SuggestionNum int - MaxParallel int -} - type RandomSuggestService struct { - parameters map[string]*RandomSuggestParameters } func NewRandomSuggestService() *RandomSuggestService { - return &RandomSuggestService{parameters: make(map[string]*RandomSuggestParameters)} + return &RandomSuggestService{} } func (s *RandomSuggestService) DoubelRandom(min, max float64) float64 { @@ -36,52 +31,30 @@ func (s *RandomSuggestService) IntRandom(min, max int) int { return rand.Intn(max-min+1) + min } -func (s *RandomSuggestService) SetSuggestionParameters(ctx context.Context, in *api.SetSuggestionParametersRequest) (*api.SetSuggestionParametersReply, error) { - p := &RandomSuggestParameters{} - for _, sp := range in.SuggestionParameters { - switch sp.Name { - case "SuggestionNum": - p.SuggestionNum, _ = strconv.Atoi(sp.Value) - case "MaxParallel": - p.MaxParallel, _ = strconv.Atoi(sp.Value) - default: - log.Printf("Unknown Suggestion Parameter %v", sp.Name) - } - } - s.parameters[in.StudyId] = p - return &api.SetSuggestionParametersReply{}, nil -} - -func (s *RandomSuggestService) GenerateTrials(ctx context.Context, in *api.GenerateTrialsRequest) (*api.GenerateTrialsReply, error) { - if len(in.CompletedTrials) >= s.parameters[in.StudyId].SuggestionNum { - s.StopSuggestion(ctx, &api.StopSuggestionRequest{StudyId: in.StudyId}) - return &api.GenerateTrialsReply{Completed: true}, nil +func (s *RandomSuggestService) GetSuggestions(ctx context.Context, in *api.GetSuggestionsRequest) (*api.GetSuggestionsReply, error) { + conn, err := grpc.Dial(manager, grpc.WithInsecure()) + if err != nil { + log.Fatalf("could not connect: %v", err) + return &api.GetSuggestionsReply{}, err } - if s.parameters[in.StudyId].MaxParallel < 1 && len(in.RunningTrials) > 0 { - return &api.GenerateTrialsReply{Completed: false}, nil - } else { - if len(in.RunningTrials) >= s.parameters[in.StudyId].MaxParallel { - return &api.GenerateTrialsReply{Completed: false}, nil - } - if s.parameters[in.StudyId].SuggestionNum-len(in.CompletedTrials)-len(in.RunningTrials) <= 0 { - return &api.GenerateTrialsReply{Completed: false}, nil - } + defer conn.Close() + c := api.NewManagerClient(conn) + screq := &api.GetStudyRequest{ + StudyId: in.StudyId, } - var reqnum int = 0 - if s.parameters[in.StudyId].MaxParallel < 1 { - reqnum = s.parameters[in.StudyId].SuggestionNum - } else if s.parameters[in.StudyId].SuggestionNum-len(in.CompletedTrials) <= s.parameters[in.StudyId].MaxParallel { - reqnum = s.parameters[in.StudyId].SuggestionNum - len(in.CompletedTrials) - len(in.RunningTrials) - } else { - reqnum = s.parameters[in.StudyId].MaxParallel - len(in.RunningTrials) + scr, err := c.GetStudy(ctx, screq) + if err != nil { + log.Fatalf("GetStudyConf failed: %v", err) + return &api.GetSuggestionsReply{}, err } + reqnum := int(in.RequestNumber) s_t := make([]*api.Trial, reqnum) for i := 0; i < reqnum; i++ { s_t[i] = &api.Trial{} - s_t[i].ParameterSet = make([]*api.Parameter, len(in.Configs.ParameterConfigs.Configs)) - s_t[i].Status = api.TrialState_PENDING - s_t[i].EvalLogs = make([]*api.EvaluationLog, 0) - for j, pc := range in.Configs.ParameterConfigs.Configs { + s_t[i].StudyId = in.StudyId + s_t[i].ParameterSet = make([]*api.Parameter, len(scr.StudyConfig.ParameterConfigs.Configs)) + s_t[i].Status = api.State_PENDING + for j, pc := range scr.StudyConfig.ParameterConfigs.Configs { s_t[i].ParameterSet[j] = &api.Parameter{Name: pc.Name} s_t[i].ParameterSet[j].ParameterType = pc.ParameterType switch pc.ParameterType { @@ -98,10 +71,5 @@ func (s *RandomSuggestService) GenerateTrials(ctx context.Context, in *api.Gener } } } - return &api.GenerateTrialsReply{Trials: s_t, Completed: false}, nil -} - -func (s *RandomSuggestService) StopSuggestion(ctx context.Context, in *api.StopSuggestionRequest) (*api.StopSuggestionReply, error) { - delete(s.parameters, in.StudyId) - return &api.StopSuggestionReply{}, nil + return &api.GetSuggestionsReply{Trials: s_t}, nil } diff --git a/pkg/suggestion/types.go b/pkg/suggestion/types.go index 3187e92800d..c7c8adfa7fc 100644 --- a/pkg/suggestion/types.go +++ b/pkg/suggestion/types.go @@ -9,10 +9,10 @@ import ( const ( // DefaultPort is the port to serve the suggestion service. DefaultPort = "0.0.0.0:6789" + manager = "vizier-core:6789" ) // SuggestService is the interface for suggestion service. type SuggestService interface { - SetSuggestionParameters(ctx context.Context, in *api.SetSuggestionParametersRequest) (*api.SetSuggestionParametersReply, error) - GenerateTrials(ctx context.Context, in *api.GenerateTrialsRequest) (*api.GenerateTrialsReply, error) + GetSuggestions(ctx context.Context, in *api.GetSuggestionsRequest) (*api.GetSuggestionsReply, error) } diff --git a/scripts/build.sh b/scripts/build.sh index 888cbceb18a..c81b326e37e 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -31,18 +31,15 @@ docker build -t ${PREFIX}/vizier-core -f ${CMD_PREFIX}/manager/Dockerfile . echo "Building suggestion images..." docker build -t ${PREFIX}/suggestion-random -f ${CMD_PREFIX}/suggestion/random/Dockerfile . docker build -t ${PREFIX}/suggestion-grid -f ${CMD_PREFIX}/suggestion/grid/Dockerfile . -docker build -t ${PREFIX}/suggestion-hyperband -f ${CMD_PREFIX}/suggestion/hyperband/Dockerfile . -docker build -t ${PREFIX}/suggestion-bayesianoptimization -f ${CMD_PREFIX}/suggestion/bayesianoptimization/Dockerfile . +#docker build -t ${PREFIX}/suggestion-hyperband -f ${CMD_PREFIX}/suggestion/hyperband/Dockerfile . +#docker build -t ${PREFIX}/suggestion-bayesianoptimization -f ${CMD_PREFIX}/suggestion/bayesianoptimization/Dockerfile . echo "Building earlystopping images..." docker build -t ${PREFIX}/earlystopping-medianstopping -f ${CMD_PREFIX}/earlystopping/medianstopping/Dockerfile . -echo "Building dlk manager image..." -docker build -t ${PREFIX}/dlk-manager -f dlk/Dockerfile . - echo "Building UI image..." docker build -t ${PREFIX}/katib-frontend -f modeldb/Dockerfile . -echo "Building CLI image..." -docker build -t ${PREFIX}/katib-cli -f ${CMD_PREFIX}/cli/Dockerfile . +#echo "Building CLI image..." +#docker build -t ${PREFIX}/katib-cli -f ${CMD_PREFIX}/cli/Dockerfile . cd - > /dev/null From 4cfe906f9e6eab154887738bd48742c2bfd00371 Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Fri, 27 Apr 2018 10:37:47 +0900 Subject: [PATCH 02/15] add cli Signed-off-by: YujiOshima --- cmd/cli/get-model.go | 80 ++++--------- cmd/cli/get-study.go | 8 +- cmd/cli/pull-study.go | 105 ++++++++++++++++++ cmd/cli/pull.go | 19 ++++ cmd/cli/push-model.go | 22 ++-- cmd/cli/push-study.go | 66 ++++++----- cmd/cli/push.go | 1 - cmd/cli/root.go | 1 + cmd/cli/stop-study.go | 21 ++-- cmd/cli/type.go | 10 ++ cmd/manager/main.go | 8 +- ...suggest-demo.go => random-suggest-demo.go} | 0 12 files changed, 223 insertions(+), 118 deletions(-) create mode 100644 cmd/cli/pull-study.go create mode 100644 cmd/cli/pull.go create mode 100644 cmd/cli/type.go rename docs/MinikubeDemo/{radom-suggest-demo.go => random-suggest-demo.go} (100%) diff --git a/cmd/cli/get-model.go b/cmd/cli/get-model.go index 8b8e49ba0ca..8911d3dcd10 100644 --- a/cmd/cli/get-model.go +++ b/cmd/cli/get-model.go @@ -52,68 +52,28 @@ func getModel(cmd *cobra.Command, opt *getModelOpt) { return } defer conn.Close() - var soverviews []*api.StudyOverview c := api.NewManagerClient(conn) // Search study if Study ID or name is set - if len(opt.args) > 0 { - // Search specified study in running studies - req := &api.GetStudiesRequest{} - r, err := c.GetStudies(context.Background(), req) - if err != nil { - log.Fatalf("GetStudy failed: %v", err) - return - } - if len(r.StudyInfos) > 0 { - for _, si := range r.StudyInfos { - if len(opt.args) > 0 { - if utf8.RuneCountInString(opt.args[0]) >= 7 { - if strings.HasPrefix(si.StudyId, opt.args[0]) { - soverviews = append(soverviews, &api.StudyOverview{ - Name: si.Name, - Owner: si.Owner, - }) - break - } - } - if si.Name == opt.args[0] { - soverviews = append(soverviews, &api.StudyOverview{ - Name: si.Name, - Owner: si.Owner, - }) - break - } - } else { - soverviews = append(soverviews, &api.StudyOverview{ - Name: si.Name, - Owner: si.Owner, - }) - } - } - } + req := &api.GetStudyListRequest{} + r, err := c.GetStudyList(context.Background(), req) + if err != nil { + log.Fatalf("GetModels failed: %v", err) } - if len(soverviews) == 0 { - // Search specified study from ModelDB - sreq := &api.GetSavedStudiesRequest{} - sr, err := c.GetSavedStudies(context.Background(), sreq) - if err != nil { - log.Fatalf("GetStudy failed: %v", err) - return - } - if len(sr.Studies) == 0 { - log.Fatalf("No Studies are saved.") - return - } - for _, s := range sr.Studies { - if len(opt.args) > 0 { - if opt.args[0] == s.Name { - soverviews = append(soverviews, s) + if len(r.StudyOverviews) == 0 { + log.Println("No Study fond") + return + } + for _, si := range r.StudyOverviews { + if len(opt.args) > 0 { + if utf8.RuneCountInString(opt.args[0]) >= 7 { + if !strings.HasPrefix(si.Id, opt.args[0]) { + break } - } else { - soverviews = append(soverviews, s) + } + if si.Name != opt.args[0] { + break } } - } - for _, si := range soverviews { // Search Models from ModelDB mreq := &api.GetSavedModelsRequest{StudyName: si.Name} mr, err := c.GetSavedModels(context.Background(), mreq) @@ -127,11 +87,11 @@ func getModel(cmd *cobra.Command, opt *getModelOpt) { if opt.detail { for _, m := range mr.Models { if len(opt.args) > 1 { - if !strings.HasPrefix(m.TrialId, opt.args[1]) { + if !strings.HasPrefix(m.WorkerId, opt.args[1]) { continue } } - fmt.Printf("TrialID :%v\n", m.TrialId) + fmt.Printf("WorkerID :%v\n", m.WorkerId) fmt.Printf("Model Path: %s\n", m.ModelPath) fmt.Println("Parameters:") for _, p := range m.Parameters { @@ -148,12 +108,12 @@ func getModel(cmd *cobra.Command, opt *getModelOpt) { fmt.Fprintln(w, "TrialID\tParamNum\tMetricsNum") for _, m := range mr.Models { if len(opt.args) > 1 { - if !strings.HasPrefix(m.TrialId, opt.args[1]) { + if !strings.HasPrefix(m.WorkerId, opt.args[1]) { continue } } fmt.Fprintf(w, "%s\t%d\t%d\n", - string([]rune(m.TrialId)[:7]), + string([]rune(m.WorkerId)[:7]), len(m.Parameters), len(m.Metrics), ) diff --git a/cmd/cli/get-study.go b/cmd/cli/get-study.go index 50f4b04cb4b..b4e7b3e3481 100644 --- a/cmd/cli/get-study.go +++ b/cmd/cli/get-study.go @@ -50,12 +50,12 @@ func getStudy(cmd *cobra.Command, args []string) { log.Fatalf("GetStudy failed: %v", err) return } - result = []*api.StudyOverviews{} + result := []*api.StudyOverview{} // Search study if Study ID or name is set if len(args) > 0 { for _, si := range r.StudyOverviews { if utf8.RuneCountInString(args[0]) >= 7 { - if strings.HasPrefix(si.StudyId, args[0]) { + if strings.HasPrefix(si.Id, args[0]) { result = append(result, si) break } @@ -72,8 +72,8 @@ func getStudy(cmd *cobra.Command, args []string) { w.Init(os.Stdout, 0, 8, 0, '\t', tabwriter.TabIndent) fmt.Fprintln(w, "StudyID\tName\tOwner") for _, si := range result { - fmt.Fprintf(w, "%s\t%s\t%sn", - string([]rune(si.StudyId)[:7]), + fmt.Fprintf(w, "%s\t%s\t%s\n", + string([]rune(si.Id)[:7]), si.Name, si.Owner, ) diff --git a/cmd/cli/pull-study.go b/cmd/cli/pull-study.go new file mode 100644 index 00000000000..0b70505863d --- /dev/null +++ b/cmd/cli/pull-study.go @@ -0,0 +1,105 @@ +package main + +import ( + "context" + "fmt" + "io/ioutil" + "log" + "os" + "strings" + "unicode/utf8" + + "github.com/kubeflow/katib/pkg/api" + "github.com/spf13/cobra" + "google.golang.org/grpc" + yaml "gopkg.in/yaml.v2" +) + +type pullStudyOpt struct { + outfile string + args []string +} + +//NewCommandPullStudy generate pull studies cmd +func NewCommandPullStudy() *cobra.Command { + var opt pullStudyOpt + cmd := &cobra.Command{ + Use: "studies", + Args: cobra.ExactArgs(1), + Short: "Export a Study and its Models lnfo", + Long: `Export Information of a Study and its Models to yaml format`, + Run: func(cmd *cobra.Command, args []string) { + opt.args = args + pullStudy(cmd, &opt) + }, + Aliases: []string{"st"}, + } + cmd.Flags().StringVarP(&opt.outfile, "output", "o", "", "File path to export") + return cmd +} + +func pullStudy(cmd *cobra.Command, opt *pullStudyOpt) { + //check and get persistent flag volume + var pf *PersistentFlags + pf, err := CheckPersistentFlags() + if err != nil { + log.Fatalf("Fail to Check Flags: %v", err) + } + conn, err := grpc.Dial(pf.server, grpc.WithInsecure()) + if err != nil { + log.Fatalf("could not connect: %v", err) + } + defer conn.Close() + + c := api.NewManagerClient(conn) + listreq := &api.GetStudyListRequest{} + listr, err := c.GetStudyList(context.Background(), listreq) + if err != nil { + log.Fatalf("GetStudy failed: %v", err) + return + } + studyId := "" + // Search study by Study ID or name + for _, si := range listr.StudyOverviews { + if utf8.RuneCountInString(opt.args[0]) >= 7 { + if strings.HasPrefix(si.Id, opt.args[0]) { + studyId = si.Id + break + } + } + if si.Name == opt.args[0] { + studyId = si.Id + break + } + } + if studyId == "" { + log.Fatalf("Study %s is not found", opt.args[0]) + } + req := &api.GetStudyRequest{ + StudyId: studyId, + } + r, err := c.GetStudy(context.Background(), req) + if err != nil { + log.Fatalf("GetStudy failed: %v", err) + } + mreq := &api.GetSavedModelsRequest{ + StudyName: r.StudyConfig.Name, + } + mr, err := c.GetSavedModels(context.Background(), mreq) + if err != nil { + log.Fatalf("GetModel failed: %v", err) + } + sd := StudyData{ + StudyConf: r.StudyConfig, + Models: mr.Models, + } + yst, err := yaml.Marshal(sd) + if err != nil { + log.Fatalf("Failed to Marshal: %v", err) + } + if opt.outfile != "" { + ioutil.WriteFile(opt.outfile, yst, os.ModePerm) + } else { + fmt.Println(string(yst)) + } +} diff --git a/cmd/cli/pull.go b/cmd/cli/pull.go new file mode 100644 index 00000000000..bc561760a6b --- /dev/null +++ b/cmd/cli/pull.go @@ -0,0 +1,19 @@ +package main + +import ( + "github.com/spf13/cobra" +) + +//NewCommandPull generate run cmd +func NewCommandPull() *cobra.Command { + cmd := &cobra.Command{ + Use: "pull", + Short: "Pull a resource from a file or from stdin.", + Long: `YAML or JSON formats are accepted.`, + } + + cmd.AddCommand(NewCommandPullStudy()) + // cmd.AddCommand(NewCommandPullModel()) + + return cmd +} diff --git a/cmd/cli/push-model.go b/cmd/cli/push-model.go index 73abdc3cc17..31c0d570d1e 100644 --- a/cmd/cli/push-model.go +++ b/cmd/cli/push-model.go @@ -14,7 +14,7 @@ import ( ) type pushModelOpt struct { - conf string + file string args []string } @@ -26,13 +26,13 @@ func NewCommandPushModel() *cobra.Command { Args: cobra.MaximumNArgs(1), Short: "Push a model Info from a file or from stdin", Long: "YAML or JSON formats are accepted.", - Aliases: []string{"st"}, + Aliases: []string{"md"}, Run: func(cmd *cobra.Command, args []string) { opt.args = args pushModel(cmd, &opt) }, } - cmd.Flags().StringVarP(&opt.conf, "config", "f", "", "File path of study config") + cmd.Flags().StringVarP(&opt.file, "file", "f", "", "File path of model config file") return cmd } @@ -44,9 +44,9 @@ func pushModel(cmd *cobra.Command, opt *pushModelOpt) { log.Fatalf("Fail to Check Flags: %v", err) return } - var req api.SaveModelRequest - if opt.conf != "" { - buf, _ := ioutil.ReadFile(opt.conf) + var req []*api.SaveModelRequest + if opt.file != "" { + buf, _ := ioutil.ReadFile(opt.file) err = yaml.Unmarshal(buf, &req) if err != nil { log.Fatalf("Fail to Purse config: %v", err) @@ -70,9 +70,11 @@ func pushModel(cmd *cobra.Command, opt *pushModelOpt) { } defer conn.Close() c := api.NewManagerClient(conn) - _, err = c.SaveModel(context.Background(), &req) - if err != nil { - log.Fatalf("PushModel failed: %v", err) + for _, m := range req { + _, err = c.SaveModel(context.Background(), m) + if err != nil { + log.Fatalf("PushModel failed: %v", err) + } + fmt.Printf("Model %v is Pushed.\n", m.Model.WorkerId) } - fmt.Printf("Model %v is Pushed.\n", req.Model.TrialId) } diff --git a/cmd/cli/push-study.go b/cmd/cli/push-study.go index 2027b807242..1a5a25ffc35 100644 --- a/cmd/cli/push-study.go +++ b/cmd/cli/push-study.go @@ -2,6 +2,7 @@ package main import ( "context" + "encoding/json" "fmt" "io/ioutil" "log" @@ -13,31 +14,25 @@ import ( ) type pushStudyOpt struct { - conf string - name string - owner string - desc string - args []string + file string + args []string } -//NewCommandPushStudy generate push study cmd +//NewCommandPushStudy generate push model cmd func NewCommandPushStudy() *cobra.Command { var opt pushStudyOpt cmd := &cobra.Command{ - Use: "study", - Args: cobra.NoArgs, - Short: "Push a study Info from a file or from option", - Long: "YAML or JSON formats are accepted.", + Use: "model", + Args: cobra.MaximumNArgs(1), + Short: "Push a Study Info and its Models from a file or from stdin", + Long: "Push a Study Info and its Models from a file or from stdin\nYAML formats are accepted.", Aliases: []string{"st"}, Run: func(cmd *cobra.Command, args []string) { opt.args = args pushStudy(cmd, &opt) }, } - cmd.Flags().StringVarP(&opt.conf, "config", "f", "", "File path of study config") - cmd.Flags().StringVarP(&opt.name, "name", "n", "", "Study name") - cmd.Flags().StringVarP(&opt.owner, "owner", "o", "Anonymous", "Study owner name") - cmd.Flags().StringVarP(&opt.desc, "description", "d", "Anonymous", "Description of Study") + cmd.Flags().StringVarP(&opt.file, "file", "f", "", "File path of model config file") return cmd } @@ -49,22 +44,21 @@ func pushStudy(cmd *cobra.Command, opt *pushStudyOpt) { log.Fatalf("Fail to Check Flags: %v", err) return } - var so api.SaveStudyRequest - if opt.conf != "" { - var sc api.StudyConfig - buf, _ := ioutil.ReadFile(opt.conf) - err = yaml.Unmarshal(buf, &sc) + var in StudyData + + if opt.file != "" { + buf, _ := ioutil.ReadFile(opt.file) + err = yaml.Unmarshal(buf, &in) if err != nil { log.Fatalf("Fail to Purse config: %v", err) return } - so.StudyName = sc.Name - so.Owner = sc.Owner - so.Description = opt.desc - } else if opt.name != "" { - so.StudyName = opt.name - so.Owner = opt.owner - so.Description = opt.desc + } else if len(opt.args) > 0 { + err := json.Unmarshal(([]byte)(opt.args[0]), &in) + if err != nil { + log.Fatalf("Fail to Purse input: %v", err) + return + } } else { log.Fatalf("You shoud specify study config from a file or options: %v", err) return @@ -77,9 +71,23 @@ func pushStudy(cmd *cobra.Command, opt *pushStudyOpt) { } defer conn.Close() c := api.NewManagerClient(conn) - _, err = c.SaveStudy(context.Background(), &so) + sreq := &api.CreateStudyRequest{ + StudyConfig: in.StudyConf, + } + sr, err := c.CreateStudy(context.Background(), sreq) if err != nil { - log.Fatalf("PushStudy failed: %v", err) + log.Fatalf("CreateStudy failed: %v", err) + } + + for _, m := range in.Models { + req := &api.SaveModelRequest{ + Model: m, + } + _, err = c.SaveModel(context.Background(), req) + if err != nil { + log.Fatalf("PushModel failed: %v", err) + } + fmt.Printf("Model %v is Pushed.\n", m.WorkerId) } - fmt.Printf("Study %v is Pushed.\n", so.StudyName) + fmt.Printf("Study %s is Pushd. ID: %s", in.StudyConf.Name, sr.StudyId) } diff --git a/cmd/cli/push.go b/cmd/cli/push.go index b15cff65439..13eda3990f4 100644 --- a/cmd/cli/push.go +++ b/cmd/cli/push.go @@ -13,7 +13,6 @@ func NewCommandPush() *cobra.Command { } cmd.AddCommand(NewCommandPushStudy()) - cmd.AddCommand(NewCommandPushModel()) return cmd } diff --git a/cmd/cli/root.go b/cmd/cli/root.go index 03a70da3bc2..e84212c7b37 100644 --- a/cmd/cli/root.go +++ b/cmd/cli/root.go @@ -29,6 +29,7 @@ func NewRootCommand() *cobra.Command { cmd.AddCommand(NewCommandGet()) cmd.AddCommand(NewCommandStop()) cmd.AddCommand(NewCommandPush()) + cmd.AddCommand(NewCommandPull()) // cmd.AddCommand(NewCommandModel()) diff --git a/cmd/cli/stop-study.go b/cmd/cli/stop-study.go index 953d5608614..cf639f87a48 100644 --- a/cmd/cli/stop-study.go +++ b/cmd/cli/stop-study.go @@ -41,35 +41,34 @@ func stopStudy(cmd *cobra.Command, args []string) { } defer conn.Close() c := api.NewManagerClient(conn) - req := &api.GetStudiesRequest{} - r, err := c.GetStudies(context.Background(), req) + req := &api.GetStudyListRequest{} + r, err := c.GetStudyList(context.Background(), req) if err != nil { log.Fatalf("StopStudy failed: %v", err) return } - var sInfo *api.StudyInfo - for _, si := range r.StudyInfos { + var sov *api.StudyOverview + for _, si := range r.StudyOverviews { if utf8.RuneCountInString(args[0]) >= 7 { - if strings.HasPrefix(si.StudyId, args[0]) { - sInfo = si + if strings.HasPrefix(si.Id, args[0]) { + sov = si break } } if si.Name == args[0] { - sInfo = si + sov = si break } } - if sInfo == nil { + if sov == nil { log.Fatalf("Study %s is not found.", args[0]) return } - - sreq := &api.StopStudyRequest{StudyId: sInfo.StudyId} + sreq := &api.StopStudyRequest{StudyId: sov.Id} _, err = c.StopStudy(context.Background(), sreq) if err != nil { log.Fatalf("StopStudy failed: %v", err) } - fmt.Printf("Study %v has been stopped.\n", sInfo.StudyId) + fmt.Printf("Study %v has been stopped.\n", sov.Id) } diff --git a/cmd/cli/type.go b/cmd/cli/type.go new file mode 100644 index 00000000000..b2290f1b47f --- /dev/null +++ b/cmd/cli/type.go @@ -0,0 +1,10 @@ +package main + +import ( + "github.com/kubeflow/katib/pkg/api" +) + +type StudyData struct { + StudyConf *api.StudyConfig + Models []*api.ModelInfo +} diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 25500a46305..16648f2099b 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -72,9 +72,11 @@ func (s *server) GetStudyList(ctx context.Context, in *pb.GetStudyListRequest) ( if err != nil { return &pb.GetStudyListReply{}, err } - result[i].Name = sc.Name - result[i].Owner = sc.Owner - result[i].Id = id + result[i] = &pb.StudyOverview{ + Name: sc.Name, + Owner: sc.Owner, + Id: id, + } } return &pb.GetStudyListReply{StudyOverviews: result}, err } diff --git a/docs/MinikubeDemo/radom-suggest-demo.go b/docs/MinikubeDemo/random-suggest-demo.go similarity index 100% rename from docs/MinikubeDemo/radom-suggest-demo.go rename to docs/MinikubeDemo/random-suggest-demo.go From 0bb6d59c1a5a057ad6d77d4ef77dcfe78add308b Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Fri, 27 Apr 2018 12:41:19 +0900 Subject: [PATCH 03/15] add gird demo Signed-off-by: YujiOshima --- cmd/manager/main.go | 3 - docs/MinikubeDemo/MinikubeDemo.md | 10 ++ docs/MinikubeDemo/deploy.sh | 1 + docs/MinikubeDemo/grid-suggest-demo.go | 201 +++++++++++++++++++++++ docs/MinikubeDemo/random-suggest-demo.go | 4 +- pkg/db/interface.go | 2 +- pkg/suggestion/grid_service.go | 8 +- 7 files changed, 220 insertions(+), 9 deletions(-) create mode 100644 docs/MinikubeDemo/grid-suggest-demo.go diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 16648f2099b..d5676f174f2 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -173,7 +173,6 @@ func (s *server) GetMetrics(ctx context.Context, in *pb.GetMetricsRequest) (*pb. mNames = in.MetricsNames } else { sc, err := dbIf.GetStudyConfig(in.StudyId) - log.Printf("dbIf.GetStudyConfig(in.StudyId) %v", err) if err != nil { return &pb.GetMetricsReply{}, err } @@ -182,7 +181,6 @@ func (s *server) GetMetrics(ctx context.Context, in *pb.GetMetricsRequest) (*pb. err := s.wIF.UpdateWorkerStatus(in.StudyId) if err != nil { return &pb.GetMetricsReply{}, err - log.Printf("s.wIF.UpdateWorkerStatus(in.StudyId)%v", err) } mls := make([]*pb.MetricsLogSet, len(in.WorkerIds)) for i, w := range in.WorkerIds { @@ -192,7 +190,6 @@ func (s *server) GetMetrics(ctx context.Context, in *pb.GetMetricsRequest) (*pb. } for j, m := range mNames { ls, err := dbIf.GetWorkerLogs(w, &kdb.GetWorkerLogOpts{Name: m}) - log.Printf("dbIf.GetWorkerLogs(w, &kdb.GetWorkerLogOpts{Name: m}) %v", err) if err != nil { return &pb.GetMetricsReply{}, err } diff --git a/docs/MinikubeDemo/MinikubeDemo.md b/docs/MinikubeDemo/MinikubeDemo.md index 15ab7b4cfb4..ffd33e6f43e 100644 --- a/docs/MinikubeDemo/MinikubeDemo.md +++ b/docs/MinikubeDemo/MinikubeDemo.md @@ -12,9 +12,12 @@ You don't worry if the `vizier-core` get an error. It will be recovered after DB Wait until all components are Running status. ## Create Study +### Random Suggestion Demo +You can run rundom suggesiton demo. ``` go run radom-suggest-demo.go ``` +In this demo, 2 random learning rate parameters generated randomly between Min 0.03 and Max 0.07. Logs ``` 2018/04/26 17:43:26 Study ID n9debe3de9ef67c8 @@ -24,6 +27,13 @@ Logs 2018/04/26 17:43:26 WorkerID c19ca08ca4e6aab1 start ``` +### Grid Demo +Same as random. +``` +go run grid-suggest-demo.go +``` +In this demo, make 4 grids Min 0.03 and Max 0.07. + ## UI You can check your Model with Web UI. Acsess to `http://192.168.99.100:30080/` diff --git a/docs/MinikubeDemo/deploy.sh b/docs/MinikubeDemo/deploy.sh index b07a1d7c5be..201ab8a2762 100755 --- a/docs/MinikubeDemo/deploy.sh +++ b/docs/MinikubeDemo/deploy.sh @@ -9,4 +9,5 @@ kubectl apply -f manifests/modeldb/frontend kubectl apply -f manifests/vizier/db kubectl apply -f manifests/vizier/core kubectl apply -f manifests/vizier/suggestion/random +kubectl apply -f manifests/vizier/suggestion/grid kubectl apply -f manifests/vizier/earlystopping/medianstopping diff --git a/docs/MinikubeDemo/grid-suggest-demo.go b/docs/MinikubeDemo/grid-suggest-demo.go new file mode 100644 index 00000000000..37fba02b7bf --- /dev/null +++ b/docs/MinikubeDemo/grid-suggest-demo.go @@ -0,0 +1,201 @@ +package main + +import ( + "context" + "log" + "time" + + "github.com/kubeflow/katib/pkg/api" + "google.golang.org/grpc" +) + +const ( + manager = "192.168.99.100:30678" +) + +var studyConfig = api.StudyConfig{ + Name: "grid-demo", + Owner: "katib", + OptimizationType: api.OptimizationType_MAXIMIZE, + OptimizationGoal: 0.99, + DefaultSuggestionAlgorithm: "grid", + DefaultEarlyStoppingAlgorithm: "medianstopping", + ObjectiveValueName: "Validation-accuracy", + Metrics: []string{ + "accuracy", + }, + ParameterConfigs: &api.StudyConfig_ParameterConfigs{ + Configs: []*api.ParameterConfig{ + &api.ParameterConfig{ + Name: "--lr", + ParameterType: api.ParameterType_DOUBLE, + Feasible: &api.FeasibleSpace{ + Min: "0,03", + Max: "0.07", + }, + }, + }, + }, +} + +var workerConfig = api.WorkerConfig{ + Image: "mxnet/python", + Command: []string{ + "python", + "/mxnet/example/image-classification/train_mnist.py", + "--batch-size=64", + }, + Gpu: 0, + Scheduler: "default-scheduler", +} + +var gridConfig = []*api.SuggestionParameter{ + &api.SuggestionParameter{ + Name: "DefaultGrid", + Value: "2", + }, + &api.SuggestionParameter{ + Name: "--lr", + Value: "4", + }, +} + +func main() { + conn, err := grpc.Dial(manager, grpc.WithInsecure()) + if err != nil { + log.Fatalf("could not connect: %v", err) + } + defer conn.Close() + ctx := context.Background() + c := api.NewManagerClient(conn) + createStudyreq := &api.CreateStudyRequest{ + StudyConfig: &studyConfig, + } + createStudyreply, err := c.CreateStudy(ctx, createStudyreq) + if err != nil { + log.Fatalf("StudyConfig Error %v", err) + } + studyId := createStudyreply.StudyId + log.Printf("Study ID %s", studyId) + getStudyreq := &api.GetStudyRequest{ + StudyId: studyId, + } + getStudyReply, err := c.GetStudy(ctx, getStudyreq) + if err != nil { + log.Fatalf("GetConfig Error %v", err) + } + log.Printf("Study ID %s StudyConf%v", studyId, getStudyReply.StudyConfig) + setSuggesitonParameterRequest := &api.SetSuggestionParametersRequest{ + StudyId: studyId, + SuggestionAlgorithm: "grid", + SuggestionParameters: gridConfig, + } + setSuggesitonParameterReply, err := c.SetSuggestionParameters(ctx, setSuggesitonParameterRequest) + if err != nil { + log.Fatalf("SetConfig Error %v", err) + } + log.Printf("Grid Prameter ID %s", setSuggesitonParameterReply.ParamId) + getGridSuggestRequest := &api.GetSuggestionsRequest{ + StudyId: studyId, + SuggestionAlgorithm: "grid", + RequestNumber: 0, + //RequestNumber=0 means get all grids. + ParamId: setSuggesitonParameterReply.ParamId, + } + getGridSuggestReply, err := c.GetSuggestions(ctx, getGridSuggestRequest) + if err != nil { + log.Fatalf("GetSuggestion Error %v", err) + } + log.Println("Get Grid Suggestions:") + for _, t := range getGridSuggestReply.Trials { + log.Printf("%v", t) + } + workerIds := make([]string, len(getGridSuggestReply.Trials)) + workerParameter := make(map[string][]*api.Parameter) + for i, t := range getGridSuggestReply.Trials { + rtr := &api.RunTrialRequest{ + StudyId: studyId, + TrialId: t.TrialId, + Runtime: "kubernetes", + WorkerConfig: &workerConfig, + } + for _, p := range t.ParameterSet { + rtr.WorkerConfig.Command = append(rtr.WorkerConfig.Command, p.Name) + rtr.WorkerConfig.Command = append(rtr.WorkerConfig.Command, p.Value) + } + workerReply, err := c.RunTrial(ctx, rtr) + if err != nil { + log.Fatalf("RunTrial Error %v", err) + } + workerIds[i] = workerReply.WorkerId + workerParameter[workerReply.WorkerId] = t.ParameterSet + saveModelRequest := &api.SaveModelRequest{ + Model: &api.ModelInfo{ + StudyName: studyConfig.Name, + WorkerId: workerReply.WorkerId, + Parameters: t.ParameterSet, + Metrics: []*api.Metrics{}, + ModelPath: "pvc:/Path/to/Model", + }, + DataSet: &api.DataSetInfo{ + Name: "Mnist", + Path: "/path/to/data", + }, + } + _, err = c.SaveModel(ctx, saveModelRequest) + if err != nil { + log.Fatalf("SaveModel Error %v", err) + } + log.Printf("WorkerID %s start\n", workerReply.WorkerId) + } + for true { + time.Sleep(10 * time.Second) + getMetricsRequest := &api.GetMetricsRequest{ + StudyId: studyId, + WorkerIds: workerIds, + } + getMetricsReply, err := c.GetMetrics(ctx, getMetricsRequest) + if err != nil { + log.Printf("GetMetErr %v", err) + continue + } + for _, mls := range getMetricsReply.MetricsLogSets { + if len(mls.MetricsLogs) > 0 { + log.Printf("WorkerID %s :", mls.WorkerId) + //Only Metrics can be updated. + saveModelRequest := &api.SaveModelRequest{ + Model: &api.ModelInfo{ + StudyName: studyConfig.Name, + WorkerId: mls.WorkerId, + Metrics: []*api.Metrics{}, + }, + } + for _, ml := range mls.MetricsLogs { + if len(ml.Values) > 0 { + log.Printf("\t Metrics Name %s Value %v", ml.Name, ml.Values[len(ml.Values)-1]) + saveModelRequest.Model.Metrics = append(saveModelRequest.Model.Metrics, &api.Metrics{Name: ml.Name, Value: ml.Values[len(ml.Values)-1]}) + } + } + _, err = c.SaveModel(ctx, saveModelRequest) + if err != nil { + log.Fatalf("SaveModel Error %v", err) + } + } + } + getWorkerRequest := &api.GetWorkersRequest{StudyId: studyId} + getWorkerReply, err := c.GetWorkers(ctx, getWorkerRequest) + if err != nil { + log.Fatalf("GetWorker Error %v", err) + } + completeCount := 0 + for _, w := range getWorkerReply.Workers { + if w.Status == api.State_COMPLETED { + completeCount++ + } + } + if completeCount == len(getWorkerReply.Workers) { + log.Printf("All Worker Completed!") + break + } + } +} diff --git a/docs/MinikubeDemo/random-suggest-demo.go b/docs/MinikubeDemo/random-suggest-demo.go index 39ede12cfd3..88e05126027 100644 --- a/docs/MinikubeDemo/random-suggest-demo.go +++ b/docs/MinikubeDemo/random-suggest-demo.go @@ -30,8 +30,8 @@ var studyConfig = api.StudyConfig{ Name: "--lr", ParameterType: api.ParameterType_DOUBLE, Feasible: &api.FeasibleSpace{ - Max: "0,03", - Min: "0.07", + Min: "0,03", + Max: "0.07", }, }, }, diff --git a/pkg/db/interface.go b/pkg/db/interface.go index 89bb1fcf156..4134fd0571d 100644 --- a/pkg/db/interface.go +++ b/pkg/db/interface.go @@ -780,7 +780,7 @@ func (d *db_conn) SetSuggestionParam(algorithm string, studyId string, params [] } var paramId string for true { - paramId := generate_randid() + paramId = generate_randid() _, err = d.db.Exec("INSERT INTO suggestion_param VALUES (?, ?, ?, ?)", paramId, algorithm, studyId, strings.Join(ps, ",\n")) if err == nil { diff --git a/pkg/suggestion/grid_service.go b/pkg/suggestion/grid_service.go index 3a1aa181d2e..364cccb68da 100644 --- a/pkg/suggestion/grid_service.go +++ b/pkg/suggestion/grid_service.go @@ -164,9 +164,11 @@ func (s *GridSuggestService) GetSuggestions(ctx context.Context, in *api.GetSugg } trials := make([]*api.Trial, reqnum) for i := 0; i < int(reqnum); i++ { - trials[i] = &api.Trial{} - trials[i].Status = api.State_PENDING - trials[i].ParameterSet = grids[i] + trials[i] = &api.Trial{ + StudyId: in.StudyId, + Status: api.State_PENDING, + ParameterSet: grids[i], + } } return &api.GetSuggestionsReply{Trials: trials}, nil } From ebf97d6867dbd995e63ecf6ebb18120c9da527d8 Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Fri, 27 Apr 2018 17:58:02 +0900 Subject: [PATCH 04/15] fix Signed-off-by: YujiOshima --- docs/MinikubeDemo/grid-suggest-demo.go | 5 +++-- docs/MinikubeDemo/random-suggest-demo.go | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/MinikubeDemo/grid-suggest-demo.go b/docs/MinikubeDemo/grid-suggest-demo.go index 37fba02b7bf..98f23ba40cc 100644 --- a/docs/MinikubeDemo/grid-suggest-demo.go +++ b/docs/MinikubeDemo/grid-suggest-demo.go @@ -30,7 +30,7 @@ var studyConfig = api.StudyConfig{ Name: "--lr", ParameterType: api.ParameterType_DOUBLE, Feasible: &api.FeasibleSpace{ - Min: "0,03", + Min: "0.03", Max: "0.07", }, }, @@ -113,11 +113,12 @@ func main() { workerIds := make([]string, len(getGridSuggestReply.Trials)) workerParameter := make(map[string][]*api.Parameter) for i, t := range getGridSuggestReply.Trials { + wc := workerConfig rtr := &api.RunTrialRequest{ StudyId: studyId, TrialId: t.TrialId, Runtime: "kubernetes", - WorkerConfig: &workerConfig, + WorkerConfig: &wc, } for _, p := range t.ParameterSet { rtr.WorkerConfig.Command = append(rtr.WorkerConfig.Command, p.Name) diff --git a/docs/MinikubeDemo/random-suggest-demo.go b/docs/MinikubeDemo/random-suggest-demo.go index 88e05126027..7142a039813 100644 --- a/docs/MinikubeDemo/random-suggest-demo.go +++ b/docs/MinikubeDemo/random-suggest-demo.go @@ -30,7 +30,7 @@ var studyConfig = api.StudyConfig{ Name: "--lr", ParameterType: api.ParameterType_DOUBLE, Feasible: &api.FeasibleSpace{ - Min: "0,03", + Min: "0.03", Max: "0.07", }, }, From 114ca04bdc661000cc6e0d95034e6f2fcc9232dc Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Fri, 27 Apr 2018 17:59:20 +0900 Subject: [PATCH 05/15] add GKEDemo Signed-off-by: YujiOshima --- docs/GKEDemo/GKE-Demo.md | 41 ++++ docs/GKEDemo/deploy.sh | 32 +++ docs/GKEDemo/destroy.sh | 5 + docs/GKEDemo/down.sh | 3 + docs/GKEDemo/git-issue-summarize-demo.go | 208 ++++++++++++++++++ docs/GKEDemo/manifests/0-namespace.yaml | 4 + .../manifests/modeldb/backend/deployment.yaml | 32 +++ .../manifests/modeldb/backend/service.yaml | 17 ++ .../manifests/modeldb/db/deployment.yaml | 30 +++ .../GKEDemo/manifests/modeldb/db/service.yaml | 17 ++ .../modeldb/frontend/deployment.yaml | 36 +++ .../manifests/modeldb/frontend/ingress.yaml | 9 + .../manifests/modeldb/frontend/service.yaml | 18 ++ .../manifests/vizier/core/deployment.yaml | 37 ++++ .../manifests/vizier/core/ingress.yaml | 9 + docs/GKEDemo/manifests/vizier/core/rbac.yaml | 37 ++++ .../manifests/vizier/core/service.yaml | 18 ++ .../manifests/vizier/db/deployment.yaml | 37 ++++ docs/GKEDemo/manifests/vizier/db/service.yaml | 17 ++ .../medianstopping/deployment.yaml | 30 +++ .../earlystopping/medianstopping/service.yaml | 17 ++ .../vizier/suggestion/grid/deployment.yaml | 30 +++ .../vizier/suggestion/grid/service.yaml | 17 ++ .../vizier/suggestion/random/deployment.yaml | 30 +++ .../vizier/suggestion/random/service.yaml | 17 ++ 25 files changed, 748 insertions(+) create mode 100644 docs/GKEDemo/GKE-Demo.md create mode 100755 docs/GKEDemo/deploy.sh create mode 100755 docs/GKEDemo/destroy.sh create mode 100755 docs/GKEDemo/down.sh create mode 100644 docs/GKEDemo/git-issue-summarize-demo.go create mode 100644 docs/GKEDemo/manifests/0-namespace.yaml create mode 100644 docs/GKEDemo/manifests/modeldb/backend/deployment.yaml create mode 100644 docs/GKEDemo/manifests/modeldb/backend/service.yaml create mode 100644 docs/GKEDemo/manifests/modeldb/db/deployment.yaml create mode 100644 docs/GKEDemo/manifests/modeldb/db/service.yaml create mode 100644 docs/GKEDemo/manifests/modeldb/frontend/deployment.yaml create mode 100644 docs/GKEDemo/manifests/modeldb/frontend/ingress.yaml create mode 100644 docs/GKEDemo/manifests/modeldb/frontend/service.yaml create mode 100644 docs/GKEDemo/manifests/vizier/core/deployment.yaml create mode 100644 docs/GKEDemo/manifests/vizier/core/ingress.yaml create mode 100644 docs/GKEDemo/manifests/vizier/core/rbac.yaml create mode 100644 docs/GKEDemo/manifests/vizier/core/service.yaml create mode 100644 docs/GKEDemo/manifests/vizier/db/deployment.yaml create mode 100644 docs/GKEDemo/manifests/vizier/db/service.yaml create mode 100644 docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml create mode 100644 docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/service.yaml create mode 100644 docs/GKEDemo/manifests/vizier/suggestion/grid/deployment.yaml create mode 100644 docs/GKEDemo/manifests/vizier/suggestion/grid/service.yaml create mode 100644 docs/GKEDemo/manifests/vizier/suggestion/random/deployment.yaml create mode 100644 docs/GKEDemo/manifests/vizier/suggestion/random/service.yaml diff --git a/docs/GKEDemo/GKE-Demo.md b/docs/GKEDemo/GKE-Demo.md new file mode 100644 index 00000000000..452ef0fff44 --- /dev/null +++ b/docs/GKEDemo/GKE-Demo.md @@ -0,0 +1,41 @@ +# Simple GKE Demo +You can deploy katib components and try simple mnist demo on the cloud! + +## deploy Cluster +This is grid parameter search demo for [KubeFlow's Github issue summaraize example](https://github.com/kubeflow/examples/tree/master/github_issue_summarization) +Let's deploy GKE cluster by gcloud commnad. +And you need to set GCP service account. +See https://github.com/kubeflow/examples/blob/master/github_issue_summarization/training_the_model_tfjob.md +Then deploy Katib compenents. +``` +kubectl config set-credentials temp-admin --username=admin --password=$(gcloud container clusters describe katib --format="value(masterAuth.password)") +kubectl config set-context temp-context --cluster=$(kubectl config get-clusters | grep katib) --user=temp-admin +kubectl config use-context temp-context +kubectl apply -f manifests/0-namespace.yaml +kubectl --namespace=${NAMESPACE} create secret generic gcp-credentials --from-file=key.json="${KEY_FILE}" +kubectl apply -f manifests/modeldb/db +kubectl apply -f manifests/modeldb/backend +kubectl apply -f manifests/modeldb/frontend +kubectl apply -f manifests/vizier/db +kubectl apply -f manifests/vizier/core +kubectl apply -f manifests/vizier/suggestion/random +kubectl apply -f manifests/vizier/suggestion/grid +kubectl apply -f manifests/vizier/earlystopping/medianstopping +gcloud compute firewall-rules create katibservice --allow tcp:30080,tcp:30678 +``` +In this demo, katib components export using NodePort. +So you should set firewall to allow the ports. + + +## Create Study +Please edit `git-issue-summarize-demo.go` the `manager` address to the node address that vizier-core deployed. +Then +``` +go run git-issue-summarize-demo.go +``` +Katib will make 4 girds of learling-rate parameter from 0.005 to 0.5. + +## UI +You can check your Model with Web UI. +Acsess to `http://{{node address}}:30080/` +The Results will be saved automatically. diff --git a/docs/GKEDemo/deploy.sh b/docs/GKEDemo/deploy.sh new file mode 100755 index 00000000000..6b057c37613 --- /dev/null +++ b/docs/GKEDemo/deploy.sh @@ -0,0 +1,32 @@ +#/bin/bash +set -x +set -e +gcloud container clusters create --machine-type n1-highmem-2 katib +SERVICE_ACCOUNT=github-issue-summarization +PROJECT=katib-202401 # The GCP Project name +NAMESPACE=katib +gcloud iam service-accounts --project=${PROJECT} create ${SERVICE_ACCOUNT} \ + --display-name "GCP Service Account for use with kubeflow examples" + +gcloud projects add-iam-policy-binding ${PROJECT} --member \ + serviceAccount:${SERVICE_ACCOUNT}@${PROJECT}.iam.gserviceaccount.com --role=roles/storage.admin + +KEY_FILE=/home/user/secrets/${SERVICE_ACCOUNT}@${PROJECT}.iam.gserviceaccount.com.json +gcloud iam service-accounts keys create ${KEY_FILE} \ + --iam-account ${SERVICE_ACCOUNT}@${PROJECT}.iam.gserviceaccount.com +set -e +kubectl config set-credentials temp-admin --username=admin --password=$(gcloud container clusters describe katib --format="value(masterAuth.password)") +kubectl config set-context temp-context --cluster=$(kubectl config get-clusters | grep katib) --user=temp-admin +kubectl config use-context temp-context +kubectl apply -f manifests/0-namespace.yaml +kubectl --namespace=${NAMESPACE} create secret generic gcp-credentials --from-file=key.json="${KEY_FILE}" +kubectl apply -f manifests/modeldb/db +kubectl apply -f manifests/modeldb/backend +kubectl apply -f manifests/modeldb/frontend +kubectl apply -f manifests/vizier/db +kubectl apply -f manifests/vizier/core +kubectl apply -f manifests/vizier/suggestion/random +kubectl apply -f manifests/vizier/suggestion/grid +kubectl apply -f manifests/vizier/earlystopping/medianstopping +gcloud compute firewall-rules create katibservice --allow tcp:30080,tcp:30678 +gcloud compute instances list diff --git a/docs/GKEDemo/destroy.sh b/docs/GKEDemo/destroy.sh new file mode 100755 index 00000000000..87883faa30f --- /dev/null +++ b/docs/GKEDemo/destroy.sh @@ -0,0 +1,5 @@ +#/bin/bash +set -x +gcloud compute firewall-rules delete katibservice +gcloud container clusters delete katib +gcloud compute disks delete katib-pv diff --git a/docs/GKEDemo/down.sh b/docs/GKEDemo/down.sh new file mode 100755 index 00000000000..0ffdf8c3900 --- /dev/null +++ b/docs/GKEDemo/down.sh @@ -0,0 +1,3 @@ +#/bin/bash +set -x +kubectl delete ns katib diff --git a/docs/GKEDemo/git-issue-summarize-demo.go b/docs/GKEDemo/git-issue-summarize-demo.go new file mode 100644 index 00000000000..da9f8df6db5 --- /dev/null +++ b/docs/GKEDemo/git-issue-summarize-demo.go @@ -0,0 +1,208 @@ +package main + +import ( + "context" + "log" + "time" + + "github.com/kubeflow/katib/pkg/api" + "google.golang.org/grpc" +) + +const ( + manager = "35.194.127.138:30678" +) + +var studyConfig = api.StudyConfig{ + Name: "grid-demo", + Owner: "katib", + OptimizationType: api.OptimizationType_MAXIMIZE, + OptimizationGoal: 0.99, + DefaultSuggestionAlgorithm: "grid", + DefaultEarlyStoppingAlgorithm: "medianstopping", + ObjectiveValueName: "Validation-accuracy", + Metrics: []string{ + "accuracy", + }, + ParameterConfigs: &api.StudyConfig_ParameterConfigs{ + Configs: []*api.ParameterConfig{ + &api.ParameterConfig{ + Name: "--learning_rate", + ParameterType: api.ParameterType_DOUBLE, + Feasible: &api.FeasibleSpace{ + Min: "0.005", + Max: "0.5", + }, + }, + }, + }, +} + +var workerConfig = api.WorkerConfig{ + Image: "yujioshima/tf-job-issue-summarization:latest", + Command: []string{ + "python", + "/workdir/train.py", + "--input_data_gcs_bucket", + "katib-gi-example", + "--input_data_gcs_path", + "github-issue-summarization-data/github-issues.zip", + "--output_model_gcs_bucket", + "katib-gi-example", + }, + Gpu: 0, + Scheduler: "default-scheduler", +} + +var gridConfig = []*api.SuggestionParameter{ + &api.SuggestionParameter{ + Name: "DefaultGrid", + Value: "2", + }, + &api.SuggestionParameter{ + Name: "--learning_rate", + Value: "4", + }, +} + +func main() { + conn, err := grpc.Dial(manager, grpc.WithInsecure()) + if err != nil { + log.Fatalf("could not connect: %v", err) + } + defer conn.Close() + ctx := context.Background() + c := api.NewManagerClient(conn) + createStudyreq := &api.CreateStudyRequest{ + StudyConfig: &studyConfig, + } + createStudyreply, err := c.CreateStudy(ctx, createStudyreq) + if err != nil { + log.Fatalf("StudyConfig Error %v", err) + } + studyId := createStudyreply.StudyId + log.Printf("Study ID %s", studyId) + getStudyreq := &api.GetStudyRequest{ + StudyId: studyId, + } + getStudyReply, err := c.GetStudy(ctx, getStudyreq) + if err != nil { + log.Fatalf("GetConfig Error %v", err) + } + log.Printf("Study ID %s StudyConf%v", studyId, getStudyReply.StudyConfig) + setSuggesitonParameterRequest := &api.SetSuggestionParametersRequest{ + StudyId: studyId, + SuggestionAlgorithm: "grid", + SuggestionParameters: gridConfig, + } + setSuggesitonParameterReply, err := c.SetSuggestionParameters(ctx, setSuggesitonParameterRequest) + if err != nil { + log.Fatalf("SetConfig Error %v", err) + } + log.Printf("Grid Prameter ID %s", setSuggesitonParameterReply.ParamId) + getGridSuggestRequest := &api.GetSuggestionsRequest{ + StudyId: studyId, + SuggestionAlgorithm: "grid", + RequestNumber: 0, + //RequestNumber=0 means get all grids. + ParamId: setSuggesitonParameterReply.ParamId, + } + getGridSuggestReply, err := c.GetSuggestions(ctx, getGridSuggestRequest) + if err != nil { + log.Fatalf("GetSuggestion Error %v", err) + } + log.Println("Get Grid Suggestions:") + for _, t := range getGridSuggestReply.Trials { + log.Printf("%v", t) + } + workerIds := make([]string, len(getGridSuggestReply.Trials)) + workerParameter := make(map[string][]*api.Parameter) + for i, t := range getGridSuggestReply.Trials { + ws := workerConfig + rtr := &api.RunTrialRequest{ + StudyId: studyId, + TrialId: t.TrialId, + Runtime: "kubernetes", + WorkerConfig: &ws, + } + rtr.WorkerConfig.Command = append(rtr.WorkerConfig.Command, "--output_model_gcs_path") + rtr.WorkerConfig.Command = append(rtr.WorkerConfig.Command, "github-issue-summarization-data/"+t.TrialId+"output_model.h5") + for _, p := range t.ParameterSet { + rtr.WorkerConfig.Command = append(rtr.WorkerConfig.Command, p.Name) + rtr.WorkerConfig.Command = append(rtr.WorkerConfig.Command, p.Value) + } + workerReply, err := c.RunTrial(ctx, rtr) + if err != nil { + log.Fatalf("RunTrial Error %v", err) + } + workerIds[i] = workerReply.WorkerId + workerParameter[workerReply.WorkerId] = t.ParameterSet + saveModelRequest := &api.SaveModelRequest{ + Model: &api.ModelInfo{ + StudyName: studyConfig.Name, + WorkerId: workerReply.WorkerId, + Parameters: t.ParameterSet, + Metrics: []*api.Metrics{}, + ModelPath: "pvc:/Path/to/Model", + }, + DataSet: &api.DataSetInfo{ + Name: "Mnist", + Path: "/path/to/data", + }, + } + _, err = c.SaveModel(ctx, saveModelRequest) + if err != nil { + log.Fatalf("SaveModel Error %v", err) + } + log.Printf("WorkerID %s start\n", workerReply.WorkerId) + } + for true { + time.Sleep(10 * time.Second) + getMetricsRequest := &api.GetMetricsRequest{ + StudyId: studyId, + WorkerIds: workerIds, + } + getMetricsReply, err := c.GetMetrics(ctx, getMetricsRequest) + if err != nil { + log.Printf("GetMetErr %v", err) + continue + } + for _, mls := range getMetricsReply.MetricsLogSets { + if len(mls.MetricsLogs) > 0 { + //Only Metrics can be updated. + saveModelRequest := &api.SaveModelRequest{ + Model: &api.ModelInfo{ + StudyName: studyConfig.Name, + WorkerId: mls.WorkerId, + Metrics: []*api.Metrics{}, + }, + } + for _, ml := range mls.MetricsLogs { + if len(ml.Values) > 0 { + log.Printf("WorkerID %s :\t Metrics Name %s Value %v", mls.WorkerId, ml.Name, ml.Values[len(ml.Values)-1]) + saveModelRequest.Model.Metrics = append(saveModelRequest.Model.Metrics, &api.Metrics{Name: ml.Name, Value: ml.Values[len(ml.Values)-1]}) + } + } + _, err = c.SaveModel(ctx, saveModelRequest) + if err != nil { + log.Fatalf("SaveModel Error %v", err) + } + } + } + getWorkerRequest := &api.GetWorkersRequest{StudyId: studyId} + getWorkerReply, err := c.GetWorkers(ctx, getWorkerRequest) + if err != nil { + log.Fatalf("GetWorker Error %v", err) + } + completeCount := 0 + for _, w := range getWorkerReply.Workers { + if w.Status == api.State_COMPLETED { + completeCount++ + } + } + if completeCount == len(getWorkerReply.Workers) { + log.Printf("All Worker Completed!") + break + } + } +} diff --git a/docs/GKEDemo/manifests/0-namespace.yaml b/docs/GKEDemo/manifests/0-namespace.yaml new file mode 100644 index 00000000000..9bac532fac9 --- /dev/null +++ b/docs/GKEDemo/manifests/0-namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: katib diff --git a/docs/GKEDemo/manifests/modeldb/backend/deployment.yaml b/docs/GKEDemo/manifests/modeldb/backend/deployment.yaml new file mode 100644 index 00000000000..bc7fd1dc9f6 --- /dev/null +++ b/docs/GKEDemo/manifests/modeldb/backend/deployment.yaml @@ -0,0 +1,32 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: modeldb-backend + namespace: katib + labels: + app: modeldb + component: backend +spec: + replicas: 1 + template: + metadata: + name: modeldb-backend + labels: + app: modeldb + component: backend + spec: + containers: + - name: modeldb-backend + image: mitdbg/modeldb-backend:latest + args: + - 'modeldb-db' + ports: + - name: api + containerPort: 6543 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/GKEDemo/manifests/modeldb/backend/service.yaml b/docs/GKEDemo/manifests/modeldb/backend/service.yaml new file mode 100644 index 00000000000..71d9d5f7fe8 --- /dev/null +++ b/docs/GKEDemo/manifests/modeldb/backend/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: modeldb-backend + namespace: katib + labels: + app: modeldb + component: backend +spec: + type: ClusterIP + ports: + - port: 6543 + protocol: TCP + name: api + selector: + app: modeldb + component: backend diff --git a/docs/GKEDemo/manifests/modeldb/db/deployment.yaml b/docs/GKEDemo/manifests/modeldb/db/deployment.yaml new file mode 100644 index 00000000000..eaa83fa2db6 --- /dev/null +++ b/docs/GKEDemo/manifests/modeldb/db/deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: modeldb-db + namespace: katib + labels: + app: modeldb + component: db +spec: + replicas: 1 + template: + metadata: + name: modeldb-db + labels: + app: modeldb + component: db + spec: + containers: + - name: modeldb-db + image: mongo:3.4 + ports: + - name: dbapi + containerPort: 27017 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/GKEDemo/manifests/modeldb/db/service.yaml b/docs/GKEDemo/manifests/modeldb/db/service.yaml new file mode 100644 index 00000000000..966fb4155ea --- /dev/null +++ b/docs/GKEDemo/manifests/modeldb/db/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: modeldb-db + namespace: katib + labels: + app: modeldb + component: db +spec: + type: ClusterIP + ports: + - port: 27017 + protocol: TCP + name: dbapi + selector: + app: modeldb + component: db diff --git a/docs/GKEDemo/manifests/modeldb/frontend/deployment.yaml b/docs/GKEDemo/manifests/modeldb/frontend/deployment.yaml new file mode 100644 index 00000000000..9e4da69841c --- /dev/null +++ b/docs/GKEDemo/manifests/modeldb/frontend/deployment.yaml @@ -0,0 +1,36 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: modeldb-frontend + namespace: katib + labels: + app: modeldb + component: frontend +spec: + replicas: 1 + template: + metadata: + name: modeldb-frontend + labels: + app: modeldb + component: frontend + spec: + containers: + - name: modeldb-frontend + image: yujioshima/katib-frontend + imagePullPolicy: Always + args: + - 'modeldb-backend' + env: + - name: ROOT_PATH + value: "" + ports: + - name: webapi + containerPort: 3000 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/GKEDemo/manifests/modeldb/frontend/ingress.yaml b/docs/GKEDemo/manifests/modeldb/frontend/ingress.yaml new file mode 100644 index 00000000000..fbb4eb24819 --- /dev/null +++ b/docs/GKEDemo/manifests/modeldb/frontend/ingress.yaml @@ -0,0 +1,9 @@ + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: katib-ui + namespace: katib + spec: + backend: + serviceName: modeldb-frontend + servicePort: 80 diff --git a/docs/GKEDemo/manifests/modeldb/frontend/service.yaml b/docs/GKEDemo/manifests/modeldb/frontend/service.yaml new file mode 100644 index 00000000000..422f93ce5ce --- /dev/null +++ b/docs/GKEDemo/manifests/modeldb/frontend/service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: modeldb-frontend + namespace: katib + labels: + app: modeldb + component: frontend +spec: + type: NodePort + ports: + - port: 3000 + protocol: TCP + name: ui + nodePort: 30080 + selector: + app: modeldb + component: frontend diff --git a/docs/GKEDemo/manifests/vizier/core/deployment.yaml b/docs/GKEDemo/manifests/vizier/core/deployment.yaml new file mode 100644 index 00000000000..698f9da3077 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/core/deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-core + namespace: katib + labels: + app: vizier + component: core +spec: + replicas: 1 + template: + metadata: + name: vizier-core + labels: + app: vizier + component: core + spec: + serviceAccountName: vizier-core + containers: + - name: vizier-core + image: yujioshima/vizier-core + command: + - './vizier-manager' + - "-w" + - "kubernetes" + - "-i" + - "k-cluster.osrg.net" + ports: + - name: api + containerPort: 6789 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/GKEDemo/manifests/vizier/core/ingress.yaml b/docs/GKEDemo/manifests/vizier/core/ingress.yaml new file mode 100644 index 00000000000..e0c307146b5 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/core/ingress.yaml @@ -0,0 +1,9 @@ + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: vizier-core + namespace: katib + spec: + backend: + serviceName: vizier-core + servicePort: 6789 diff --git a/docs/GKEDemo/manifests/vizier/core/rbac.yaml b/docs/GKEDemo/manifests/vizier/core/rbac.yaml new file mode 100644 index 00000000000..a0858e752af --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/core/rbac.yaml @@ -0,0 +1,37 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: vizier-core +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: vizier-core +subjects: +- kind: ServiceAccount + name: vizier-core + namespace: katib +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: vizier-core +rules: + - apiGroups: [""] + resources: ["pods", "nodes", "nodes/*", "pods/log", "pods/status", "services", "persistentvolumes", "persistentvolumes/status","persistentvolumeclaims","persistentvolumeclaims/status"] + verbs: ["*"] + - apiGroups: ["batch"] + resources: ["jobs", "jobs/status"] + verbs: ["*"] + - verbs: ["*"] + apiGroups: ["extensions"] + resources: ["ingresses","ingresses/status","deployments","deployments/status"] + - verbs: ["*"] + apiGroups: [""] + resources: ["services"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vizier-core + namespace: katib diff --git a/docs/GKEDemo/manifests/vizier/core/service.yaml b/docs/GKEDemo/manifests/vizier/core/service.yaml new file mode 100644 index 00000000000..a822225b787 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/core/service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-core + namespace: katib + labels: + app: vizier + component: core +spec: + type: NodePort + ports: + - port: 6789 + protocol: TCP + nodePort: 30678 + name: api + selector: + app: vizier + component: core diff --git a/docs/GKEDemo/manifests/vizier/db/deployment.yaml b/docs/GKEDemo/manifests/vizier/db/deployment.yaml new file mode 100644 index 00000000000..bd4a9ef1958 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/db/deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-db + namespace: katib + labels: + app: vizier + component: db +spec: + replicas: 1 + template: + metadata: + name: vizier-db + labels: + app: vizier + component: db + spec: + containers: + - name: vizier-db + image: mysql:8.0.3 + env: + - name: MYSQL_ROOT_PASSWORD + value: "test" + - name: MYSQL_ALLOW_EMPTY_PASSWORD + value: "true" + - name: MYSQL_DATABASE + value: "vizier" + ports: + - name: dbapi + containerPort: 3306 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/GKEDemo/manifests/vizier/db/service.yaml b/docs/GKEDemo/manifests/vizier/db/service.yaml new file mode 100644 index 00000000000..dde0b2c31a0 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/db/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-db + namespace: katib + labels: + app: vizier + component: db +spec: + type: ClusterIP + ports: + - port: 3306 + protocol: TCP + name: dbapi + selector: + app: vizier + component: db diff --git a/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml b/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml new file mode 100644 index 00000000000..2b1743e73d1 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-earlystopping-medianstopping + namespace: katib + labels: + app: vizier + component: earlystopping-medianstopping +spec: + replicas: 1 + template: + metadata: + name: vizier-earlystopping-medianstopping + labels: + app: vizier + component: earlystopping-medianstopping + spec: + containers: + - name: vizier-earlystopping-medianstopping + image: yujioshima/earlystopping-medianstopping + ports: + - name: api + containerPort: 6789 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/service.yaml b/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/service.yaml new file mode 100644 index 00000000000..dd6aa39c465 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-earlystopping-medianstopping + namespace: katib + labels: + app: vizier + component: earlystopping-medianstopping +spec: + type: ClusterIP + ports: + - port: 6789 + protocol: TCP + name: api + selector: + app: vizier + component: earlystopping-medianstopping diff --git a/docs/GKEDemo/manifests/vizier/suggestion/grid/deployment.yaml b/docs/GKEDemo/manifests/vizier/suggestion/grid/deployment.yaml new file mode 100644 index 00000000000..8a2b01d8f3c --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/suggestion/grid/deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-suggestion-grid + namespace: katib + labels: + app: vizier + component: suggestion-grid +spec: + replicas: 1 + template: + metadata: + name: vizier-suggestion-grid + labels: + app: vizier + component: suggestion-grid + spec: + containers: + - name: vizier-suggestion-grid + image: yujioshima/suggestion-grid + ports: + - name: api + containerPort: 6789 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/GKEDemo/manifests/vizier/suggestion/grid/service.yaml b/docs/GKEDemo/manifests/vizier/suggestion/grid/service.yaml new file mode 100644 index 00000000000..4a1cf6b64a0 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/suggestion/grid/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-suggestion-grid + namespace: katib + labels: + app: vizier + component: suggestion-grid +spec: + type: ClusterIP + ports: + - port: 6789 + protocol: TCP + name: api + selector: + app: vizier + component: suggestion-grid diff --git a/docs/GKEDemo/manifests/vizier/suggestion/random/deployment.yaml b/docs/GKEDemo/manifests/vizier/suggestion/random/deployment.yaml new file mode 100644 index 00000000000..5884741e045 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/suggestion/random/deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: vizier-suggestion-random + namespace: katib + labels: + app: vizier + component: suggestion-random +spec: + replicas: 1 + template: + metadata: + name: vizier-suggestion-random + labels: + app: vizier + component: suggestion-random + spec: + containers: + - name: vizier-suggestion-random + image: yujioshima/suggestion-random + ports: + - name: api + containerPort: 6789 +# resources: +# requests: +# cpu: 500m +# memory: 500M +# limits: +# cpu: 500m +# memory: 500M diff --git a/docs/GKEDemo/manifests/vizier/suggestion/random/service.yaml b/docs/GKEDemo/manifests/vizier/suggestion/random/service.yaml new file mode 100644 index 00000000000..463cdca1da0 --- /dev/null +++ b/docs/GKEDemo/manifests/vizier/suggestion/random/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: vizier-suggestion-random + namespace: katib + labels: + app: vizier + component: suggestion-random +spec: + type: ClusterIP + ports: + - port: 6789 + protocol: TCP + name: api + selector: + app: vizier + component: suggestion-random From 3b6ec7d3beeb4c020b93b0cce6f87ca794dd2aeb Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Sat, 28 Apr 2018 02:35:36 +0900 Subject: [PATCH 06/15] fix test Signed-off-by: YujiOshima --- cmd/manager/main.go | 11 +- cmd/manager/main_test.go | 57 ++-- docs/MinikubeDemo/MinikubeDemo.md | 4 +- .../{ => grid}/grid-suggest-demo.go | 0 .../{ => random}/random-suggest-demo.go | 4 +- pkg/db/interface_test.go | 6 +- pkg/mock/api/manager.go | 244 ++++++++++++------ pkg/mock/api/suggestion.go | 50 +--- pkg/mock/db/db.go | 206 +++++++++++++-- pkg/mock/worker/worker.go | 112 +++----- test/scripts/build.sh | 14 +- test/scripts/run-tests.sh | 5 +- 12 files changed, 424 insertions(+), 289 deletions(-) rename docs/MinikubeDemo/{ => grid}/grid-suggest-demo.go (100%) rename docs/MinikubeDemo/{ => random}/random-suggest-demo.go (98%) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index d5676f174f2..59e5812e9b8 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -30,14 +30,9 @@ var workerType = flag.String("w", "kubernetes", "Worker Type") var ingressHost = flag.String("i", "kube-cluster.example.net", "Ingress host for TensorBoard visualize") var dbIf kdb.VizierDBInterface -type studyCh struct { - stopCh chan bool - addMetricsCh chan string -} type server struct { - wIF worker.Interface - msIf modelstore.ModelStore - StudyChList map[string]studyCh + wIF worker.Interface + msIf modelstore.ModelStore } func (s *server) CreateStudy(ctx context.Context, in *pb.CreateStudyRequest) (*pb.CreateStudyReply, error) { @@ -316,7 +311,7 @@ func main() { if err != nil { log.Fatalf("Failed to Create Kubernetes Worker: %v", err) } - pb.RegisterManagerServer(s, &server{wIF: kw, msIf: modelstore.NewModelDB("modeldb-backend", "6543"), StudyChList: make(map[string]studyCh)}) + pb.RegisterManagerServer(s, &server{wIF: kw, msIf: modelstore.NewModelDB("modeldb-backend", "6543")}) default: log.Fatalf("Unknown worker") } diff --git a/cmd/manager/main_test.go b/cmd/manager/main_test.go index 28d95b41cdb..c680cd4cbd5 100644 --- a/cmd/manager/main_test.go +++ b/cmd/manager/main_test.go @@ -24,22 +24,21 @@ func TestCreateStudy(t *testing.T) { Owner: "admin", OptimizationType: 1, ObjectiveValueName: "obj_name", - Gpu: 1, } dbIf = mockDB mockDB.EXPECT().CreateStudy( sc, ).Return(sid, nil) ssr := &api.SaveStudyRequest{ - StudyName: "test", - Owner: "admin", + StudyName: "test", + Owner: "admin", + Description: "StudyID: " + sid, } mockModelStore.EXPECT().SaveStudy(ssr).Return(nil) s := &server{ - wIF: mockWif, - msIf: mockModelStore, - StudyChList: make(map[string]studyCh), + wIF: mockWif, + msIf: mockModelStore, } req := &api.CreateStudyRequest{StudyConfig: sc} ret, err := s.CreateStudy(context.Background(), req) @@ -49,14 +48,6 @@ func TestCreateStudy(t *testing.T) { if ret.StudyId != sid { t.Fatalf("Study ID expect "+sid+", get %s", ret.StudyId) } - if len(s.StudyChList) != 1 { - t.Fatalf("Study register failed. Registered number is %d", len(s.StudyChList)) - } else { - _, ok := s.StudyChList[sid] - if !ok { - t.Fatalf("Study %s is failed to register.", sid) - } - } } func TestGetStudies(t *testing.T) { ctrl := gomock.NewController(t) @@ -68,20 +59,14 @@ func TestGetStudies(t *testing.T) { s := &server{ wIF: mockWif, msIf: mockModelStore, - StudyChList: map[string]studyCh{ - sid[0]: studyCh{}, - sid[1]: studyCh{}, - }, } dbIf = mockDB - sc := []*api.StudyConfig{ &api.StudyConfig{ Name: "test1", Owner: "admin", OptimizationType: 1, ObjectiveValueName: "obj_name1", - Gpu: 1, }, &api.StudyConfig{ Name: "test2", @@ -90,45 +75,35 @@ func TestGetStudies(t *testing.T) { ObjectiveValueName: "obj_name2", }, } - rts := []int32{10, 20} - cts := []int32{5, 1} + mockDB.EXPECT().GetStudyList().Return(sid, nil) for i := range sid { mockDB.EXPECT().GetStudyConfig(sid[i]).Return(sc[i], nil) - mockWif.EXPECT().GetRunningTrials(sid[i]).Return(make([]*api.Trial, rts[i])) - mockWif.EXPECT().GetCompletedTrials(sid[i]).Return(make([]*api.Trial, cts[i])) } - req := &api.GetStudiesRequest{} - ret, err := s.GetStudies(context.Background(), req) + req := &api.GetStudyListRequest{} + ret, err := s.GetStudyList(context.Background(), req) if err != nil { t.Fatalf("CreateStudy Error %v", err) } - if len(ret.StudyInfos) != len(sid) { - t.Fatalf("Study Info number %d, expected%d", len(ret.StudyInfos), len(sid)) + if len(ret.StudyOverviews) != len(sid) { + t.Fatalf("Study Info number %d, expected%d", len(ret.StudyOverviews), len(sid)) } else { var j int for i := range sid { - switch ret.StudyInfos[i].StudyId { + switch ret.StudyOverviews[i].Id { case sid[0]: j = 0 case sid[1]: j = 1 default: - t.Fatalf("GetStudy Error Study ID %s is not expected", ret.StudyInfos[j].StudyId) - } - if ret.StudyInfos[i].Name != sc[j].Name { - t.Fatalf("GetStudy Error Name %s expected %s", ret.StudyInfos[i].Name, sc[j].Name) + t.Fatalf("GetStudy Error Study ID %s is not expected", ret.StudyOverviews[j].Id) } - if ret.StudyInfos[i].Owner != sc[j].Owner { - t.Fatalf("GetStudy Error Owner %s expected %s", ret.StudyInfos[i].Owner, sc[j].Owner) + if ret.StudyOverviews[i].Name != sc[j].Name { + t.Fatalf("GetStudy Error Name %s expected %s", ret.StudyOverviews[i].Name, sc[j].Name) } - if ret.StudyInfos[i].RunningTrialNum != rts[j] { - t.Fatalf("GetStudy Error RunningTrialNum %d expected %d", ret.StudyInfos[i].RunningTrialNum, rts[j]) + if ret.StudyOverviews[i].Owner != sc[j].Owner { + t.Fatalf("GetStudy Error Owner %s expected %s", ret.StudyOverviews[i].Owner, sc[j].Owner) } - if ret.StudyInfos[i].CompletedTrialNum != cts[j] { - t.Fatalf("GetStudy Error CompletedTrialNum %d expected %d", ret.StudyInfos[i].CompletedTrialNum, cts[j]) - } - } } } diff --git a/docs/MinikubeDemo/MinikubeDemo.md b/docs/MinikubeDemo/MinikubeDemo.md index ffd33e6f43e..5c7ac864f71 100644 --- a/docs/MinikubeDemo/MinikubeDemo.md +++ b/docs/MinikubeDemo/MinikubeDemo.md @@ -15,7 +15,7 @@ Wait until all components are Running status. ### Random Suggestion Demo You can run rundom suggesiton demo. ``` -go run radom-suggest-demo.go +go run random/radom-suggest-demo.go ``` In this demo, 2 random learning rate parameters generated randomly between Min 0.03 and Max 0.07. Logs @@ -30,7 +30,7 @@ Logs ### Grid Demo Same as random. ``` -go run grid-suggest-demo.go +go run grid/grid-suggest-demo.go ``` In this demo, make 4 grids Min 0.03 and Max 0.07. diff --git a/docs/MinikubeDemo/grid-suggest-demo.go b/docs/MinikubeDemo/grid/grid-suggest-demo.go similarity index 100% rename from docs/MinikubeDemo/grid-suggest-demo.go rename to docs/MinikubeDemo/grid/grid-suggest-demo.go diff --git a/docs/MinikubeDemo/random-suggest-demo.go b/docs/MinikubeDemo/random/random-suggest-demo.go similarity index 98% rename from docs/MinikubeDemo/random-suggest-demo.go rename to docs/MinikubeDemo/random/random-suggest-demo.go index 7142a039813..879f3d0e54b 100644 --- a/docs/MinikubeDemo/random-suggest-demo.go +++ b/docs/MinikubeDemo/random/random-suggest-demo.go @@ -14,11 +14,11 @@ const ( ) var studyConfig = api.StudyConfig{ - Name: "random-demo", + Name: "grid-demo", Owner: "katib", OptimizationType: api.OptimizationType_MAXIMIZE, OptimizationGoal: 0.99, - DefaultSuggestionAlgorithm: "random", + DefaultSuggestionAlgorithm: "grid", DefaultEarlyStoppingAlgorithm: "medianstopping", ObjectiveValueName: "Validation-accuracy", Metrics: []string{ diff --git a/pkg/db/interface_test.go b/pkg/db/interface_test.go index 5aa0617f69f..25026244507 100644 --- a/pkg/db/interface_test.go +++ b/pkg/db/interface_test.go @@ -33,9 +33,11 @@ func TestMain(m *testing.M) { mock.ExpectExec("CREATE TABLE IF NOT EXISTS studies").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec("CREATE TABLE IF NOT EXISTS study_permissions").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 workers").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec("CREATE TABLE IF NOT EXISTS worker_metrics").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec("CREATE TABLE IF NOT EXISTS worker_lastlogs").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec("CREATE TABLE IF NOT EXISTS workers").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectExec("CREATE TABLE IF NOT EXISTS suggestion_param").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectExec("CREATE TABLE IF NOT EXISTS earlystop_param").WithArgs().WillReturnResult(sqlmock.NewResult(1, 1)) db_interface.DB_Init() os.Exit(m.Run()) @@ -70,7 +72,7 @@ func TestGetStudyConfig(t *testing.T) { "objective_value_name", "metrics", }). - AddRow("abc", "test", "admin", 1, 0.99, "{}", "random", "test", "", "", "", "")) + AddRow("abc", "test", "admin", 1, 0.99, "{}", "random", "medianstopping", "", "", "")) study, err := db_interface.GetStudyConfig(id) if err != nil { t.Errorf("GetStudyConfig failed: %v", err) diff --git a/pkg/mock/api/manager.go b/pkg/mock/api/manager.go index b0629cdd1f6..5c116910dee 100644 --- a/pkg/mock/api/manager.go +++ b/pkg/mock/api/manager.go @@ -35,184 +35,238 @@ func (m *MockManagerClient) EXPECT() *MockManagerClientMockRecorder { return m.recorder } -// AddMeasurementToTrials mocks base method -func (m *MockManagerClient) AddMeasurementToTrials(arg0 context.Context, arg1 *api.AddMeasurementToTrialsRequest, arg2 ...grpc.CallOption) (*api.AddMeasurementToTrialsReply, error) { +// CreateStudy mocks base method +func (m *MockManagerClient) CreateStudy(arg0 context.Context, arg1 *api.CreateStudyRequest, arg2 ...grpc.CallOption) (*api.CreateStudyReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "AddMeasurementToTrials", varargs...) - ret0, _ := ret[0].(*api.AddMeasurementToTrialsReply) + ret := m.ctrl.Call(m, "CreateStudy", varargs...) + ret0, _ := ret[0].(*api.CreateStudyReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// AddMeasurementToTrials indicates an expected call of AddMeasurementToTrials -func (mr *MockManagerClientMockRecorder) AddMeasurementToTrials(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// CreateStudy indicates an expected call of CreateStudy +func (mr *MockManagerClientMockRecorder) CreateStudy(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddMeasurementToTrials", reflect.TypeOf((*MockManagerClient)(nil).AddMeasurementToTrials), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStudy", reflect.TypeOf((*MockManagerClient)(nil).CreateStudy), varargs...) } -// CompleteTrial mocks base method -func (m *MockManagerClient) CompleteTrial(arg0 context.Context, arg1 *api.CompleteTrialRequest, arg2 ...grpc.CallOption) (*api.CompleteTrialReply, error) { +// GetEarlyStoppingParameters mocks base method +func (m *MockManagerClient) GetEarlyStoppingParameters(arg0 context.Context, arg1 *api.GetEarlyStoppingParametersRequest, arg2 ...grpc.CallOption) (*api.GetEarlyStoppingParametersReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "CompleteTrial", varargs...) - ret0, _ := ret[0].(*api.CompleteTrialReply) + ret := m.ctrl.Call(m, "GetEarlyStoppingParameters", varargs...) + ret0, _ := ret[0].(*api.GetEarlyStoppingParametersReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// CompleteTrial indicates an expected call of CompleteTrial -func (mr *MockManagerClientMockRecorder) CompleteTrial(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetEarlyStoppingParameters indicates an expected call of GetEarlyStoppingParameters +func (mr *MockManagerClientMockRecorder) GetEarlyStoppingParameters(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CompleteTrial", reflect.TypeOf((*MockManagerClient)(nil).CompleteTrial), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEarlyStoppingParameters", reflect.TypeOf((*MockManagerClient)(nil).GetEarlyStoppingParameters), varargs...) } -// CreateStudy mocks base method -func (m *MockManagerClient) CreateStudy(arg0 context.Context, arg1 *api.CreateStudyRequest, arg2 ...grpc.CallOption) (*api.CreateStudyReply, error) { +// GetMetrics mocks base method +func (m *MockManagerClient) GetMetrics(arg0 context.Context, arg1 *api.GetMetricsRequest, arg2 ...grpc.CallOption) (*api.GetMetricsReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "CreateStudy", varargs...) - ret0, _ := ret[0].(*api.CreateStudyReply) + ret := m.ctrl.Call(m, "GetMetrics", varargs...) + ret0, _ := ret[0].(*api.GetMetricsReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// CreateStudy indicates an expected call of CreateStudy -func (mr *MockManagerClientMockRecorder) CreateStudy(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetMetrics indicates an expected call of GetMetrics +func (mr *MockManagerClientMockRecorder) GetMetrics(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStudy", reflect.TypeOf((*MockManagerClient)(nil).CreateStudy), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMetrics", reflect.TypeOf((*MockManagerClient)(nil).GetMetrics), varargs...) } -// EarlyStopping mocks base method -func (m *MockManagerClient) EarlyStopping(arg0 context.Context, arg1 *api.EarlyStoppingRequest, arg2 ...grpc.CallOption) (*api.EarlyStoppingReply, error) { +// GetSavedModels mocks base method +func (m *MockManagerClient) GetSavedModels(arg0 context.Context, arg1 *api.GetSavedModelsRequest, arg2 ...grpc.CallOption) (*api.GetSavedModelsReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "EarlyStopping", varargs...) - ret0, _ := ret[0].(*api.EarlyStoppingReply) + ret := m.ctrl.Call(m, "GetSavedModels", varargs...) + ret0, _ := ret[0].(*api.GetSavedModelsReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// EarlyStopping indicates an expected call of EarlyStopping -func (mr *MockManagerClientMockRecorder) EarlyStopping(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetSavedModels indicates an expected call of GetSavedModels +func (mr *MockManagerClientMockRecorder) GetSavedModels(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EarlyStopping", reflect.TypeOf((*MockManagerClient)(nil).EarlyStopping), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSavedModels", reflect.TypeOf((*MockManagerClient)(nil).GetSavedModels), varargs...) } -// GetObjectValue mocks base method -func (m *MockManagerClient) GetObjectValue(arg0 context.Context, arg1 *api.GetObjectValueRequest, arg2 ...grpc.CallOption) (*api.GetObjectValueReply, error) { +// GetSavedStudies mocks base method +func (m *MockManagerClient) GetSavedStudies(arg0 context.Context, arg1 *api.GetSavedStudiesRequest, arg2 ...grpc.CallOption) (*api.GetSavedStudiesReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "GetObjectValue", varargs...) - ret0, _ := ret[0].(*api.GetObjectValueReply) + ret := m.ctrl.Call(m, "GetSavedStudies", varargs...) + ret0, _ := ret[0].(*api.GetSavedStudiesReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetObjectValue indicates an expected call of GetObjectValue -func (mr *MockManagerClientMockRecorder) GetObjectValue(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetSavedStudies indicates an expected call of GetSavedStudies +func (mr *MockManagerClientMockRecorder) GetSavedStudies(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectValue", reflect.TypeOf((*MockManagerClient)(nil).GetObjectValue), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSavedStudies", reflect.TypeOf((*MockManagerClient)(nil).GetSavedStudies), varargs...) } -// GetSavedModel mocks base method -func (m *MockManagerClient) GetSavedModel(arg0 context.Context, arg1 *api.GetSavedModelRequest, arg2 ...grpc.CallOption) (*api.GetSavedModelReply, error) { +// GetShouldStopWorkers mocks base method +func (m *MockManagerClient) GetShouldStopWorkers(arg0 context.Context, arg1 *api.GetShouldStopWorkersRequest, arg2 ...grpc.CallOption) (*api.GetShouldStopWorkersReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "GetSavedModel", varargs...) - ret0, _ := ret[0].(*api.GetSavedModelReply) + ret := m.ctrl.Call(m, "GetShouldStopWorkers", varargs...) + ret0, _ := ret[0].(*api.GetShouldStopWorkersReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetSavedModel indicates an expected call of GetSavedModel -func (mr *MockManagerClientMockRecorder) GetSavedModel(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetShouldStopWorkers indicates an expected call of GetShouldStopWorkers +func (mr *MockManagerClientMockRecorder) GetShouldStopWorkers(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSavedModel", reflect.TypeOf((*MockManagerClient)(nil).GetSavedModel), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShouldStopWorkers", reflect.TypeOf((*MockManagerClient)(nil).GetShouldStopWorkers), varargs...) } -// GetSavedModels mocks base method -func (m *MockManagerClient) GetSavedModels(arg0 context.Context, arg1 *api.GetSavedModelsRequest, arg2 ...grpc.CallOption) (*api.GetSavedModelsReply, error) { +// GetStudy mocks base method +func (m *MockManagerClient) GetStudy(arg0 context.Context, arg1 *api.GetStudyRequest, arg2 ...grpc.CallOption) (*api.GetStudyReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "GetSavedModels", varargs...) - ret0, _ := ret[0].(*api.GetSavedModelsReply) + ret := m.ctrl.Call(m, "GetStudy", varargs...) + ret0, _ := ret[0].(*api.GetStudyReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetSavedModels indicates an expected call of GetSavedModels -func (mr *MockManagerClientMockRecorder) GetSavedModels(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetStudy indicates an expected call of GetStudy +func (mr *MockManagerClientMockRecorder) GetStudy(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSavedModels", reflect.TypeOf((*MockManagerClient)(nil).GetSavedModels), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStudy", reflect.TypeOf((*MockManagerClient)(nil).GetStudy), varargs...) } -// GetSavedStudies mocks base method -func (m *MockManagerClient) GetSavedStudies(arg0 context.Context, arg1 *api.GetSavedStudiesRequest, arg2 ...grpc.CallOption) (*api.GetSavedStudiesReply, error) { +// GetStudyList mocks base method +func (m *MockManagerClient) GetStudyList(arg0 context.Context, arg1 *api.GetStudyListRequest, arg2 ...grpc.CallOption) (*api.GetStudyListReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "GetSavedStudies", varargs...) - ret0, _ := ret[0].(*api.GetSavedStudiesReply) + ret := m.ctrl.Call(m, "GetStudyList", varargs...) + ret0, _ := ret[0].(*api.GetStudyListReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetSavedStudies indicates an expected call of GetSavedStudies -func (mr *MockManagerClientMockRecorder) GetSavedStudies(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetStudyList indicates an expected call of GetStudyList +func (mr *MockManagerClientMockRecorder) GetStudyList(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSavedStudies", reflect.TypeOf((*MockManagerClient)(nil).GetSavedStudies), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStudyList", reflect.TypeOf((*MockManagerClient)(nil).GetStudyList), varargs...) } -// GetStudies mocks base method -func (m *MockManagerClient) GetStudies(arg0 context.Context, arg1 *api.GetStudiesRequest, arg2 ...grpc.CallOption) (*api.GetStudiesReply, error) { +// GetSuggestionParameters mocks base method +func (m *MockManagerClient) GetSuggestionParameters(arg0 context.Context, arg1 *api.GetSuggestionParametersRequest, arg2 ...grpc.CallOption) (*api.GetSuggestionParametersReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "GetStudies", varargs...) - ret0, _ := ret[0].(*api.GetStudiesReply) + ret := m.ctrl.Call(m, "GetSuggestionParameters", varargs...) + ret0, _ := ret[0].(*api.GetSuggestionParametersReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetStudies indicates an expected call of GetStudies -func (mr *MockManagerClientMockRecorder) GetStudies(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetSuggestionParameters indicates an expected call of GetSuggestionParameters +func (mr *MockManagerClientMockRecorder) GetSuggestionParameters(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStudies", reflect.TypeOf((*MockManagerClient)(nil).GetStudies), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestionParameters", reflect.TypeOf((*MockManagerClient)(nil).GetSuggestionParameters), varargs...) } -// InitializeSuggestService mocks base method -func (m *MockManagerClient) InitializeSuggestService(arg0 context.Context, arg1 *api.InitializeSuggestServiceRequest, arg2 ...grpc.CallOption) (*api.InitializeSuggestServiceReply, error) { +// GetSuggestions mocks base method +func (m *MockManagerClient) GetSuggestions(arg0 context.Context, arg1 *api.GetSuggestionsRequest, arg2 ...grpc.CallOption) (*api.GetSuggestionsReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "InitializeSuggestService", varargs...) - ret0, _ := ret[0].(*api.InitializeSuggestServiceReply) + ret := m.ctrl.Call(m, "GetSuggestions", varargs...) + ret0, _ := ret[0].(*api.GetSuggestionsReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// InitializeSuggestService indicates an expected call of InitializeSuggestService -func (mr *MockManagerClientMockRecorder) InitializeSuggestService(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetSuggestions indicates an expected call of GetSuggestions +func (mr *MockManagerClientMockRecorder) GetSuggestions(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitializeSuggestService", reflect.TypeOf((*MockManagerClient)(nil).InitializeSuggestService), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestions", reflect.TypeOf((*MockManagerClient)(nil).GetSuggestions), varargs...) +} + +// GetTrials mocks base method +func (m *MockManagerClient) GetTrials(arg0 context.Context, arg1 *api.GetTrialsRequest, arg2 ...grpc.CallOption) (*api.GetTrialsReply, error) { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetTrials", varargs...) + ret0, _ := ret[0].(*api.GetTrialsReply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTrials indicates an expected call of GetTrials +func (mr *MockManagerClientMockRecorder) GetTrials(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrials", reflect.TypeOf((*MockManagerClient)(nil).GetTrials), varargs...) +} + +// GetWorkers mocks base method +func (m *MockManagerClient) GetWorkers(arg0 context.Context, arg1 *api.GetWorkersRequest, arg2 ...grpc.CallOption) (*api.GetWorkersReply, error) { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetWorkers", varargs...) + ret0, _ := ret[0].(*api.GetWorkersReply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetWorkers indicates an expected call of GetWorkers +func (mr *MockManagerClientMockRecorder) GetWorkers(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkers", reflect.TypeOf((*MockManagerClient)(nil).GetWorkers), varargs...) +} + +// RunTrial mocks base method +func (m *MockManagerClient) RunTrial(arg0 context.Context, arg1 *api.RunTrialRequest, arg2 ...grpc.CallOption) (*api.RunTrialReply, error) { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "RunTrial", varargs...) + ret0, _ := ret[0].(*api.RunTrialReply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RunTrial indicates an expected call of RunTrial +func (mr *MockManagerClientMockRecorder) RunTrial(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunTrial", reflect.TypeOf((*MockManagerClient)(nil).RunTrial), varargs...) } // SaveModel mocks base method @@ -251,6 +305,42 @@ func (mr *MockManagerClientMockRecorder) SaveStudy(arg0, arg1 interface{}, arg2 return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveStudy", reflect.TypeOf((*MockManagerClient)(nil).SaveStudy), varargs...) } +// SetEarlyStoppingParameters mocks base method +func (m *MockManagerClient) SetEarlyStoppingParameters(arg0 context.Context, arg1 *api.SetEarlyStoppingParametersRequest, arg2 ...grpc.CallOption) (*api.SetEarlyStoppingParametersReply, error) { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SetEarlyStoppingParameters", varargs...) + ret0, _ := ret[0].(*api.SetEarlyStoppingParametersReply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetEarlyStoppingParameters indicates an expected call of SetEarlyStoppingParameters +func (mr *MockManagerClientMockRecorder) SetEarlyStoppingParameters(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetEarlyStoppingParameters", reflect.TypeOf((*MockManagerClient)(nil).SetEarlyStoppingParameters), varargs...) +} + +// SetSuggestionParameters mocks base method +func (m *MockManagerClient) SetSuggestionParameters(arg0 context.Context, arg1 *api.SetSuggestionParametersRequest, arg2 ...grpc.CallOption) (*api.SetSuggestionParametersReply, error) { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SetSuggestionParameters", varargs...) + ret0, _ := ret[0].(*api.SetSuggestionParametersReply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetSuggestionParameters indicates an expected call of SetSuggestionParameters +func (mr *MockManagerClientMockRecorder) SetSuggestionParameters(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSuggestionParameters", reflect.TypeOf((*MockManagerClient)(nil).SetSuggestionParameters), varargs...) +} + // StopStudy mocks base method func (m *MockManagerClient) StopStudy(arg0 context.Context, arg1 *api.StopStudyRequest, arg2 ...grpc.CallOption) (*api.StopStudyReply, error) { varargs := []interface{}{arg0, arg1} @@ -269,20 +359,20 @@ func (mr *MockManagerClientMockRecorder) StopStudy(arg0, arg1 interface{}, arg2 return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopStudy", reflect.TypeOf((*MockManagerClient)(nil).StopStudy), varargs...) } -// SuggestTrials mocks base method -func (m *MockManagerClient) SuggestTrials(arg0 context.Context, arg1 *api.SuggestTrialsRequest, arg2 ...grpc.CallOption) (*api.SuggestTrialsReply, error) { +// StopWorkers mocks base method +func (m *MockManagerClient) StopWorkers(arg0 context.Context, arg1 *api.StopWorkersRequest, arg2 ...grpc.CallOption) (*api.StopWorkersReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "SuggestTrials", varargs...) - ret0, _ := ret[0].(*api.SuggestTrialsReply) + ret := m.ctrl.Call(m, "StopWorkers", varargs...) + ret0, _ := ret[0].(*api.StopWorkersReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// SuggestTrials indicates an expected call of SuggestTrials -func (mr *MockManagerClientMockRecorder) SuggestTrials(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// StopWorkers indicates an expected call of StopWorkers +func (mr *MockManagerClientMockRecorder) StopWorkers(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SuggestTrials", reflect.TypeOf((*MockManagerClient)(nil).SuggestTrials), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopWorkers", reflect.TypeOf((*MockManagerClient)(nil).StopWorkers), varargs...) } diff --git a/pkg/mock/api/suggestion.go b/pkg/mock/api/suggestion.go index f4af59e79b5..423e7aa0404 100644 --- a/pkg/mock/api/suggestion.go +++ b/pkg/mock/api/suggestion.go @@ -35,56 +35,20 @@ func (m *MockSuggestionClient) EXPECT() *MockSuggestionClientMockRecorder { return m.recorder } -// GenerateTrials mocks base method -func (m *MockSuggestionClient) GenerateTrials(arg0 context.Context, arg1 *api.GenerateTrialsRequest, arg2 ...grpc.CallOption) (*api.GenerateTrialsReply, error) { +// GetSuggestions mocks base method +func (m *MockSuggestionClient) GetSuggestions(arg0 context.Context, arg1 *api.GetSuggestionsRequest, arg2 ...grpc.CallOption) (*api.GetSuggestionsReply, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "GenerateTrials", varargs...) - ret0, _ := ret[0].(*api.GenerateTrialsReply) + ret := m.ctrl.Call(m, "GetSuggestions", varargs...) + ret0, _ := ret[0].(*api.GetSuggestionsReply) ret1, _ := ret[1].(error) return ret0, ret1 } -// GenerateTrials indicates an expected call of GenerateTrials -func (mr *MockSuggestionClientMockRecorder) GenerateTrials(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// GetSuggestions indicates an expected call of GetSuggestions +func (mr *MockSuggestionClientMockRecorder) GetSuggestions(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenerateTrials", reflect.TypeOf((*MockSuggestionClient)(nil).GenerateTrials), varargs...) -} - -// SetSuggestionParameters mocks base method -func (m *MockSuggestionClient) SetSuggestionParameters(arg0 context.Context, arg1 *api.SetSuggestionParametersRequest, arg2 ...grpc.CallOption) (*api.SetSuggestionParametersReply, error) { - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "SetSuggestionParameters", varargs...) - ret0, _ := ret[0].(*api.SetSuggestionParametersReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SetSuggestionParameters indicates an expected call of SetSuggestionParameters -func (mr *MockSuggestionClientMockRecorder) SetSuggestionParameters(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSuggestionParameters", reflect.TypeOf((*MockSuggestionClient)(nil).SetSuggestionParameters), varargs...) -} - -// StopSuggestion mocks base method -func (m *MockSuggestionClient) StopSuggestion(arg0 context.Context, arg1 *api.StopSuggestionRequest, arg2 ...grpc.CallOption) (*api.StopSuggestionReply, error) { - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "StopSuggestion", varargs...) - ret0, _ := ret[0].(*api.StopSuggestionReply) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// StopSuggestion indicates an expected call of StopSuggestion -func (mr *MockSuggestionClientMockRecorder) StopSuggestion(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopSuggestion", reflect.TypeOf((*MockSuggestionClient)(nil).StopSuggestion), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestions", reflect.TypeOf((*MockSuggestionClient)(nil).GetSuggestions), varargs...) } diff --git a/pkg/mock/db/db.go b/pkg/mock/db/db.go index e09841e8c7b..80030137bf7 100644 --- a/pkg/mock/db/db.go +++ b/pkg/mock/db/db.go @@ -60,6 +60,19 @@ func (mr *MockVizierDBInterfaceMockRecorder) CreateTrial(arg0 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTrial", reflect.TypeOf((*MockVizierDBInterface)(nil).CreateTrial), arg0) } +// CreateWorker mocks base method +func (m *MockVizierDBInterface) CreateWorker(arg0 *api.Worker) (string, error) { + ret := m.ctrl.Call(m, "CreateWorker", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateWorker indicates an expected call of CreateWorker +func (mr *MockVizierDBInterfaceMockRecorder) CreateWorker(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateWorker", reflect.TypeOf((*MockVizierDBInterface)(nil).CreateWorker), arg0) +} + // DB_Init mocks base method func (m *MockVizierDBInterface) DB_Init() { m.ctrl.Call(m, "DB_Init") @@ -94,6 +107,31 @@ func (mr *MockVizierDBInterfaceMockRecorder) DeleteTrial(arg0 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTrial", reflect.TypeOf((*MockVizierDBInterface)(nil).DeleteTrial), arg0) } +// DeleteWorker mocks base method +func (m *MockVizierDBInterface) DeleteWorker(arg0 string) error { + ret := m.ctrl.Call(m, "DeleteWorker", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteWorker indicates an expected call of DeleteWorker +func (mr *MockVizierDBInterfaceMockRecorder) DeleteWorker(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWorker", reflect.TypeOf((*MockVizierDBInterface)(nil).DeleteWorker), arg0) +} + +// GetEarlyStopParam mocks base method +func (m *MockVizierDBInterface) GetEarlyStopParam(arg0 string) ([]*api.EarlyStoppingParameter, error) { + ret := m.ctrl.Call(m, "GetEarlyStopParam", arg0) + ret0, _ := ret[0].([]*api.EarlyStoppingParameter) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetEarlyStopParam indicates an expected call of GetEarlyStopParam +func (mr *MockVizierDBInterfaceMockRecorder) GetEarlyStopParam(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEarlyStopParam", reflect.TypeOf((*MockVizierDBInterface)(nil).GetEarlyStopParam), arg0) +} + // GetStudyConfig mocks base method func (m *MockVizierDBInterface) GetStudyConfig(arg0 string) (*api.StudyConfig, error) { ret := m.ctrl.Call(m, "GetStudyConfig", arg0) @@ -120,6 +158,19 @@ func (mr *MockVizierDBInterfaceMockRecorder) GetStudyList() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStudyList", reflect.TypeOf((*MockVizierDBInterface)(nil).GetStudyList)) } +// GetSuggestionParam mocks base method +func (m *MockVizierDBInterface) GetSuggestionParam(arg0 string) ([]*api.SuggestionParameter, error) { + ret := m.ctrl.Call(m, "GetSuggestionParam", arg0) + ret0, _ := ret[0].([]*api.SuggestionParameter) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSuggestionParam indicates an expected call of GetSuggestionParam +func (mr *MockVizierDBInterfaceMockRecorder) GetSuggestionParam(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestionParam", reflect.TypeOf((*MockVizierDBInterface)(nil).GetSuggestionParam), arg0) +} + // GetTrial mocks base method func (m *MockVizierDBInterface) GetTrial(arg0 string) (*api.Trial, error) { ret := m.ctrl.Call(m, "GetTrial", arg0) @@ -146,59 +197,148 @@ func (mr *MockVizierDBInterfaceMockRecorder) GetTrialList(arg0 interface{}) *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialList", reflect.TypeOf((*MockVizierDBInterface)(nil).GetTrialList), arg0) } -// GetTrialLogs mocks base method -func (m *MockVizierDBInterface) GetTrialLogs(arg0 string, arg1 *db.GetTrialLogOpts) ([]*db.TrialLog, error) { - ret := m.ctrl.Call(m, "GetTrialLogs", arg0, arg1) - ret0, _ := ret[0].([]*db.TrialLog) +// GetTrialStatus mocks base method +func (m *MockVizierDBInterface) GetTrialStatus(arg0 string) (api.State, error) { + ret := m.ctrl.Call(m, "GetTrialStatus", arg0) + ret0, _ := ret[0].(api.State) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetTrialLogs indicates an expected call of GetTrialLogs -func (mr *MockVizierDBInterfaceMockRecorder) GetTrialLogs(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialLogs", reflect.TypeOf((*MockVizierDBInterface)(nil).GetTrialLogs), arg0, arg1) +// GetTrialStatus indicates an expected call of GetTrialStatus +func (mr *MockVizierDBInterfaceMockRecorder) GetTrialStatus(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialStatus", reflect.TypeOf((*MockVizierDBInterface)(nil).GetTrialStatus), arg0) } -// GetTrialStatus mocks base method -func (m *MockVizierDBInterface) GetTrialStatus(arg0 string) (api.TrialState, error) { - ret := m.ctrl.Call(m, "GetTrialStatus", arg0) - ret0, _ := ret[0].(api.TrialState) +// GetWorker mocks base method +func (m *MockVizierDBInterface) GetWorker(arg0 string) (*api.Worker, error) { + ret := m.ctrl.Call(m, "GetWorker", arg0) + ret0, _ := ret[0].(*api.Worker) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetTrialStatus indicates an expected call of GetTrialStatus -func (mr *MockVizierDBInterfaceMockRecorder) GetTrialStatus(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialStatus", reflect.TypeOf((*MockVizierDBInterface)(nil).GetTrialStatus), arg0) +// GetWorker indicates an expected call of GetWorker +func (mr *MockVizierDBInterfaceMockRecorder) GetWorker(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorker", reflect.TypeOf((*MockVizierDBInterface)(nil).GetWorker), arg0) +} + +// GetWorkerList mocks base method +func (m *MockVizierDBInterface) GetWorkerList(arg0 string) ([]*api.Worker, error) { + ret := m.ctrl.Call(m, "GetWorkerList", arg0) + ret0, _ := ret[0].([]*api.Worker) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetWorkerList indicates an expected call of GetWorkerList +func (mr *MockVizierDBInterfaceMockRecorder) GetWorkerList(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkerList", reflect.TypeOf((*MockVizierDBInterface)(nil).GetWorkerList), arg0) } -// GetTrialTimestamp mocks base method -func (m *MockVizierDBInterface) GetTrialTimestamp(arg0 string) (*time.Time, error) { - ret := m.ctrl.Call(m, "GetTrialTimestamp", arg0) +// GetWorkerLogs mocks base method +func (m *MockVizierDBInterface) GetWorkerLogs(arg0 string, arg1 *db.GetWorkerLogOpts) ([]*db.WorkerLog, error) { + ret := m.ctrl.Call(m, "GetWorkerLogs", arg0, arg1) + ret0, _ := ret[0].([]*db.WorkerLog) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetWorkerLogs indicates an expected call of GetWorkerLogs +func (mr *MockVizierDBInterfaceMockRecorder) GetWorkerLogs(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkerLogs", reflect.TypeOf((*MockVizierDBInterface)(nil).GetWorkerLogs), arg0, arg1) +} + +// GetWorkerStatus mocks base method +func (m *MockVizierDBInterface) GetWorkerStatus(arg0 string) (*api.State, error) { + ret := m.ctrl.Call(m, "GetWorkerStatus", arg0) + ret0, _ := ret[0].(*api.State) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetWorkerStatus indicates an expected call of GetWorkerStatus +func (mr *MockVizierDBInterfaceMockRecorder) GetWorkerStatus(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkerStatus", reflect.TypeOf((*MockVizierDBInterface)(nil).GetWorkerStatus), arg0) +} + +// GetWorkerTimestamp mocks base method +func (m *MockVizierDBInterface) GetWorkerTimestamp(arg0 string) (*time.Time, error) { + ret := m.ctrl.Call(m, "GetWorkerTimestamp", arg0) ret0, _ := ret[0].(*time.Time) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetTrialTimestamp indicates an expected call of GetTrialTimestamp -func (mr *MockVizierDBInterfaceMockRecorder) GetTrialTimestamp(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialTimestamp", reflect.TypeOf((*MockVizierDBInterface)(nil).GetTrialTimestamp), arg0) +// GetWorkerTimestamp indicates an expected call of GetWorkerTimestamp +func (mr *MockVizierDBInterfaceMockRecorder) GetWorkerTimestamp(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkerTimestamp", reflect.TypeOf((*MockVizierDBInterface)(nil).GetWorkerTimestamp), arg0) +} + +// SetEarlyStopParam mocks base method +func (m *MockVizierDBInterface) SetEarlyStopParam(arg0, arg1 string, arg2 []*api.EarlyStoppingParameter) (string, error) { + ret := m.ctrl.Call(m, "SetEarlyStopParam", arg0, arg1, arg2) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetEarlyStopParam indicates an expected call of SetEarlyStopParam +func (mr *MockVizierDBInterfaceMockRecorder) SetEarlyStopParam(arg0, arg1, arg2 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetEarlyStopParam", reflect.TypeOf((*MockVizierDBInterface)(nil).SetEarlyStopParam), arg0, arg1, arg2) +} + +// SetSuggestionParam mocks base method +func (m *MockVizierDBInterface) SetSuggestionParam(arg0, arg1 string, arg2 []*api.SuggestionParameter) (string, error) { + ret := m.ctrl.Call(m, "SetSuggestionParam", arg0, arg1, arg2) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetSuggestionParam indicates an expected call of SetSuggestionParam +func (mr *MockVizierDBInterfaceMockRecorder) SetSuggestionParam(arg0, arg1, arg2 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSuggestionParam", reflect.TypeOf((*MockVizierDBInterface)(nil).SetSuggestionParam), arg0, arg1, arg2) } -// StoreTrialLogs mocks base method -func (m *MockVizierDBInterface) StoreTrialLogs(arg0 string, arg1 []string) error { - ret := m.ctrl.Call(m, "StoreTrialLogs", arg0, arg1) +// StoreWorkerLogs mocks base method +func (m *MockVizierDBInterface) StoreWorkerLogs(arg0 string, arg1 []string) error { + ret := m.ctrl.Call(m, "StoreWorkerLogs", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// StoreTrialLogs indicates an expected call of StoreTrialLogs -func (mr *MockVizierDBInterfaceMockRecorder) StoreTrialLogs(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreTrialLogs", reflect.TypeOf((*MockVizierDBInterface)(nil).StoreTrialLogs), arg0, arg1) +// StoreWorkerLogs indicates an expected call of StoreWorkerLogs +func (mr *MockVizierDBInterfaceMockRecorder) StoreWorkerLogs(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreWorkerLogs", reflect.TypeOf((*MockVizierDBInterface)(nil).StoreWorkerLogs), arg0, arg1) +} + +// UpdateEarlyStopParam mocks base method +func (m *MockVizierDBInterface) UpdateEarlyStopParam(arg0 string, arg1 []*api.EarlyStoppingParameter) error { + ret := m.ctrl.Call(m, "UpdateEarlyStopParam", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateEarlyStopParam indicates an expected call of UpdateEarlyStopParam +func (mr *MockVizierDBInterfaceMockRecorder) UpdateEarlyStopParam(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEarlyStopParam", reflect.TypeOf((*MockVizierDBInterface)(nil).UpdateEarlyStopParam), arg0, arg1) +} + +// UpdateSuggestionParam mocks base method +func (m *MockVizierDBInterface) UpdateSuggestionParam(arg0 string, arg1 []*api.SuggestionParameter) error { + ret := m.ctrl.Call(m, "UpdateSuggestionParam", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateSuggestionParam indicates an expected call of UpdateSuggestionParam +func (mr *MockVizierDBInterfaceMockRecorder) UpdateSuggestionParam(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSuggestionParam", reflect.TypeOf((*MockVizierDBInterface)(nil).UpdateSuggestionParam), arg0, arg1) } // UpdateTrial mocks base method -func (m *MockVizierDBInterface) UpdateTrial(arg0 string, arg1 api.TrialState) error { +func (m *MockVizierDBInterface) UpdateTrial(arg0 string, arg1 api.State) error { ret := m.ctrl.Call(m, "UpdateTrial", arg0, arg1) ret0, _ := ret[0].(error) return ret0 @@ -208,3 +348,15 @@ func (m *MockVizierDBInterface) UpdateTrial(arg0 string, arg1 api.TrialState) er func (mr *MockVizierDBInterfaceMockRecorder) UpdateTrial(arg0, arg1 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTrial", reflect.TypeOf((*MockVizierDBInterface)(nil).UpdateTrial), arg0, arg1) } + +// UpdateWorker mocks base method +func (m *MockVizierDBInterface) UpdateWorker(arg0 string, arg1 api.State) error { + ret := m.ctrl.Call(m, "UpdateWorker", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateWorker indicates an expected call of UpdateWorker +func (mr *MockVizierDBInterfaceMockRecorder) UpdateWorker(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorker", reflect.TypeOf((*MockVizierDBInterface)(nil).UpdateWorker), arg0, arg1) +} diff --git a/pkg/mock/worker/worker.go b/pkg/mock/worker/worker.go index 6672a59cbce..4651142852e 100644 --- a/pkg/mock/worker/worker.go +++ b/pkg/mock/worker/worker.go @@ -33,18 +33,6 @@ func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder { return m.recorder } -// CheckRunningTrials mocks base method -func (m *MockInterface) CheckRunningTrials(arg0, arg1 string) error { - ret := m.ctrl.Call(m, "CheckRunningTrials", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// CheckRunningTrials indicates an expected call of CheckRunningTrials -func (mr *MockInterfaceMockRecorder) CheckRunningTrials(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckRunningTrials", reflect.TypeOf((*MockInterface)(nil).CheckRunningTrials), arg0, arg1) -} - // CleanWorkers mocks base method func (m *MockInterface) CleanWorkers(arg0 string) error { ret := m.ctrl.Call(m, "CleanWorkers", arg0) @@ -57,89 +45,63 @@ func (mr *MockInterfaceMockRecorder) CleanWorkers(arg0 interface{}) *gomock.Call return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CleanWorkers", reflect.TypeOf((*MockInterface)(nil).CleanWorkers), arg0) } -// CompleteTrial mocks base method -func (m *MockInterface) CompleteTrial(arg0, arg1 string, arg2 bool) error { - ret := m.ctrl.Call(m, "CompleteTrial", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 +// IsWorkerComplete mocks base method +func (m *MockInterface) IsWorkerComplete(arg0 string) (bool, error) { + ret := m.ctrl.Call(m, "IsWorkerComplete", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// CompleteTrial indicates an expected call of CompleteTrial -func (mr *MockInterfaceMockRecorder) CompleteTrial(arg0, arg1, arg2 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CompleteTrial", reflect.TypeOf((*MockInterface)(nil).CompleteTrial), arg0, arg1, arg2) +// IsWorkerComplete indicates an expected call of IsWorkerComplete +func (mr *MockInterfaceMockRecorder) IsWorkerComplete(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsWorkerComplete", reflect.TypeOf((*MockInterface)(nil).IsWorkerComplete), arg0) } -// GetCompletedTrials mocks base method -func (m *MockInterface) GetCompletedTrials(arg0 string) []*api.Trial { - ret := m.ctrl.Call(m, "GetCompletedTrials", arg0) - ret0, _ := ret[0].([]*api.Trial) +// SpawnWorker mocks base method +func (m *MockInterface) SpawnWorker(arg0 string, arg1 *api.WorkerConfig) error { + ret := m.ctrl.Call(m, "SpawnWorker", arg0, arg1) + ret0, _ := ret[0].(error) return ret0 } -// GetCompletedTrials indicates an expected call of GetCompletedTrials -func (mr *MockInterfaceMockRecorder) GetCompletedTrials(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCompletedTrials", reflect.TypeOf((*MockInterface)(nil).GetCompletedTrials), arg0) +// SpawnWorker indicates an expected call of SpawnWorker +func (mr *MockInterfaceMockRecorder) SpawnWorker(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpawnWorker", reflect.TypeOf((*MockInterface)(nil).SpawnWorker), arg0, arg1) } -// GetRunningTrials mocks base method -func (m *MockInterface) GetRunningTrials(arg0 string) []*api.Trial { - ret := m.ctrl.Call(m, "GetRunningTrials", arg0) - ret0, _ := ret[0].([]*api.Trial) +// StopWorkers mocks base method +func (m *MockInterface) StopWorkers(arg0 string, arg1 []string, arg2 bool) error { + ret := m.ctrl.Call(m, "StopWorkers", arg0, arg1, arg2) + ret0, _ := ret[0].(error) return ret0 } -// GetRunningTrials indicates an expected call of GetRunningTrials -func (mr *MockInterfaceMockRecorder) GetRunningTrials(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRunningTrials", reflect.TypeOf((*MockInterface)(nil).GetRunningTrials), arg0) -} - -// GetTrialEvLogs mocks base method -func (m *MockInterface) GetTrialEvLogs(arg0, arg1 string, arg2 []string, arg3 string) ([]*api.EvaluationLog, error) { - ret := m.ctrl.Call(m, "GetTrialEvLogs", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].([]*api.EvaluationLog) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTrialEvLogs indicates an expected call of GetTrialEvLogs -func (mr *MockInterfaceMockRecorder) GetTrialEvLogs(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialEvLogs", reflect.TypeOf((*MockInterface)(nil).GetTrialEvLogs), arg0, arg1, arg2, arg3) -} - -// GetTrialObjValue mocks base method -func (m *MockInterface) GetTrialObjValue(arg0, arg1, arg2 string) (string, error) { - ret := m.ctrl.Call(m, "GetTrialObjValue", arg0, arg1, arg2) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 +// StopWorkers indicates an expected call of StopWorkers +func (mr *MockInterfaceMockRecorder) StopWorkers(arg0, arg1, arg2 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopWorkers", reflect.TypeOf((*MockInterface)(nil).StopWorkers), arg0, arg1, arg2) } -// GetTrialObjValue indicates an expected call of GetTrialObjValue -func (mr *MockInterfaceMockRecorder) GetTrialObjValue(arg0, arg1, arg2 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrialObjValue", reflect.TypeOf((*MockInterface)(nil).GetTrialObjValue), arg0, arg1, arg2) -} - -// IsTrialComplete mocks base method -func (m *MockInterface) IsTrialComplete(arg0, arg1 string) (bool, error) { - ret := m.ctrl.Call(m, "IsTrialComplete", arg0, arg1) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 +// StoreWorkerLog mocks base method +func (m *MockInterface) StoreWorkerLog(arg0 string) error { + ret := m.ctrl.Call(m, "StoreWorkerLog", arg0) + ret0, _ := ret[0].(error) + return ret0 } -// IsTrialComplete indicates an expected call of IsTrialComplete -func (mr *MockInterfaceMockRecorder) IsTrialComplete(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsTrialComplete", reflect.TypeOf((*MockInterface)(nil).IsTrialComplete), arg0, arg1) +// StoreWorkerLog indicates an expected call of StoreWorkerLog +func (mr *MockInterfaceMockRecorder) StoreWorkerLog(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreWorkerLog", reflect.TypeOf((*MockInterface)(nil).StoreWorkerLog), arg0) } -// SpawnWorkers mocks base method -func (m *MockInterface) SpawnWorkers(arg0 []*api.Trial, arg1 string) error { - ret := m.ctrl.Call(m, "SpawnWorkers", arg0, arg1) +// UpdateWorkerStatus mocks base method +func (m *MockInterface) UpdateWorkerStatus(arg0 string) error { + ret := m.ctrl.Call(m, "UpdateWorkerStatus", arg0) ret0, _ := ret[0].(error) return ret0 } -// SpawnWorkers indicates an expected call of SpawnWorkers -func (mr *MockInterfaceMockRecorder) SpawnWorkers(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpawnWorkers", reflect.TypeOf((*MockInterface)(nil).SpawnWorkers), arg0, arg1) +// UpdateWorkerStatus indicates an expected call of UpdateWorkerStatus +func (mr *MockInterfaceMockRecorder) UpdateWorkerStatus(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkerStatus", reflect.TypeOf((*MockInterface)(nil).UpdateWorkerStatus), arg0) } diff --git a/test/scripts/build.sh b/test/scripts/build.sh index 97672930a22..3cd8f00032c 100755 --- a/test/scripts/build.sh +++ b/test/scripts/build.sh @@ -50,14 +50,15 @@ pids+=($!) sleep 30 # wait for copy code to gcloud cp cmd/suggestion/grid/Dockerfile . +<<<<<<< HEAD gcloud container builds submit . --tag=${REGISTRY}/${REPO_NAME}/suggestion-grid:${VERSION} --project=${PROJECT} & pids+=($!) sleep 30 # wait for copy code to gcloud -cp cmd/suggestion/hyperband/Dockerfile . -gcloud container builds submit . --tag=${REGISTRY}/${REPO_NAME}/suggestion-hyperband:${VERSION} --project=${PROJECT} & -pids+=($!) -sleep 30 # wait for copy code to gcloud +#cp cmd/suggestion/hyperband/Dockerfile . +#gcloud container builds submit . --tag=${REGISTRY}/${REPO_NAME}/suggestion-hyperband:${VERSION} --project=${PROJECT} & +#pids+=($!) +#sleep 30 # wait for copy code to gcloud cp cmd/suggestion/bayesianoptimization/Dockerfile . gcloud container builds submit . --tag=${REGISTRY}/${REPO_NAME}/suggestion-bayesianoptimization:${VERSION} --project=${PROJECT} & @@ -69,11 +70,6 @@ gcloud container builds submit . --tag=${REGISTRY}/${REPO_NAME}/earlystopping-me pids+=($!) sleep 30 # wait for copy code to gcloud -cp dlk/Dockerfile . -gcloud container builds submit . --tag=${REGISTRY}/${REPO_NAME}/dlk-manager:${VERSION} --project=${PROJECT} & -pids+=($!) -sleep 30 # wait for copy code to gcloud - cp modeldb/Dockerfile . gcloud container builds submit . --tag=${REGISTRY}/${REPO_NAME}/katib-frontend:${VERSION} --project=${PROJECT} & pids+=($!) diff --git a/test/scripts/run-tests.sh b/test/scripts/run-tests.sh index 6f1f8ef7ac4..5e354793b7d 100755 --- a/test/scripts/run-tests.sh +++ b/test/scripts/run-tests.sh @@ -45,10 +45,9 @@ echo "Install Katib " sed -i -e "s@image: katib\/vizier-core@image: ${REGISTRY}\/${REPO_NAME}\/vizier-core:${VERSION}@" manifests/vizier/core/deployment.yaml sed -i -e "s@image: katib\/suggestion-random@image: ${REGISTRY}\/${REPO_NAME}\/suggestion-random:${VERSION}@" manifests/vizier/suggestion/random/deployment.yaml sed -i -e "s@image: katib\/suggestion-grid@image: ${REGISTRY}\/${REPO_NAME}\/suggestion-grid:${VERSION}@" manifests/vizier/suggestion/grid/deployment.yaml -sed -i -e "s@image: katib\/suggestion-hyperband@image: ${REGISTRY}\/${REPO_NAME}\/suggestion-hyperband:${VERSION}@" manifests/vizier/suggestion/hyperband/deployment.yaml -sed -i -e "s@image: katib\/suggestion-bayesianoptimization@image: ${REGISTRY}\/${REPO_NAME}\/suggestion-bayesianoptimization:${VERSION}@" manifests/vizier/suggestion/bayesianoptimization/deployment.yaml +#sed -i -e "s@image: katib\/suggestion-hyperband@image: ${REGISTRY}\/${REPO_NAME}\/suggestion-hyperband:${VERSION}@" manifests/vizier/suggestion/hyperband/deployment.yaml +#sed -i -e "s@image: katib\/suggestion-bayesianoptimization@image: ${REGISTRY}\/${REPO_NAME}\/suggestion-bayesianoptimization:${VERSION}@" manifests/vizier/suggestion/bayesianoptimization/deployment.yaml sed -i -e "s@image: katib\/earlystopping-medianstopping@image: ${REGISTRY}\/${REPO_NAME}\/earlystopping-medianstopping:${VERSION}@" manifests/vizier/earlystopping/medianstopping/deployment.yaml -sed -i -e "s@image: katib\/dlk-manager@image: ${REGISTRY}\/${REPO_NAME}\/dlk-manager:${VERSION}@" manifests/dlk/deployment.yaml sed -i -e "s@image: katib\/katib-frontend@image: ${REGISTRY}\/${REPO_NAME}\/katib-frontend:${VERSION}@" manifests/modeldb/frontend/deployment.yaml cd ${GO_DIR} ./scripts/deploy.sh From 5b8f02dc1b151ee9c4283bd5faa5a05203b50746 Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Sat, 28 Apr 2018 03:27:48 +0900 Subject: [PATCH 07/15] add mnist-models.yaml Signed-off-by: YujiOshima --- cmd/cli/push-study.go | 2 +- docs/MinikubeDemo/MinikubeDemo.md | 47 ++- docs/MinikubeDemo/mnist-models.yaml | 487 ++++++++++++++++++++++++++++ 3 files changed, 534 insertions(+), 2 deletions(-) create mode 100755 docs/MinikubeDemo/mnist-models.yaml diff --git a/cmd/cli/push-study.go b/cmd/cli/push-study.go index 1a5a25ffc35..7229d325154 100644 --- a/cmd/cli/push-study.go +++ b/cmd/cli/push-study.go @@ -22,7 +22,7 @@ type pushStudyOpt struct { func NewCommandPushStudy() *cobra.Command { var opt pushStudyOpt cmd := &cobra.Command{ - Use: "model", + Use: "study", Args: cobra.MaximumNArgs(1), Short: "Push a Study Info and its Models from a file or from stdin", Long: "Push a Study Info and its Models from a file or from stdin\nYAML formats are accepted.", diff --git a/docs/MinikubeDemo/MinikubeDemo.md b/docs/MinikubeDemo/MinikubeDemo.md index 5c7ac864f71..7a47f5fa4a1 100644 --- a/docs/MinikubeDemo/MinikubeDemo.md +++ b/docs/MinikubeDemo/MinikubeDemo.md @@ -28,7 +28,7 @@ Logs ``` ### Grid Demo -Same as random. +Almost same as random suggestion. ``` go run grid/grid-suggest-demo.go ``` @@ -38,3 +38,48 @@ In this demo, make 4 grids Min 0.03 and Max 0.07. You can check your Model with Web UI. Acsess to `http://192.168.99.100:30080/` The Results will be saved automatically. + +## ModelManagement +You can export model data to yaml file with CLI. +``` +katib-cli -s {{server-cli}} pull study {{study ID or name}} -o {{filename}} +``` + +And you can push your existing models to Katib with CLI. +`mnist-models.yaml` is traind 22 models using random suggestion with this Parameter Config. + +``` +configs: + - name: --lr + parametertype: 1 + feasible: + max: "0.07" + min: "0.03" + list: [] + - name: --lr-factor + parametertype: 1 + feasible: + max: "0.05" + min: "0.005" + list: [] + - name: --lr-step + parametertype: 2 + feasible: + max: "20" + min: "5" + list: [] + - name: --optimizer + parametertype: 4 + feasible: + max: "" + min: "" + list: + - sgd + - adam + - ftrl +``` +You can easy to explore the model on ModelDB. + +``` +katib-cli -s 192.168.99.100:30678 push md -f mnist-models.yaml +``` diff --git a/docs/MinikubeDemo/mnist-models.yaml b/docs/MinikubeDemo/mnist-models.yaml new file mode 100755 index 00000000000..cd5e396be16 --- /dev/null +++ b/docs/MinikubeDemo/mnist-models.yaml @@ -0,0 +1,487 @@ +studyconf: + name: mnist-demo + owner: katib + optimizationtype: 2 + optimizationgoal: 0.99 + parameterconfigs: + configs: + - name: --lr + parametertype: 1 + feasible: + max: "0.07" + min: "0.03" + list: [] + - name: --lr-factor + parametertype: 1 + feasible: + max: "0.05" + min: "0.005" + list: [] + - name: --lr-step + parametertype: 2 + feasible: + max: "20" + min: "5" + list: [] + - name: --optimizer + parametertype: 4 + feasible: + max: "" + min: "" + list: + - sgd + - adam + - ftrl + accesspermissions: [] + defaultsuggestionalgorithm: random + defaultearlystoppingalgorithm: medianstopping + tags: [] + objectivevaluename: Validation-accuracy + metrics: + - accuracy + - Validation-accuracy +models: +- studyname: mnist-demo + workerid: odd34caefd536735 + parameters: + - name: --lr + parametertype: 0 + value: "0.0567" + metrics: + - name: Validation-accuracy + value: "0.9828" + - name: accuracy + value: "1.0000" + modelpath: "" +- studyname: mnist-demo + workerid: m2b516fa31c2d9bf + parameters: + - name: --lr + parametertype: 0 + value: "0.0538" + metrics: + - name: Validation-accuracy + value: "0.9821" + - name: accuracy + value: "0.9998" + modelpath: "" +- studyname: mnist-demo + workerid: la940f5d392951f5 + parameters: + - name: --lr + parametertype: 0 + value: "0.0465" + - name: --lr-factor + parametertype: 0 + value: "0.0339" + - name: --lr-step + parametertype: 0 + value: "6" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9830" + - name: accuracy + value: "0.9987" + modelpath: "" +- studyname: mnist-demo + workerid: ae1d680d8c959758 + parameters: + - name: --lr + parametertype: 0 + value: "0.0367" + - name: --lr-factor + parametertype: 0 + value: "0.0483" + - name: --lr-step + parametertype: 0 + value: "13" + - name: --optimizer + parametertype: 0 + value: adam + metrics: + - name: Validation-accuracy + value: "0.9593" + - name: accuracy + value: "0.9714" + modelpath: "" +- studyname: mnist-demo + workerid: lb3c4b6222527bcc + parameters: + - name: --lr + parametertype: 0 + value: "0.0584" + - name: --lr-factor + parametertype: 0 + value: "0.0175" + - name: --lr-step + parametertype: 0 + value: "13" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9825" + - name: accuracy + value: "0.9994" + modelpath: "" +- studyname: mnist-demo + workerid: f69f8d062d73af57 + parameters: + - name: --lr + parametertype: 0 + value: "0.0622" + - name: --lr-factor + parametertype: 0 + value: "0.0331" + - name: --lr-step + parametertype: 0 + value: "20" + - name: --optimizer + parametertype: 0 + value: adam + metrics: + - name: Validation-accuracy + value: "0.8422" + - name: accuracy + value: "0.8489" + modelpath: "" +- studyname: mnist-demo + workerid: p3cb7fadef40f21a + parameters: + - name: --lr + parametertype: 0 + value: "0.0610" + - name: --lr-factor + parametertype: 0 + value: "0.0464" + - name: --lr-step + parametertype: 0 + value: "8" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9832" + - name: accuracy + value: "0.9998" + modelpath: "" +- studyname: mnist-demo + workerid: u9340b9902384469 + parameters: + - name: --lr + parametertype: 0 + value: "0.0575" + - name: --lr-factor + parametertype: 0 + value: "0.0409" + - name: --lr-step + parametertype: 0 + value: "11" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9817" + - name: accuracy + value: "0.9994" + modelpath: "" +- studyname: mnist-demo + workerid: o2dc7c8e45045ed8 + parameters: + - name: --lr + parametertype: 0 + value: "0.0415" + - name: --lr-factor + parametertype: 0 + value: "0.0311" + - name: --lr-step + parametertype: 0 + value: "18" + - name: --optimizer + parametertype: 0 + value: ftrl + metrics: + - name: Validation-accuracy + value: "0.1139" + - name: accuracy + value: "0.1100" + modelpath: "" +- studyname: mnist-demo + workerid: be6095255e24914a + parameters: + - name: --lr + parametertype: 0 + value: "0.0440" + - name: --lr-factor + parametertype: 0 + value: "0.0220" + - name: --lr-step + parametertype: 0 + value: "11" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9835" + - name: accuracy + value: "0.9995" + modelpath: "" +- studyname: mnist-demo + workerid: y8f85fd17360ced8 + parameters: + - name: --lr + parametertype: 0 + value: "0.0319" + - name: --lr-factor + parametertype: 0 + value: "0.0215" + - name: --lr-step + parametertype: 0 + value: "7" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9819" + - name: accuracy + value: "0.9983" + modelpath: "" +- studyname: mnist-demo + workerid: h4906ef693a4575f + parameters: + - name: --lr + parametertype: 0 + value: "0.0475" + - name: --lr-factor + parametertype: 0 + value: "0.0442" + - name: --lr-step + parametertype: 0 + value: "12" + - name: --optimizer + parametertype: 0 + value: ftrl + metrics: + - name: Validation-accuracy + value: "0.1139" + - name: accuracy + value: "0.1117" + modelpath: "" +- studyname: mnist-demo + workerid: w308208fde1c610b + parameters: + - name: --lr + parametertype: 0 + value: "0.0646" + - name: --lr-factor + parametertype: 0 + value: "0.0305" + - name: --lr-step + parametertype: 0 + value: "13" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9834" + - name: accuracy + value: "1.0000" + modelpath: "" +- studyname: mnist-demo + workerid: f61ef84cc4cbda11 + parameters: + - name: --lr + parametertype: 0 + value: "0.0496" + - name: --lr-factor + parametertype: 0 + value: "0.0228" + - name: --lr-step + parametertype: 0 + value: "16" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9830" + - name: accuracy + value: "1.0000" + modelpath: "" +- studyname: mnist-demo + workerid: i9929c85ea046ee1 + parameters: + - name: --lr + parametertype: 0 + value: "0.0546" + - name: --lr-factor + parametertype: 0 + value: "0.0445" + - name: --lr-step + parametertype: 0 + value: "20" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9759" + - name: accuracy + value: "0.9967" + modelpath: "" +- studyname: mnist-demo + workerid: ma8820fd661d8e15 + parameters: + - name: --lr + parametertype: 0 + value: "0.0467" + - name: --lr-factor + parametertype: 0 + value: "0.0368" + - name: --lr-step + parametertype: 0 + value: "5" + - name: --optimizer + parametertype: 0 + value: ftrl + metrics: + - name: Validation-accuracy + value: "0.1139" + - name: accuracy + value: "0.1141" + modelpath: "" +- studyname: mnist-demo + workerid: m14f499c6470a4d5 + parameters: + - name: --lr + parametertype: 0 + value: "0.0430" + - name: --lr-factor + parametertype: 0 + value: "0.0269" + - name: --lr-step + parametertype: 0 + value: "11" + - name: --optimizer + parametertype: 0 + value: ftrl + metrics: + - name: Validation-accuracy + value: "0.1139" + - name: accuracy + value: "0.1039" + modelpath: "" +- studyname: mnist-demo + workerid: ce80dc2d63d8afd6 + parameters: + - name: --lr + parametertype: 0 + value: "0.0524" + - name: --lr-factor + parametertype: 0 + value: "0.0453" + - name: --lr-step + parametertype: 0 + value: "9" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9840" + - name: accuracy + value: "1.0000" + modelpath: "" +- studyname: mnist-demo + workerid: adb51b30836f6307 + parameters: + - name: --lr + parametertype: 0 + value: "0.0436" + - name: --lr-factor + parametertype: 0 + value: "0.0074" + - name: --lr-step + parametertype: 0 + value: "5" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9814" + - name: accuracy + value: "0.9972" + modelpath: "" +- studyname: mnist-demo + workerid: gcc32f240f169c24 + parameters: + - name: --lr + parametertype: 0 + value: "0.0477" + - name: --lr-factor + parametertype: 0 + value: "0.0151" + - name: --lr-step + parametertype: 0 + value: "9" + - name: --optimizer + parametertype: 0 + value: adam + metrics: + - name: accuracy + value: "0.9466" + - name: Validation-accuracy + value: "0.9405" + modelpath: "" +- studyname: mnist-demo + workerid: ad9011a472d85379 + parameters: + - name: --lr + parametertype: 0 + value: "0.0448" + - name: --lr-factor + parametertype: 0 + value: "0.0376" + - name: --lr-step + parametertype: 0 + value: "15" + - name: --optimizer + parametertype: 0 + value: sgd + metrics: + - name: Validation-accuracy + value: "0.9821" + - name: accuracy + value: "0.9998" + modelpath: "" +- studyname: mnist-demo + workerid: g962f6bd6bb8facd + parameters: + - name: --lr + parametertype: 0 + value: "0.0636" + - name: --lr-factor + parametertype: 0 + value: "0.0281" + - name: --lr-step + parametertype: 0 + value: "16" + - name: --optimizer + parametertype: 0 + value: adam + metrics: + - name: Validation-accuracy + value: "0.9053" + - name: accuracy + value: "0.9067" + modelpath: "" From 28080e036f3eba764c68811487d4341dde71386b Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Sat, 28 Apr 2018 03:36:11 +0900 Subject: [PATCH 08/15] fix docs Signed-off-by: YujiOshima --- docs/GKEDemo/GKE-Demo.md | 13 ++++++++++--- docs/MinikubeDemo/MinikubeDemo.md | 7 +++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/GKEDemo/GKE-Demo.md b/docs/GKEDemo/GKE-Demo.md index 452ef0fff44..5cacf7556b7 100644 --- a/docs/GKEDemo/GKE-Demo.md +++ b/docs/GKEDemo/GKE-Demo.md @@ -3,10 +3,14 @@ You can deploy katib components and try simple mnist demo on the cloud! ## deploy Cluster This is grid parameter search demo for [KubeFlow's Github issue summaraize example](https://github.com/kubeflow/examples/tree/master/github_issue_summarization) + Let's deploy GKE cluster by gcloud commnad. -And you need to set GCP service account. -See https://github.com/kubeflow/examples/blob/master/github_issue_summarization/training_the_model_tfjob.md + +You need to confidurate GCP service account. +See also https://github.com/kubeflow/examples/blob/master/github_issue_summarization/training_the_model_tfjob.md + Then deploy Katib compenents. + ``` kubectl config set-credentials temp-admin --username=admin --password=$(gcloud container clusters describe katib --format="value(masterAuth.password)") kubectl config set-context temp-context --cluster=$(kubectl config get-clusters | grep katib) --user=temp-admin @@ -23,9 +27,10 @@ kubectl apply -f manifests/vizier/suggestion/grid kubectl apply -f manifests/vizier/earlystopping/medianstopping gcloud compute firewall-rules create katibservice --allow tcp:30080,tcp:30678 ``` + In this demo, katib components export using NodePort. -So you should set firewall to allow the ports. +So you should set firewall to allow the ports. ## Create Study Please edit `git-issue-summarize-demo.go` the `manager` address to the node address that vizier-core deployed. @@ -37,5 +42,7 @@ Katib will make 4 girds of learling-rate parameter from 0.005 to 0.5. ## UI You can check your Model with Web UI. + Acsess to `http://{{node address}}:30080/` + The Results will be saved automatically. diff --git a/docs/MinikubeDemo/MinikubeDemo.md b/docs/MinikubeDemo/MinikubeDemo.md index 7a47f5fa4a1..8594f05ed30 100644 --- a/docs/MinikubeDemo/MinikubeDemo.md +++ b/docs/MinikubeDemo/MinikubeDemo.md @@ -6,10 +6,13 @@ You can deploy katib components and try a simple mnist demo on your laptop! * kubectl ## deploy Only type command `./deploy`. + A Minikube cluster and Katib components will be deployed! + You can check them with `kubectl get -n katib get pods`. -You don't worry if the `vizier-core` get an error. It will be recovered after DB will be prepared. -Wait until all components are Running status. +Don't worry if the `vizier-core` get an error. +It will be recovered after DB will be prepared. +Wait until all components will be Running status. ## Create Study ### Random Suggestion Demo From 35784166d357d26ebacc64fefdcc5c351983df0d Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Sat, 28 Apr 2018 19:27:06 +0900 Subject: [PATCH 09/15] improve GKEdemo docs Signed-off-by: YujiOshima --- docs/GKEDemo/GKE-Demo.md | 27 +- docs/GKEDemo/deploy.sh | 15 +- docs/GKEDemo/destroy.sh | 1 - docs/GKEDemo/docker-image/Dockerfile | 7 + docs/GKEDemo/docker-image/Dockerfile-gpu | 7 + .../docker-image/IssueSummarization.py | 25 + docs/GKEDemo/docker-image/requirements.txt | 11 + docs/GKEDemo/docker-image/seq2seq_utils.py | 432 ++++++++++++++++++ docs/GKEDemo/docker-image/train.py | 211 +++++++++ docs/GKEDemo/git-issue-summarize-demo.go | 28 +- 10 files changed, 730 insertions(+), 34 deletions(-) create mode 100644 docs/GKEDemo/docker-image/Dockerfile create mode 100644 docs/GKEDemo/docker-image/Dockerfile-gpu create mode 100644 docs/GKEDemo/docker-image/IssueSummarization.py create mode 100644 docs/GKEDemo/docker-image/requirements.txt create mode 100644 docs/GKEDemo/docker-image/seq2seq_utils.py create mode 100644 docs/GKEDemo/docker-image/train.py diff --git a/docs/GKEDemo/GKE-Demo.md b/docs/GKEDemo/GKE-Demo.md index 5cacf7556b7..ec61749721d 100644 --- a/docs/GKEDemo/GKE-Demo.md +++ b/docs/GKEDemo/GKE-Demo.md @@ -1,13 +1,18 @@ # Simple GKE Demo You can deploy katib components and try simple mnist demo on the cloud! +## build your training docker image +The sample code is docker-image directory. +It is based on [KubeFlow's Github issue summaraize example](https://github.com/kubeflow/examples/tree/master/github_issue_summarization/notebooks) image. + ## deploy Cluster This is grid parameter search demo for [KubeFlow's Github issue summaraize example](https://github.com/kubeflow/examples/tree/master/github_issue_summarization) Let's deploy GKE cluster by gcloud commnad. +``` +gcloud container clusters create --machine-type n1-highmem-4 --num-nodes 2 katib +``` -You need to confidurate GCP service account. -See also https://github.com/kubeflow/examples/blob/master/github_issue_summarization/training_the_model_tfjob.md Then deploy Katib compenents. @@ -32,13 +37,23 @@ In this demo, katib components export using NodePort. So you should set firewall to allow the ports. +### Push data to GCS +If you want to pull input data and push logs to google cloud storage, You need to confidurate GCP service account. + +See also https://github.com/kubeflow/examples/blob/master/github_issue_summarization/training_the_model_tfjob.md + ## Create Study -Please edit `git-issue-summarize-demo.go` the `manager` address to the node address that vizier-core deployed. -Then +Run study with `go run`. you should set endpoint of vizier-core. + ``` -go run git-issue-summarize-demo.go +go run git-issue-summarize-demo.go -s {{ip-addr of node vizier-core deployed}}:30678 ``` -Katib will make 4 girds of learling-rate parameter from 0.005 to 0.5. +Katib will make 2 girds of learling-rate parameter from 0.005 to 0.5. + +The `git-issue-summarize-demo.go` is a controller of this study. +It sets hyper parameter config, suggestion config, k8s job config and then, create study and run trial with katib-API. + +The training logic is `docker-image/train.py` ## UI You can check your Model with Web UI. diff --git a/docs/GKEDemo/deploy.sh b/docs/GKEDemo/deploy.sh index 6b057c37613..1443d48e36c 100755 --- a/docs/GKEDemo/deploy.sh +++ b/docs/GKEDemo/deploy.sh @@ -1,25 +1,12 @@ #/bin/bash set -x -set -e -gcloud container clusters create --machine-type n1-highmem-2 katib +gcloud container clusters create --machine-type n1-highmem-4 --num-nodes 2 katib SERVICE_ACCOUNT=github-issue-summarization -PROJECT=katib-202401 # The GCP Project name -NAMESPACE=katib -gcloud iam service-accounts --project=${PROJECT} create ${SERVICE_ACCOUNT} \ - --display-name "GCP Service Account for use with kubeflow examples" - -gcloud projects add-iam-policy-binding ${PROJECT} --member \ - serviceAccount:${SERVICE_ACCOUNT}@${PROJECT}.iam.gserviceaccount.com --role=roles/storage.admin - -KEY_FILE=/home/user/secrets/${SERVICE_ACCOUNT}@${PROJECT}.iam.gserviceaccount.com.json -gcloud iam service-accounts keys create ${KEY_FILE} \ - --iam-account ${SERVICE_ACCOUNT}@${PROJECT}.iam.gserviceaccount.com set -e kubectl config set-credentials temp-admin --username=admin --password=$(gcloud container clusters describe katib --format="value(masterAuth.password)") kubectl config set-context temp-context --cluster=$(kubectl config get-clusters | grep katib) --user=temp-admin kubectl config use-context temp-context kubectl apply -f manifests/0-namespace.yaml -kubectl --namespace=${NAMESPACE} create secret generic gcp-credentials --from-file=key.json="${KEY_FILE}" kubectl apply -f manifests/modeldb/db kubectl apply -f manifests/modeldb/backend kubectl apply -f manifests/modeldb/frontend diff --git a/docs/GKEDemo/destroy.sh b/docs/GKEDemo/destroy.sh index 87883faa30f..d1443e87e9f 100755 --- a/docs/GKEDemo/destroy.sh +++ b/docs/GKEDemo/destroy.sh @@ -2,4 +2,3 @@ set -x gcloud compute firewall-rules delete katibservice gcloud container clusters delete katib -gcloud compute disks delete katib-pv diff --git a/docs/GKEDemo/docker-image/Dockerfile b/docs/GKEDemo/docker-image/Dockerfile new file mode 100644 index 00000000000..9c3bf2ef03c --- /dev/null +++ b/docs/GKEDemo/docker-image/Dockerfile @@ -0,0 +1,7 @@ +FROM gcr.io/kubeflow-images-staging/tensorflow-1.6.0-notebook-cpu +COPY requirements.txt /workdir/requirements.txt +RUN pip install -r /workdir/requirements.txt +RUN pip install google.cloud sklearn ktext annoy nltk +COPY train.py /workdir/train.py +COPY seq2seq_utils.py /workdir/seq2seq_utils.py +COPY IssueSummarization.py /workdir/IssueSummarization.py diff --git a/docs/GKEDemo/docker-image/Dockerfile-gpu b/docs/GKEDemo/docker-image/Dockerfile-gpu new file mode 100644 index 00000000000..dc7e88e9411 --- /dev/null +++ b/docs/GKEDemo/docker-image/Dockerfile-gpu @@ -0,0 +1,7 @@ +FROM gcr.io/kubeflow-images-staging/tensorflow-1.6.0-notebook-gpu +COPY requirements.txt /workdir/requirements.txt +RUN pip install -r /workdir/requirements.txt +RUN pip install google.cloud sklearn ktext annoy nltk +COPY train.py /workdir/train.py +COPY seq2seq_utils.py /workdir/seq2seq_utils.py +COPY IssueSummarization.py /workdir/IssueSummarization.py diff --git a/docs/GKEDemo/docker-image/IssueSummarization.py b/docs/GKEDemo/docker-image/IssueSummarization.py new file mode 100644 index 00000000000..b992b2ddc3a --- /dev/null +++ b/docs/GKEDemo/docker-image/IssueSummarization.py @@ -0,0 +1,25 @@ +"""Generates predictions using a stored model. + +Uses trained model files to generate a prediction. +""" + +from __future__ import print_function + +import numpy as np +import dill as dpickle +from keras.models import load_model +from seq2seq_utils import Seq2Seq_Inference + +class IssueSummarization(object): + + def __init__(self): + with open('body_pp.dpkl', 'rb') as body_file: + body_pp = dpickle.load(body_file) + with open('title_pp.dpkl', 'rb') as title_file: + title_pp = dpickle.load(title_file) + self.model = Seq2Seq_Inference(encoder_preprocessor=body_pp, + decoder_preprocessor=title_pp, + seq2seq_model=load_model('seq2seq_model_tutorial.h5')) + + def predict(self, input_text, feature_names): # pylint: disable=unused-argument + return np.asarray([[self.model.generate_issue_title(body[0])[1]] for body in input_text]) diff --git a/docs/GKEDemo/docker-image/requirements.txt b/docs/GKEDemo/docker-image/requirements.txt new file mode 100644 index 00000000000..27f1c6e8992 --- /dev/null +++ b/docs/GKEDemo/docker-image/requirements.txt @@ -0,0 +1,11 @@ +numpy +keras +dill +matplotlib +tensorflow +annoy +tqdm +nltk +IPython +ktext +h5py diff --git a/docs/GKEDemo/docker-image/seq2seq_utils.py b/docs/GKEDemo/docker-image/seq2seq_utils.py new file mode 100644 index 00000000000..0ddaebfabe1 --- /dev/null +++ b/docs/GKEDemo/docker-image/seq2seq_utils.py @@ -0,0 +1,432 @@ +import logging +import dill as dpickle +import numpy as np +from matplotlib import pyplot as plt +import tensorflow as tf +from IPython.display import SVG, display +from keras import backend as K +from keras.layers import Input +from keras.models import Model +from keras.utils.vis_utils import model_to_dot +from annoy import AnnoyIndex +from tqdm import tqdm, tqdm_notebook +from nltk.translate.bleu_score import corpus_bleu + + +def load_text_processor(fname='title_pp.dpkl'): + """ + Load preprocessors from disk. + + Parameters + ---------- + fname: str + file name of ktext.proccessor object + + Returns + ------- + num_tokens : int + size of vocabulary loaded into ktext.processor + pp : ktext.processor + the processor you are trying to load + + Typical Usage: + ------------- + + num_decoder_tokens, title_pp = load_text_processor(fname='title_pp.dpkl') + num_encoder_tokens, body_pp = load_text_processor(fname='body_pp.dpkl') + + """ + # Load files from disk + with open(fname, 'rb') as f: + pp = dpickle.load(f) + + num_tokens = max(pp.id2token.keys()) + 1 + print('Size of vocabulary for {}: {}'.format(fname, num_tokens)) + return num_tokens, pp + + +def load_decoder_inputs(decoder_np_vecs='train_title_vecs.npy'): + """ + Load decoder inputs. + + Parameters + ---------- + decoder_np_vecs : str + filename of serialized numpy.array of decoder input (issue title) + + Returns + ------- + decoder_input_data : numpy.array + The data fed to the decoder as input during training for teacher forcing. + This is the same as `decoder_np_vecs` except the last position. + decoder_target_data : numpy.array + The data that the decoder data is trained to generate (issue title). + Calculated by sliding `decoder_np_vecs` one position forward. + + """ + vectorized_title = np.load(decoder_np_vecs) + # For Decoder Input, you don't need the last word as that is only for prediction + # when we are training using Teacher Forcing. + decoder_input_data = vectorized_title[:, :-1] + + # Decoder Target Data Is Ahead By 1 Time Step From Decoder Input Data (Teacher Forcing) + decoder_target_data = vectorized_title[:, 1:] + + print('Shape of decoder input: {}'.format(decoder_input_data.shape)) + print('Shape of decoder target: {}'.format(decoder_target_data.shape)) + return decoder_input_data, decoder_target_data + + +def load_encoder_inputs(encoder_np_vecs='train_body_vecs.npy'): + """ + Load variables & data that are inputs to encoder. + + Parameters + ---------- + encoder_np_vecs : str + filename of serialized numpy.array of encoder input (issue title) + + Returns + ------- + encoder_input_data : numpy.array + The issue body + doc_length : int + The standard document length of the input for the encoder after padding + the shape of this array will be (num_examples, doc_length) + + """ + vectorized_body = np.load(encoder_np_vecs) + # Encoder input is simply the body of the issue text + encoder_input_data = vectorized_body + doc_length = encoder_input_data.shape[1] + print('Shape of encoder input: {}'.format(encoder_input_data.shape)) + return encoder_input_data, doc_length + + +def viz_model_architecture(model): + """Visualize model architecture in Jupyter notebook.""" + display(SVG(model_to_dot(model).create(prog='dot', format='svg'))) + + +def free_gpu_mem(): + """Attempt to free gpu memory.""" + K.get_session().close() + cfg = K.tf.ConfigProto() + cfg.gpu_options.allow_growth = True + K.set_session(K.tf.Session(config=cfg)) + + +def test_gpu(): + """Run a toy computation task in tensorflow to test GPU.""" + config = tf.ConfigProto() + config.gpu_options.allow_growth = True + session = tf.Session(config=config) + hello = tf.constant('Hello, TensorFlow!') + print(session.run(hello)) + + +def plot_model_training_history(history_object): + """Plots model train vs. validation loss.""" + plt.title('model accuracy') + plt.ylabel('accuracy') + plt.xlabel('epoch') + plt.plot(history_object.history['loss']) + plt.plot(history_object.history['val_loss']) + plt.legend(['train', 'test'], loc='upper left') + plt.show() + + +def extract_encoder_model(model): + """ + Extract the encoder from the original Sequence to Sequence Model. + + Returns a keras model object that has one input (body of issue) and one + output (encoding of issue, which is the last hidden state). + + Input: + ----- + model: keras model object + + Returns: + ----- + keras model object + + """ + encoder_model = model.get_layer('Encoder-Model') + return encoder_model + + +def extract_decoder_model(model): + """ + Extract the decoder from the original model. + + Inputs: + ------ + model: keras model object + + Returns: + ------- + A Keras model object with the following inputs and outputs: + + Inputs of Keras Model That Is Returned: + 1: the embedding index for the last predicted word or the indicator + 2: the last hidden state, or in the case of the first word the hidden state from the encoder + + Outputs of Keras Model That Is Returned: + 1. Prediction (class probabilities) for the next word + 2. The hidden state of the decoder, to be fed back into the decoder at the next time step + + Implementation Notes: + ---------------------- + Must extract relevant layers and reconstruct part of the computation graph + to allow for different inputs as we are not going to use teacher forcing at + inference time. + + """ + # the latent dimension is the same throughout the architecture so we are going to + # cheat and grab the latent dimension of the embedding because that is the same as what is + # output from the decoder + latent_dim = model.get_layer('Decoder-Word-Embedding').output_shape[-1] + + # Reconstruct the input into the decoder + decoder_inputs = model.get_layer('Decoder-Input').input + dec_emb = model.get_layer('Decoder-Word-Embedding')(decoder_inputs) + dec_bn = model.get_layer('Decoder-Batchnorm-1')(dec_emb) + + # Instead of setting the intial state from the encoder and forgetting about it, during inference + # we are not doing teacher forcing, so we will have to have a feedback loop from predictions back + # into the GRU, thus we define this input layer for the state so we can add this capability + gru_inference_state_input = Input(shape=(latent_dim,), name='hidden_state_input') + + # we need to reuse the weights that is why we are getting this + # If you inspect the decoder GRU that we created for training, it will take as input + # 2 tensors -> (1) is the embedding layer output for the teacher forcing + # (which will now be the last step's prediction, and will be _start_ on the + # first time step) + # (2) is the state, which we will initialize with the encoder on the first time step + # but then grab the state after the first prediction and feed that back in again. + gru_out, gru_state_out = model.get_layer('Decoder-GRU')([dec_bn, gru_inference_state_input]) + + # Reconstruct dense layers + dec_bn2 = model.get_layer('Decoder-Batchnorm-2')(gru_out) + dense_out = model.get_layer('Final-Output-Dense')(dec_bn2) + decoder_model = Model([decoder_inputs, gru_inference_state_input], + [dense_out, gru_state_out]) + return decoder_model + + +class Seq2Seq_Inference(object): + + # pylint: disable=too-many-instance-attributes + + def __init__(self, + encoder_preprocessor, + decoder_preprocessor, + seq2seq_model): + + self.pp_body = encoder_preprocessor + self.pp_title = decoder_preprocessor + self.seq2seq_model = seq2seq_model + self.encoder_model = extract_encoder_model(seq2seq_model) + self.decoder_model = extract_decoder_model(seq2seq_model) + self.default_max_len_title = self.pp_title.padding_maxlen + self.nn = None + self.rec_df = None + + def generate_issue_title(self, + raw_input_text, + max_len_title=None): + """ + Use the seq2seq model to generate a title given the body of an issue. + + Inputs + ------ + raw_input: str + The body of the issue text as an input string + + max_len_title: int (optional) + The maximum length of the title the model will generate + + """ + if max_len_title is None: + max_len_title = self.default_max_len_title + # get the encoder's features for the decoder + raw_tokenized = self.pp_body.transform([raw_input_text]) + body_encoding = self.encoder_model.predict(raw_tokenized) + # we want to save the encoder's embedding before its updated by decoder + # because we can use that as an embedding for other tasks. + original_body_encoding = body_encoding + state_value = np.array(self.pp_title.token2id['_start_']).reshape(1, 1) + + decoded_sentence = [] + stop_condition = False + while not stop_condition: + preds, st = self.decoder_model.predict([state_value, body_encoding]) + + # We are going to ignore indices 0 (padding) and indices 1 (unknown) + # Argmax will return the integer index corresponding to the + # prediction + 2 b/c we chopped off first two + pred_idx = np.argmax(preds[:, :, 2:]) + 2 + + # retrieve word from index prediction + pred_word_str = self.pp_title.id2token[pred_idx] + + if pred_word_str == '_end_' or len(decoded_sentence) >= max_len_title: + stop_condition = True + break + decoded_sentence.append(pred_word_str) + + # update the decoder for the next word + body_encoding = st + state_value = np.array(pred_idx).reshape(1, 1) + + return original_body_encoding, ' '.join(decoded_sentence) + + + def print_example(self, + i, + body_text, + title_text, + url, + threshold): + """ + Prints an example of the model's prediction for manual inspection. + """ + if i: + print('\n\n==============================================') + print('============== Example # {} =================\n'.format(i)) + + if url: + print(url) + + print("Issue Body:\n {} \n".format(body_text)) + + if title_text: + print("Original Title:\n {}".format(title_text)) + + emb, gen_title = self.generate_issue_title(body_text) + print("\n****** Machine Generated Title (Prediction) ******:\n {}".format(gen_title)) + + if self.nn: + # return neighbors and distances + n, d = self.nn.get_nns_by_vector(emb.flatten(), n=4, + include_distances=True) + neighbors = n[1:] + dist = d[1:] + + if min(dist) <= threshold: + cols = ['issue_url', 'issue_title', 'body'] + dfcopy = self.rec_df.iloc[neighbors][cols].copy(deep=True) + dfcopy['dist'] = dist + similar_issues_df = dfcopy.query('dist <= {}'.format(threshold)) + + print("\n**** Similar Issues (using encoder embedding) ****:\n") + display(similar_issues_df) + + + def demo_model_predictions(self, + n, + issue_df, + threshold=1): + """ + Pick n random Issues and display predictions. + + Input: + ------ + n : int + Number of issues to display from issue_df + issue_df : pandas DataFrame + DataFrame that contains two columns: `body` and `issue_title`. + threshold : float + distance threshold for recommendation of similar issues. + + Returns: + -------- + None + Prints the original issue body and the model's prediction. + """ + # Extract body and title from DF + body_text = issue_df.body.tolist() + title_text = issue_df.issue_title.tolist() + url = issue_df.issue_url.tolist() + + demo_list = np.random.randint(low=1, high=len(body_text), size=n) + for i in demo_list: + self.print_example(i, + body_text=body_text[i], + title_text=title_text[i], + url=url[i], + threshold=threshold) + + def prepare_recommender(self, vectorized_array, original_df): + """ + Use the annoy library to build recommender + + Parameters + ---------- + vectorized_array : List[List[int]] + This is the list of list of integers that represents your corpus + that is fed into the seq2seq model for training. + original_df : pandas.DataFrame + This is the original dataframe that has the columns + ['issue_url', 'issue_title', 'body'] + + Returns + ------- + annoy.AnnoyIndex object (see https://github.com/spotify/annoy) + """ + self.rec_df = original_df + emb = self.encoder_model.predict(x=vectorized_array, + batch_size=vectorized_array.shape[0]//200) + + f = emb.shape[1] + self.nn = AnnoyIndex(f) + logging.warning('Adding embeddings') + for i in tqdm(range(len(emb))): + self.nn.add_item(i, emb[i]) + logging.warning('Building trees for similarity lookup.') + self.nn.build(50) + return self.nn + + def set_recsys_data(self, original_df): + self.rec_df = original_df + + def set_recsys_annoyobj(self, annoyobj): + self.nn = annoyobj + + def evaluate_model(self, holdout_bodies, holdout_titles): + """ + Method for calculating BLEU Score. + + Parameters + ---------- + holdout_bodies : List[str] + These are the issue bodies that we want to summarize + holdout_titles : List[str] + This is the ground truth we are trying to predict --> issue titles + + Returns + ------- + bleu : float + The BLEU Score + + """ + actual, predicted = list(), list() + assert len(holdout_bodies) == len(holdout_titles) + num_examples = len(holdout_bodies) + + logging.warning('Generating predictions.') + # step over the whole set TODO: parallelize this + for i in tqdm_notebook(range(num_examples)): + _, yhat = self.generate_issue_title(holdout_bodies[i]) + + actual.append(self.pp_title.process_text([holdout_titles[i]])[0]) + predicted.append(self.pp_title.process_text([yhat])[0]) + + # calculate BLEU score + logging.warning('Calculating BLEU.') + #must be careful with nltk api for corpus_bleu!, + # expects List[List[List[str]]] for ground truth, using List[List[str]] will give you + # erroneous results. + bleu = corpus_bleu([[a] for a in actual], predicted) + return bleu diff --git a/docs/GKEDemo/docker-image/train.py b/docs/GKEDemo/docker-image/train.py new file mode 100644 index 00000000000..ec290915055 --- /dev/null +++ b/docs/GKEDemo/docker-image/train.py @@ -0,0 +1,211 @@ +"""Train the github-issue-summarization model +train.py trains the github-issue-summarization model. + +It reads the input data from GCS in a zip file format. +--input_data_gcs_bucket and --input_data_gcs_path specify +the location of input data. + +It write the model back to GCS. +--output_model_gcs_bucket and --output_model_gcs_path specify +the location of output. + +It also has parameters which control the training like +--learning_rate and --sample_size + +""" +import argparse +import logging +import zipfile +import urllib + +from google.cloud import storage # pylint: disable=no-name-in-module +import dill as dpickle +import numpy as np +import pandas as pd +from keras import optimizers +from keras.layers import GRU, BatchNormalization, Dense, Embedding, Input +from keras.models import Model +from sklearn.model_selection import train_test_split + +from ktext.preprocess import processor +from seq2seq_utils import load_encoder_inputs, load_text_processor + +def main(): # pylint: disable=too-many-statements + # Parsing flags. + parser = argparse.ArgumentParser() + parser.add_argument("--sample_size", type=int, default=2000000) + parser.add_argument("--learning_rate", default="0.001") + + parser.add_argument( + "--input_data_gcs_bucket", type=str, default="") + parser.add_argument( + "--input_data_gcs_path", + type=str, + default="") + + parser.add_argument( + "--output_model_gcs_bucket", type=str, default="") + parser.add_argument( + "--output_model_gcs_path", + type=str, + default="") + + parser.add_argument( + "--output_body_preprocessor_dpkl", + type=str, + default="body_preprocessor.dpkl") + parser.add_argument( + "--output_title_preprocessor_dpkl", + type=str, + default="title_preprocessor.dpkl") + parser.add_argument( + "--output_train_title_vecs_npy", type=str, default="train_title_vecs.npy") + parser.add_argument( + "--output_train_body_vecs_npy", type=str, default="train_body_vecs.npy") + parser.add_argument("--output_model_h5", type=str, default="output_model.h5") + + args = parser.parse_args() + logging.info(args) + + learning_rate = float(args.learning_rate) + + pd.set_option('display.max_colwidth', 500) + print("Download iput file") + if args.input_data_gcs_bucket != "" and args.input_data_gcs_path != "": + bucket = storage.Bucket(storage.Client(), args.input_data_gcs_bucket) + storage.Blob(args.input_data_gcs_path, + bucket).download_to_filename('github-issues.zip') + else: + urllib.request.urlretrieve("https://storage.googleapis.com/kubeflow-examples/github-issue-summarization-data/github-issues.zip",'github-issues.zip') + + print("unzip iput file") + zip_ref = zipfile.ZipFile('github-issues.zip', 'r') + zip_ref.extractall('.') + zip_ref.close() + + # Read in data sample 2M rows (for speed of tutorial) + traindf, testdf = train_test_split( + pd.read_csv('github_issues.csv').sample(n=args.sample_size), test_size=.10) + + # Print stats about the shape of the data. + logging.info('Train: %d rows %d columns', traindf.shape[0], traindf.shape[1]) + logging.info('Test: %d rows %d columns', testdf.shape[0], testdf.shape[1]) + + train_body_raw = traindf.body.tolist() + train_title_raw = traindf.issue_title.tolist() + + # Clean, tokenize, and apply padding / truncating such that each document + # length = 70. Also, retain only the top 8,000 words in the vocabulary and set + # the remaining words to 1 which will become common index for rare words. + body_pp = processor(keep_n=8000, padding_maxlen=70) + train_body_vecs = body_pp.fit_transform(train_body_raw) + + logging.info('Example original body: %s', train_body_raw[0]) + logging.info('Example body after pre-processing: %s', train_body_vecs[0]) + + # Instantiate a text processor for the titles, with some different parameters. + title_pp = processor( + append_indicators=True, keep_n=4500, padding_maxlen=12, padding='post') + + # process the title data + train_title_vecs = title_pp.fit_transform(train_title_raw) + + logging.info('Example original title: %s', train_title_raw[0]) + logging.info('Example title after pre-processing: %s', train_title_vecs[0]) + + # Save the preprocessor. + with open(args.output_body_preprocessor_dpkl, 'wb') as f: + dpickle.dump(body_pp, f) + + with open(args.output_title_preprocessor_dpkl, 'wb') as f: + dpickle.dump(title_pp, f) + + # Save the processed data. + np.save(args.output_train_title_vecs_npy, train_title_vecs) + np.save(args.output_train_body_vecs_npy, train_body_vecs) + + _, doc_length = load_encoder_inputs( + args.output_train_body_vecs_npy) + + num_encoder_tokens, body_pp = load_text_processor( + args.output_body_preprocessor_dpkl) + num_decoder_tokens, title_pp = load_text_processor( + args.output_title_preprocessor_dpkl) + + # Arbitrarly set latent dimension for embedding and hidden units + latent_dim = 300 + + ############### + # Encoder Model. + ############### + encoder_inputs = Input(shape=(doc_length,), name='Encoder-Input') + + # Word embeding for encoder (ex: Issue Body) + x = Embedding( + num_encoder_tokens, latent_dim, name='Body-Word-Embedding', + mask_zero=False)(encoder_inputs) + x = BatchNormalization(name='Encoder-Batchnorm-1')(x) + + # We do not need the `encoder_output` just the hidden state. + _, state_h = GRU(latent_dim, return_state=True, name='Encoder-Last-GRU')(x) + + # Encapsulate the encoder as a separate entity so we can just + # encode without decoding if we want to. + encoder_model = Model( + inputs=encoder_inputs, outputs=state_h, name='Encoder-Model') + + seq2seq_encoder_out = encoder_model(encoder_inputs) + + ################ + # Decoder Model. + ################ + decoder_inputs = Input( + shape=(None,), name='Decoder-Input') # for teacher forcing + + # Word Embedding For Decoder (ex: Issue Titles) + dec_emb = Embedding( + num_decoder_tokens, + latent_dim, + name='Decoder-Word-Embedding', + mask_zero=False)(decoder_inputs) + dec_bn = BatchNormalization(name='Decoder-Batchnorm-1')(dec_emb) + + # Set up the decoder, using `decoder_state_input` as initial state. + decoder_gru = GRU( + latent_dim, return_state=True, return_sequences=True, name='Decoder-GRU') + decoder_gru_output, _ = decoder_gru(dec_bn, initial_state=seq2seq_encoder_out) + x = BatchNormalization(name='Decoder-Batchnorm-2')(decoder_gru_output) + + # Dense layer for prediction + decoder_dense = Dense( + num_decoder_tokens, activation='softmax', name='Final-Output-Dense') + decoder_outputs = decoder_dense(x) + + ################ + # Seq2Seq Model. + ################ + + seq2seq_Model = Model([encoder_inputs, decoder_inputs], decoder_outputs) + + seq2seq_Model.compile( + optimizer=optimizers.Nadam(lr=learning_rate), + loss='sparse_categorical_crossentropy') + + seq2seq_Model.summary() + + ############# + # Save model. + ############# + seq2seq_Model.save(args.output_model_h5) + + ###################### + # Upload model to GCS. + ###################### + if args.output_model_gcs_bucket != "": + bucket = storage.Bucket(storage.Client(), args.output_model_gcs_bucket) + storage.Blob(args.output_model_gcs_path, bucket).upload_from_filename( + args.output_model_h5) + + +if __name__ == '__main__': + main() diff --git a/docs/GKEDemo/git-issue-summarize-demo.go b/docs/GKEDemo/git-issue-summarize-demo.go index da9f8df6db5..8f6350e47c6 100644 --- a/docs/GKEDemo/git-issue-summarize-demo.go +++ b/docs/GKEDemo/git-issue-summarize-demo.go @@ -2,6 +2,7 @@ package main import ( "context" + "flag" "log" "time" @@ -9,10 +10,6 @@ import ( "google.golang.org/grpc" ) -const ( - manager = "35.194.127.138:30678" -) - var studyConfig = api.StudyConfig{ Name: "grid-demo", Owner: "katib", @@ -43,12 +40,14 @@ var workerConfig = api.WorkerConfig{ Command: []string{ "python", "/workdir/train.py", - "--input_data_gcs_bucket", - "katib-gi-example", - "--input_data_gcs_path", - "github-issue-summarization-data/github-issues.zip", - "--output_model_gcs_bucket", - "katib-gi-example", + "--sample_size", + "20000", + // "--input_data_gcs_bucket", + // "katib-gi-example", + // "--input_data_gcs_path", + // "github-issue-summarization-data/github-issues.zip", + // "--output_model_gcs_bucket", + // "katib-gi-example", }, Gpu: 0, Scheduler: "default-scheduler", @@ -57,16 +56,19 @@ var workerConfig = api.WorkerConfig{ var gridConfig = []*api.SuggestionParameter{ &api.SuggestionParameter{ Name: "DefaultGrid", - Value: "2", + Value: "4", }, &api.SuggestionParameter{ Name: "--learning_rate", - Value: "4", + Value: "2", }, } +var managerAddr = flag.String("s", "127.0.0.1:6789", "Endpoint of manager default 127.0.0.1:6789") + func main() { - conn, err := grpc.Dial(manager, grpc.WithInsecure()) + flag.Parse() + conn, err := grpc.Dial(*managerAddr, grpc.WithInsecure()) if err != nil { log.Fatalf("could not connect: %v", err) } From bc878181c0c99ca768919a85b4510a380b7fcb08 Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Sat, 28 Apr 2018 20:07:58 +0900 Subject: [PATCH 10/15] add more docs Signed-off-by: YujiOshima --- docs/GKEDemo/GKE-Demo.md | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/docs/GKEDemo/GKE-Demo.md b/docs/GKEDemo/GKE-Demo.md index ec61749721d..fd2755403c6 100644 --- a/docs/GKEDemo/GKE-Demo.md +++ b/docs/GKEDemo/GKE-Demo.md @@ -61,3 +61,95 @@ You can check your Model with Web UI. Acsess to `http://{{node address}}:30080/` The Results will be saved automatically. + +## Description of git-issue-summarize-demo.go +You can make hyperparameter and evaluate it by Katib-API. +Katib-APIs are grpc. So you can use any language grpc supported(e.g. golang, python, c++). +A typical case, you will call APIs in the order as below. +In git-issue-summarize-demo.go, it wait for the status of all workers will be Completed. + +### CreateStudy +First, you should create Study. +The input is StudyConfig. +It has Study name, owner, optimization info, and Parameter config(parameter name, min, and max). +This function generates a unique ID for your study and stores the config to DB. +Input: +* StudyConfig: + * Name: string + * Owner: string + * OptimizationType: enum(OptimizationType_MAXIMIZE, OptimizationType_MINIMIZE) + * OptimizationGoal: float + * DefaultSuggestionAlgorithm: string + * DefaultEarlyStoppingAlgorithm: string + * ObjectiveValueName: string + * Metrics: List of Metrics name + * ParameterConfigs: List of parameter config. +Return: +* StudyID + +### SetSuggestionParameters +Hyperparameters are generated by suggestion services with Parameter config of Study. +You can set the specific config for each suggestion. +Input: +* StudyID: ID of your study. +* SuggestionAlgorithm: name of suggestion service (e.g. random, grid) +* SuggestionParameters: key-value pairs parameter for suggestions. The wanted key is different for each suggestion. +Return: +* ParameterID + +### GetSuggestions +This function will create Trials(set of Parameters). +Input: +* StudyID: ID of your study. +* SuggestionAlgorithm: name of suggestion service (e.g. random, grid) +* RequestNumber: the number you want to evaluate. +* ParamID: ParameterID you got from SetSuggestionParameters func. +Return +* List of Trials + * TrialID + * Parameter Sets + +### RunTrial +Start to evaluate Trial. +When you use kubernetes runtime, the pods are created the specified config. +Input: +* StudyId: ID of your study. +* TrialId: ID of Trial. +* Runtime: worker type(e.g. kubernetes) +* WorkerConfig: runtime config + * Image: name of docker image + * Command: running commands + * GPU: number of GPU + * Scheduler: scheduler name +Return: +* List of WorkerID + +### GetMetrics +Get metrics of running workers. +Input: +* StudyId: ID of your study. +* WorkerIDs: List of worker ID you want to get metrics from. +Return: +* List of Metrics + +### SaveModel +Save the Model date to KatibDB. After you called this function, you can look model info in the KatibUI. +When you call this API multiple time, only Metrics will be updated. +Input: +* ModelInfo + * StudyName + * WorkerId + * Parameters: List of Parameter + * Metrics: List of Metrics + * ModelPath: path to model saved. (PVCname:mountpath) +* DataSet: informatino of input date + * Name + * Path: path to input data.(PVCname:mountpath) + +Return: + +### GetWorkers +You can get worker list and status of workers. +Input: +Return: +* List of worker information From 6cc775c74f25c1d5bbfa231ac5292813a6a4811a Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Sat, 28 Apr 2018 20:13:53 +0900 Subject: [PATCH 11/15] fix test Signed-off-by: YujiOshima --- scripts/deploy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 3afeb8e42f3..77fed8b5b2c 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -25,7 +25,6 @@ kubectl apply -f manifests/0-namespace.yaml kubectl apply -f manifests/modeldb/db kubectl apply -f manifests/modeldb/backend kubectl apply -f manifests/modeldb/frontend -kubectl apply -f manifests/dlk kubectl apply -f manifests/vizier/db kubectl apply -f manifests/vizier/core kubectl apply -f manifests/vizier/suggestion/random From f8392d6fe897dd107df653e10ecf12163e1a3d2e Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Fri, 11 May 2018 10:33:01 +0900 Subject: [PATCH 12/15] enable get worker from trialid ana add getParameterList from studyid Signed-off-by: YujiOshima --- cmd/manager/main.go | 33 +- .../modeldb/frontend/deployment.yaml | 2 +- .../manifests/vizier/core/deployment.yaml | 2 +- .../medianstopping/deployment.yaml | 2 +- .../vizier/suggestion/grid/deployment.yaml | 2 +- .../vizier/suggestion/random/deployment.yaml | 2 +- .../modeldb/frontend/deployment.yaml | 2 +- .../medianstopping/deployment.yaml | 2 +- .../vizier/suggestion/grid/deployment.yaml | 2 +- .../vizier/suggestion/random/deployment.yaml | 2 +- pkg/api/api.pb.go | 666 +++++++++++++----- pkg/api/api.proto | 42 ++ pkg/db/db_init.go | 9 +- pkg/db/interface.go | 90 ++- pkg/earlystopping/medianstopping.go | 2 +- pkg/manager/worker/kubernetes/kubernetes.go | 6 +- pkg/suggestion/grid_service.go | 10 + pkg/suggestion/random_service.go | 8 + 18 files changed, 679 insertions(+), 205 deletions(-) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 59e5812e9b8..3c1c523d117 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -75,10 +75,17 @@ func (s *server) GetStudyList(ctx context.Context, in *pb.GetStudyListRequest) ( } return &pb.GetStudyListReply{StudyOverviews: result}, err } + +func (s *server) CreateTrial(ctx context.Context, in *pb.CreateTrialRequest) (*pb.CreateTrialReply, error) { + err := dbIf.CreateTrial(in.Trial) + return &pb.CreateTrialReply{TrialId: in.Trial.TrialId}, err +} + func (s *server) GetTrials(ctx context.Context, in *pb.GetTrialsRequest) (*pb.GetTrialsReply, error) { tl, err := dbIf.GetTrialList(in.StudyId) return &pb.GetTrialsReply{Trials: tl}, err } + func (s *server) GetSuggestions(ctx context.Context, in *pb.GetSuggestionsRequest) (*pb.GetSuggestionsReply, error) { suggestAlgorithm := "" if in.SuggestionAlgorithm != "" { @@ -105,12 +112,6 @@ func (s *server) GetSuggestions(ctx context.Context, in *pb.GetSuggestionsReques if err != nil { return &pb.GetSuggestionsReply{Trials: []*pb.Trial{}}, err } - for i := range r.Trials { - err = dbIf.CreateTrial(r.Trials[i]) - if err != nil { - return &pb.GetSuggestionsReply{Trials: []*pb.Trial{}}, err - } - } return r, nil } @@ -135,7 +136,15 @@ func (s *server) StopWorkers(ctx context.Context, in *pb.StopWorkersRequest) (*p } func (s *server) GetWorkers(ctx context.Context, in *pb.GetWorkersRequest) (*pb.GetWorkersReply, error) { - ws, err := dbIf.GetWorkerList(in.StudyId) + var ws []*pb.Worker + var err error + if in.WorkerId == "" { + ws, err = dbIf.GetWorkerList(in.StudyId, in.TrialId) + } else { + var w *pb.Worker + w, err = dbIf.GetWorker(in.WorkerId) + ws = append(ws, w) + } return &pb.GetWorkersReply{Workers: ws}, err } @@ -229,11 +238,21 @@ func (s *server) GetSuggestionParameters(ctx context.Context, in *pb.GetSuggesti return &pb.GetSuggestionParametersReply{SuggestionParameters: ps}, err } +func (s *server) GetSuggestionParameterList(ctx context.Context, in *pb.GetSuggestionParameterListRequest) (*pb.GetSuggestionParameterListReply, error) { + pss, err := dbIf.GetSuggestionParamList(in.StudyId) + return &pb.GetSuggestionParameterListReply{SuggestionParameterSets: pss}, err +} + func (s *server) GetEarlyStoppingParameters(ctx context.Context, in *pb.GetEarlyStoppingParametersRequest) (*pb.GetEarlyStoppingParametersReply, error) { ps, err := dbIf.GetEarlyStopParam(in.ParamId) return &pb.GetEarlyStoppingParametersReply{EarlyStoppingParameters: ps}, err } +func (s *server) GetEarlyStoppingParameterList(ctx context.Context, in *pb.GetEarlyStoppingParameterListRequest) (*pb.GetEarlyStoppingParameterListReply, error) { + pss, err := dbIf.GetEarlyStopParamList(in.StudyId) + return &pb.GetEarlyStoppingParameterListReply{EarlyStoppingParameterSets: pss}, err +} + func (s *server) StopStudy(ctx context.Context, in *pb.StopStudyRequest) (*pb.StopStudyReply, error) { err := s.wIF.CleanWorkers(in.StudyId) return &pb.StopStudyReply{}, err diff --git a/docs/GKEDemo/manifests/modeldb/frontend/deployment.yaml b/docs/GKEDemo/manifests/modeldb/frontend/deployment.yaml index 9e4da69841c..3c1e679c0e4 100644 --- a/docs/GKEDemo/manifests/modeldb/frontend/deployment.yaml +++ b/docs/GKEDemo/manifests/modeldb/frontend/deployment.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: modeldb-frontend - image: yujioshima/katib-frontend + image: katib/katib-frontend imagePullPolicy: Always args: - 'modeldb-backend' diff --git a/docs/GKEDemo/manifests/vizier/core/deployment.yaml b/docs/GKEDemo/manifests/vizier/core/deployment.yaml index 698f9da3077..cc0578ef069 100644 --- a/docs/GKEDemo/manifests/vizier/core/deployment.yaml +++ b/docs/GKEDemo/manifests/vizier/core/deployment.yaml @@ -18,7 +18,7 @@ spec: serviceAccountName: vizier-core containers: - name: vizier-core - image: yujioshima/vizier-core + image: katib/vizier-core command: - './vizier-manager' - "-w" diff --git a/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml b/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml index 2b1743e73d1..7a4ef2c5425 100644 --- a/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml +++ b/docs/GKEDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: vizier-earlystopping-medianstopping - image: yujioshima/earlystopping-medianstopping + image: katib/earlystopping-medianstopping ports: - name: api containerPort: 6789 diff --git a/docs/GKEDemo/manifests/vizier/suggestion/grid/deployment.yaml b/docs/GKEDemo/manifests/vizier/suggestion/grid/deployment.yaml index 8a2b01d8f3c..707f170ddf9 100644 --- a/docs/GKEDemo/manifests/vizier/suggestion/grid/deployment.yaml +++ b/docs/GKEDemo/manifests/vizier/suggestion/grid/deployment.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: vizier-suggestion-grid - image: yujioshima/suggestion-grid + image: katib/suggestion-grid ports: - name: api containerPort: 6789 diff --git a/docs/GKEDemo/manifests/vizier/suggestion/random/deployment.yaml b/docs/GKEDemo/manifests/vizier/suggestion/random/deployment.yaml index 5884741e045..187cac3998b 100644 --- a/docs/GKEDemo/manifests/vizier/suggestion/random/deployment.yaml +++ b/docs/GKEDemo/manifests/vizier/suggestion/random/deployment.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: vizier-suggestion-random - image: yujioshima/suggestion-random + image: katib/suggestion-random ports: - name: api containerPort: 6789 diff --git a/docs/MinikubeDemo/manifests/modeldb/frontend/deployment.yaml b/docs/MinikubeDemo/manifests/modeldb/frontend/deployment.yaml index 9e4da69841c..3c1e679c0e4 100644 --- a/docs/MinikubeDemo/manifests/modeldb/frontend/deployment.yaml +++ b/docs/MinikubeDemo/manifests/modeldb/frontend/deployment.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: modeldb-frontend - image: yujioshima/katib-frontend + image: katib/katib-frontend imagePullPolicy: Always args: - 'modeldb-backend' diff --git a/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml b/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml index 2b1743e73d1..7a4ef2c5425 100644 --- a/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml +++ b/docs/MinikubeDemo/manifests/vizier/earlystopping/medianstopping/deployment.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: vizier-earlystopping-medianstopping - image: yujioshima/earlystopping-medianstopping + image: katib/earlystopping-medianstopping ports: - name: api containerPort: 6789 diff --git a/docs/MinikubeDemo/manifests/vizier/suggestion/grid/deployment.yaml b/docs/MinikubeDemo/manifests/vizier/suggestion/grid/deployment.yaml index 8a2b01d8f3c..707f170ddf9 100644 --- a/docs/MinikubeDemo/manifests/vizier/suggestion/grid/deployment.yaml +++ b/docs/MinikubeDemo/manifests/vizier/suggestion/grid/deployment.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: vizier-suggestion-grid - image: yujioshima/suggestion-grid + image: katib/suggestion-grid ports: - name: api containerPort: 6789 diff --git a/docs/MinikubeDemo/manifests/vizier/suggestion/random/deployment.yaml b/docs/MinikubeDemo/manifests/vizier/suggestion/random/deployment.yaml index 5884741e045..187cac3998b 100644 --- a/docs/MinikubeDemo/manifests/vizier/suggestion/random/deployment.yaml +++ b/docs/MinikubeDemo/manifests/vizier/suggestion/random/deployment.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: vizier-suggestion-random - image: yujioshima/suggestion-random + image: katib/suggestion-random ports: - name: api containerPort: 6789 diff --git a/pkg/api/api.pb.go b/pkg/api/api.pb.go index dba49fb226b..74458ae382e 100644 --- a/pkg/api/api.pb.go +++ b/pkg/api/api.pb.go @@ -31,6 +31,8 @@ It has these top-level messages: GetStudyReply GetStudyListRequest GetStudyListReply + CreateTrialRequest + CreateTrialReply GetTrialsRequest GetTrialsReply RunTrialRequest @@ -61,12 +63,18 @@ It has these top-level messages: SetSuggestionParametersReply GetSuggestionParametersRequest GetSuggestionParametersReply + GetSuggestionParameterListRequest + SuggestionParameterSet + GetSuggestionParameterListReply StopSuggestionRequest StopSuggestionReply SetEarlyStoppingParametersRequest SetEarlyStoppingParametersReply GetEarlyStoppingParametersRequest GetEarlyStoppingParametersReply + GetEarlyStoppingParameterListRequest + EarlyStoppingParameterSet + GetEarlyStoppingParameterListReply */ package api @@ -884,6 +892,38 @@ func (m *GetStudyListReply) GetStudyOverviews() []*StudyOverview { return nil } +type CreateTrialRequest struct { + Trial *Trial `protobuf:"bytes,1,opt,name=trial" json:"trial,omitempty"` +} + +func (m *CreateTrialRequest) Reset() { *m = CreateTrialRequest{} } +func (m *CreateTrialRequest) String() string { return proto.CompactTextString(m) } +func (*CreateTrialRequest) ProtoMessage() {} +func (*CreateTrialRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } + +func (m *CreateTrialRequest) GetTrial() *Trial { + if m != nil { + return m.Trial + } + return nil +} + +type CreateTrialReply struct { + TrialId string `protobuf:"bytes,1,opt,name=trial_id,json=trialId" json:"trial_id,omitempty"` +} + +func (m *CreateTrialReply) Reset() { *m = CreateTrialReply{} } +func (m *CreateTrialReply) String() string { return proto.CompactTextString(m) } +func (*CreateTrialReply) ProtoMessage() {} +func (*CreateTrialReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } + +func (m *CreateTrialReply) GetTrialId() string { + if m != nil { + return m.TrialId + } + return "" +} + type GetTrialsRequest struct { StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` } @@ -891,7 +931,7 @@ type GetTrialsRequest struct { func (m *GetTrialsRequest) Reset() { *m = GetTrialsRequest{} } func (m *GetTrialsRequest) String() string { return proto.CompactTextString(m) } func (*GetTrialsRequest) ProtoMessage() {} -func (*GetTrialsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } +func (*GetTrialsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } func (m *GetTrialsRequest) GetStudyId() string { if m != nil { @@ -907,7 +947,7 @@ type GetTrialsReply struct { func (m *GetTrialsReply) Reset() { *m = GetTrialsReply{} } func (m *GetTrialsReply) String() string { return proto.CompactTextString(m) } func (*GetTrialsReply) ProtoMessage() {} -func (*GetTrialsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } +func (*GetTrialsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } func (m *GetTrialsReply) GetTrials() []*Trial { if m != nil { @@ -926,7 +966,7 @@ type RunTrialRequest struct { func (m *RunTrialRequest) Reset() { *m = RunTrialRequest{} } func (m *RunTrialRequest) String() string { return proto.CompactTextString(m) } func (*RunTrialRequest) ProtoMessage() {} -func (*RunTrialRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } +func (*RunTrialRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } func (m *RunTrialRequest) GetStudyId() string { if m != nil { @@ -963,7 +1003,7 @@ type RunTrialReply struct { func (m *RunTrialReply) Reset() { *m = RunTrialReply{} } func (m *RunTrialReply) String() string { return proto.CompactTextString(m) } func (*RunTrialReply) ProtoMessage() {} -func (*RunTrialReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } +func (*RunTrialReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } func (m *RunTrialReply) GetWorkerId() string { if m != nil { @@ -981,7 +1021,7 @@ type StopWorkersRequest struct { func (m *StopWorkersRequest) Reset() { *m = StopWorkersRequest{} } func (m *StopWorkersRequest) String() string { return proto.CompactTextString(m) } func (*StopWorkersRequest) ProtoMessage() {} -func (*StopWorkersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } +func (*StopWorkersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } func (m *StopWorkersRequest) GetStudyId() string { if m != nil { @@ -1010,16 +1050,18 @@ type StopWorkersReply struct { func (m *StopWorkersReply) Reset() { *m = StopWorkersReply{} } func (m *StopWorkersReply) String() string { return proto.CompactTextString(m) } func (*StopWorkersReply) ProtoMessage() {} -func (*StopWorkersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } +func (*StopWorkersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } type GetWorkersRequest struct { - StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` + TrialId string `protobuf:"bytes,2,opt,name=trial_id,json=trialId" json:"trial_id,omitempty"` + WorkerId string `protobuf:"bytes,3,opt,name=worker_id,json=workerId" json:"worker_id,omitempty"` } func (m *GetWorkersRequest) Reset() { *m = GetWorkersRequest{} } func (m *GetWorkersRequest) String() string { return proto.CompactTextString(m) } func (*GetWorkersRequest) ProtoMessage() {} -func (*GetWorkersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } +func (*GetWorkersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } func (m *GetWorkersRequest) GetStudyId() string { if m != nil { @@ -1028,6 +1070,20 @@ func (m *GetWorkersRequest) GetStudyId() string { return "" } +func (m *GetWorkersRequest) GetTrialId() string { + if m != nil { + return m.TrialId + } + return "" +} + +func (m *GetWorkersRequest) GetWorkerId() string { + if m != nil { + return m.WorkerId + } + return "" +} + type GetWorkersReply struct { Workers []*Worker `protobuf:"bytes,1,rep,name=workers" json:"workers,omitempty"` } @@ -1035,7 +1091,7 @@ type GetWorkersReply struct { func (m *GetWorkersReply) Reset() { *m = GetWorkersReply{} } func (m *GetWorkersReply) String() string { return proto.CompactTextString(m) } func (*GetWorkersReply) ProtoMessage() {} -func (*GetWorkersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } +func (*GetWorkersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } func (m *GetWorkersReply) GetWorkers() []*Worker { if m != nil { @@ -1055,7 +1111,7 @@ type GetSuggestionsRequest struct { 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{31} } +func (*GetSuggestionsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } func (m *GetSuggestionsRequest) GetStudyId() string { if m != nil { @@ -1099,7 +1155,7 @@ type GetSuggestionsReply struct { 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{32} } +func (*GetSuggestionsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } func (m *GetSuggestionsReply) GetTrials() []*Trial { if m != nil { @@ -1117,7 +1173,7 @@ type GetShouldStopWorkersRequest struct { func (m *GetShouldStopWorkersRequest) Reset() { *m = GetShouldStopWorkersRequest{} } func (m *GetShouldStopWorkersRequest) String() string { return proto.CompactTextString(m) } func (*GetShouldStopWorkersRequest) ProtoMessage() {} -func (*GetShouldStopWorkersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } +func (*GetShouldStopWorkersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } func (m *GetShouldStopWorkersRequest) GetStudyId() string { if m != nil { @@ -1147,7 +1203,7 @@ type GetShouldStopWorkersReply struct { func (m *GetShouldStopWorkersReply) Reset() { *m = GetShouldStopWorkersReply{} } func (m *GetShouldStopWorkersReply) String() string { return proto.CompactTextString(m) } func (*GetShouldStopWorkersReply) ProtoMessage() {} -func (*GetShouldStopWorkersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } +func (*GetShouldStopWorkersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } func (m *GetShouldStopWorkersReply) GetShouldStopWorkerIds() []string { if m != nil { @@ -1165,7 +1221,7 @@ type GetMetricsRequest struct { func (m *GetMetricsRequest) Reset() { *m = GetMetricsRequest{} } func (m *GetMetricsRequest) String() string { return proto.CompactTextString(m) } func (*GetMetricsRequest) ProtoMessage() {} -func (*GetMetricsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } +func (*GetMetricsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } func (m *GetMetricsRequest) GetStudyId() string { if m != nil { @@ -1195,7 +1251,7 @@ type GetMetricsReply struct { func (m *GetMetricsReply) Reset() { *m = GetMetricsReply{} } func (m *GetMetricsReply) String() string { return proto.CompactTextString(m) } func (*GetMetricsReply) ProtoMessage() {} -func (*GetMetricsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } +func (*GetMetricsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } func (m *GetMetricsReply) GetMetricsLogSets() []*MetricsLogSet { if m != nil { @@ -1215,7 +1271,7 @@ type ModelInfo struct { func (m *ModelInfo) Reset() { *m = ModelInfo{} } func (m *ModelInfo) String() string { return proto.CompactTextString(m) } func (*ModelInfo) ProtoMessage() {} -func (*ModelInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } +func (*ModelInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } func (m *ModelInfo) GetStudyName() string { if m != nil { @@ -1260,7 +1316,7 @@ type DataSetInfo struct { func (m *DataSetInfo) Reset() { *m = DataSetInfo{} } func (m *DataSetInfo) String() string { return proto.CompactTextString(m) } func (*DataSetInfo) ProtoMessage() {} -func (*DataSetInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } +func (*DataSetInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } func (m *DataSetInfo) GetName() string { if m != nil { @@ -1285,7 +1341,7 @@ type SaveStudyRequest struct { func (m *SaveStudyRequest) Reset() { *m = SaveStudyRequest{} } func (m *SaveStudyRequest) String() string { return proto.CompactTextString(m) } func (*SaveStudyRequest) ProtoMessage() {} -func (*SaveStudyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } +func (*SaveStudyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } func (m *SaveStudyRequest) GetStudyName() string { if m != nil { @@ -1314,7 +1370,7 @@ type SaveStudyReply struct { func (m *SaveStudyReply) Reset() { *m = SaveStudyReply{} } func (m *SaveStudyReply) String() string { return proto.CompactTextString(m) } func (*SaveStudyReply) ProtoMessage() {} -func (*SaveStudyReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } +func (*SaveStudyReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } type SaveModelRequest struct { Model *ModelInfo `protobuf:"bytes,1,opt,name=model" json:"model,omitempty"` @@ -1325,7 +1381,7 @@ type SaveModelRequest struct { func (m *SaveModelRequest) Reset() { *m = SaveModelRequest{} } func (m *SaveModelRequest) String() string { return proto.CompactTextString(m) } func (*SaveModelRequest) ProtoMessage() {} -func (*SaveModelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } +func (*SaveModelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } func (m *SaveModelRequest) GetModel() *ModelInfo { if m != nil { @@ -1354,7 +1410,7 @@ type SaveModelReply struct { func (m *SaveModelReply) Reset() { *m = SaveModelReply{} } func (m *SaveModelReply) String() string { return proto.CompactTextString(m) } func (*SaveModelReply) ProtoMessage() {} -func (*SaveModelReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } +func (*SaveModelReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } type GetSavedStudiesRequest struct { } @@ -1362,7 +1418,7 @@ type GetSavedStudiesRequest struct { func (m *GetSavedStudiesRequest) Reset() { *m = GetSavedStudiesRequest{} } func (m *GetSavedStudiesRequest) String() string { return proto.CompactTextString(m) } func (*GetSavedStudiesRequest) ProtoMessage() {} -func (*GetSavedStudiesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } +func (*GetSavedStudiesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } type GetSavedStudiesReply struct { Studies []*StudyOverview `protobuf:"bytes,1,rep,name=studies" json:"studies,omitempty"` @@ -1371,7 +1427,7 @@ type GetSavedStudiesReply struct { func (m *GetSavedStudiesReply) Reset() { *m = GetSavedStudiesReply{} } func (m *GetSavedStudiesReply) String() string { return proto.CompactTextString(m) } func (*GetSavedStudiesReply) ProtoMessage() {} -func (*GetSavedStudiesReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } +func (*GetSavedStudiesReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} } func (m *GetSavedStudiesReply) GetStudies() []*StudyOverview { if m != nil { @@ -1387,7 +1443,7 @@ type GetSavedModelsRequest struct { func (m *GetSavedModelsRequest) Reset() { *m = GetSavedModelsRequest{} } func (m *GetSavedModelsRequest) String() string { return proto.CompactTextString(m) } func (*GetSavedModelsRequest) ProtoMessage() {} -func (*GetSavedModelsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } +func (*GetSavedModelsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} } func (m *GetSavedModelsRequest) GetStudyName() string { if m != nil { @@ -1403,7 +1459,7 @@ type GetSavedModelsReply struct { func (m *GetSavedModelsReply) Reset() { *m = GetSavedModelsReply{} } func (m *GetSavedModelsReply) String() string { return proto.CompactTextString(m) } func (*GetSavedModelsReply) ProtoMessage() {} -func (*GetSavedModelsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} } +func (*GetSavedModelsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} } func (m *GetSavedModelsReply) GetModels() []*ModelInfo { if m != nil { @@ -1420,7 +1476,7 @@ type GetSavedModelRequest struct { func (m *GetSavedModelRequest) Reset() { *m = GetSavedModelRequest{} } func (m *GetSavedModelRequest) String() string { return proto.CompactTextString(m) } func (*GetSavedModelRequest) ProtoMessage() {} -func (*GetSavedModelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} } +func (*GetSavedModelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} } func (m *GetSavedModelRequest) GetStudyName() string { if m != nil { @@ -1443,7 +1499,7 @@ type GetSavedModelReply struct { func (m *GetSavedModelReply) Reset() { *m = GetSavedModelReply{} } func (m *GetSavedModelReply) String() string { return proto.CompactTextString(m) } func (*GetSavedModelReply) ProtoMessage() {} -func (*GetSavedModelReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} } +func (*GetSavedModelReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} } func (m *GetSavedModelReply) GetModel() *ModelInfo { if m != nil { @@ -1462,7 +1518,7 @@ type SetSuggestionParametersRequest struct { func (m *SetSuggestionParametersRequest) Reset() { *m = SetSuggestionParametersRequest{} } func (m *SetSuggestionParametersRequest) String() string { return proto.CompactTextString(m) } func (*SetSuggestionParametersRequest) ProtoMessage() {} -func (*SetSuggestionParametersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} } +func (*SetSuggestionParametersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} } func (m *SetSuggestionParametersRequest) GetStudyId() string { if m != nil { @@ -1499,7 +1555,7 @@ type SetSuggestionParametersReply struct { func (m *SetSuggestionParametersReply) Reset() { *m = SetSuggestionParametersReply{} } func (m *SetSuggestionParametersReply) String() string { return proto.CompactTextString(m) } func (*SetSuggestionParametersReply) ProtoMessage() {} -func (*SetSuggestionParametersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} } +func (*SetSuggestionParametersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} } func (m *SetSuggestionParametersReply) GetParamId() string { if m != nil { @@ -1515,7 +1571,7 @@ type GetSuggestionParametersRequest struct { func (m *GetSuggestionParametersRequest) Reset() { *m = GetSuggestionParametersRequest{} } func (m *GetSuggestionParametersRequest) String() string { return proto.CompactTextString(m) } func (*GetSuggestionParametersRequest) ProtoMessage() {} -func (*GetSuggestionParametersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} } +func (*GetSuggestionParametersRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} } func (m *GetSuggestionParametersRequest) GetParamId() string { if m != nil { @@ -1531,7 +1587,7 @@ type GetSuggestionParametersReply struct { func (m *GetSuggestionParametersReply) Reset() { *m = GetSuggestionParametersReply{} } func (m *GetSuggestionParametersReply) String() string { return proto.CompactTextString(m) } func (*GetSuggestionParametersReply) ProtoMessage() {} -func (*GetSuggestionParametersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} } +func (*GetSuggestionParametersReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54} } func (m *GetSuggestionParametersReply) GetSuggestionParameters() []*SuggestionParameter { if m != nil { @@ -1540,6 +1596,74 @@ func (m *GetSuggestionParametersReply) GetSuggestionParameters() []*SuggestionPa return nil } +type GetSuggestionParameterListRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` +} + +func (m *GetSuggestionParameterListRequest) Reset() { *m = GetSuggestionParameterListRequest{} } +func (m *GetSuggestionParameterListRequest) String() string { return proto.CompactTextString(m) } +func (*GetSuggestionParameterListRequest) ProtoMessage() {} +func (*GetSuggestionParameterListRequest) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{55} +} + +func (m *GetSuggestionParameterListRequest) GetStudyId() string { + if m != nil { + return m.StudyId + } + return "" +} + +type SuggestionParameterSet struct { + ParamId string `protobuf:"bytes,1,opt,name=param_id,json=paramId" json:"param_id,omitempty"` + SuggestionAlgorithm string `protobuf:"bytes,2,opt,name=suggestion_algorithm,json=suggestionAlgorithm" json:"suggestion_algorithm,omitempty"` + SuggestionParameters []*SuggestionParameter `protobuf:"bytes,3,rep,name=suggestion_parameters,json=suggestionParameters" json:"suggestion_parameters,omitempty"` +} + +func (m *SuggestionParameterSet) Reset() { *m = SuggestionParameterSet{} } +func (m *SuggestionParameterSet) String() string { return proto.CompactTextString(m) } +func (*SuggestionParameterSet) ProtoMessage() {} +func (*SuggestionParameterSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56} } + +func (m *SuggestionParameterSet) GetParamId() string { + if m != nil { + return m.ParamId + } + return "" +} + +func (m *SuggestionParameterSet) GetSuggestionAlgorithm() string { + if m != nil { + return m.SuggestionAlgorithm + } + return "" +} + +func (m *SuggestionParameterSet) GetSuggestionParameters() []*SuggestionParameter { + if m != nil { + return m.SuggestionParameters + } + return nil +} + +type GetSuggestionParameterListReply struct { + SuggestionParameterSets []*SuggestionParameterSet `protobuf:"bytes,1,rep,name=suggestion_parameter_sets,json=suggestionParameterSets" json:"suggestion_parameter_sets,omitempty"` +} + +func (m *GetSuggestionParameterListReply) Reset() { *m = GetSuggestionParameterListReply{} } +func (m *GetSuggestionParameterListReply) String() string { return proto.CompactTextString(m) } +func (*GetSuggestionParameterListReply) ProtoMessage() {} +func (*GetSuggestionParameterListReply) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{57} +} + +func (m *GetSuggestionParameterListReply) GetSuggestionParameterSets() []*SuggestionParameterSet { + if m != nil { + return m.SuggestionParameterSets + } + return nil +} + type StopSuggestionRequest struct { StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` } @@ -1547,7 +1671,7 @@ type StopSuggestionRequest struct { func (m *StopSuggestionRequest) Reset() { *m = StopSuggestionRequest{} } func (m *StopSuggestionRequest) String() string { return proto.CompactTextString(m) } func (*StopSuggestionRequest) ProtoMessage() {} -func (*StopSuggestionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} } +func (*StopSuggestionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{58} } func (m *StopSuggestionRequest) GetStudyId() string { if m != nil { @@ -1562,7 +1686,7 @@ type StopSuggestionReply struct { func (m *StopSuggestionReply) Reset() { *m = StopSuggestionReply{} } func (m *StopSuggestionReply) String() string { return proto.CompactTextString(m) } func (*StopSuggestionReply) ProtoMessage() {} -func (*StopSuggestionReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54} } +func (*StopSuggestionReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{59} } type SetEarlyStoppingParametersRequest struct { StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` @@ -1575,7 +1699,7 @@ func (m *SetEarlyStoppingParametersRequest) Reset() { *m = SetEarlyStopp func (m *SetEarlyStoppingParametersRequest) String() string { return proto.CompactTextString(m) } func (*SetEarlyStoppingParametersRequest) ProtoMessage() {} func (*SetEarlyStoppingParametersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{55} + return fileDescriptor0, []int{60} } func (m *SetEarlyStoppingParametersRequest) GetStudyId() string { @@ -1614,7 +1738,7 @@ func (m *SetEarlyStoppingParametersReply) Reset() { *m = SetEarlyStoppin func (m *SetEarlyStoppingParametersReply) String() string { return proto.CompactTextString(m) } func (*SetEarlyStoppingParametersReply) ProtoMessage() {} func (*SetEarlyStoppingParametersReply) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{56} + return fileDescriptor0, []int{61} } func (m *SetEarlyStoppingParametersReply) GetParamId() string { @@ -1632,7 +1756,7 @@ func (m *GetEarlyStoppingParametersRequest) Reset() { *m = GetEarlyStopp func (m *GetEarlyStoppingParametersRequest) String() string { return proto.CompactTextString(m) } func (*GetEarlyStoppingParametersRequest) ProtoMessage() {} func (*GetEarlyStoppingParametersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{57} + return fileDescriptor0, []int{62} } func (m *GetEarlyStoppingParametersRequest) GetParamId() string { @@ -1650,7 +1774,7 @@ func (m *GetEarlyStoppingParametersReply) Reset() { *m = GetEarlyStoppin func (m *GetEarlyStoppingParametersReply) String() string { return proto.CompactTextString(m) } func (*GetEarlyStoppingParametersReply) ProtoMessage() {} func (*GetEarlyStoppingParametersReply) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{58} + return fileDescriptor0, []int{63} } func (m *GetEarlyStoppingParametersReply) GetEarlyStoppingParameters() []*EarlyStoppingParameter { @@ -1660,6 +1784,74 @@ func (m *GetEarlyStoppingParametersReply) GetEarlyStoppingParameters() []*EarlyS return nil } +type GetEarlyStoppingParameterListRequest struct { + StudyId string `protobuf:"bytes,1,opt,name=study_id,json=studyId" json:"study_id,omitempty"` +} + +func (m *GetEarlyStoppingParameterListRequest) Reset() { *m = GetEarlyStoppingParameterListRequest{} } +func (m *GetEarlyStoppingParameterListRequest) String() string { return proto.CompactTextString(m) } +func (*GetEarlyStoppingParameterListRequest) ProtoMessage() {} +func (*GetEarlyStoppingParameterListRequest) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{64} +} + +func (m *GetEarlyStoppingParameterListRequest) GetStudyId() string { + if m != nil { + return m.StudyId + } + return "" +} + +type EarlyStoppingParameterSet struct { + ParamId string `protobuf:"bytes,1,opt,name=param_id,json=paramId" json:"param_id,omitempty"` + EarlyStoppingAlgorithm string `protobuf:"bytes,2,opt,name=early_stopping_algorithm,json=earlyStoppingAlgorithm" json:"early_stopping_algorithm,omitempty"` + EarlyStoppingParameters []*EarlyStoppingParameter `protobuf:"bytes,3,rep,name=early_stopping_parameters,json=earlyStoppingParameters" json:"early_stopping_parameters,omitempty"` +} + +func (m *EarlyStoppingParameterSet) Reset() { *m = EarlyStoppingParameterSet{} } +func (m *EarlyStoppingParameterSet) String() string { return proto.CompactTextString(m) } +func (*EarlyStoppingParameterSet) ProtoMessage() {} +func (*EarlyStoppingParameterSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{65} } + +func (m *EarlyStoppingParameterSet) GetParamId() string { + if m != nil { + return m.ParamId + } + return "" +} + +func (m *EarlyStoppingParameterSet) GetEarlyStoppingAlgorithm() string { + if m != nil { + return m.EarlyStoppingAlgorithm + } + return "" +} + +func (m *EarlyStoppingParameterSet) GetEarlyStoppingParameters() []*EarlyStoppingParameter { + if m != nil { + return m.EarlyStoppingParameters + } + return nil +} + +type GetEarlyStoppingParameterListReply struct { + EarlyStoppingParameterSets []*EarlyStoppingParameterSet `protobuf:"bytes,1,rep,name=early_stopping_parameter_sets,json=earlyStoppingParameterSets" json:"early_stopping_parameter_sets,omitempty"` +} + +func (m *GetEarlyStoppingParameterListReply) Reset() { *m = GetEarlyStoppingParameterListReply{} } +func (m *GetEarlyStoppingParameterListReply) String() string { return proto.CompactTextString(m) } +func (*GetEarlyStoppingParameterListReply) ProtoMessage() {} +func (*GetEarlyStoppingParameterListReply) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{66} +} + +func (m *GetEarlyStoppingParameterListReply) GetEarlyStoppingParameterSets() []*EarlyStoppingParameterSet { + if m != nil { + return m.EarlyStoppingParameterSets + } + return nil +} + func init() { proto.RegisterType((*FeasibleSpace)(nil), "api.FeasibleSpace") proto.RegisterType((*ParameterConfig)(nil), "api.ParameterConfig") @@ -1685,6 +1877,8 @@ func init() { proto.RegisterType((*GetStudyReply)(nil), "api.GetStudyReply") proto.RegisterType((*GetStudyListRequest)(nil), "api.GetStudyListRequest") proto.RegisterType((*GetStudyListReply)(nil), "api.GetStudyListReply") + proto.RegisterType((*CreateTrialRequest)(nil), "api.CreateTrialRequest") + proto.RegisterType((*CreateTrialReply)(nil), "api.CreateTrialReply") proto.RegisterType((*GetTrialsRequest)(nil), "api.GetTrialsRequest") proto.RegisterType((*GetTrialsReply)(nil), "api.GetTrialsReply") proto.RegisterType((*RunTrialRequest)(nil), "api.RunTrialRequest") @@ -1715,12 +1909,18 @@ func init() { proto.RegisterType((*SetSuggestionParametersReply)(nil), "api.SetSuggestionParametersReply") proto.RegisterType((*GetSuggestionParametersRequest)(nil), "api.GetSuggestionParametersRequest") proto.RegisterType((*GetSuggestionParametersReply)(nil), "api.GetSuggestionParametersReply") + proto.RegisterType((*GetSuggestionParameterListRequest)(nil), "api.GetSuggestionParameterListRequest") + proto.RegisterType((*SuggestionParameterSet)(nil), "api.SuggestionParameterSet") + proto.RegisterType((*GetSuggestionParameterListReply)(nil), "api.GetSuggestionParameterListReply") proto.RegisterType((*StopSuggestionRequest)(nil), "api.StopSuggestionRequest") proto.RegisterType((*StopSuggestionReply)(nil), "api.StopSuggestionReply") proto.RegisterType((*SetEarlyStoppingParametersRequest)(nil), "api.SetEarlyStoppingParametersRequest") proto.RegisterType((*SetEarlyStoppingParametersReply)(nil), "api.SetEarlyStoppingParametersReply") proto.RegisterType((*GetEarlyStoppingParametersRequest)(nil), "api.GetEarlyStoppingParametersRequest") proto.RegisterType((*GetEarlyStoppingParametersReply)(nil), "api.GetEarlyStoppingParametersReply") + proto.RegisterType((*GetEarlyStoppingParameterListRequest)(nil), "api.GetEarlyStoppingParameterListRequest") + proto.RegisterType((*EarlyStoppingParameterSet)(nil), "api.EarlyStoppingParameterSet") + proto.RegisterType((*GetEarlyStoppingParameterListReply)(nil), "api.GetEarlyStoppingParameterListReply") proto.RegisterEnum("api.ParameterType", ParameterType_name, ParameterType_value) proto.RegisterEnum("api.OptimizationType", OptimizationType_name, OptimizationType_value) proto.RegisterEnum("api.State", State_name, State_value) @@ -1741,6 +1941,7 @@ type ManagerClient interface { StopStudy(ctx context.Context, in *StopStudyRequest, opts ...grpc.CallOption) (*StopStudyReply, error) GetStudy(ctx context.Context, in *GetStudyRequest, opts ...grpc.CallOption) (*GetStudyReply, error) GetStudyList(ctx context.Context, in *GetStudyListRequest, opts ...grpc.CallOption) (*GetStudyListReply, error) + CreateTrial(ctx context.Context, in *CreateTrialRequest, opts ...grpc.CallOption) (*CreateTrialReply, error) GetTrials(ctx context.Context, in *GetTrialsRequest, opts ...grpc.CallOption) (*GetTrialsReply, error) RunTrial(ctx context.Context, in *RunTrialRequest, opts ...grpc.CallOption) (*RunTrialReply, error) StopWorkers(ctx context.Context, in *StopWorkersRequest, opts ...grpc.CallOption) (*StopWorkersReply, error) @@ -1750,8 +1951,10 @@ type ManagerClient interface { GetMetrics(ctx context.Context, in *GetMetricsRequest, opts ...grpc.CallOption) (*GetMetricsReply, error) SetSuggestionParameters(ctx context.Context, in *SetSuggestionParametersRequest, opts ...grpc.CallOption) (*SetSuggestionParametersReply, error) GetSuggestionParameters(ctx context.Context, in *GetSuggestionParametersRequest, opts ...grpc.CallOption) (*GetSuggestionParametersReply, error) + GetSuggestionParameterList(ctx context.Context, in *GetSuggestionParameterListRequest, opts ...grpc.CallOption) (*GetSuggestionParameterListReply, error) SetEarlyStoppingParameters(ctx context.Context, in *SetEarlyStoppingParametersRequest, opts ...grpc.CallOption) (*SetEarlyStoppingParametersReply, error) GetEarlyStoppingParameters(ctx context.Context, in *GetEarlyStoppingParametersRequest, opts ...grpc.CallOption) (*GetEarlyStoppingParametersReply, error) + GetEarlyStoppingParameterList(ctx context.Context, in *GetEarlyStoppingParameterListRequest, opts ...grpc.CallOption) (*GetEarlyStoppingParameterListReply, error) SaveStudy(ctx context.Context, in *SaveStudyRequest, opts ...grpc.CallOption) (*SaveStudyReply, error) SaveModel(ctx context.Context, in *SaveModelRequest, opts ...grpc.CallOption) (*SaveModelReply, error) GetSavedStudies(ctx context.Context, in *GetSavedStudiesRequest, opts ...grpc.CallOption) (*GetSavedStudiesReply, error) @@ -1802,6 +2005,15 @@ func (c *managerClient) GetStudyList(ctx context.Context, in *GetStudyListReques return out, nil } +func (c *managerClient) CreateTrial(ctx context.Context, in *CreateTrialRequest, opts ...grpc.CallOption) (*CreateTrialReply, error) { + out := new(CreateTrialReply) + err := grpc.Invoke(ctx, "/api.Manager/CreateTrial", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *managerClient) GetTrials(ctx context.Context, in *GetTrialsRequest, opts ...grpc.CallOption) (*GetTrialsReply, error) { out := new(GetTrialsReply) err := grpc.Invoke(ctx, "/api.Manager/GetTrials", in, out, c.cc, opts...) @@ -1883,6 +2095,15 @@ func (c *managerClient) GetSuggestionParameters(ctx context.Context, in *GetSugg return out, nil } +func (c *managerClient) GetSuggestionParameterList(ctx context.Context, in *GetSuggestionParameterListRequest, opts ...grpc.CallOption) (*GetSuggestionParameterListReply, error) { + out := new(GetSuggestionParameterListReply) + err := grpc.Invoke(ctx, "/api.Manager/GetSuggestionParameterList", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *managerClient) SetEarlyStoppingParameters(ctx context.Context, in *SetEarlyStoppingParametersRequest, opts ...grpc.CallOption) (*SetEarlyStoppingParametersReply, error) { out := new(SetEarlyStoppingParametersReply) err := grpc.Invoke(ctx, "/api.Manager/SetEarlyStoppingParameters", in, out, c.cc, opts...) @@ -1901,6 +2122,15 @@ func (c *managerClient) GetEarlyStoppingParameters(ctx context.Context, in *GetE return out, nil } +func (c *managerClient) GetEarlyStoppingParameterList(ctx context.Context, in *GetEarlyStoppingParameterListRequest, opts ...grpc.CallOption) (*GetEarlyStoppingParameterListReply, error) { + out := new(GetEarlyStoppingParameterListReply) + err := grpc.Invoke(ctx, "/api.Manager/GetEarlyStoppingParameterList", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *managerClient) SaveStudy(ctx context.Context, in *SaveStudyRequest, opts ...grpc.CallOption) (*SaveStudyReply, error) { out := new(SaveStudyReply) err := grpc.Invoke(ctx, "/api.Manager/SaveStudy", in, out, c.cc, opts...) @@ -1944,6 +2174,7 @@ type ManagerServer interface { StopStudy(context.Context, *StopStudyRequest) (*StopStudyReply, error) GetStudy(context.Context, *GetStudyRequest) (*GetStudyReply, error) GetStudyList(context.Context, *GetStudyListRequest) (*GetStudyListReply, error) + CreateTrial(context.Context, *CreateTrialRequest) (*CreateTrialReply, error) GetTrials(context.Context, *GetTrialsRequest) (*GetTrialsReply, error) RunTrial(context.Context, *RunTrialRequest) (*RunTrialReply, error) StopWorkers(context.Context, *StopWorkersRequest) (*StopWorkersReply, error) @@ -1953,8 +2184,10 @@ type ManagerServer interface { GetMetrics(context.Context, *GetMetricsRequest) (*GetMetricsReply, error) SetSuggestionParameters(context.Context, *SetSuggestionParametersRequest) (*SetSuggestionParametersReply, error) GetSuggestionParameters(context.Context, *GetSuggestionParametersRequest) (*GetSuggestionParametersReply, error) + GetSuggestionParameterList(context.Context, *GetSuggestionParameterListRequest) (*GetSuggestionParameterListReply, error) SetEarlyStoppingParameters(context.Context, *SetEarlyStoppingParametersRequest) (*SetEarlyStoppingParametersReply, error) GetEarlyStoppingParameters(context.Context, *GetEarlyStoppingParametersRequest) (*GetEarlyStoppingParametersReply, error) + GetEarlyStoppingParameterList(context.Context, *GetEarlyStoppingParameterListRequest) (*GetEarlyStoppingParameterListReply, error) SaveStudy(context.Context, *SaveStudyRequest) (*SaveStudyReply, error) SaveModel(context.Context, *SaveModelRequest) (*SaveModelReply, error) GetSavedStudies(context.Context, *GetSavedStudiesRequest) (*GetSavedStudiesReply, error) @@ -2037,6 +2270,24 @@ func _Manager_GetStudyList_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _Manager_CreateTrial_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateTrialRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServer).CreateTrial(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Manager/CreateTrial", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServer).CreateTrial(ctx, req.(*CreateTrialRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Manager_GetTrials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetTrialsRequest) if err := dec(in); err != nil { @@ -2199,6 +2450,24 @@ func _Manager_GetSuggestionParameters_Handler(srv interface{}, ctx context.Conte return interceptor(ctx, in, info, handler) } +func _Manager_GetSuggestionParameterList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSuggestionParameterListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServer).GetSuggestionParameterList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Manager/GetSuggestionParameterList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServer).GetSuggestionParameterList(ctx, req.(*GetSuggestionParameterListRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Manager_SetEarlyStoppingParameters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SetEarlyStoppingParametersRequest) if err := dec(in); err != nil { @@ -2235,6 +2504,24 @@ func _Manager_GetEarlyStoppingParameters_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _Manager_GetEarlyStoppingParameterList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetEarlyStoppingParameterListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServer).GetEarlyStoppingParameterList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Manager/GetEarlyStoppingParameterList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServer).GetEarlyStoppingParameterList(ctx, req.(*GetEarlyStoppingParameterListRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Manager_SaveStudy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SaveStudyRequest) if err := dec(in); err != nil { @@ -2327,6 +2614,10 @@ var _Manager_serviceDesc = grpc.ServiceDesc{ MethodName: "GetStudyList", Handler: _Manager_GetStudyList_Handler, }, + { + MethodName: "CreateTrial", + Handler: _Manager_CreateTrial_Handler, + }, { MethodName: "GetTrials", Handler: _Manager_GetTrials_Handler, @@ -2363,6 +2654,10 @@ var _Manager_serviceDesc = grpc.ServiceDesc{ MethodName: "GetSuggestionParameters", Handler: _Manager_GetSuggestionParameters_Handler, }, + { + MethodName: "GetSuggestionParameterList", + Handler: _Manager_GetSuggestionParameterList_Handler, + }, { MethodName: "SetEarlyStoppingParameters", Handler: _Manager_SetEarlyStoppingParameters_Handler, @@ -2371,6 +2666,10 @@ var _Manager_serviceDesc = grpc.ServiceDesc{ MethodName: "GetEarlyStoppingParameters", Handler: _Manager_GetEarlyStoppingParameters_Handler, }, + { + MethodName: "GetEarlyStoppingParameterList", + Handler: _Manager_GetEarlyStoppingParameterList_Handler, + }, { MethodName: "SaveStudy", Handler: _Manager_SaveStudy_Handler, @@ -2523,145 +2822,156 @@ var _EarlyStopping_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("api.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 2228 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x19, 0x49, 0x73, 0xdb, 0xd6, - 0xd9, 0x20, 0x25, 0x2e, 0x1f, 0x17, 0x41, 0x4f, 0x8b, 0x21, 0x5a, 0xb1, 0x25, 0xc4, 0x71, 0x5d, - 0xc7, 0x51, 0x1b, 0xda, 0x4d, 0xed, 0x24, 0x6e, 0xa3, 0x85, 0x61, 0x39, 0x91, 0x48, 0x0d, 0x48, - 0xd7, 0x69, 0x2f, 0x2c, 0x44, 0x3c, 0xd3, 0x48, 0x40, 0x02, 0xc5, 0x03, 0xe5, 0x28, 0xbf, 0xa0, - 0x97, 0xce, 0xf4, 0xda, 0x1f, 0xd2, 0x6b, 0xff, 0x41, 0xef, 0xbd, 0x74, 0xa6, 0xd3, 0xe9, 0xb1, - 0x3f, 0xa2, 0xf3, 0x16, 0x00, 0x0f, 0xe0, 0x22, 0xc6, 0x89, 0x73, 0xc3, 0xfb, 0xde, 0xf7, 0xbe, - 0x7d, 0x25, 0xa1, 0x68, 0x7a, 0xf6, 0x81, 0xe7, 0xbb, 0x81, 0x8b, 0xb2, 0xa6, 0x67, 0xeb, 0x4d, - 0xa8, 0x7c, 0x8e, 0x4d, 0x62, 0x5f, 0x38, 0xb8, 0xeb, 0x99, 0x03, 0x8c, 0x54, 0xc8, 0x8e, 0xcc, - 0x6f, 0x34, 0x65, 0x4f, 0xb9, 0x5f, 0x34, 0xe8, 0x27, 0x83, 0xd8, 0x63, 0x2d, 0x23, 0x20, 0xf6, - 0x18, 0x21, 0x58, 0x71, 0x6c, 0x12, 0x68, 0xd9, 0xbd, 0xec, 0xfd, 0xa2, 0xc1, 0xbe, 0xf5, 0xbf, - 0x28, 0xb0, 0x76, 0x6e, 0xfa, 0xe6, 0x08, 0x07, 0xd8, 0x3f, 0x76, 0xc7, 0x2f, 0xed, 0x21, 0xc5, - 0x1b, 0x9b, 0x23, 0x2c, 0x88, 0xb1, 0x6f, 0xf4, 0x14, 0xaa, 0x5e, 0x88, 0xd6, 0x0f, 0xae, 0x3c, - 0xcc, 0x08, 0x57, 0xeb, 0xe8, 0x80, 0x4a, 0x16, 0x51, 0xe8, 0x5d, 0x79, 0xd8, 0xa8, 0x78, 0xf2, - 0x11, 0x1d, 0x40, 0xe1, 0xa5, 0x90, 0x55, 0xcb, 0xee, 0x29, 0xf7, 0x4b, 0xe2, 0x51, 0x42, 0x01, - 0x23, 0xc2, 0xd1, 0x3d, 0x28, 0x46, 0xf4, 0x7e, 0x68, 0x59, 0x36, 0x61, 0xf5, 0xd2, 0x74, 0x26, - 0x5c, 0x90, 0xa2, 0xc1, 0x0f, 0xfa, 0x1f, 0xa0, 0x72, 0x86, 0x03, 0xdf, 0x1e, 0x90, 0x53, 0x77, - 0xd8, 0xc5, 0x01, 0xba, 0x05, 0xc5, 0xd7, 0xae, 0xff, 0x35, 0xf6, 0xfb, 0xb6, 0x25, 0x58, 0x17, - 0x38, 0xa0, 0x65, 0xa1, 0x3a, 0x94, 0x47, 0x1c, 0xbb, 0xef, 0xb8, 0x43, 0xa2, 0x65, 0xf6, 0xb2, - 0xf7, 0x4b, 0xf5, 0x35, 0xc6, 0x3c, 0x26, 0x63, 0x94, 0x46, 0xd1, 0x37, 0xd1, 0x1f, 0x41, 0x5e, - 0x5c, 0xcd, 0xd4, 0x28, 0x12, 0x2b, 0x23, 0x8b, 0xf5, 0x04, 0x20, 0xa6, 0x37, 0xf3, 0xdd, 0x36, - 0xe4, 0x18, 0x2a, 0x17, 0xa2, 0x68, 0x88, 0x93, 0xfe, 0x6b, 0xd8, 0xe8, 0x4e, 0x86, 0x43, 0x4c, - 0x02, 0xdb, 0x1d, 0x2f, 0x36, 0xe6, 0x6c, 0xd6, 0x47, 0xb0, 0xdd, 0x30, 0x7d, 0xe7, 0xaa, 0x1b, - 0xb8, 0x9e, 0x67, 0x8f, 0x87, 0x6f, 0x42, 0xe3, 0x67, 0x90, 0xed, 0x99, 0xc3, 0xef, 0xf0, 0xe0, - 0x43, 0x28, 0x9e, 0xb9, 0x93, 0x71, 0x40, 0xc3, 0x90, 0x86, 0xaf, 0x77, 0x39, 0x08, 0x03, 0xda, - 0xbb, 0x1c, 0x50, 0x42, 0x9e, 0x19, 0xbc, 0x12, 0x6f, 0xd8, 0xb7, 0xfe, 0x35, 0x54, 0xba, 0xc1, - 0xc4, 0xba, 0xea, 0x5c, 0x62, 0xff, 0xd2, 0xc6, 0xaf, 0xe7, 0x71, 0x73, 0x5f, 0x8f, 0xb1, 0x1f, - 0x72, 0x63, 0x07, 0x54, 0x85, 0x8c, 0x6d, 0x89, 0x38, 0xc8, 0xd8, 0x16, 0xda, 0x83, 0x92, 0x85, - 0xc9, 0xc0, 0xb7, 0x3d, 0x6a, 0x34, 0x6d, 0x85, 0x5d, 0xc8, 0x20, 0xfd, 0x5f, 0x0a, 0xac, 0xf6, - 0x7c, 0xdb, 0x74, 0xd0, 0x0e, 0x14, 0x02, 0xfa, 0x11, 0x87, 0x47, 0x9e, 0x9d, 0x5b, 0x16, 0xbd, - 0x22, 0x54, 0x22, 0x7a, 0xc5, 0xf9, 0xe5, 0xd9, 0xb9, 0x65, 0xa1, 0x47, 0x10, 0x47, 0x63, 0x9f, - 0x60, 0x9e, 0x88, 0xa5, 0x7a, 0x35, 0x19, 0xb6, 0x46, 0x39, 0x42, 0xa2, 0xa1, 0xa8, 0x43, 0x8e, - 0x04, 0x66, 0x30, 0x21, 0x4c, 0xa2, 0x6a, 0x1d, 0x18, 0x76, 0x37, 0x30, 0x03, 0x6c, 0x88, 0x1b, - 0xf4, 0x13, 0x58, 0x73, 0x2f, 0xbe, 0xc2, 0x83, 0xc0, 0xbe, 0xc4, 0x7d, 0x6e, 0xd8, 0x55, 0xc6, - 0xba, 0x1a, 0x81, 0x7f, 0x4b, 0xa1, 0x68, 0x17, 0x56, 0x02, 0x73, 0x48, 0xb4, 0x02, 0x63, 0x5c, - 0x60, 0xa4, 0x7a, 0xe6, 0xd0, 0x60, 0x50, 0xfd, 0x6f, 0x0a, 0x94, 0x5f, 0xb0, 0x28, 0x17, 0x85, - 0x60, 0x13, 0x56, 0xed, 0x91, 0x39, 0x0c, 0xad, 0xc9, 0x0f, 0x48, 0x83, 0xfc, 0xc0, 0x1d, 0x8d, - 0xcc, 0xb1, 0x25, 0xa2, 0x2e, 0x3c, 0x52, 0x9f, 0x0d, 0xbd, 0x09, 0xb3, 0xe9, 0xaa, 0x41, 0x3f, - 0xd1, 0x2e, 0x14, 0xc9, 0xe0, 0x15, 0xb6, 0x26, 0x0e, 0xf6, 0x85, 0x49, 0x63, 0x00, 0xba, 0x0b, - 0xab, 0x23, 0xea, 0x70, 0x26, 0x6d, 0x68, 0x88, 0x28, 0x04, 0x0c, 0x7e, 0x89, 0xee, 0x40, 0xc9, - 0x9b, 0x38, 0x4e, 0x9f, 0xe0, 0x81, 0x8f, 0x03, 0x2d, 0xc7, 0xa8, 0x00, 0x05, 0x75, 0x19, 0x44, - 0xff, 0x8f, 0x02, 0x39, 0x2e, 0xf7, 0xe2, 0xc4, 0x5d, 0xe0, 0x1a, 0xd9, 0xa1, 0xd9, 0xa4, 0x43, - 0x35, 0xc8, 0xfb, 0x93, 0x71, 0x60, 0x8f, 0xb0, 0x50, 0x20, 0x3c, 0x4a, 0xae, 0x59, 0x9d, 0xeb, - 0x9a, 0x9f, 0x42, 0x6e, 0xc0, 0x8c, 0xc9, 0xe4, 0x2e, 0xd5, 0xd7, 0x19, 0x8e, 0x6c, 0x65, 0x43, - 0x20, 0x44, 0xce, 0xc9, 0xcf, 0x74, 0xce, 0xbf, 0x57, 0xa0, 0xc4, 0x42, 0x7d, 0x41, 0x91, 0x9e, - 0x1d, 0xe8, 0x47, 0xb0, 0xee, 0x7a, 0x81, 0x3d, 0xb2, 0xbf, 0x35, 0x69, 0x18, 0xf3, 0x8a, 0x99, - 0x65, 0x12, 0x6f, 0x31, 0x26, 0x1d, 0xe9, 0x96, 0x15, 0x4d, 0xd5, 0x4d, 0x41, 0xd0, 0xfb, 0x29, - 0x1a, 0x43, 0xd7, 0x74, 0x98, 0x39, 0x94, 0x24, 0x72, 0xd3, 0x35, 0x1d, 0xd4, 0x86, 0xf5, 0x38, - 0xce, 0xb9, 0x72, 0x44, 0xb8, 0x78, 0x5f, 0x98, 0x28, 0xd2, 0xe3, 0x20, 0xd5, 0x7c, 0x88, 0xa1, - 0x7a, 0x29, 0x08, 0xfa, 0x00, 0x90, 0x39, 0x18, 0x60, 0x42, 0xfa, 0x1e, 0xf6, 0x47, 0x36, 0x21, - 0xb6, 0x3b, 0x26, 0x5a, 0x8e, 0xc5, 0xde, 0x3a, 0xbf, 0x39, 0x8f, 0x2f, 0xd0, 0x67, 0xb0, 0x6b, - 0xe1, 0x97, 0xe6, 0xc4, 0x09, 0xfa, 0x24, 0x2a, 0x82, 0x7d, 0xd3, 0x19, 0xba, 0xbe, 0x1d, 0xbc, - 0x1a, 0x69, 0x79, 0x66, 0x9c, 0x9a, 0xc0, 0x89, 0xeb, 0xe4, 0x61, 0x88, 0x81, 0x9a, 0xb0, 0x17, - 0x52, 0xc0, 0xb4, 0x0a, 0xf6, 0x89, 0x28, 0x83, 0x12, 0x95, 0x02, 0xa3, 0xf2, 0x8e, 0xc0, 0x4b, - 0x14, 0xcb, 0x98, 0x50, 0xe8, 0xd2, 0xe2, 0x2c, 0x97, 0xa2, 0x9f, 0xc3, 0x66, 0x2a, 0x6d, 0xfb, - 0xcc, 0xa5, 0xc0, 0x48, 0xa3, 0x64, 0xee, 0xb6, 0xa9, 0x83, 0x35, 0xc8, 0x8b, 0xae, 0xa2, 0x95, - 0x78, 0xea, 0x89, 0x63, 0xed, 0x08, 0xd4, 0xb4, 0x25, 0xd1, 0x01, 0x4d, 0x54, 0x6e, 0x7d, 0x85, - 0x09, 0xb0, 0x99, 0xac, 0x34, 0x22, 0xfe, 0x42, 0x24, 0xbd, 0x05, 0xe8, 0xd8, 0xc7, 0x66, 0x80, - 0x99, 0x7f, 0x0c, 0xfc, 0xc7, 0x09, 0x26, 0x01, 0x7a, 0x04, 0x65, 0x9e, 0x35, 0x22, 0x8e, 0x15, - 0xe6, 0x48, 0x35, 0xed, 0x48, 0xa3, 0x44, 0xe2, 0x83, 0xfe, 0x01, 0xa8, 0x09, 0x52, 0x9e, 0x73, - 0x95, 0x48, 0x3f, 0x25, 0x91, 0x7e, 0x14, 0x9d, 0x1a, 0x2f, 0xc1, 0x77, 0x01, 0xba, 0x0a, 0x55, - 0x09, 0xdd, 0x73, 0xae, 0xf4, 0x87, 0xb0, 0xd6, 0xc4, 0xc1, 0xb2, 0xef, 0x4f, 0xa0, 0x12, 0x63, - 0x53, 0xd1, 0xde, 0x48, 0xc7, 0x2d, 0xd8, 0x08, 0xa9, 0x9c, 0xda, 0x24, 0x10, 0x7c, 0xf5, 0x73, - 0x58, 0x4f, 0x82, 0x29, 0x83, 0x4f, 0x60, 0x8d, 0x33, 0x70, 0x45, 0xa3, 0x0a, 0x5d, 0x82, 0x62, - 0x1e, 0x61, 0x0f, 0x33, 0xaa, 0x44, 0x3e, 0x12, 0x6a, 0x9d, 0x26, 0x0e, 0x58, 0xe7, 0x21, 0x4b, - 0x68, 0xf7, 0x18, 0xaa, 0x12, 0x3a, 0xe5, 0xae, 0x43, 0x8e, 0x55, 0xb3, 0x90, 0x29, 0x2f, 0x54, - 0x0c, 0xc3, 0x10, 0x37, 0xfa, 0x5f, 0x15, 0x58, 0x33, 0x26, 0x63, 0x0e, 0xbc, 0x96, 0x49, 0xa2, - 0x60, 0x66, 0xe6, 0x16, 0xcc, 0x6c, 0xb2, 0x60, 0x7e, 0x04, 0x15, 0x51, 0x9d, 0x85, 0x9d, 0x57, - 0xe6, 0xd5, 0xc4, 0xf2, 0x6b, 0xe9, 0xa4, 0x3f, 0x84, 0x4a, 0x2c, 0x1a, 0x55, 0x68, 0x51, 0x99, - 0xd7, 0x5d, 0x40, 0x34, 0x3a, 0x38, 0xbd, 0x25, 0x0c, 0x86, 0xde, 0x01, 0x88, 0xa8, 0x85, 0x93, - 0x54, 0x31, 0x24, 0x47, 0x68, 0xff, 0xb1, 0x49, 0x7f, 0xe0, 0x8e, 0x3c, 0x07, 0x07, 0x5c, 0xa7, - 0x82, 0x01, 0x36, 0x39, 0x16, 0x10, 0x1d, 0xf1, 0xe8, 0x8d, 0x18, 0xd2, 0x80, 0x3c, 0x60, 0x51, - 0xb0, 0xb4, 0x0c, 0xfa, 0x13, 0x16, 0xc0, 0x32, 0x09, 0xf4, 0x1e, 0xe4, 0xb9, 0x10, 0xa1, 0xdb, - 0x4a, 0x92, 0x9d, 0x8c, 0xf0, 0x4e, 0xff, 0x87, 0x02, 0x5b, 0x34, 0xe0, 0xa2, 0x3a, 0xb6, 0x8c, - 0xca, 0x1f, 0xc2, 0xe6, 0xcc, 0xda, 0xc8, 0x5d, 0xb9, 0x41, 0x66, 0x14, 0xc5, 0xf7, 0xa0, 0xea, - 0x73, 0xc2, 0xfd, 0xf1, 0x64, 0x74, 0x81, 0x7d, 0xd1, 0xe7, 0x2b, 0x02, 0xda, 0x66, 0x40, 0x74, - 0x17, 0xaa, 0x8e, 0x3b, 0xec, 0x4b, 0x06, 0x5d, 0x61, 0x06, 0x2d, 0x3b, 0xee, 0xf0, 0x45, 0x64, - 0xd3, 0x1d, 0x28, 0xb0, 0x32, 0x4f, 0x45, 0xe3, 0xa3, 0x4a, 0x9e, 0x9d, 0x5b, 0x96, 0xfe, 0x94, - 0xa7, 0x95, 0xac, 0xce, 0xb2, 0x31, 0xfc, 0x67, 0x05, 0x6e, 0xd1, 0xb7, 0xaf, 0xdc, 0x89, 0x63, - 0x7d, 0xb7, 0x18, 0x78, 0x02, 0xda, 0xdc, 0x52, 0xcf, 0x8d, 0xb2, 0x8d, 0x67, 0xd7, 0xf8, 0x05, - 0xaa, 0x9c, 0xc3, 0xce, 0x6c, 0x71, 0x78, 0xcd, 0xd9, 0x26, 0xec, 0x86, 0xb1, 0x94, 0x0d, 0xa6, - 0x30, 0x83, 0x6d, 0x90, 0xd4, 0xbb, 0x96, 0x45, 0x74, 0x9f, 0x85, 0x95, 0xd8, 0x0a, 0xbe, 0x7f, - 0x68, 0xbf, 0x0b, 0x95, 0x70, 0x95, 0xa1, 0x9d, 0x87, 0x88, 0xd5, 0x30, 0xdc, 0x6f, 0x68, 0xcf, - 0x21, 0x7a, 0x87, 0x85, 0x66, 0xc4, 0x93, 0xca, 0xfe, 0x29, 0xa8, 0xd2, 0x0a, 0x44, 0x67, 0xd9, - 0x64, 0x3d, 0x4b, 0x6c, 0x53, 0x46, 0x75, 0x24, 0x1f, 0x89, 0xfe, 0x77, 0x85, 0x0e, 0xfa, 0x16, - 0x76, 0x5a, 0xe3, 0x97, 0x2e, 0x15, 0x91, 0x4b, 0x2f, 0x8d, 0x33, 0x45, 0x06, 0x61, 0x2d, 0x2f, - 0x91, 0xea, 0x99, 0xd4, 0x44, 0x77, 0x00, 0x10, 0x4d, 0x0b, 0x64, 0xce, 0x38, 0x2d, 0x61, 0xa0, - 0x7b, 0x71, 0xff, 0x5c, 0x61, 0xc8, 0x65, 0x59, 0xdc, 0xa8, 0x9b, 0x52, 0x99, 0x46, 0x54, 0xc0, - 0x3e, 0x5b, 0x38, 0xb8, 0x57, 0x8b, 0x0c, 0x72, 0x4e, 0xb7, 0x8e, 0x5f, 0x40, 0xe9, 0xc4, 0x0c, - 0xcc, 0x2e, 0x0e, 0x98, 0x06, 0xb3, 0x46, 0xb1, 0x59, 0xcb, 0x8a, 0x0d, 0x6a, 0xd7, 0xbc, 0x4c, - 0x76, 0xd7, 0x6b, 0xb4, 0x9f, 0x3d, 0xd1, 0xa5, 0x56, 0x95, 0xec, 0xf4, 0xaa, 0x42, 0x3b, 0x64, - 0xcc, 0x8a, 0x16, 0xa4, 0x3f, 0x29, 0x9c, 0x3b, 0x33, 0x7c, 0xc8, 0x9d, 0x0d, 0xe0, 0x16, 0x76, - 0x44, 0xc3, 0x0b, 0x07, 0x70, 0xe1, 0x1a, 0x83, 0x5f, 0xa2, 0xf7, 0xa1, 0x60, 0x99, 0x81, 0xc9, - 0x56, 0x96, 0x8c, 0xd4, 0x19, 0x25, 0x1b, 0x18, 0x79, 0x8b, 0x1f, 0xd0, 0x3e, 0x94, 0x03, 0x3c, - 0x26, 0xae, 0xdf, 0xbf, 0x70, 0x4d, 0xdf, 0x12, 0xe5, 0xb2, 0xc4, 0x61, 0x47, 0x14, 0x14, 0x0a, - 0x27, 0x24, 0xa1, 0xc2, 0x69, 0xb0, 0x4d, 0x13, 0xc5, 0xbc, 0xc4, 0x16, 0x15, 0xd9, 0xc6, 0x61, - 0x6c, 0xeb, 0x27, 0xb0, 0x39, 0x75, 0x43, 0x23, 0xf0, 0x21, 0xb0, 0x18, 0xb7, 0xf1, 0xa2, 0x46, - 0x1a, 0xa2, 0xe8, 0x1f, 0xf1, 0x12, 0x49, 0xa9, 0x30, 0xae, 0x64, 0x39, 0xf3, 0xeb, 0xcf, 0x78, - 0x2d, 0x92, 0xdf, 0x51, 0xe6, 0xf7, 0x20, 0xc7, 0x2c, 0x13, 0xf2, 0x4e, 0xdb, 0x4d, 0xdc, 0xea, - 0x46, 0x2c, 0x7c, 0xc2, 0xec, 0xdf, 0x23, 0xe4, 0xf5, 0x8f, 0x01, 0xa5, 0x68, 0x52, 0x89, 0x96, - 0x72, 0xa4, 0xfe, 0x4f, 0x05, 0x6e, 0x77, 0xe5, 0xda, 0x1a, 0x65, 0xc9, 0x5b, 0xea, 0x19, 0x72, - 0x6d, 0xcc, 0x26, 0x6a, 0x23, 0x3a, 0x83, 0x2d, 0x89, 0x9a, 0x94, 0xc5, 0x3c, 0x31, 0x35, 0xee, - 0xce, 0x69, 0x49, 0x0d, 0x49, 0x88, 0x58, 0x7c, 0xfd, 0x29, 0xec, 0xce, 0xd5, 0x4c, 0x0c, 0x9f, - 0x91, 0x24, 0x4a, 0xb2, 0x4a, 0x7f, 0x02, 0xb7, 0x9b, 0xd7, 0x1a, 0x65, 0xde, 0xe3, 0x11, 0xec, - 0x36, 0x17, 0xf1, 0x9d, 0xab, 0xa6, 0xf2, 0x46, 0x6a, 0xd6, 0x61, 0x8b, 0x4d, 0xbe, 0xd1, 0xdd, - 0x12, 0xa3, 0xc5, 0x16, 0x6c, 0xa4, 0xdf, 0xd0, 0x9c, 0xfb, 0x9f, 0x02, 0xfb, 0x5d, 0x1c, 0xcc, - 0xfe, 0x99, 0xe7, 0xc7, 0x6b, 0x99, 0xa9, 0xb0, 0x78, 0x01, 0x3b, 0x29, 0xa2, 0x53, 0xa1, 0x71, - 0x8b, 0xd9, 0x6c, 0xb6, 0xdc, 0xc6, 0x4d, 0x3c, 0x5b, 0x1f, 0xfd, 0x53, 0xb8, 0xb3, 0x48, 0xdb, - 0x6b, 0x62, 0xe4, 0x57, 0xb0, 0xdf, 0x5c, 0xc6, 0x56, 0xf3, 0xde, 0x7f, 0x0b, 0x77, 0x9a, 0xd7, - 0x70, 0x5f, 0xa8, 0xb9, 0xf2, 0xe6, 0x9a, 0x3f, 0x78, 0x0e, 0x95, 0xc4, 0x6f, 0xa2, 0x48, 0x85, - 0xf2, 0xf3, 0xf6, 0x17, 0xed, 0xce, 0x8b, 0x76, 0xbf, 0xf7, 0xbb, 0xf3, 0x86, 0x7a, 0x03, 0x01, - 0xe4, 0x4e, 0x3a, 0xcf, 0x8f, 0x4e, 0x1b, 0xaa, 0x82, 0xf2, 0x90, 0x6d, 0xb5, 0x7b, 0x6a, 0x06, - 0x95, 0xa1, 0x70, 0xd2, 0xea, 0x1e, 0x1b, 0x8d, 0x5e, 0x43, 0xcd, 0xa2, 0x35, 0x28, 0x1d, 0x1f, - 0xf6, 0x1a, 0xcd, 0x8e, 0xd1, 0x3a, 0x3e, 0x3c, 0x55, 0x57, 0x1e, 0xfc, 0x06, 0xd4, 0xf4, 0x0f, - 0x07, 0x48, 0x83, 0xcd, 0x90, 0x72, 0xe7, 0xbc, 0xd7, 0x3a, 0x6b, 0xfd, 0xfe, 0xb0, 0xd7, 0xea, - 0xb4, 0xd5, 0x1b, 0x94, 0xd8, 0x59, 0xab, 0x4d, 0x21, 0x94, 0x07, 0x3d, 0x1d, 0x7e, 0xc9, 0x4f, - 0x99, 0x07, 0x4d, 0x58, 0x65, 0x3f, 0x9a, 0xa0, 0x12, 0xe4, 0xcf, 0x1b, 0xed, 0x93, 0x56, 0xbb, - 0xa9, 0xde, 0xa0, 0x07, 0xe3, 0x79, 0xbb, 0x4d, 0x0f, 0x0a, 0xaa, 0x40, 0xf1, 0xb8, 0x73, 0x76, - 0x7e, 0xda, 0xe8, 0x35, 0x4e, 0xd4, 0x0c, 0x95, 0xf7, 0x8b, 0xd6, 0xe9, 0x69, 0xe3, 0x44, 0xcd, - 0xa2, 0x22, 0xac, 0x36, 0x0c, 0xa3, 0x63, 0xa8, 0xdf, 0xd4, 0xff, 0x0b, 0x90, 0x3f, 0x33, 0xc7, - 0xe6, 0x10, 0xfb, 0xe8, 0x19, 0x94, 0xa4, 0x0d, 0x14, 0xdd, 0x64, 0xa6, 0x9b, 0x5e, 0x6f, 0x6b, - 0x5b, 0xd3, 0x17, 0xd4, 0x1b, 0xbf, 0x84, 0x62, 0xb4, 0x62, 0xa2, 0x2d, 0xd1, 0x5b, 0x92, 0x1b, - 0x6a, 0x6d, 0x23, 0x0d, 0xa6, 0x0f, 0x1f, 0x43, 0x21, 0x5c, 0xff, 0x10, 0xdf, 0xb7, 0x53, 0x8b, - 0x69, 0x0d, 0xa5, 0xa0, 0xf4, 0xd5, 0x67, 0x50, 0x96, 0x97, 0x46, 0xa4, 0x25, 0x70, 0xa4, 0xf5, - 0xb2, 0xb6, 0x3d, 0xe3, 0x46, 0x08, 0x1c, 0x6d, 0x7d, 0x42, 0xe0, 0xf4, 0xd2, 0x28, 0x04, 0x4e, - 0x2d, 0x87, 0x8f, 0xa1, 0x10, 0x2e, 0x57, 0x42, 0xe0, 0xd4, 0x1a, 0x28, 0x04, 0x4e, 0x6e, 0x60, - 0xcf, 0xa0, 0x24, 0x4d, 0xb4, 0xc2, 0xbc, 0xd3, 0x23, 0x77, 0x6d, 0x6b, 0xfa, 0x82, 0x3e, 0xff, - 0x18, 0x20, 0x5e, 0x77, 0x50, 0xa4, 0x53, 0xea, 0xf1, 0xe6, 0x14, 0x9c, 0xbe, 0xfd, 0x9c, 0xed, - 0xb7, 0xd2, 0x82, 0x80, 0x6a, 0x91, 0x4d, 0xa6, 0x96, 0xa0, 0x9a, 0x36, 0xf3, 0x8e, 0xd2, 0xf9, - 0x92, 0x77, 0xe7, 0xf4, 0x74, 0x8e, 0xf6, 0xa2, 0x17, 0x73, 0xf6, 0x88, 0xda, 0xed, 0x05, 0x18, - 0xb1, 0x76, 0xe1, 0x0f, 0xfe, 0x91, 0x76, 0xc9, 0xb1, 0x3d, 0xd6, 0x2e, 0x31, 0x5a, 0x9b, 0x70, - 0x73, 0x4e, 0x23, 0x43, 0xef, 0x72, 0x5b, 0x2e, 0xec, 0x55, 0xb5, 0xfd, 0xc5, 0x48, 0x82, 0x45, - 0x73, 0x21, 0x8b, 0xe6, 0x32, 0x2c, 0x16, 0xb6, 0xbd, 0xaf, 0xa0, 0x36, 0xbf, 0xda, 0xa2, 0x7b, - 0xa1, 0x8c, 0x8b, 0x0b, 0x6a, 0xed, 0xee, 0xb5, 0x78, 0x82, 0x57, 0xf3, 0x3a, 0x5e, 0xcd, 0x25, - 0x79, 0x5d, 0x57, 0xa4, 0x69, 0x59, 0x08, 0xe7, 0xea, 0xb0, 0x2c, 0xa4, 0x46, 0xfa, 0xb0, 0x2c, - 0x24, 0xc6, 0xef, 0xf0, 0x21, 0x1b, 0xc9, 0xa4, 0x87, 0xf2, 0x58, 0x28, 0x3d, 0x94, 0x26, 0xbb, - 0x16, 0xff, 0x65, 0x4b, 0x1a, 0x80, 0xd1, 0xad, 0xc8, 0xfe, 0xd3, 0x03, 0x73, 0x6d, 0x67, 0xf6, - 0xa5, 0x94, 0x38, 0xf1, 0x34, 0x2b, 0x25, 0xce, 0xd4, 0x68, 0x2c, 0x25, 0x4e, 0x6a, 0xfc, 0xad, - 0xf7, 0x00, 0x62, 0xcf, 0xff, 0x50, 0xe9, 0x58, 0xb7, 0xa1, 0x92, 0x30, 0xfd, 0xdb, 0xcb, 0xcf, - 0x8b, 0x1c, 0xfb, 0x27, 0xf5, 0xd1, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x5a, 0x15, 0x33, 0x11, - 0x56, 0x1d, 0x00, 0x00, + // 2414 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3a, 0xcb, 0x73, 0xdb, 0xc6, + 0xf9, 0x06, 0x29, 0x89, 0xe4, 0xc7, 0x87, 0xe0, 0xd5, 0xc3, 0x14, 0xfd, 0x92, 0x11, 0xc7, 0x71, + 0x1c, 0x47, 0xbf, 0x5f, 0x64, 0xd7, 0xb1, 0x93, 0xb8, 0x8d, 0x2c, 0x31, 0x2c, 0x27, 0x12, 0xa5, + 0x01, 0xe9, 0x3a, 0xed, 0x85, 0x85, 0x89, 0x35, 0x8d, 0x04, 0x24, 0x50, 0x2c, 0x28, 0x47, 0x39, + 0x77, 0xa6, 0xbd, 0x74, 0xa6, 0xd7, 0xfe, 0x21, 0xb9, 0xf6, 0xde, 0x43, 0xef, 0xbd, 0x74, 0xa6, + 0xd3, 0x73, 0xff, 0x88, 0xce, 0x3e, 0x00, 0x2c, 0x40, 0x00, 0x62, 0xe4, 0xa4, 0x37, 0xec, 0xb7, + 0xdf, 0x7e, 0xef, 0xc7, 0x7e, 0x4b, 0x42, 0xc5, 0x70, 0xad, 0x1d, 0xd7, 0x73, 0x7c, 0x07, 0x15, + 0x0d, 0xd7, 0xd2, 0x3a, 0x50, 0xff, 0x02, 0x1b, 0xc4, 0x7a, 0x69, 0xe3, 0xbe, 0x6b, 0x8c, 0x30, + 0x52, 0xa1, 0x38, 0x31, 0xbe, 0x6d, 0x2a, 0xdb, 0xca, 0xdd, 0x8a, 0x4e, 0x3f, 0x19, 0xc4, 0x9a, + 0x36, 0x0b, 0x02, 0x62, 0x4d, 0x11, 0x82, 0x25, 0xdb, 0x22, 0x7e, 0xb3, 0xb8, 0x5d, 0xbc, 0x5b, + 0xd1, 0xd9, 0xb7, 0xf6, 0x67, 0x05, 0x56, 0x4f, 0x0c, 0xcf, 0x98, 0x60, 0x1f, 0x7b, 0xfb, 0xce, + 0xf4, 0x95, 0x35, 0xa6, 0x78, 0x53, 0x63, 0x82, 0x05, 0x31, 0xf6, 0x8d, 0x9e, 0x40, 0xc3, 0x0d, + 0xd0, 0x86, 0xfe, 0x99, 0x8b, 0x19, 0xe1, 0xc6, 0x2e, 0xda, 0xa1, 0x92, 0x85, 0x14, 0x06, 0x67, + 0x2e, 0xd6, 0xeb, 0xae, 0xbc, 0x44, 0x3b, 0x50, 0x7e, 0x25, 0x64, 0x6d, 0x16, 0xb7, 0x95, 0xbb, + 0x55, 0x71, 0x28, 0xa6, 0x80, 0x1e, 0xe2, 0x68, 0x2e, 0x54, 0x42, 0x7a, 0x3f, 0xb6, 0x2c, 0xeb, + 0xb0, 0x7c, 0x6a, 0xd8, 0x33, 0x2e, 0x48, 0x45, 0xe7, 0x0b, 0xed, 0xb7, 0x50, 0x3f, 0xc2, 0xbe, + 0x67, 0x8d, 0xc8, 0xa1, 0x33, 0xee, 0x63, 0x1f, 0x5d, 0x85, 0xca, 0x1b, 0xc7, 0xfb, 0x06, 0x7b, + 0x43, 0xcb, 0x14, 0xac, 0xcb, 0x1c, 0xd0, 0x35, 0xd1, 0x2e, 0xd4, 0x26, 0x1c, 0x7b, 0x68, 0x3b, + 0x63, 0xd2, 0x2c, 0x6c, 0x17, 0xef, 0x56, 0x77, 0x57, 0x19, 0xf3, 0x88, 0x8c, 0x5e, 0x9d, 0x84, + 0xdf, 0x44, 0x7b, 0x00, 0x25, 0xb1, 0x95, 0xaa, 0x51, 0x28, 0x56, 0x41, 0x16, 0xeb, 0x31, 0x40, + 0x44, 0x2f, 0xf5, 0xdc, 0x26, 0xac, 0x30, 0x54, 0x2e, 0x44, 0x45, 0x17, 0x2b, 0xed, 0x17, 0xb0, + 0xd6, 0x9f, 0x8d, 0xc7, 0x98, 0xf8, 0x96, 0x33, 0xcd, 0x37, 0x66, 0x3a, 0xeb, 0x67, 0xb0, 0xd9, + 0x36, 0x3c, 0xfb, 0xac, 0xef, 0x3b, 0xae, 0x6b, 0x4d, 0xc7, 0x17, 0xa1, 0xf1, 0x7f, 0x50, 0x1c, + 0x18, 0xe3, 0x1f, 0x70, 0xe0, 0x23, 0xa8, 0x1c, 0x39, 0xb3, 0xa9, 0x4f, 0xc3, 0x90, 0x86, 0xaf, + 0x7b, 0x3a, 0x0a, 0x02, 0xda, 0x3d, 0x1d, 0x51, 0x42, 0xae, 0xe1, 0xbf, 0x16, 0x67, 0xd8, 0xb7, + 0xf6, 0x0d, 0xd4, 0xfb, 0xfe, 0xcc, 0x3c, 0x3b, 0x3e, 0xc5, 0xde, 0xa9, 0x85, 0xdf, 0x64, 0x71, + 0x73, 0xde, 0x4c, 0xb1, 0x17, 0x70, 0x63, 0x0b, 0xd4, 0x80, 0x82, 0x65, 0x8a, 0x38, 0x28, 0x58, + 0x26, 0xda, 0x86, 0xaa, 0x89, 0xc9, 0xc8, 0xb3, 0x5c, 0x6a, 0xb4, 0xe6, 0x12, 0xdb, 0x90, 0x41, + 0xda, 0x3f, 0x15, 0x58, 0x1e, 0x78, 0x96, 0x61, 0xa3, 0x2d, 0x28, 0xfb, 0xf4, 0x23, 0x0a, 0x8f, + 0x12, 0x5b, 0x77, 0x4d, 0xba, 0x45, 0xa8, 0x44, 0x74, 0x8b, 0xf3, 0x2b, 0xb1, 0x75, 0xd7, 0x44, + 0x0f, 0x20, 0x8a, 0xc6, 0x21, 0xc1, 0x3c, 0x11, 0xab, 0xbb, 0x8d, 0x78, 0xd8, 0xea, 0xb5, 0x10, + 0x89, 0x86, 0xa2, 0x06, 0x2b, 0xc4, 0x37, 0xfc, 0x19, 0x61, 0x12, 0x35, 0x76, 0x81, 0x61, 0xf7, + 0x7d, 0xc3, 0xc7, 0xba, 0xd8, 0x41, 0xef, 0xc1, 0xaa, 0xf3, 0xf2, 0x6b, 0x3c, 0xf2, 0xad, 0x53, + 0x3c, 0xe4, 0x86, 0x5d, 0x66, 0xac, 0x1b, 0x21, 0xf8, 0x57, 0x14, 0x8a, 0xae, 0xc1, 0x92, 0x6f, + 0x8c, 0x49, 0xb3, 0xcc, 0x18, 0x97, 0x19, 0xa9, 0x81, 0x31, 0xd6, 0x19, 0x54, 0xfb, 0x5e, 0x81, + 0xda, 0x0b, 0x16, 0xe5, 0xa2, 0x10, 0xac, 0xc3, 0xb2, 0x35, 0x31, 0xc6, 0x81, 0x35, 0xf9, 0x02, + 0x35, 0xa1, 0x34, 0x72, 0x26, 0x13, 0x63, 0x6a, 0x8a, 0xa8, 0x0b, 0x96, 0xd4, 0x67, 0x63, 0x77, + 0xc6, 0x6c, 0xba, 0xac, 0xd3, 0x4f, 0x74, 0x0d, 0x2a, 0x64, 0xf4, 0x1a, 0x9b, 0x33, 0x1b, 0x7b, + 0xc2, 0xa4, 0x11, 0x00, 0xdd, 0x86, 0xe5, 0x09, 0x75, 0x38, 0x93, 0x36, 0x30, 0x44, 0x18, 0x02, + 0x3a, 0xdf, 0x44, 0x37, 0xa1, 0xea, 0xce, 0x6c, 0x7b, 0x48, 0xf0, 0xc8, 0xc3, 0x7e, 0x73, 0x85, + 0x51, 0x01, 0x0a, 0xea, 0x33, 0x88, 0xf6, 0x6f, 0x05, 0x56, 0xb8, 0xdc, 0xf9, 0x89, 0x9b, 0xe3, + 0x1a, 0xd9, 0xa1, 0xc5, 0xb8, 0x43, 0x9b, 0x50, 0xf2, 0x66, 0x53, 0xdf, 0x9a, 0x60, 0xa1, 0x40, + 0xb0, 0x94, 0x5c, 0xb3, 0x9c, 0xe9, 0x9a, 0xf7, 0x61, 0x65, 0xc4, 0x8c, 0xc9, 0xe4, 0xae, 0xee, + 0x5e, 0x66, 0x38, 0xb2, 0x95, 0x75, 0x81, 0x10, 0x3a, 0xa7, 0x94, 0xea, 0x9c, 0x7f, 0x2d, 0x41, + 0x95, 0x85, 0x7a, 0x4e, 0x91, 0x4e, 0x0f, 0xf4, 0x67, 0x70, 0xd9, 0x71, 0x7d, 0x6b, 0x62, 0x7d, + 0x67, 0xd0, 0x30, 0xe6, 0x15, 0xb3, 0xc8, 0x24, 0xde, 0x60, 0x4c, 0x8e, 0xa5, 0x5d, 0x56, 0x34, + 0x55, 0x27, 0x01, 0x41, 0x1f, 0x24, 0x68, 0x8c, 0x1d, 0xc3, 0x66, 0xe6, 0x50, 0xe2, 0xc8, 0x1d, + 0xc7, 0xb0, 0x51, 0x0f, 0x2e, 0x47, 0x71, 0xce, 0x95, 0x23, 0xc2, 0xc5, 0xb7, 0x84, 0x89, 0x42, + 0x3d, 0x76, 0x12, 0xcd, 0x87, 0xe8, 0xaa, 0x9b, 0x80, 0xa0, 0x0f, 0x01, 0x19, 0xa3, 0x11, 0x26, + 0x64, 0xe8, 0x62, 0x6f, 0x62, 0x11, 0x62, 0x39, 0x53, 0xd2, 0x5c, 0x61, 0xb1, 0x77, 0x99, 0xef, + 0x9c, 0x44, 0x1b, 0xe8, 0x73, 0xb8, 0x66, 0xe2, 0x57, 0xc6, 0xcc, 0xf6, 0x87, 0x24, 0x2c, 0x82, + 0x43, 0xc3, 0x1e, 0x3b, 0x9e, 0xe5, 0xbf, 0x9e, 0x34, 0x4b, 0xcc, 0x38, 0x2d, 0x81, 0x13, 0xd5, + 0xc9, 0xbd, 0x00, 0x03, 0x75, 0x60, 0x3b, 0xa0, 0x80, 0x69, 0x15, 0x1c, 0x12, 0x51, 0x06, 0x25, + 0x2a, 0x65, 0x46, 0xe5, 0xba, 0xc0, 0x8b, 0x15, 0xcb, 0x88, 0x50, 0xe0, 0xd2, 0x4a, 0x9a, 0x4b, + 0xd1, 0xff, 0xc3, 0x7a, 0x22, 0x6d, 0x87, 0xcc, 0xa5, 0xc0, 0x48, 0xa3, 0x78, 0xee, 0xf6, 0xa8, + 0x83, 0x9b, 0x50, 0x12, 0x5d, 0xa5, 0x59, 0xe5, 0xa9, 0x27, 0x96, 0xad, 0x67, 0xa0, 0x26, 0x2d, + 0x89, 0x76, 0x68, 0xa2, 0x72, 0xeb, 0x2b, 0x4c, 0x80, 0xf5, 0x78, 0xa5, 0x11, 0xf1, 0x17, 0x20, + 0x69, 0x5d, 0x40, 0xfb, 0x1e, 0x36, 0x7c, 0xcc, 0xfc, 0xa3, 0xe3, 0xdf, 0xcd, 0x30, 0xf1, 0xd1, + 0x03, 0xa8, 0xf1, 0xac, 0x11, 0x71, 0xac, 0x30, 0x47, 0xaa, 0x49, 0x47, 0xea, 0x55, 0x12, 0x2d, + 0xb4, 0x0f, 0x41, 0x8d, 0x91, 0x72, 0xed, 0xb3, 0x58, 0xfa, 0x29, 0xb1, 0xf4, 0xa3, 0xe8, 0xd4, + 0x78, 0x31, 0xbe, 0x39, 0xe8, 0x2a, 0x34, 0x24, 0x74, 0xd7, 0x3e, 0xd3, 0xee, 0xc3, 0x6a, 0x07, + 0xfb, 0x8b, 0x9e, 0x3f, 0x80, 0x7a, 0x84, 0x4d, 0x45, 0xbb, 0x90, 0x8e, 0x1b, 0xb0, 0x16, 0x50, + 0x39, 0xb4, 0x88, 0x2f, 0xf8, 0x6a, 0x27, 0x70, 0x39, 0x0e, 0xa6, 0x0c, 0x3e, 0x85, 0x55, 0xce, + 0xc0, 0x11, 0x8d, 0x2a, 0x70, 0x09, 0x8a, 0x78, 0x04, 0x3d, 0x4c, 0x6f, 0x10, 0x79, 0x49, 0xb4, + 0x47, 0x81, 0x5f, 0x58, 0xf3, 0x09, 0xf4, 0xdb, 0x86, 0x65, 0x56, 0xa2, 0x84, 0xb0, 0xbc, 0xf8, + 0x70, 0x0c, 0xbe, 0x11, 0x39, 0x41, 0x9c, 0x13, 0x4e, 0xc8, 0xe8, 0x5c, 0x14, 0xbd, 0x83, 0x7d, + 0x86, 0x4b, 0x16, 0x30, 0xe2, 0x43, 0x68, 0x48, 0xe8, 0x94, 0xb6, 0x06, 0x2b, 0x8c, 0x56, 0xa0, + 0x9b, 0x2c, 0x92, 0xd8, 0xd1, 0xfe, 0xa2, 0xc0, 0xaa, 0x3e, 0x9b, 0xc6, 0x34, 0xc9, 0x66, 0x12, + 0x13, 0xb7, 0x90, 0x59, 0x97, 0x8b, 0xf1, 0xba, 0xfc, 0x08, 0xea, 0xa2, 0x09, 0x08, 0x77, 0x2e, + 0x65, 0x95, 0xde, 0xda, 0x1b, 0x69, 0xa5, 0xdd, 0x87, 0x7a, 0x24, 0x1a, 0x55, 0x28, 0xaf, 0x9b, + 0x68, 0x0e, 0x20, 0x1a, 0x84, 0x9c, 0xde, 0x02, 0x06, 0x43, 0xd7, 0x01, 0x42, 0x6a, 0xc1, 0x85, + 0xad, 0x12, 0x90, 0x23, 0xb4, 0xcd, 0x59, 0x64, 0x38, 0x72, 0x26, 0xae, 0x8d, 0x7d, 0xae, 0x53, + 0x59, 0x07, 0x8b, 0xec, 0x0b, 0x88, 0x86, 0x78, 0x92, 0x84, 0x0c, 0x69, 0xdc, 0xbf, 0x62, 0xc1, + 0xb6, 0xb8, 0x0c, 0x39, 0xf6, 0x8c, 0x29, 0x5b, 0x4c, 0x28, 0xfb, 0x98, 0xe5, 0x97, 0xcc, 0x1a, + 0xbd, 0x0b, 0x25, 0xbe, 0x1d, 0xb8, 0xbb, 0x2a, 0xd9, 0x57, 0x0f, 0xf6, 0xb4, 0xbf, 0x2b, 0xb0, + 0x41, 0xf3, 0x21, 0x2c, 0xb3, 0x8b, 0x88, 0xf9, 0x11, 0xac, 0xa7, 0x96, 0x6e, 0x2e, 0xf2, 0x1a, + 0x49, 0xa9, 0xd9, 0xef, 0x42, 0xc3, 0xe3, 0x84, 0x87, 0xd3, 0xd9, 0xe4, 0x25, 0xf6, 0xc4, 0x35, + 0xa4, 0x2e, 0xa0, 0x3d, 0x06, 0x44, 0xb7, 0xa1, 0x61, 0x3b, 0xe3, 0xa1, 0xe4, 0x88, 0x25, 0xe6, + 0x88, 0x9a, 0xed, 0x8c, 0x5f, 0x84, 0xbe, 0xd8, 0x82, 0x32, 0xeb, 0x42, 0x54, 0x34, 0x7e, 0x93, + 0x2a, 0xb1, 0x75, 0xd7, 0xd4, 0x9e, 0xf0, 0xac, 0x97, 0xd5, 0x59, 0x34, 0xf6, 0xff, 0xa4, 0xc0, + 0x55, 0x7a, 0xf6, 0xb5, 0x33, 0xb3, 0xcd, 0x1f, 0x16, 0x3b, 0x8f, 0xa1, 0x99, 0xd9, 0x89, 0xb8, + 0x51, 0x36, 0x71, 0x7a, 0x0b, 0xca, 0x51, 0xe5, 0x04, 0xb6, 0xd2, 0xc5, 0xe1, 0x25, 0x71, 0x93, + 0xb0, 0x1d, 0xc6, 0x52, 0x36, 0x98, 0xc2, 0x0c, 0xb6, 0x46, 0x12, 0xe7, 0xba, 0x26, 0xd1, 0x3c, + 0x16, 0x8e, 0x62, 0x68, 0x79, 0xfb, 0x94, 0x78, 0x07, 0xea, 0xc1, 0xa4, 0x45, 0x1b, 0x23, 0x11, + 0x93, 0x6b, 0x30, 0x7e, 0xd1, 0x96, 0x48, 0xb4, 0x63, 0x16, 0x9a, 0x21, 0x4f, 0x2a, 0xfb, 0x67, + 0xa0, 0x4a, 0x13, 0x1a, 0xbd, 0x6a, 0xc7, 0xcb, 0x6d, 0x6c, 0xd8, 0xd3, 0x1b, 0x13, 0x79, 0x49, + 0xb4, 0xbf, 0x2a, 0x74, 0x0e, 0x31, 0xb1, 0xdd, 0x9d, 0xbe, 0x72, 0xa8, 0x88, 0x5c, 0x7a, 0xe9, + 0xb6, 0x55, 0x61, 0x10, 0xd6, 0x91, 0x63, 0x59, 0x53, 0x48, 0x5c, 0x38, 0x77, 0x00, 0xc2, 0xcb, + 0x0c, 0xc9, 0xb8, 0xed, 0x4b, 0x18, 0xe8, 0x4e, 0xd4, 0xde, 0x97, 0x18, 0x72, 0x4d, 0x16, 0x37, + 0x6c, 0xf6, 0x54, 0xa6, 0x09, 0x15, 0x70, 0xc8, 0xe6, 0x21, 0xee, 0xd5, 0x0a, 0x83, 0x9c, 0xd0, + 0xa1, 0xe8, 0x67, 0x50, 0x3d, 0x30, 0x7c, 0xa3, 0x8f, 0x7d, 0xa6, 0x41, 0xda, 0x4d, 0x31, 0x6d, + 0x96, 0xb2, 0x40, 0xed, 0x1b, 0xa7, 0xf1, 0xe6, 0x7f, 0x8e, 0xf6, 0xe9, 0x17, 0xce, 0xc4, 0x24, + 0x55, 0x9c, 0x9f, 0xa4, 0x68, 0x03, 0x8f, 0x58, 0xd1, 0x42, 0xf6, 0x47, 0x85, 0x73, 0x67, 0x86, + 0x0f, 0xb8, 0xb3, 0xf9, 0xc0, 0xc4, 0x41, 0x8b, 0x0b, 0xe6, 0x03, 0xe1, 0x1a, 0x9d, 0x6f, 0xa2, + 0x0f, 0xa0, 0x6c, 0x1a, 0xbe, 0xc1, 0x26, 0xaa, 0x82, 0xd4, 0xb8, 0x25, 0x1b, 0xe8, 0x25, 0x93, + 0x2f, 0xd0, 0x2d, 0xa8, 0xf9, 0x78, 0x4a, 0x1c, 0x6f, 0xf8, 0xd2, 0x31, 0x3c, 0x53, 0x94, 0xd9, + 0x2a, 0x87, 0x3d, 0xa3, 0xa0, 0x40, 0x38, 0x21, 0x09, 0x15, 0xae, 0x09, 0x9b, 0x34, 0x51, 0x8c, + 0x53, 0x6c, 0x52, 0x91, 0x2d, 0x1c, 0xc4, 0xb6, 0x76, 0x00, 0xeb, 0x73, 0x3b, 0x34, 0x02, 0xef, + 0x03, 0x8b, 0x71, 0x0b, 0xe7, 0xf5, 0xf9, 0x00, 0x45, 0x7b, 0xc4, 0x4b, 0x24, 0xa5, 0xc2, 0xb8, + 0x92, 0xc5, 0xcc, 0xaf, 0x3d, 0xe5, 0xb5, 0x48, 0x3e, 0x47, 0x99, 0xdf, 0x81, 0x15, 0x66, 0x99, + 0x80, 0x77, 0xd2, 0x6e, 0x62, 0x57, 0xd3, 0x23, 0xe1, 0x63, 0x66, 0x7f, 0x8b, 0x90, 0xd7, 0x3e, + 0x01, 0x94, 0xa0, 0x49, 0x25, 0x5a, 0xc8, 0x91, 0xda, 0x3f, 0x14, 0xb8, 0xd1, 0x97, 0x6b, 0x6b, + 0x98, 0x25, 0x3f, 0x51, 0xcf, 0x90, 0x6b, 0x63, 0x31, 0x56, 0x1b, 0xd1, 0x11, 0x6c, 0x48, 0xd4, + 0xa4, 0x2c, 0xe6, 0x89, 0xd9, 0xe4, 0xee, 0x9c, 0x97, 0x54, 0x97, 0x84, 0x88, 0xc4, 0xd7, 0x9e, + 0xc0, 0xb5, 0x4c, 0xcd, 0xc4, 0xb5, 0x2c, 0x94, 0x44, 0x89, 0x57, 0xe9, 0x4f, 0xe1, 0x46, 0xe7, + 0x5c, 0xa3, 0x64, 0x1d, 0x9e, 0xc0, 0xb5, 0x4e, 0x1e, 0xdf, 0x4c, 0x35, 0x95, 0x0b, 0xa9, 0xf9, + 0x73, 0xb8, 0x95, 0xce, 0x4e, 0xba, 0x20, 0xe7, 0xdd, 0x29, 0xbf, 0x57, 0x60, 0x33, 0xe5, 0x34, + 0x4d, 0xdc, 0x6c, 0x25, 0x2f, 0xe2, 0xf9, 0x4c, 0xbd, 0x8b, 0x17, 0xd2, 0xfb, 0x3b, 0xb8, 0x99, + 0xa7, 0x37, 0xb5, 0xf4, 0x0b, 0xd8, 0x4a, 0xe3, 0x28, 0x37, 0xa7, 0xab, 0x59, 0x5c, 0x69, 0x97, + 0xba, 0x42, 0x52, 0xe1, 0x44, 0xdb, 0x85, 0x0d, 0x36, 0x0c, 0x85, 0xdb, 0x0b, 0xd8, 0x79, 0x03, + 0xd6, 0x92, 0x67, 0x68, 0x9d, 0xfb, 0x8f, 0x02, 0xb7, 0xfa, 0xd8, 0x4f, 0x7f, 0xf9, 0xfb, 0xdf, + 0x5d, 0x53, 0x12, 0xa9, 0xf8, 0x02, 0xb6, 0x12, 0x44, 0xe7, 0xd2, 0x91, 0x5b, 0x2e, 0x5d, 0x6e, + 0xfd, 0x0a, 0x4e, 0xd7, 0x47, 0xfb, 0x0c, 0x6e, 0xe6, 0x69, 0x7b, 0x4e, 0x5e, 0xf2, 0x58, 0x3f, + 0xdf, 0x56, 0x59, 0xe7, 0x79, 0xcc, 0xe4, 0x72, 0xcf, 0xd5, 0x5c, 0x79, 0x0b, 0xcd, 0xf7, 0xe0, + 0x76, 0x26, 0xef, 0x05, 0x53, 0xf5, 0x6f, 0x0a, 0x6c, 0xa5, 0x13, 0x38, 0x27, 0x5b, 0x2f, 0x1e, + 0x23, 0xb9, 0xe6, 0x28, 0xbe, 0x85, 0x39, 0xfe, 0xa0, 0x80, 0x76, 0x8e, 0x3d, 0xa8, 0x3b, 0x0c, + 0xb8, 0x9e, 0xc5, 0x5f, 0x4e, 0xe3, 0x1b, 0x39, 0x32, 0xd0, 0x4c, 0x6e, 0xe1, 0xac, 0x2d, 0x72, + 0xef, 0x39, 0xd4, 0x63, 0xbf, 0x5f, 0x20, 0x15, 0x6a, 0xcf, 0x7b, 0x5f, 0xf6, 0x8e, 0x5f, 0xf4, + 0x86, 0x83, 0x5f, 0x9f, 0xb4, 0xd5, 0x4b, 0x08, 0x60, 0xe5, 0xe0, 0xf8, 0xf9, 0xb3, 0xc3, 0xb6, + 0xaa, 0xa0, 0x12, 0x14, 0xbb, 0xbd, 0x81, 0x5a, 0x40, 0x35, 0x28, 0x1f, 0x74, 0xfb, 0xfb, 0x7a, + 0x7b, 0xd0, 0x56, 0x8b, 0x68, 0x15, 0xaa, 0xfb, 0x7b, 0x83, 0x76, 0xe7, 0x58, 0xef, 0xee, 0xef, + 0x1d, 0xaa, 0x4b, 0xf7, 0x7e, 0x09, 0x6a, 0xf2, 0x91, 0x0f, 0x35, 0x61, 0x3d, 0xa0, 0x7c, 0x7c, + 0x32, 0xe8, 0x1e, 0x75, 0x7f, 0xb3, 0x37, 0xe8, 0x1e, 0xf7, 0xd4, 0x4b, 0x94, 0xd8, 0x51, 0xb7, + 0x47, 0x21, 0x94, 0x07, 0x5d, 0xed, 0x7d, 0xc5, 0x57, 0x85, 0x7b, 0x1d, 0x58, 0x66, 0x0f, 0x9c, + 0xa8, 0x0a, 0xa5, 0x93, 0x76, 0xef, 0xa0, 0xdb, 0xeb, 0xa8, 0x97, 0xe8, 0x42, 0x7f, 0xde, 0xeb, + 0xd1, 0x85, 0x82, 0xea, 0x50, 0xd9, 0x3f, 0x3e, 0x3a, 0x39, 0x6c, 0x0f, 0xda, 0x07, 0x6a, 0x81, + 0xca, 0xfb, 0x65, 0xf7, 0xf0, 0xb0, 0x7d, 0xa0, 0x16, 0x51, 0x05, 0x96, 0xdb, 0xba, 0x7e, 0xac, + 0xab, 0xdf, 0xee, 0xfe, 0xbe, 0x0e, 0xa5, 0x23, 0x63, 0x6a, 0x8c, 0xb1, 0x87, 0x9e, 0x42, 0x55, + 0x7a, 0x2d, 0x42, 0x57, 0x98, 0x01, 0xe7, 0x9f, 0xa2, 0x5a, 0x1b, 0xf3, 0x1b, 0xd4, 0x2f, 0x1f, + 0x43, 0x25, 0x7c, 0x0e, 0x42, 0x1b, 0xe2, 0xa2, 0x15, 0x7f, 0x4d, 0x6a, 0xad, 0x25, 0xc1, 0xf4, + 0xe0, 0x43, 0x28, 0x07, 0x4f, 0x35, 0x88, 0xbf, 0x8d, 0x25, 0x1e, 0x91, 0x5a, 0x28, 0x01, 0xa5, + 0xa7, 0x3e, 0x87, 0x9a, 0xfc, 0xc0, 0x83, 0x9a, 0x31, 0x1c, 0x29, 0x7d, 0x5a, 0x9b, 0x29, 0x3b, + 0x94, 0x42, 0xa8, 0x2f, 0xff, 0x35, 0x41, 0xd6, 0x57, 0x7e, 0x18, 0x89, 0xe9, 0x2b, 0x3d, 0x4b, + 0x7c, 0x0c, 0x95, 0xf0, 0xe5, 0x45, 0xe8, 0x9b, 0x7c, 0xb8, 0x11, 0xfa, 0x26, 0x1e, 0x68, 0x1e, + 0x42, 0x39, 0x78, 0xe0, 0x10, 0xfa, 0x26, 0x9e, 0x62, 0x84, 0xbe, 0xf1, 0x57, 0x90, 0xa7, 0x50, + 0x95, 0xa6, 0x43, 0x21, 0xed, 0xfc, 0xf8, 0xda, 0xda, 0x98, 0xdf, 0xa0, 0xc7, 0x3f, 0x01, 0x88, + 0x9e, 0x0e, 0x50, 0x68, 0x92, 0xc4, 0xe1, 0xf5, 0x39, 0x38, 0x3d, 0xfb, 0x05, 0x7b, 0x63, 0x92, + 0x86, 0x6d, 0xd4, 0x0a, 0x4d, 0x3a, 0xf7, 0xa0, 0xd0, 0x6a, 0xa6, 0xee, 0x51, 0x3a, 0x5f, 0xf1, + 0x9b, 0x6e, 0x72, 0xd2, 0x45, 0xdb, 0xe1, 0x89, 0x8c, 0x99, 0xbc, 0x75, 0x23, 0x07, 0x23, 0xd2, + 0x2e, 0xf8, 0x6d, 0x2f, 0xd4, 0x2e, 0x3e, 0x02, 0x47, 0xda, 0xc5, 0xc6, 0x54, 0x03, 0xae, 0x64, + 0x5c, 0x0a, 0xd1, 0x3b, 0xdc, 0x96, 0xb9, 0xf7, 0xbe, 0xd6, 0xad, 0x7c, 0x24, 0xc1, 0xa2, 0x93, + 0xcb, 0xa2, 0xb3, 0x08, 0x8b, 0xdc, 0x2b, 0xe4, 0xd7, 0xd0, 0xca, 0xbe, 0xfb, 0xa0, 0x3b, 0x39, + 0x04, 0xe4, 0x54, 0xb9, 0x7d, 0x2e, 0x9e, 0xe0, 0x95, 0xdd, 0xb1, 0x05, 0xaf, 0x73, 0x2f, 0x30, + 0x82, 0xd7, 0x79, 0xad, 0x9f, 0xeb, 0x95, 0xcf, 0xab, 0xb3, 0x20, 0xaf, 0xf3, 0x1a, 0x3d, 0x81, + 0xeb, 0xb9, 0xfd, 0x07, 0xbd, 0x9f, 0x4f, 0x46, 0xb6, 0xe4, 0x7b, 0x8b, 0xa0, 0x06, 0x65, 0x33, + 0x18, 0xc2, 0x83, 0xb2, 0x99, 0x98, 0xff, 0x83, 0xb2, 0x19, 0x9b, 0xd5, 0x83, 0x83, 0x6c, 0x7e, + 0x93, 0x0e, 0xca, 0x33, 0xa4, 0x74, 0x50, 0x1a, 0x03, 0xbb, 0xfc, 0x95, 0x5e, 0x9a, 0x96, 0xd1, + 0xd5, 0xd0, 0xef, 0xf3, 0xd3, 0x75, 0x6b, 0x2b, 0x7d, 0x53, 0xaa, 0x0c, 0xd1, 0xe8, 0x2b, 0x55, + 0x86, 0xb9, 0x39, 0x5a, 0xaa, 0x0c, 0x89, 0x59, 0x79, 0x77, 0x00, 0x10, 0x45, 0xdc, 0x8f, 0x55, + 0x6f, 0x76, 0x2d, 0xa8, 0xc7, 0xac, 0xff, 0xd3, 0x15, 0xa0, 0x97, 0x2b, 0xec, 0x5f, 0x21, 0x0f, + 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xe1, 0xd3, 0x80, 0xbf, 0x22, 0x22, 0x00, 0x00, } diff --git a/pkg/api/api.proto b/pkg/api/api.proto index a57c81d0892..c0b1c80246e 100644 --- a/pkg/api/api.proto +++ b/pkg/api/api.proto @@ -7,6 +7,7 @@ service Manager { rpc StopStudy(StopStudyRequest) returns (StopStudyReply); rpc GetStudy(GetStudyRequest) returns (GetStudyReply); rpc GetStudyList(GetStudyListRequest) returns (GetStudyListReply); + rpc CreateTrial(CreateTrialRequest) returns (CreateTrialReply); rpc GetTrials(GetTrialsRequest) returns (GetTrialsReply); rpc RunTrial(RunTrialRequest) returns (RunTrialReply); rpc StopWorkers(StopWorkersRequest) returns (StopWorkersReply); @@ -16,8 +17,10 @@ service Manager { rpc GetMetrics(GetMetricsRequest) returns (GetMetricsReply); rpc SetSuggestionParameters(SetSuggestionParametersRequest) returns (SetSuggestionParametersReply); rpc GetSuggestionParameters(GetSuggestionParametersRequest) returns (GetSuggestionParametersReply); + rpc GetSuggestionParameterList(GetSuggestionParameterListRequest) returns (GetSuggestionParameterListReply); rpc SetEarlyStoppingParameters(SetEarlyStoppingParametersRequest) returns (SetEarlyStoppingParametersReply); rpc GetEarlyStoppingParameters(GetEarlyStoppingParametersRequest) returns (GetEarlyStoppingParametersReply); + rpc GetEarlyStoppingParameterList(GetEarlyStoppingParameterListRequest) returns (GetEarlyStoppingParameterListReply); rpc SaveStudy(SaveStudyRequest) returns(SaveStudyReply); rpc SaveModel(SaveModelRequest) returns(SaveModelReply); rpc GetSavedStudies(GetSavedStudiesRequest) returns(GetSavedStudiesReply); @@ -195,6 +198,14 @@ message GetStudyListReply { repeated StudyOverview study_overviews = 1; } +message CreateTrialRequest { + Trial trial = 1; +} + +message CreateTrialReply { + string trial_id = 1; +} + message GetTrialsRequest { string study_id = 1; } @@ -225,6 +236,8 @@ message StopWorkersReply { message GetWorkersRequest { string study_id = 1; + string trial_id = 2; + string worker_id = 3; } message GetWorkersReply { @@ -337,6 +350,21 @@ message GetSuggestionParametersReply { repeated SuggestionParameter suggestion_parameters = 1; } +message GetSuggestionParameterListRequest { + string study_id = 1; +} + +message SuggestionParameterSet { + string param_id = 1; + string suggestion_algorithm = 2; + repeated SuggestionParameter suggestion_parameters = 3; +} + +message GetSuggestionParameterListReply { + + repeated SuggestionParameterSet suggestion_parameter_sets = 1; +} + message StopSuggestionRequest { string study_id = 1; } @@ -362,3 +390,17 @@ message GetEarlyStoppingParametersRequest { message GetEarlyStoppingParametersReply { repeated EarlyStoppingParameter early_stopping_parameters = 1; } + +message GetEarlyStoppingParameterListRequest { + string study_id = 1; +} + +message EarlyStoppingParameterSet { + string param_id = 1; + string early_stopping_algorithm = 2; + repeated EarlyStoppingParameter early_stopping_parameters = 3; +} + +message GetEarlyStoppingParameterListReply { + repeated EarlyStoppingParameterSet early_stopping_parameter_sets = 1; +} diff --git a/pkg/db/db_init.go b/pkg/db/db_init.go index f92812f8286..8ea300d96d3 100644 --- a/pkg/db/db_init.go +++ b/pkg/db/db_init.go @@ -50,7 +50,8 @@ func (d *db_conn) DB_Init() { "status TINYINT, " + "config TEXT, " + "tags TEXT, " + - "FOREIGN KEY(study_id) REFERENCES studies(id))") + "FOREIGN KEY(study_id) REFERENCES studies(id), " + + "FOREIGN KEY(trial_id) REFERENCES trials(id))") if err != nil { log.Fatalf("Error creating workers table: %v", err) } @@ -78,7 +79,8 @@ func (d *db_conn) DB_Init() { "(id CHAR(16) PRIMARY KEY," + "suggestion_algo TEXT, " + "study_id CHAR(16), " + - "parameters TEXT)") + "parameters TEXT, " + + "FOREIGN KEY(study_id) REFERENCES studies(id))") if err != nil { log.Fatalf("Error creating suggestion_param table: %v", err) } @@ -87,7 +89,8 @@ func (d *db_conn) DB_Init() { "(id CHAR(16) PRIMARY KEY, " + "earlystop_argo TEXT, " + "study_id CHAR(16), " + - "parameters TEXT)") + "parameters TEXT, " + + "FOREIGN KEY(study_id) REFERENCES studies(id))") if err != nil { log.Fatalf("Error creating earlystop_param table: %v", err) } diff --git a/pkg/db/interface.go b/pkg/db/interface.go index 4134fd0571d..fbaaeff5012 100644 --- a/pkg/db/interface.go +++ b/pkg/db/interface.go @@ -53,7 +53,7 @@ type VizierDBInterface interface { GetWorker(string) (*api.Worker, error) GetWorkerStatus(string) (*api.State, error) - GetWorkerList(string) ([]*api.Worker, error) + GetWorkerList(string, string) ([]*api.Worker, error) GetWorkerLogs(string, *GetWorkerLogOpts) ([]*WorkerLog, error) GetWorkerTimestamp(string) (*time.Time, error) StoreWorkerLogs(string, []string) error @@ -64,9 +64,11 @@ type VizierDBInterface interface { SetSuggestionParam(string, string, []*api.SuggestionParameter) (string, error) UpdateSuggestionParam(string, []*api.SuggestionParameter) error GetSuggestionParam(string) ([]*api.SuggestionParameter, error) + GetSuggestionParamList(string) ([]*api.SuggestionParameterSet, error) SetEarlyStopParam(string, string, []*api.EarlyStoppingParameter) (string, error) UpdateEarlyStopParam(string, []*api.EarlyStoppingParameter) error GetEarlyStopParam(string) ([]*api.EarlyStoppingParameter, error) + GetEarlyStopParamList(string) ([]*api.EarlyStoppingParameterSet, error) } type db_conn struct { @@ -709,8 +711,8 @@ func (d *db_conn) GetWorkerStatus(id string) (*api.State, error) { return &status, nil } -func (d *db_conn) GetWorkerList(id string) ([]*api.Worker, error) { - workers, err := d.getWorkers("", "", id) +func (d *db_conn) GetWorkerList(sid string, tid string) ([]*api.Worker, error) { + workers, err := d.getWorkers("", tid, sid) return workers, err } @@ -831,6 +833,47 @@ func (d *db_conn) GetSuggestionParam(paramId string) ([]*api.SuggestionParameter return ret, nil } +func (d *db_conn) GetSuggestionParamList(studyId string) ([]*api.SuggestionParameterSet, error) { + var rows *sql.Rows + var err error + rows, err = d.db.Query("SELECT * FROM suggestion_param WHERE study_id = ?", studyId) + if err != nil { + return nil, err + } + var result []*api.SuggestionParameterSet + for rows.Next() { + var id string + var algorithm string + var params string + err := rows.Scan(&id, &algorithm, ¶ms) + if err != nil { + return nil, err + } + var p_array []string + if len(params) > 0 { + p_array = strings.Split(params, ",\n") + } else { + return nil, nil + } + suggestparams := make([]*api.SuggestionParameter, len(p_array)) + for i, j := range p_array { + p := new(api.SuggestionParameter) + err = jsonpb.UnmarshalString(j, p) + if err != nil { + log.Printf("err unmarshal %s", j) + return nil, err + } + suggestparams[i] = p + } + result = append(result, &api.SuggestionParameterSet{ + ParamId: id, + SuggestionAlgorithm: algorithm, + SuggestionParameters: suggestparams, + }) + } + return result, nil +} + func (d *db_conn) SetEarlyStopParam(algorithm string, studyId string, params []*api.EarlyStoppingParameter) (string, error) { ps := make([]string, len(params)) var err error @@ -891,7 +934,46 @@ func (d *db_conn) GetEarlyStopParam(paramId string) ([]*api.EarlyStoppingParamet } ret[i] = p } - return ret, nil +} +func (d *db_conn) GetEarlyStopParamList(studyId string) ([]*api.EarlyStoppingParameterSet, error) { + var rows *sql.Rows + var err error + rows, err = d.db.Query("SELECT * FROM earlystopping_param WHERE study_id = ?", studyId) + if err != nil { + return nil, err + } + var result []*api.EarlyStoppingParameterSet + for rows.Next() { + var id string + var algorithm string + var params string + err := rows.Scan(&id, &algorithm, ¶ms) + if err != nil { + return nil, err + } + var p_array []string + if len(params) > 0 { + p_array = strings.Split(params, ",\n") + } else { + return nil, nil + } + esparams := make([]*api.EarlyStoppingParameter, len(p_array)) + for i, j := range p_array { + p := new(api.EarlyStoppingParameter) + err = jsonpb.UnmarshalString(j, p) + if err != nil { + log.Printf("err unmarshal %s", j) + return nil, err + } + esparams[i] = p + } + result = append(result, &api.EarlyStoppingParameterSet{ + ParamId: id, + EarlyStoppingAlgorithm: algorithm, + EarlyStoppingParameters: esparams, + }) + } + return result, nil } diff --git a/pkg/earlystopping/medianstopping.go b/pkg/earlystopping/medianstopping.go index c119fb1aecd..1b4bd724067 100644 --- a/pkg/earlystopping/medianstopping.go +++ b/pkg/earlystopping/medianstopping.go @@ -133,7 +133,7 @@ func (m *MedianStoppingRule) getBestValue(sid string, sc *api.StudyConfig, logs return ret, nil } func (m *MedianStoppingRule) GetShouldStopWorkers(ctx context.Context, in *api.GetShouldStopWorkersRequest) (*api.GetShouldStopWorkersReply, error) { - wl, err := m.dbIf.GetWorkerList(in.StudyId) + wl, err := m.dbIf.GetWorkerList(in.StudyId, "") if err != nil { return &api.GetShouldStopWorkersReply{}, err } diff --git a/pkg/manager/worker/kubernetes/kubernetes.go b/pkg/manager/worker/kubernetes/kubernetes.go index 7ce696ad3a4..fee2c8b432b 100644 --- a/pkg/manager/worker/kubernetes/kubernetes.go +++ b/pkg/manager/worker/kubernetes/kubernetes.go @@ -165,7 +165,7 @@ func (d *KubernetesWorkerInterface) IsWorkerComplete(wID string) (bool, error) { } func (d *KubernetesWorkerInterface) UpdateWorkerStatus(studyId string) error { - ws, err := d.db.GetWorkerList(studyId) + ws, err := d.db.GetWorkerList(studyId, "") if err != nil { return err } @@ -214,7 +214,7 @@ func (d *KubernetesWorkerInterface) SpawnWorker(wid string, workerConf *api.Work func (d *KubernetesWorkerInterface) CleanWorkers(studyId string) error { jcl := d.clientset.BatchV1().Jobs(kubeNamespace) pcl := d.clientset.CoreV1().Pods(kubeNamespace) - ws, err := d.db.GetWorkerList(studyId) + ws, err := d.db.GetWorkerList(studyId, "") if err != nil { return err } @@ -233,7 +233,7 @@ func (d *KubernetesWorkerInterface) CleanWorkers(studyId string) error { } func (d *KubernetesWorkerInterface) StopWorkers(studyId string, wIDs []string, iscomplete bool) error { - ws, err := d.db.GetWorkerList(studyId) + ws, err := d.db.GetWorkerList(studyId, "") if err != nil { return err } diff --git a/pkg/suggestion/grid_service.go b/pkg/suggestion/grid_service.go index 364cccb68da..33f6a638b56 100644 --- a/pkg/suggestion/grid_service.go +++ b/pkg/suggestion/grid_service.go @@ -170,5 +170,15 @@ func (s *GridSuggestService) GetSuggestions(ctx context.Context, in *api.GetSugg ParameterSet: grids[i], } } + for i, t := range trials { + req := &api.CreateTrialRequest{ + Trial: t, + } + ret, err := c.CreateTrial(ctx, req) + if err != nil { + return &api.GetSuggestionsReply{Trials: []*api.Trial{}}, err + } + trials[i].TrialId = ret.TrialId + } return &api.GetSuggestionsReply{Trials: trials}, nil } diff --git a/pkg/suggestion/random_service.go b/pkg/suggestion/random_service.go index b0ac9f5733c..1be7d4b11d8 100644 --- a/pkg/suggestion/random_service.go +++ b/pkg/suggestion/random_service.go @@ -70,6 +70,14 @@ func (s *RandomSuggestService) GetSuggestions(ctx context.Context, in *api.GetSu s_t[i].ParameterSet[j].Value = pc.Feasible.List[s.IntRandom(0, len(pc.Feasible.List)-1)] } } + ctreq := &api.CreateTrialRequest{ + Trial: s_t[i], + } + ctret, err := c.CreateTrial(ctx, ctreq) + if err != nil { + return &api.GetSuggestionsReply{Trials: []*api.Trial{}}, err + } + s_t[i].TrialId = ctret.TrialId } return &api.GetSuggestionsReply{Trials: s_t}, nil } From 4db26987194c6e6bf26c0684c8f1520a418ac9d6 Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Fri, 11 May 2018 10:34:20 +0900 Subject: [PATCH 13/15] fix doc Signed-off-by: YujiOshima --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 191503cb519..7595b324c3e 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,6 @@ Each component communicates with others via GRPC and the API is defined at `api/ - vizier: main components. - vizier-core : API server of vizier. - vizier-db -- dlk-manager : a interface of kubernetes. - suggestion : implementation of each exploration algorithm. - vizier-suggestion-random - vizier-suggestion-grid From 9bad650f58da5b5b74d1c6bbd90f9459271f4897 Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Fri, 11 May 2018 13:05:36 +0900 Subject: [PATCH 14/15] fix test Signed-off-by: YujiOshima --- pkg/mock/api/manager.go | 54 +++++++++++++++++++++++++++++++++++++++++ pkg/mock/db/db.go | 34 +++++++++++++++++++++++--- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/pkg/mock/api/manager.go b/pkg/mock/api/manager.go index 5c116910dee..d607acf2400 100644 --- a/pkg/mock/api/manager.go +++ b/pkg/mock/api/manager.go @@ -53,6 +53,42 @@ func (mr *MockManagerClientMockRecorder) CreateStudy(arg0, arg1 interface{}, arg return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStudy", reflect.TypeOf((*MockManagerClient)(nil).CreateStudy), varargs...) } +// CreateTrial mocks base method +func (m *MockManagerClient) CreateTrial(arg0 context.Context, arg1 *api.CreateTrialRequest, arg2 ...grpc.CallOption) (*api.CreateTrialReply, error) { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateTrial", varargs...) + ret0, _ := ret[0].(*api.CreateTrialReply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateTrial indicates an expected call of CreateTrial +func (mr *MockManagerClientMockRecorder) CreateTrial(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTrial", reflect.TypeOf((*MockManagerClient)(nil).CreateTrial), varargs...) +} + +// GetEarlyStoppingParameterList mocks base method +func (m *MockManagerClient) GetEarlyStoppingParameterList(arg0 context.Context, arg1 *api.GetEarlyStoppingParameterListRequest, arg2 ...grpc.CallOption) (*api.GetEarlyStoppingParameterListReply, error) { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetEarlyStoppingParameterList", varargs...) + ret0, _ := ret[0].(*api.GetEarlyStoppingParameterListReply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetEarlyStoppingParameterList indicates an expected call of GetEarlyStoppingParameterList +func (mr *MockManagerClientMockRecorder) GetEarlyStoppingParameterList(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEarlyStoppingParameterList", reflect.TypeOf((*MockManagerClient)(nil).GetEarlyStoppingParameterList), varargs...) +} + // GetEarlyStoppingParameters mocks base method func (m *MockManagerClient) GetEarlyStoppingParameters(arg0 context.Context, arg1 *api.GetEarlyStoppingParametersRequest, arg2 ...grpc.CallOption) (*api.GetEarlyStoppingParametersReply, error) { varargs := []interface{}{arg0, arg1} @@ -179,6 +215,24 @@ func (mr *MockManagerClientMockRecorder) GetStudyList(arg0, arg1 interface{}, ar return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStudyList", reflect.TypeOf((*MockManagerClient)(nil).GetStudyList), varargs...) } +// GetSuggestionParameterList mocks base method +func (m *MockManagerClient) GetSuggestionParameterList(arg0 context.Context, arg1 *api.GetSuggestionParameterListRequest, arg2 ...grpc.CallOption) (*api.GetSuggestionParameterListReply, error) { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetSuggestionParameterList", varargs...) + ret0, _ := ret[0].(*api.GetSuggestionParameterListReply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSuggestionParameterList indicates an expected call of GetSuggestionParameterList +func (mr *MockManagerClientMockRecorder) GetSuggestionParameterList(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestionParameterList", reflect.TypeOf((*MockManagerClient)(nil).GetSuggestionParameterList), varargs...) +} + // GetSuggestionParameters mocks base method func (m *MockManagerClient) GetSuggestionParameters(arg0 context.Context, arg1 *api.GetSuggestionParametersRequest, arg2 ...grpc.CallOption) (*api.GetSuggestionParametersReply, error) { varargs := []interface{}{arg0, arg1} diff --git a/pkg/mock/db/db.go b/pkg/mock/db/db.go index 80030137bf7..138752898a0 100644 --- a/pkg/mock/db/db.go +++ b/pkg/mock/db/db.go @@ -132,6 +132,19 @@ func (mr *MockVizierDBInterfaceMockRecorder) GetEarlyStopParam(arg0 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEarlyStopParam", reflect.TypeOf((*MockVizierDBInterface)(nil).GetEarlyStopParam), arg0) } +// GetEarlyStopParamList mocks base method +func (m *MockVizierDBInterface) GetEarlyStopParamList(arg0 string) ([]*api.EarlyStoppingParameterSet, error) { + ret := m.ctrl.Call(m, "GetEarlyStopParamList", arg0) + ret0, _ := ret[0].([]*api.EarlyStoppingParameterSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetEarlyStopParamList indicates an expected call of GetEarlyStopParamList +func (mr *MockVizierDBInterfaceMockRecorder) GetEarlyStopParamList(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEarlyStopParamList", reflect.TypeOf((*MockVizierDBInterface)(nil).GetEarlyStopParamList), arg0) +} + // GetStudyConfig mocks base method func (m *MockVizierDBInterface) GetStudyConfig(arg0 string) (*api.StudyConfig, error) { ret := m.ctrl.Call(m, "GetStudyConfig", arg0) @@ -171,6 +184,19 @@ func (mr *MockVizierDBInterfaceMockRecorder) GetSuggestionParam(arg0 interface{} return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestionParam", reflect.TypeOf((*MockVizierDBInterface)(nil).GetSuggestionParam), arg0) } +// GetSuggestionParamList mocks base method +func (m *MockVizierDBInterface) GetSuggestionParamList(arg0 string) ([]*api.SuggestionParameterSet, error) { + ret := m.ctrl.Call(m, "GetSuggestionParamList", arg0) + ret0, _ := ret[0].([]*api.SuggestionParameterSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSuggestionParamList indicates an expected call of GetSuggestionParamList +func (mr *MockVizierDBInterfaceMockRecorder) GetSuggestionParamList(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSuggestionParamList", reflect.TypeOf((*MockVizierDBInterface)(nil).GetSuggestionParamList), arg0) +} + // GetTrial mocks base method func (m *MockVizierDBInterface) GetTrial(arg0 string) (*api.Trial, error) { ret := m.ctrl.Call(m, "GetTrial", arg0) @@ -224,16 +250,16 @@ func (mr *MockVizierDBInterfaceMockRecorder) GetWorker(arg0 interface{}) *gomock } // GetWorkerList mocks base method -func (m *MockVizierDBInterface) GetWorkerList(arg0 string) ([]*api.Worker, error) { - ret := m.ctrl.Call(m, "GetWorkerList", arg0) +func (m *MockVizierDBInterface) GetWorkerList(arg0, arg1 string) ([]*api.Worker, error) { + ret := m.ctrl.Call(m, "GetWorkerList", arg0, arg1) ret0, _ := ret[0].([]*api.Worker) ret1, _ := ret[1].(error) return ret0, ret1 } // GetWorkerList indicates an expected call of GetWorkerList -func (mr *MockVizierDBInterfaceMockRecorder) GetWorkerList(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkerList", reflect.TypeOf((*MockVizierDBInterface)(nil).GetWorkerList), arg0) +func (mr *MockVizierDBInterfaceMockRecorder) GetWorkerList(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkerList", reflect.TypeOf((*MockVizierDBInterface)(nil).GetWorkerList), arg0, arg1) } // GetWorkerLogs mocks base method From a72f0ed5fbef9858e08732a34d0f3d1601fd9591 Mon Sep 17 00:00:00 2001 From: YujiOshima Date: Tue, 15 May 2018 22:57:53 +0900 Subject: [PATCH 15/15] fix Signed-off-by: YujiOshima --- test/scripts/build.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/test/scripts/build.sh b/test/scripts/build.sh index 3cd8f00032c..d09821317e9 100755 --- a/test/scripts/build.sh +++ b/test/scripts/build.sh @@ -50,7 +50,6 @@ pids+=($!) sleep 30 # wait for copy code to gcloud cp cmd/suggestion/grid/Dockerfile . -<<<<<<< HEAD gcloud container builds submit . --tag=${REGISTRY}/${REPO_NAME}/suggestion-grid:${VERSION} --project=${PROJECT} & pids+=($!) sleep 30 # wait for copy code to gcloud