<commit_before>package suggestion

import (
	"context"
	"fmt"
	"log"
	"math"
	"sort"
	"strconv"
	"strings"

	"github.com/kubeflow/katib/pkg"
	"github.com/kubeflow/katib/pkg/api"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

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
	bL                 float64
	rL                 float64
	r                  float64
	n                  int
	shloopitr          int
	currentS           int
	ResourceName       string
	ObjectiveValueName string
	evaluatingTrials   []string
}

type HyperBandSuggestService struct {
	RandomSuggestService
}

func NewHyperBandSuggestService() *HyperBandSuggestService {
	return &HyperBandSuggestService{}
}

func (h *HyperBandSuggestService) makeBracket(ctx context.Context, c api.ManagerClient, studyID string, n int, r float64, hbparam *HyperBandParameters) ([]string, []*api.Trial, error) {
	if len(hbparam.evaluatingTrials) == 0 || hbparam.shloopitr == 0 {
		return h.makeMasterBracket(ctx, c, studyID, n, r, hbparam)
	} else {
		err, b := h.evalWorkers(ctx, c, studyID, hbparam)
		if err != nil {
			return nil, nil, err
		}
		if b == nil {
			return nil, nil, nil
		}
		return h.makeChildBracket(ctx, c, b, studyID, n, r, hbparam)
	}
}

func (h *HyperBandSuggestService) makeMasterBracket(ctx context.Context, c api.ManagerClient, studyID string, n int, r float64, hbparam *HyperBandParameters) ([]string, []*api.Trial, error) {
	log.Printf("Make MasterBracket %v Trials", n)
	gsreq := &api.GetStudyRequest{
		StudyId: studyID,
	}
	gsrep, err := c.GetStudy(ctx, gsreq)
	if err != nil {
		log.Printf("GetStudy Error")
		return nil, nil, err
	}
	sconf := gsrep.StudyConfig
	tids := make([]string, n)
	ts := make([]*api.Trial, n)
	for i := 0; i < n; i++ {
		t := &api.Trial{
			StudyId: studyID,
		}
		t.ParameterSet = make([]*api.Parameter, len(sconf.ParameterConfigs.Configs))
		for j, pc := range sconf.ParameterConfigs.Configs {
			t.ParameterSet[j] = &api.Parameter{Name: pc.Name}
			t.ParameterSet[j].ParameterType = pc.ParameterType
			if pc.Name == hbparam.ResourceName {
				if pc.ParameterType == api.ParameterType_INT {
					t.ParameterSet[j].Value = strconv.Itoa(int(r))
				} else {
					t.ParameterSet[j].Value = strconv.FormatFloat(r, 'f', 4, 64)
				}
			} else {
				switch pc.ParameterType {
				case api.ParameterType_INT:
					imin, _ := strconv.Atoi(pc.Feasible.Min)
					imax, _ := strconv.Atoi(pc.Feasible.Max)
					t.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)
					t.ParameterSet[j].Value = strconv.FormatFloat(h.DoubelRandom(dmin, dmax), 'f', 4, 64)
				case api.ParameterType_CATEGORICAL:
					t.ParameterSet[j].Value = pc.Feasible.List[h.IntRandom(0, len(pc.Feasible.List)-1)]
				}
			}
		}
		req := &api.CreateTrialRequest{
			Trial: t,
		}
		ret, err := c.CreateTrial(ctx, req)
		if err != nil {
			log.Printf("CreateTrial Error")
			return nil, nil, err
		}
		tids[i] = ret.TrialId
		t.TrialId = ret.TrialId
		ts[i] = t
	}
	return tids, ts, nil
}

