Example #1
0
 def load_dependency(self, module_name, dependencies, recursive, greedy, ismapping = False):
     """Loads the module with the specified name if it isn't already loaded."""
     key = module_name.lower()
     if key not in self.modules:
         if key == "fortpy":
             #Manually specify the correct path to the fortpy.f90 that shipped with
             #the distribution
             from fortpy.utility import get_fortpy_templates_dir
             from os import path
             fpy_path = path.join(get_fortpy_templates_dir(), "fortpy.f90")
             self.parse(fpy_path, False, False)
             return
         
         fkey = key + ".f90"
         if fkey in self._pathfiles:
             self.parse(self._pathfiles[fkey], dependencies, recursive)
         elif greedy:
             #The default naming doesn't match for this module
             #we will load all modules until we find the right
             #one
             self._load_greedy(key, dependencies, recursive)
         elif key in self.mappings and self.mappings[key] in self._pathfiles:
             #See if they have a mapping specified to a code file for this module name.
             if self.verbose:
                 msg.info("MAPPING: using {} as the file".format(self.mappings[key]) + 
                          " name for module {}".format(key))
             self.parse(self._pathfiles[self.mappings[key]], dependencies, recursive)
         elif key not in ["mkl_vsl_type", "mkl_vsl", "iso_c_binding"]:
             #The parsing can't continue without the necessary dependency modules.
             msg.err(("could not find module {}. Enable greedy search or"
                    " add a module filename mapping.".format(key)))
             if self.austere:
                 exit(1)
Example #2
0
    def template_version(self, filename):
        """Returns the version number of the latest fortpy.f90 file."""
        if filename not in self._templatev:
            from os import path
            from fortpy.utility import get_fortpy_templates_dir
            tempath = path.join(get_fortpy_templates_dir(), filename)
            self._templatev[filename] = self.get_fortpy_version(tempath)

        return self._templatev[filename]
Example #3
0
def template_version(compiler, filename):
    """Returns the version number of the specified file."""
    global _templatev
    if filename not in _templatev:
        from os import path
        from fortpy.utility import get_fortpy_templates_dir
        tempath = path.join(get_fortpy_templates_dir(), filename)
        _templatev[filename] = get_fortpy_version(compiler, tempath, attribute="codeversion")

    return _templatev[filename]
Example #4
0
def generate(parser, coderoot, stagedir, compiler=None, debug=False, profile=False,
             strict=False, docompile=True):
    """Generates the f90 module file for all members referenced in the parser's
    modules list.
    """
    import fortpy
    from fortpy.utility import get_fortpy_templates_dir
    from fortpy.testing.elements import AutoClasser
    
    members = _find_members(parser, coderoot)
    folder = "filename"
    classers = [AutoClasser(m, folder, m.name, [], coderoot, True) for m in members]
    
    from os import path
    templates = get_fortpy_templates_dir()
    statpath = path.join(templates, "fpy_auxiliary.f90")
    with open(statpath) as f:
        static = f.read()
        
    from fortpy.printing.formatting import present_params
    xnames, modcode, routines, modules = _generate_single(classers)

    from fortpy.code import order_module_dependencies
    modules = order_module_dependencies(modules, parser)

    from os import mkdir, path
    if docompile:
        auxdir = path.join(stagedir, "fortpy.aux")
        if not path.isdir(auxdir):
            mkdir(auxdir)
    else:
        auxdir = coderoot

    if docompile and not _should_recompile(auxdir, parser, modules, compiler):
        msg.okay("The current version of fpy_auxiliary.f90 is up-to-date.")
        from fortpy.testing.compilers import replace
        target = replace(auxdir + ".[c]", compiler)
        return (0, True, target)
    
    static = static.replace("__auxsave__", present_params(xnames, 21))
    static = static.replace("__aux_uses__", '\n'.join(modcode))        
    static = static.replace("__version__", fortpy.__version__)
    static = static.replace("__fxauxsave__", '\n'.join(routines))

    xnames, modcode, routines, dmods = _generate_single(classers, False)
    static = static.replace("__auxread__", present_params(xnames, 21))
    static = static.replace("__fxauxread__", '\n'.join(routines))

    fortpath = path.join(auxdir, "fpy_auxiliary.f90")
    with open(fortpath, 'w') as f:
        f.write(static)

    if docompile:
        _prepare_dir(parser, modules, auxdir)
        return _compile(auxdir, compiler, debug, profile)
