Spaces:
Sleeping
Sleeping
# Copyright 2020 The HuggingFace Team. All rights reserved. | |
# | |
# 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. | |
import copy | |
import re | |
class TrialShortNamer: | |
PREFIX = "hp" | |
DEFAULTS = {} | |
NAMING_INFO = None | |
def set_defaults(cls, prefix, defaults): | |
cls.PREFIX = prefix | |
cls.DEFAULTS = defaults | |
cls.build_naming_info() | |
def shortname_for_word(info, word): | |
if len(word) == 0: | |
return "" | |
short_word = None | |
if any(char.isdigit() for char in word): | |
raise Exception(f"Parameters should not contain numbers: '{word}' contains a number") | |
if word in info["short_word"]: | |
return info["short_word"][word] | |
for prefix_len in range(1, len(word) + 1): | |
prefix = word[:prefix_len] | |
if prefix in info["reverse_short_word"]: | |
continue | |
else: | |
short_word = prefix | |
break | |
if short_word is None: | |
# Paranoid fallback | |
def int_to_alphabetic(integer): | |
s = "" | |
while integer != 0: | |
s = chr(ord("A") + integer % 10) + s | |
integer //= 10 | |
return s | |
i = 0 | |
while True: | |
sword = word + "#" + int_to_alphabetic(i) | |
if sword in info["reverse_short_word"]: | |
continue | |
else: | |
short_word = sword | |
break | |
info["short_word"][word] = short_word | |
info["reverse_short_word"][short_word] = word | |
return short_word | |
def shortname_for_key(info, param_name): | |
words = param_name.split("_") | |
shortname_parts = [TrialShortNamer.shortname_for_word(info, word) for word in words] | |
# We try to create a separatorless short name, but if there is a collision we have to fallback | |
# to a separated short name | |
separators = ["", "_"] | |
for separator in separators: | |
shortname = separator.join(shortname_parts) | |
if shortname not in info["reverse_short_param"]: | |
info["short_param"][param_name] = shortname | |
info["reverse_short_param"][shortname] = param_name | |
return shortname | |
return param_name | |
def add_new_param_name(info, param_name): | |
short_name = TrialShortNamer.shortname_for_key(info, param_name) | |
info["short_param"][param_name] = short_name | |
info["reverse_short_param"][short_name] = param_name | |
def build_naming_info(cls): | |
if cls.NAMING_INFO is not None: | |
return | |
info = { | |
"short_word": {}, | |
"reverse_short_word": {}, | |
"short_param": {}, | |
"reverse_short_param": {}, | |
} | |
field_keys = list(cls.DEFAULTS.keys()) | |
for k in field_keys: | |
cls.add_new_param_name(info, k) | |
cls.NAMING_INFO = info | |
def shortname(cls, params): | |
cls.build_naming_info() | |
assert cls.PREFIX is not None | |
name = [copy.copy(cls.PREFIX)] | |
for k, v in params.items(): | |
if k not in cls.DEFAULTS: | |
raise Exception(f"You should provide a default value for the param name {k} with value {v}") | |
if v == cls.DEFAULTS[k]: | |
# The default value is not added to the name | |
continue | |
key = cls.NAMING_INFO["short_param"][k] | |
if isinstance(v, bool): | |
v = 1 if v else 0 | |
sep = "" if isinstance(v, (int, float)) else "-" | |
e = f"{key}{sep}{v}" | |
name.append(e) | |
return "_".join(name) | |
def parse_repr(cls, repr): | |
repr = repr[len(cls.PREFIX) + 1 :] | |
if repr == "": | |
values = [] | |
else: | |
values = repr.split("_") | |
parameters = {} | |
for value in values: | |
if "-" in value: | |
p_k, p_v = value.split("-") | |
else: | |
p_k = re.sub("[0-9.]", "", value) | |
p_v = float(re.sub("[^0-9.]", "", value)) | |
key = cls.NAMING_INFO["reverse_short_param"][p_k] | |
parameters[key] = p_v | |
for k in cls.DEFAULTS: | |
if k not in parameters: | |
parameters[k] = cls.DEFAULTS[k] | |
return parameters | |