Skip to content
Snippets Groups Projects
dct_matlab_invocation.py 4.19 KiB
Newer Older
'''
Created on Feb 7, 2013

@author: ben
'''

import os
import subprocess
from . import dct_io_xml
from . import dct_utils_platform

class DCTMatlabInvocation(object):

    def __init__(self, dct_dir, work_dir = os.getcwd(), extra_args = [], \
                 extra_cmds = "", ctrl_c_kill = False, \
                 skip_functions_check = False):
        self.dct_dir = dct_dir
        self.work_dir = work_dir

        self.confPath = os.path.join(self.dct_dir, "conf.xml")
        self.confPath = os.path.abspath(self.confPath)

        self.args = extra_args
        self.extra_cmds = extra_cmds

        self.ctrl_c_kill = ctrl_c_kill
        self.skip_functions_check = skip_functions_check
        self.utils = dct_utils_platform.UtilsFactory.getMachineDep()

    @staticmethod
    def filter_parameters(args):
        launcher_accepted_args = ("--profile", "--debug", "--script")
        decoded_args = { 'profile' : None, 'debug' : None, 'script' : None }
        skip_next = False
        for ind_arg in range(len(args)):
            if skip_next is True:
                skip_next = False
                continue
            for modifier in launcher_accepted_args:
                if args[ind_arg] == modifier:
                    if len(args) <= (ind_arg + 1):
                        raise ValueError("Not enough arguments for modifier: %s" % modifier)
                    if decoded_args[modifier[2:]] is not None:
                        dct_io_xml.DCTOutput.printWarning(  \
                            "Overwriting previous argument '%s' for modifier '%s', with argument '%s'" \
                            % decoded_args[modifier[2:]], modifier, args[ind_arg+1])
                    decoded_args[modifier[2:]] = args[ind_arg+1]
                    skip_next = True
        if decoded_args["profile"] is not None and decoded_args["debug"] is not None:
            raise ValueError("Profiling and debugging cannot be used at the same time!")
        return decoded_args

    def invoke(self, profiler = None, debugger = None):
        self.conf = dct_io_xml.DCTConf(self.confPath)

        # Adding runtime libraries
        try:
            env_initial_libs = os.environ["LD_LIBRARY_PATH"]
        except KeyError:
            env_initial_libs = ""
            os.environ["LD_LIBRARY_PATH"] = ""
        libs = self.conf.getMatlabRuntimeLibraries(self.utils.hostname)
        for lib in libs:
            env_var = os.environ["LD_LIBRARY_PATH"]
            os.environ["LD_LIBRARY_PATH"] = ":".join([lib, env_var])

        # Adding preload libraries
        try:
            env_initial_preload = os.environ["LD_PRELOAD"]
        except KeyError:
            env_initial_preload = ""
            os.environ["LD_PRELOAD"] = ""
        libs = self.conf.getMatlabPreloadLibraries(self.utils.hostname)
        for lib in libs:
            env_var = os.environ["LD_PRELOAD"]
            os.environ["LD_PRELOAD"] = ":".join([lib, env_var])
        cmd = []
        if profiler == "cuda":
            cmd = cmd + ["/usr/local/cuda/bin/nvprof", "-f", "-o", "profile_cuda_matlab_script"] #, "--analysis-metrics"
        if debugger == "valgrind":
            cmd = cmd + ["valgrind", "--log-file=memcheck_matlab_script"] #, "--leak-check=yes"
        cmd = cmd + [os.path.join(self.conf.getMatlabPath(), "bin", "matlab")]

        cmd = cmd + self.conf.getMatlabOptions()
        cmd = cmd + self.args

        cmd.append("-r")

        ignore_id19 = self.conf.getIgnoreID19()
        if self.skip_functions_check is True:
            skip_functions = 'true';
        else:
            skip_functions = 'false'
        cmd.append("cd('%s');initialise_gt(%s,%s);cd('%s');%s" \
                   % (self.dct_dir, ignore_id19, skip_functions, self.work_dir, \
                      "".join(self.extra_cmds)) )

        print("Calling: %s" % " ".join(cmd))

        subobj = subprocess.Popen(cmd)
        while subobj.poll() is None:
            try:
                subobj.wait()
            except KeyboardInterrupt:
                if self.ctrl_c_kill is True:
                    print("Sending kill signal to matlab...")
                    subobj.kill()

        os.environ["LD_LIBRARY_PATH"] = env_initial_libs
        os.environ["LD_PRELOAD"] = env_initial_preload