Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merging Backtest improve #694

Merged
merged 2 commits into from
Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions qlib/utils/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ class LoadObjectError(QlibException):
"""Error type for Recorder when can not load object"""

pass


class ExpAlreadyExistError(Exception):
"""Experiment already exists"""

pass
25 changes: 21 additions & 4 deletions qlib/workflow/expm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from urllib.parse import urlparse
import mlflow
from filelock import FileLock
from mlflow.exceptions import MlflowException
from mlflow.exceptions import MlflowException, RESOURCE_ALREADY_EXISTS, ErrorCode
from mlflow.entities import ViewType
import os, logging
from pathlib import Path
Expand All @@ -15,6 +15,7 @@
from ..config import C
from .recorder import Recorder
from ..log import get_module_logger
from ..utils.exceptions import ExpAlreadyExistError

logger = get_module_logger("workflow", logging.INFO)

Expand Down Expand Up @@ -94,6 +95,10 @@ def create_exp(self, experiment_name: Optional[Text] = None):
Returns
-------
An experiment object.

Raise
-----
ExpAlreadyExistError
"""
raise NotImplementedError(f"Please implement the `create_exp` method.")

Expand Down Expand Up @@ -200,7 +205,14 @@ def _get_or_create_exp(self, experiment_id=None, experiment_name=None) -> (objec
if pr.scheme == "file":
with FileLock(os.path.join(pr.netloc, pr.path, "filelock")) as f:
return self.create_exp(experiment_name), True
return self.create_exp(experiment_name), True
# NOTE: for other schemes like http, we double check to avoid create exp conflicts
try:
return self.create_exp(experiment_name), True
except ExpAlreadyExistError:
return (
self._get_exp(experiment_id=experiment_id, experiment_name=experiment_name),
False,
)

def _get_exp(self, experiment_id=None, experiment_name=None) -> Experiment:
"""
Expand Down Expand Up @@ -345,10 +357,15 @@ def end_exp(self, recorder_status: Text = Recorder.STATUS_S):
def create_exp(self, experiment_name: Optional[Text] = None):
assert experiment_name is not None
# init experiment
experiment_id = self.client.create_experiment(experiment_name)
try:
experiment_id = self.client.create_experiment(experiment_name)
except MlflowException as e:
if e.error_code == ErrorCode.Name(RESOURCE_ALREADY_EXISTS):
raise ExpAlreadyExistError()
raise e

experiment = MLflowExperiment(experiment_id, experiment_name, self.uri)
experiment._default_name = self._default_exp_name

return experiment

def _get_exp(self, experiment_id=None, experiment_name=None):
Expand Down
2 changes: 1 addition & 1 deletion qlib/workflow/task/collect.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Collector module can collect objects from everywhere and process them such as merging, grouping, averaging and so on.
"""

from libs.qlib.qlib.log import TimeInspector
from qlib.log import TimeInspector
from typing import Callable, Dict, List
from qlib.log import get_module_logger
from qlib.utils.serial import Serializable
Expand Down