Example #5
0
def set_fortpy_templates(obj, fortpy_templates=None):
    """Sets the directory path for the fortpy templates. If no directory
    is specified, use the default one that shipped with the package.
    """
    #If they didn't specify a custom templates directory, use the default
    #one that shipped with the package.
    from os import path
    if fortpy_templates is not None:
        obj.fortpy_templates = path.abspath(path.expanduser(fortpy_templates))
    else:
        from fortpy.utility import get_fortpy_templates_dir
        obj.fortpy_templates = get_fortpy_templates_dir()
Example #6
0
def set_fortpy_templates(obj, fortpy_templates=None):
    """Sets the directory path for the fortpy templates. If no directory
    is specified, use the default one that shipped with the package.
    """
    #If they didn't specify a custom templates directory, use the default
    #one that shipped with the package.
    from os import path
    if fortpy_templates is not None:
        obj.fortpy_templates = path.abspath(path.expanduser(fortpy_templates))
    else:
        from fortpy.utility import get_fortpy_templates_dir
        obj.fortpy_templates = get_fortpy_templates_dir()
Example #7
0
def template_version(compiler, filename):
    """Returns the version number of the specified file."""
    global _templatev
    if filename not in _templatev:
        from os import path
        from fortpy.utility import get_fortpy_templates_dir
        tempath = path.join(get_fortpy_templates_dir(), filename)
        _templatev[filename] = get_fortpy_version(compiler,
                                                  tempath,
                                                  attribute="codeversion")

    return _templatev[filename]
Example #8
0
    def load_dependency(self,
                        module_name,
                        dependencies,
                        recursive,
                        greedy,
                        ismapping=False):
        """Loads the module with the specified name if it isn't already loaded."""
        key = module_name.lower()
        if key not in self.modules:
            if key == "fortpy":
                #Manually specify the correct path to the fortpy.f90 that shipped with
                #the distribution
                from fortpy.utility import get_fortpy_templates_dir
                from os import path
                fpy_path = path.join(get_fortpy_templates_dir(), "fortpy.f90")
                self.parse(fpy_path, False, False)
                return

            fkey = key + ".f90"
            if fkey in self._pathfiles:
                self.parse(self._pathfiles[fkey], dependencies, recursive)
            elif greedy:
                #The default naming doesn't match for this module
                #we will load all modules until we find the right
                #one
                self._load_greedy(key, dependencies, recursive)
            elif key in self.mappings and self.mappings[key] in self._pathfiles:
                #See if they have a mapping specified to a code file for this module name.
                if self.verbose:
                    msg.info("MAPPING: using {} as the file".format(
                        self.mappings[key]) +
                             " name for module {}".format(key))
                self.parse(self._pathfiles[self.mappings[key]], dependencies,
                           recursive)
            elif key not in ["mkl_vsl_type", "mkl_vsl", "iso_c_binding"]:
                #The parsing can't continue without the necessary dependency modules.
                msg.err(("could not find module {}. Enable greedy search or"
                         " add a module filename mapping.".format(key)))
                if self.austere:
                    exit(1)
Example #9
0
    "__fpy_read__": fpy_read,
    "__fpy_read_f__": fpy_read,
    "__fpy_read_p__": fpy_read,
    "__pysave__": pysave
}
"""Dict indicating which python function generates the fortran subroutines
for the given interface field.
"""

