Skip to content
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

(IN PROG) Feat: Parallel Repeat functionality #39

Closed
wants to merge 3 commits into from
Closed
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
3 changes: 2 additions & 1 deletion sciunit2/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from sciunit2.command.diff import DiffCommand
from sciunit2.command.export import ExportCommand
from sciunit2.command.remove import RemoveCommand
from sciunit2.command.parallel_repeat import ParallelRepeatCommand

import sys
from getopt import getopt, GetoptError
Expand All @@ -30,7 +31,7 @@
__cmds__ = [CreateCommand, OpenCommand, ExecCommand, RepeatCommand,
ListCommand, ShowCommand, GivenCommand, CommitCommand, RmCommand,
SortCommand, PushCommand, CopyCommand, PostInstallCommand,
DiffCommand, RemoveCommand, ExportCommand, CheckoutCommand]
DiffCommand, RemoveCommand, ExportCommand, CheckoutCommand, ParallelRepeatCommand]


def short_usage(out):
Expand Down
16 changes: 15 additions & 1 deletion sciunit2/command/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from contextlib import contextmanager
import os

import shutil

# returns the pkgdir and original command used
# to execute execution 'rev'
Expand All @@ -28,3 +28,17 @@ def CheckoutContext_Diff(rev):
repo.cleanup(pkgdir)
repo.checkout(rev)
yield pkgdir, orig

@contextmanager
def CheckoutContext_Parallel(rev):
emgr, repo = sciunit2.workspace.current()
with emgr.exclusive():
orig = emgr.get(rev).cmd
pkgdir = os.path.join(repo.location, 'cde-package')

# creates a different path for each execution id
pkgdir_rev = os.path.join(repo.location, rev, 'cde-package')
repo.cleanup(pkgdir_rev)
repo.checkout(rev)
shutil.copytree(pkgdir, pkgdir_rev)
yield pkgdir_rev, orig
72 changes: 72 additions & 0 deletions sciunit2/command/parallel_repeat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from __future__ import absolute_import

from sciunit2.command import AbstractCommand
from sciunit2.command.context import CheckoutContext, CheckoutContext_Parallel
from sciunit2.exceptions import CommandLineError, MalformedExecutionId
import sciunit2.core
import re
from getopt import getopt
import sys
import subprocess
import shlex
import os

class ParallelRepeatCommand(AbstractCommand):
name = 'parallel_repeat'
@staticmethod
def __to_rev(id_):
return 'e%d' % id_

@staticmethod
def __to_id_range(revrange):
r = re.match(r'^e([1-9]\d*)-e([1-9]\d*)?$', revrange)
if not r:
raise MalformedExecutionId
return tuple(int(x) if x is not None else x for x in r.groups())


@property
def usage(self):
return [('parallel_repeat <execution id1>-<execution id2> [<args...>]',
"Repeat the execution of <execution id1> to <execution id2>")]

def is_gnu_parallel_installed(self):
try:
subprocess.run(['parallel', '--version'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return True
except FileNotFoundError:
return False
except subprocess.CalledProcessError as e:
return False

def run(self, args):
optlist, args = getopt(args, '')
if len(args) == 0:
raise CommandLineError

if not self.is_gnu_parallel_installed():
print("GNU Parallel is not installed on the machine")
sys.exit(1)


start,end = self.__to_id_range(args[0])
pkgdirs = ''
origs = ''
for curr in range(start, end+1):
with CheckoutContext_Parallel(self.__to_rev(curr)) as (pkgdir, orig):
pkgdirs += '\'' + pkgdir + '\' '
origs += '\'' + str(orig).replace("'", '"') + '\' '



script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'parallel_script.py')

# command = f'parallel --link python {script_path} ::: {pkgdirs} ::: \'["python3", "test.py", "1"]\' \'["python3", "test.py", "2"]\' \'["python3", "test.py", "3"]\''

command = f'parallel --link python {script_path} ::: {pkgdirs} ::: {origs}'

subprocess.run(command, shell=True, executable='/bin/bash')


# TODO: Delete all the new directories created
sys.exit(0)
14 changes: 14 additions & 0 deletions sciunit2/command/parallel_script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import sys
import json
#from sciunit2.command import AbstractCommand
#from sciunit2.command.context import CheckoutContext
#from sciunit2.exceptions import CommandLineError
import sciunit2.core
if len(sys.argv) != 3:
print("Usage: python my_script.py pkgdir arg_list repeat_args")
sys.exit(1)

pkgdir = sys.argv[1]
arg_list = json.loads(sys.argv[2])

sciunit2.core.repeat(pkgdir, arg_list,[])
Loading