Source code for

# Copyright (c) OpenMMLab. All rights reserved.
# flake8: noqa
import os
import os.path as osp
import subprocess
import sys
from typing import Tuple, Union

import click

from import CustomCommand, param2lowercase
from mim.utils import (

PYTHON = sys.executable

@click.argument('package', type=str, callback=param2lowercase)
@click.argument('command', type=str)
@click.option('-y', '--yes', is_flag=True, help='Don\'t ask for confirmation.')
@click.argument('other_args', nargs=-1, type=click.UNPROCESSED)
def cli(package: str, command: str, yes: bool, other_args: tuple = ()) -> None:
    """Run arbitrary command of a codebase.

    Note if the command you call takes config files or checkpoint paths as
    arguments, you must use paths that do exists. We do not accept URLs or
    config names (like if that doesn't exist under
    your current directory.


    # Get the Flops of a model
    > mim run mmcls get_flops
    # Publish a model
    > mim run mmcls publish_model input.pth output.pth
    # Train models on a slurm HPC with one GPU
    > srun -p partition --gres=gpu:1 mim run mmcls train \ --work-dir tmp
    # Test models on a slurm HPC with one GPU, report accuracy
    > srun -p partition --gres=gpu:1 mim run mmcls test \ tmp/epoch_3.pth --metrics accuracy
    # Print help messages of sub-command run
    > mim run -h
    # Print help messages of sub-command run, list all available scripts in
    # codebase mmcls
    > mim run mmcls -h
    # Print help messages of sub-command run, print the help message of
    # training script in mmcls
    > mim run mmcls train -h
    is_success, msg = run(
        package=package, command=command, yes=yes, other_args=other_args)

    if is_success:
        echo_success(msg)  # type: ignore

[docs]def run( package: str, command: str, yes: bool = True, other_args: tuple = () ) -> Tuple[bool, Union[str, Exception]]: """Run arbitrary command of a codebase. This command assumes the command scripts have been put into the ``package/tools`` directory. Args: package (str): The codebase name. command (str): The command name. yes (bool): Don\'t ask for confirmation. Default: True. other_args (tuple, optional): Other arguments, will be passed to the codebase's script. Defaults to (). """ full_name = module_full_name(package) if full_name == '': msg = f"Can't determine a unique package given abbreviation {package}" raise ValueError(highlighted_error(msg)) package = full_name if not is_installed(package): msg = (f'The codebase {package} is not installed, ' 'do you want to install it? ') if yes or click.confirm(msg): click.echo(f'Installing {package}') cmd = ['mim', 'install', package] ret = subprocess.check_call(cmd) if ret != 0: msg = f'{package} is not successfully installed' raise RuntimeError(highlighted_error(msg)) else: click.echo(f'{package} is successfully installed') else: msg = (f"You can't run commands in {package} without " f'{package} installed.') return False, msg pkg_root = get_installed_path(package) possible_prefixes = [ osp.join(pkg_root, '.mim', f'tools{os.sep}'), osp.join(pkg_root, f'tools{os.sep}'), osp.join(pkg_root, '.mim', f'demo{os.sep}'), osp.join(pkg_root, f'demo{os.sep}') ] for possible_prefix in possible_prefixes: if osp.exists(possible_prefix): prefix = possible_prefix break command_domain = '' if ':' in command: split_command = command.split(':') command_domain = os.sep.join(split_command[:-1]) command = split_command[-1] files = recursively_find(prefix, command + '.py') if command_domain == '': suffix = f'{os.sep}{command}.py' else: suffix = f'{os.sep}{command_domain}{os.sep}{command}.py' files = [f for f in files if f.endswith(suffix)] if len(files) == 0: msg = f'No script in codebase {package} has suffix {suffix}.' raise ValueError(highlighted_error(msg)) elif len(files) > 1: echo_warning( f'Multiple scripts in codebase {package} have suffix {suffix}: ') for f in files: echo_warning(f) # Use the shortest path files.sort(key=lambda x: len(x.split(os.sep))) echo_warning(f'We are using the script {files[0]}. ') echo_warning('To use other scripts, you need to use these commands: ') for f in files[1:]: cmd = f.split(prefix)[1].split('.')[0].replace(os.sep, ':') echo_warning(f'Command for {f}: {cmd}') script = files[0] click.echo(f'Use the script {script} for command {command}.') cmd = [PYTHON, script] + list(other_args) cmd_text = ' '.join(cmd) click.echo(f'The command to call is {cmd_text}. ') ret = subprocess.check_call(cmd, env=dict(os.environ)) if ret == 0: return True, 'The script finished successfully.' else: return False, 'The script not finished successfully.'
Read the Docs v: latest
On Read the Docs
Project Home

Free document hosting provided by Read the Docs.