from os import path
import sys
sys.path.insert(0, path.expanduser("~/codes/fortpy-dist/"))
import fortpy
from fortpy.utility import get_fortpy_templates_dir

templates = get_fortpy_templates_dir()
statpath = path.join(templates, "static.f90")
with open(statpath) as f:
    static = f.read()

for iface, idict in list(interfaces.items()):
    if iface in generators:
        static = fpy_interface(generators[iface], static, iface, idict)
    else:
        raise ValueError("No generator for field {}".format(iface))

static = static.replace("__version__", fortpy.__version__)
fortpath = path.join(templates, "fortpy.f90")
with open(fortpath, 'w') as f:
    f.write(static)
Example #10
0
    "__fpy_read__": fpy_read,
    "__fpy_read_f__": fpy_read,
    "__fpy_read_p__": fpy_read,
    "__pysave__": pysave
}
"""Dict indicating which python function generates the fortran subroutines
for the given interface field.
"""

from os import path
import sys
sys.path.insert(0, path.expanduser("~/codes/fortpy-dist/"))
import fortpy
from fortpy.utility import get_fortpy_templates_dir

templates = get_fortpy_templates_dir()
statpath = path.join(templates, "static.f90")
with open(statpath) as f:
    static = f.read()

for iface, idict in list(interfaces.items()):
    if iface in generators:
        static = fpy_interface(generators[iface], static, iface, idict)
    else:
        raise ValueError("No generator for field {}".format(iface))

static = static.replace("__version__", fortpy.__version__)
fortpath = path.join(templates, "fortpy.f90")
with open(fortpath, 'w') as f:
    f.write(static)
Example #11
0
def compile(folder, compiler=None, identifier=None, debug=False, profile=False,
            quiet=False, moptions=None, inclfortpy=True, vupdates=None,
            strict=False, inclfpyaux=False):
    """Runs the makefile in the specified folder to compile the 'all' rule.

    :arg vupdates: a list of module names for which the output .mod and .o files
      should have version information attached.
    """
    if inclfortpy:
        #Before we can compile the library, we need to make sure that we have a fortpy
        #.mod and .o compiled with the *same* compiler version specified.
        from fortpy.utility import get_fortpy_templates_dir
        _ensure_fileversion(compiler, "fortpy", get_fortpy_templates_dir(), folder)
        
    options = ""
    if debug:
        options += " DEBUG=true"
    if profile:
        options += " GPROF=true"
    if strict:
        options += " STRICT=true"    

    if moptions is not None:
        for opt in moptions:
            options += " {}".format(opt)
        
    if identifier is not None:
        codestr = "cd {}; make -f 'Makefile.{}' F90='{}' FAM='{}'" + options
        command = codestr.format(folder, identifier, executor(compiler), family(compiler))
    else:
        codestr = "cd {}; make F90='{}' FAM='{}'" + options
        command = codestr.format(folder, executor(compiler), family(compiler))
        
    #If we are running in quiet mode, we don't want the compile information
    #to post to stdout; only errors should be redirected. This means we need
    #to wrap the execution in a subprocess and redirect the std* to PIPE
    from os import waitpid, path
    from subprocess import Popen, PIPE
    pcompile = Popen(command, shell=True, executable="/bin/bash", stdout=PIPE, stderr=PIPE)
    waitpid(pcompile.pid, 0)
    
    if not quiet:
        output = [x.decode('utf8') for x in pcompile.stdout.readlines()]
        msg.std(''.join(output))
    #else: #We don't need to get these lines since we are purposefully redirecting them.
    error = [x.decode('utf8') for x in pcompile.stderr.readlines()]
    code = len(error)
    if code != 0:
        msg.err(''.join(error))

    #It turns out that the compiler still returns a code of zero, even if the compile
    #failed because the actual compiler didn't fail; it did its job properly. We need to
    #check for the existence of errors in the 'compile.log' file.
    lcount = 0
    errors = []
    log = path.join(folder, "compile.log")
    with open(log) as f:
        for line in f:
            lcount += 1
            if lcount > 21 and lcount < 32:
                errors.append(line)
            elif lcount > 21:
                break

    if len(errors) > 0:
        #There are 21 lines in the compile.log file when everything runs correctly
        #Overwrite code with a bad exit value since we have some other problems.
        code = 1
        #We want to write the first couple of errors to the console and give them the
        #option to still execute if the compile only generated warnings.
        msg.warn("compile generated some errors or warnings:")
        msg.blank()
        msg.info(''.join(errors))

    if vupdates is not None:
        for modname in vupdates:
            _vupdate_compiled_module(compiler, modname, folder, rename=False)
        
    return (code, len(errors)==0)
