Skip to content

Commit

Permalink
sketched setting
Browse files Browse the repository at this point in the history
  • Loading branch information
schlichtanders committed Sep 29, 2019
1 parent 6e82335 commit 6f05b5e
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/metrics
.hyperopt
.vscode
45 changes: 45 additions & 0 deletions bin/git_merge_subfolder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import argparse
import subprocess

class MyArg:
pass

args = MyArg()
args.metric = "score.txt"


def check_output(*args, **kwargs):
return subprocess.check_output(*args, universal_newlines=True, **kwargs).strip()


parser = argparse.ArgumentParser(description="Merge a complete subfolder by picking the best one according to the specified metric.")
parser.add_argument("branch_subfolder")
parser.add_argument("--min", dest='optimizer', action='store_const', const=min, help="minimize given metric")
parser.add_argument("--max", dest='optimizer', action='store_const', const=max, help="maximize given metric")
parser.add_argument("--metric")

args = parser.parse_args()

assert not args.branch_subfolder.endswith("/"), "assuming branch_subfolder is given without trailing slash"

"""
hyperopt/1:
score.txt: 0.9
hyperopt/2:
score.txt: 0.73
"""
metrics = check_output(["dvc", "metrics", "show", "-a", args.metric]).splitlines()

branchnames = metrics[0::2] # every odd should be a branch name
scores = [float(m[len(args.metric)+3:]) for m in metrics[1::2]] # every even should be a metric value prepended by "metricname: "

metrics_subset = [name, score for name, score in zip(branchnames, scores) if name.startswith(args.branch_subfolder)]
best_branch = args.optimizer(metrics_subset, key=lambda t:t[1])[0]

check_output(["git", "merge", "--no-ff", best_branch]).splitlines()

branchnames_subset = [m[0] for m in metrics_subset]

check_output(["git", "merge", "--strategy=ours", *branchnames_subset])


66 changes: 66 additions & 0 deletions bin/git_push_set_upstream++.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import argparse
import subprocess

def check_output(*args, **kwargs):
return subprocess.check_output(*args, universal_newlines=True, **kwargs).strip()

def git_current_branchname():
return check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"])

def git_tracking_branch():
return check_output(["git", "for-each-ref", "--format=%(upstream:short)", check_output(["git", "symbolic-ref", "-q", "HEAD"])])

parser = argparse.ArgumentParser(description="hallo")
parser.add_argument("branchname_without_incrementsuffix", nargs='?', default=None)
parser.add_argument("--max-increments", type=int, default=3)
args = parser.parse_args()

if args.branchname_without_incrementsuffix is None:
args.branchname_without_incrementsuffix = git_current_branchname()


def get_new_increment(branchname_without_incrementsuffix):
""" get suffix which does not exist yet, autoincrement if necessary """
result = check_output(["git", "ls-remote", "origin", f"refs/heads/{branchname_without_incrementsuffix}/*"]).splitlines()
print(result)
if not result:
return 1
else:
max_increment = 0
for line in result:
# the format is """commithash-tab-branchname"""
# hence we can simply compare from the right
row = line.split("/")
if row[-2] == branchname_without_incrementsuffix:
increment_string = row[-1]
try:
max_increment = max(max_increment, int(increment_string))
except ValueError: # TODO parse errormessage to be sure
continue
return max_increment + 1


def push_set_upstream_autoincrement(branchname_without_incrementsuffix, max_auto_increase=1):
# second call should not increment again, hence we raise an Error if we find a remote tracking branch
tracking_branch = git_tracking_branch()
if tracking_branch:
raise RuntimeError(f"The branch already tracks a remote branch ({tracking_branch}). "
"Either delete the reference in order to use `git_push_set_upstream++`, or fall back to use plain `git push`.")

increment = get_new_increment(branchname_without_incrementsuffix)

for i in range(max_auto_increase):
branchname_with_incrementsuffix = f"{branchname_without_incrementsuffix}/{increment + i}"
try:
command = ["git", "push", "--set-upstream", "origin", f"{branchname_without_incrementsuffix}:{branchname_with_incrementsuffix}"]
print(" ".join(command))
result = check_output(command)
print(" ".join(command))
return result
except subprocess.CalledProcessError:
continue

raise RuntimeError(f"Reached maximum number of auto-increase attempts {max_auto_increase}. Set command-line argument like `--max-increments 10` to increase the limit.")


push_set_upstream_autoincrement(args.branchname_without_incrementsuffix, max_auto_increase=args.max_increments)
2 changes: 2 additions & 0 deletions compute_score.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from random import random
print(random())
22 changes: 22 additions & 0 deletions hyperoptimization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import subprocess
import os
from datetime import datetime
from time import time
def check_output(*args, **kwargs):
return subprocess.check_output(*args, universal_newlines=True, **kwargs).strip()

origin = os.getcwd()

# combine human-readable date suffix with utc timestamp in seconds
hyperoptfolder = f'hyperopt_{datetime.now().strftime("%Y-%m-%d")}_{int(time())}'

for i in range(2):
runfolder = f".hyperopt/{hyperoptfolder}/run{i+1}"
os.makedirs(runfolder)
os.chdir(runfolder)
check_output(["git", "clone", "../../../"])
check_output(["git", "checkout", "-b", hyperoptfolder])
check_output(["dvc", "repro", "metrics.dvc"])
check_output(["git", "commit", "-am", '"hyperopt run complete"'])
check_output(["python", "./bin/git_push_set_upstream++.py"])
os.chdir(origin)
8 changes: 8 additions & 0 deletions metrics.dvc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
md5: 1149ef1e43c04e15d229f3366692f3dc
cmd: python compute_score.py > metrics
outs:
- md5: 3529a08864f57bf05cf72d280c8dd415
path: metrics
cache: true
metric: true
persist: false

0 comments on commit 6f05b5e

Please sign in to comment.