func (h *HyperBandSuggestService) makeChildBracket(ctx context.Context, c api.ManagerClient, parent Bracket, studyID string, n int, rI float64, hbparam *HyperBandParameters) ([]string, []*api.Trial, error) {
	gsreq := &api.GetStudyRequest{
		StudyId: studyID,
	}
	gsrep, err := c.GetStudy(ctx, gsreq)
	if err != nil {
		log.Printf("GetStudy Error")
		return nil, nil, err
	}
	sconf := gsrep.StudyConfig
	child := Bracket{}

	if sconf.OptimizationType == api.OptimizationType_MINIMIZE {
		child = parent[n:]
	} else if sconf.OptimizationType == api.OptimizationType_MAXIMIZE {<commit_msg>fix slice range (#226)<commit_after>package suggestion

import (
	"context"
	"fmt"
	"log"
	"math"
	"sort"
	"strconv"
	"strings"

	"github.com/kubeflow/katib/pkg"
	"github.com/kubeflow/katib/pkg/api"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

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
	bL                 float64
	rL                 float64
	r                  float64
	n                  int
	shloopitr          int
	currentS           int
	ResourceName       string
	ObjectiveValueName string
	evaluatingTrials   []string
}

type HyperBandSuggestService struct {
	RandomSuggestService
}

func NewHyperBandSuggestService() *HyperBandSuggestService {
	return &HyperBandSuggestService{}
}

func (h *HyperBandSuggestService) makeBracket(ctx context.Context, c api.ManagerClient, studyID string, n int, r float64, hbparam *HyperBandParameters) ([]string, []*api.Trial, error) {
	if len(hbparam.evaluatingTrials) == 0 || hbparam.shloopitr == 0 {
		return h.makeMasterBracket(ctx, c, studyID, n, r, hbparam)
	} else {
		err, b := h.evalWorkers(ctx, c, studyID, hbparam)
		if err != nil {
			return nil, nil, err
		}
		if b == nil {
			return nil, nil, nil
		}
		return h.makeChildBracket(ctx, c, b, studyID, n, r, hbparam)
	}
}

func (h *HyperBandSuggestService) makeMasterBracket(ctx context.Context, c api.ManagerClient, studyID string, n int, r float64, hbparam *HyperBandParameters) ([]string, []*api.Trial, error) {
	log.Printf("Make MasterBracket %v Trials", n)
	gsreq := &api.GetStudyRequest{
		StudyId: studyID,
	}
	gsrep, err := c.GetStudy(ctx, gsreq)
	if err != nil {
		log.Printf("GetStudy Error")
		return nil, nil, err
	}
	sconf := gsrep.StudyConfig
	tids := make([]string, n)
	ts := make([]*api.Trial, n)
	for i := 0; i < n; i++ {
		t := &api.Trial{
			StudyId: studyID,
		}
		t.ParameterSet = make([]*api.Parameter, len(sconf.ParameterConfigs.Configs))
		for j, pc := range sconf.ParameterConfigs.Configs {
			t.ParameterSet[j] = &api.Parameter{Name: pc.Name}
			t.ParameterSet[j].ParameterType = pc.ParameterType
			if pc.Name == hbparam.ResourceName {
				if pc.ParameterType == api.ParameterType_INT {
					t.ParameterSet[j].Value = strconv.Itoa(int(r))
				} else {
					t.ParameterSet[j].Value = strconv.FormatFloat(r, 'f', 4, 64)
				}
			} else {
				switch pc.ParameterType {
				case api.ParameterType_INT:
					imin, _ := strconv.Atoi(pc.Feasible.Min)
					imax, _ := strconv.Atoi(pc.Feasible.Max)
					t.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)
					t.ParameterSet[j].Value = strconv.FormatFloat(h.DoubelRandom(dmin, dmax), 'f', 4, 64)
				case api.ParameterType_CATEGORICAL:
					t.ParameterSet[j].Value = pc.Feasible.List[h.IntRandom(0, len(pc.Feasible.List)-1)]
				}
			}
		}
		req := &api.CreateTrialRequest{
			Trial: t,
		}
		ret, err := c.CreateTrial(ctx, req)
		if err != nil {
			log.Printf("CreateTrial Error")
			return nil, nil, err
		}
		tids[i] = ret.TrialId
		t.TrialId = ret.TrialId
		ts[i] = t
	}
	return tids, ts, nil
}

func (h *HyperBandSuggestService) makeChildBracket(ctx context.Context, c api.ManagerClient, parent Bracket, studyID string, n int, rI float64, hbparam *HyperBandParameters) ([]string, []*api.Trial, error) {
	gsreq := &api.GetStudyRequest{
		StudyId: studyID,
	}
	gsrep, err := c.GetStudy(ctx, gsreq)
	if err != nil {
		log.Printf("GetStudy Error")
		return nil, nil, err
	}
	sconf := gsrep.StudyConfig
	child := Bracket{}

	if sconf.OptimizationType == api.OptimizationType_MINIMIZE {
		child = parent[len(parent) - n:]
	} else if sconf.OptimizationType == api.OptimizationType_MAXIMIZE {
{'fraction_non_alphanumeric': 0.1372766481823783, 'fraction_numerical': 0.008009858287122612, 'mean_word_length': 3.4373974849644613, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1866328', 'n_tokens_mistral': 3420, 'n_tokens_neox': 3045, 'n_words': 680}