Example #12
0
def compile(folder,
            compiler=None,
            identifier=None,
            debug=False,
            profile=False,
            quiet=False,
            moptions=None,
            inclfortpy=True,
            vupdates=None,
            strict=False,
            inclfpyaux=False):
    """Runs the makefile in the specified folder to compile the 'all' rule.

    :arg vupdates: a list of module names for which the output .mod and .o files
      should have version information attached.
    """
    if inclfortpy:
        #Before we can compile the library, we need to make sure that we have a fortpy
        #.mod and .o compiled with the *same* compiler version specified.
        from fortpy.utility import get_fortpy_templates_dir
        _ensure_fileversion(compiler, "fortpy", get_fortpy_templates_dir(),
                            folder)

    options = ""
    if debug:
        options += " DEBUG=true"
    if profile:
        options += " GPROF=true"
    if strict:
        options += " STRICT=true"

    if moptions is not None:
        for opt in moptions:
            options += " {}".format(opt)

    if identifier is not None:
        codestr = "cd {}; make -f 'Makefile.{}' F90='{}' FAM='{}'" + options
        command = codestr.format(folder, identifier, executor(compiler),
                                 family(compiler))
    else:
        codestr = "cd {}; make F90='{}' FAM='{}'" + options
        command = codestr.format(folder, executor(compiler), family(compiler))

    #If we are running in quiet mode, we don't want the compile information
    #to post to stdout; only errors should be redirected. This means we need
    #to wrap the execution in a subprocess and redirect the std* to PIPE
    from os import waitpid, path
    from subprocess import Popen, PIPE
    pcompile = Popen(command,
                     shell=True,
                     executable="/bin/bash",
                     stdout=PIPE,
                     stderr=PIPE,
                     close_fds=True)
    waitpid(pcompile.pid, 0)

    if not quiet:
        output = [x.decode('utf8') for x in pcompile.stdout.readlines()]
        msg.std(''.join(output))
    #else: #We don't need to get these lines since we are purposefully redirecting them.
    error = [x.decode('utf8') for x in pcompile.stderr.readlines()]
    code = len(error)
    if code != 0:
        msg.err(''.join(error))

    pcompile.stdout.close()
    pcompile.stderr.close()
    #It turns out that the compiler still returns a code of zero, even if the compile
    #failed because the actual compiler didn't fail; it did its job properly. We need to
    #check for the existence of errors in the 'compile.log' file.
    lcount = 0
    errors = []
    log = path.join(
        folder, "compile.{}.log".format(
            identifier if identifier is not None else "default"))
    with open(log) as f:
        for line in f:
            lcount += 1
            if lcount > 21 and lcount < 32:
                errors.append(line)
            elif lcount > 21:
                break

    if len(errors) > 0:
        #There are 21 lines in the compile.log file when everything runs correctly
        #Overwrite code with a bad exit value since we have some other problems.
        code = 1
        #We want to write the first couple of errors to the console and give them the
        #option to still execute if the compile only generated warnings.
        msg.warn("compile generated some errors or warnings:")
        msg.blank()
        msg.info(''.join(errors))

    if vupdates is not None:
        for modname in vupdates:
            _vupdate_compiled_module(compiler, modname, folder, rename=False)

    return (code, len(errors) == 0)