-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Push running checkpoint to remote #6332
Changes from 16 commits
14175c8
770e5bc
15036f3
205ce57
b6f147a
65eb8d6
5077862
dd7b380
92d9b07
7c271b3
34f4da3
37d2150
0cfd8d1
ce7cd7d
e666d2e
50d419f
5cf541c
dfcc946
060ec01
ffb657a
41aeaaf
488c7f3
4a16226
32677a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,8 +16,10 @@ | |
|
||
from funcy import cached_property | ||
|
||
from dvc.env import DVC_EXP_AUTO_PUSH, DVC_EXP_GIT_REMOTE | ||
from dvc.exceptions import DvcException | ||
from dvc.path_info import PathInfo | ||
from dvc.repo import Repo | ||
from dvc.repo.experiments.base import ( | ||
EXEC_BASELINE, | ||
EXEC_BRANCH, | ||
|
@@ -36,7 +38,7 @@ | |
from dvc.stage import PipelineStage | ||
from dvc.stage.monitor import CheckpointKilledError | ||
from dvc.stage.serialize import to_lockfile | ||
from dvc.utils import dict_sha256 | ||
from dvc.utils import dict_sha256, env2bool | ||
from dvc.utils.fs import remove | ||
|
||
if TYPE_CHECKING: | ||
|
@@ -248,6 +250,30 @@ def on_diverged_ref(orig_ref: str, new_rev: str): | |
) | ||
return refs | ||
|
||
@classmethod | ||
def _validate_remotes(cls, dvc: "Repo", git_remote: Optional[str]): | ||
from dulwich.client import get_transport_and_path | ||
from dulwich.porcelain import get_remote_repo | ||
|
||
from dvc.scm.base import SCMError | ||
|
||
if git_remote == dvc.root_dir: | ||
logger.warning( | ||
f"'{git_remote}' points to the current Git repo, experiment " | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is helpful since a valid remote would also point to the current Git repo, right? Maybe something like "local workspace" makes more sense than "current Git repo"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The local workspace is your current Git repo. |
||
"Git refs will not be pushed. But DVC cache and run cache " | ||
"will automatically be pushed to the default DVC remote " | ||
"(if any) on each experiment commit." | ||
) | ||
try: | ||
_, location = get_remote_repo(dvc.scm.dulwich.repo, git_remote) | ||
karajan1001 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
get_transport_and_path(location) | ||
except Exception as exc: | ||
raise SCMError( | ||
f"'{git_remote}' is not a valid Git remote or URL" | ||
) from exc | ||
|
||
dvc.cloud.get_remote_odb() | ||
|
||
@classmethod | ||
def reproduce( | ||
cls, | ||
|
@@ -270,6 +296,9 @@ def reproduce( | |
from dvc.repo.checkout import checkout as dvc_checkout | ||
from dvc.repo.reproduce import reproduce as dvc_reproduce | ||
|
||
auto_push = env2bool(DVC_EXP_AUTO_PUSH) | ||
git_remote = os.getenv(DVC_EXP_GIT_REMOTE, None) | ||
|
||
unchanged = [] | ||
|
||
if queue is not None: | ||
|
@@ -292,6 +321,9 @@ def filter_pipeline(stages): | |
log_errors, | ||
**kwargs, | ||
) as dvc: | ||
if auto_push: | ||
cls._validate_remotes(dvc, git_remote) | ||
|
||
args, kwargs = cls._repro_args(dvc) | ||
if args: | ||
targets: Optional[Union[list, str]] = args[0] | ||
|
@@ -331,6 +363,7 @@ def filter_pipeline(stages): | |
|
||
checkpoint_func = partial( | ||
cls.checkpoint_callback, | ||
dvc, | ||
dvc.scm, | ||
name, | ||
repro_force or checkpoint_reset, | ||
|
@@ -361,6 +394,8 @@ def filter_pipeline(stages): | |
force=repro_force, | ||
checkpoint=is_checkpoint, | ||
) | ||
if auto_push: | ||
cls._auto_push(dvc, dvc.scm, git_remote) | ||
except UnchangedExperimentError: | ||
pass | ||
ref = dvc.scm.get_ref(EXEC_BRANCH, follow=False) | ||
|
@@ -393,7 +428,6 @@ def _repro_dvc( | |
git_url: Optional[str] = None, | ||
**kwargs, | ||
): | ||
from dvc.repo import Repo | ||
from dvc.utils.serialize import modify_yaml | ||
|
||
dvc = Repo(dvc_dir) | ||
|
@@ -450,9 +484,32 @@ def _repro_args(cls, dvc): | |
kwargs = {} | ||
return args, kwargs | ||
|
||
@staticmethod | ||
def _auto_push( | ||
dvc: "Repo", | ||
scm: "Git", | ||
git_remote: Optional[str], | ||
push_cache=True, | ||
run_cache=True, | ||
): | ||
branch = scm.get_ref(EXEC_BRANCH, follow=False) | ||
try: | ||
dvc.experiments.push( | ||
git_remote, | ||
branch, | ||
push_cache=push_cache, | ||
run_cache=run_cache, | ||
) | ||
except BaseException: | ||
logger.warning( | ||
karajan1001 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"Something went wrong while auto pushing checkpoint cache " | ||
f"to the remote {git_remote}" | ||
) | ||
karajan1001 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@classmethod | ||
def checkpoint_callback( | ||
cls, | ||
dvc: "Repo", | ||
scm: "Git", | ||
name: Optional[str], | ||
force: bool, | ||
|
@@ -464,6 +521,10 @@ def checkpoint_callback( | |
exp_rev = cls.commit( | ||
scm, exp_hash, exp_name=name, force=force, checkpoint=True | ||
) | ||
|
||
if env2bool(DVC_EXP_AUTO_PUSH): | ||
git_remote = os.getenv(DVC_EXP_GIT_REMOTE) | ||
cls._auto_push(dvc, scm, git_remote) | ||
logger.info("Checkpoint experiment iteration '%s'.", exp_rev[:7]) | ||
except UnchangedExperimentError: | ||
pass | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to have this explicit check? Would this qualify as a valid git remote? Is there some reason to think a user might set
DVC_EXP_GIT_REMOTE
to their local project's root dir?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why fail for an invalid Git remote but only warn for this scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
git_remote
is just a variable that is either a path/URL to a git repo (including local ones) or a remote name. If this check is hit it means it's a local path that points directly to the current DVC root directory, which in most cases is a valid git repo path.This behavior can be useful - if you do
DVC_EXP_GIT_REMOTE=.
the end result would be that we auto-push DVC cache for your local experiment runs. (The git push step becomes a no-op, the same thing that happens if you do a CLIgit push
to your own current repo directory)