10
0
mirror of https://gitlab.com/scemama/irpf90.git synced 2024-06-02 11:25:19 +02:00

Fix memory debug and tab

This commit is contained in:
Thomas Applencourt 2017-03-17 11:20:18 -05:00
parent a4a6d7ceaa
commit 3c89b53828
27 changed files with 1369 additions and 1523 deletions

View File

@ -36,6 +36,7 @@ irp_id = irpf90_t.irp_id
cwd = os.getcwd()
def dress(f, in_root=False):
#(str,bool) -> str
""" Transfoms the filename into $PWD/IRPF90_temp/f
@ -65,9 +66,7 @@ def create_build_touches(l_irp_m, ninja):
result_ninja = '\n'.join([
"build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_modules_irp}",
" short_in = {short_target_F90}",
" short_out = {short_target_o}",
""
" short_in = {short_target_F90}", " short_out = {short_target_o}", ""
])
result_make = '\n'.join([
@ -96,15 +95,12 @@ def create_build_archive(l_irp_o, l_usr_o_wo_main, l_ext_o, l_irp_sup_o, ninja=T
list_of_object = ' '.join(l_irp_o + l_usr_o_wo_main + l_ext_o + l_irp_sup_o)
result_ninja = '\n'.join([
"build {lib}: archive_{irp_id} {list_of_object}",
" short_out = {short_lib}",
""])
result_ninja = '\n'.join(
["build {lib}: archive_{irp_id} {list_of_object}", " short_out = {short_lib}", ""])
result_make = '\n'.join([
"{lib}: {list_of_object}",
'\t@printf "Archive: {short_lib}\\n"',
"\t@$(AR) cr $@ $^", ""])
"{lib}: {list_of_object}", '\t@printf "Archive: {short_lib}\\n"', "\t@$(AR) cr $@ $^", ""
])
result = result_ninja if ninja else result_make
return result.format(**locals())
@ -125,7 +121,8 @@ def create_build_link(t, l_irp_m, l_usr_m, l_ext_m, ninja=True):
basename = os.path.basename(filename)
if basename != progname:
from util import logger
logger.info('program-name `{0}` != file-name `{1}` (using file-name for now...)'.format(progname,basename))
logger.info('program-name `{0}` != file-name `{1}` (using file-name for now...)'.format(
progname, basename))
target = dress(filename, in_root=True)
short_target = filename
@ -138,14 +135,13 @@ def create_build_link(t, l_irp_m, l_usr_m, l_ext_m, ninja=True):
result_ninja = '\n'.join([
"build {target}: link_{irp_id} {target_o} {irp_lib} | {list_of_module}",
" short_out = {short_target}",
""])
" short_out = {short_target}", ""
])
result_make = '\n'.join([
"{target}:{target_o} {irp_lib} | {list_of_module}",
'\t@printf "Link: {short_target}\\n"',
"\t@$(FC) $^ $(LIB) -o $@",
""])
"{target}:{target_o} {irp_lib} | {list_of_module}", '\t@printf "Link: {short_target}\\n"',
"\t@$(FC) $^ $(LIB) -o $@", ""
])
result = result_ninja if ninja else result_make
@ -220,24 +216,20 @@ def create_build_compile(t, l_module, l_ext_modfile=[], ninja=True):
l_build = [
"build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}",
" short_in = {short_target_F90}",
" short_out = {short_target}",
""
" short_in = {short_target_F90}", " short_out = {short_target}", ""
]
l_build_make = [
"{target_o}: {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}",
'\t@printf "F: {short_target_F90} -> {short_target}\\n"',
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", ""
'\t@printf "F: {short_target_F90} -> {short_target}\\n"', "\t@$(FC) $(FCFLAGS) -c $^ -o $@",
""
]
# No need of module when compiling the irp_module.
if t.has_irp_module:
l_build += [
"build {target_module_o}: compile_fortran_{irp_id} {target_module_F90} | {list_of_includes} {list_of_modules} ",
" short_in = {short_target_module_F90}",
" short_out = {short_target_module_o}",
""
" short_in = {short_target_module_F90}", " short_out = {short_target_module_o}", ""
]
l_build_make += [
@ -272,9 +264,9 @@ def create_build_remaining(f,ninja):
if extension.lower() in ['f', 'f90']:
result = ["build {target_o}: compile_fortran_{irp_id} {target_i}"]
result_make = [
'{target_o}: {target_i}',
'\t@printf "F: {short_target_o} -> {short_target_i}\\n"',
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", ""]
'{target_o}: {target_i}', '\t@printf "F: {short_target_o} -> {short_target_i}\\n"',
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", ""
]
elif extension.lower() in ['c']:
result = ["build {target_o}: compile_c_{irp_id} {target_i}"]
@ -290,78 +282,51 @@ def create_build_remaining(f,ninja):
def create_makefile(d_flags, d_var, irpf90_flags, ninja=True):
result = ["IRPF90= irpf90",
"IRPF90FLAGS= %s" % irpf90_flags,
"BUILD_SYSTEM= %s" % ('ninja' if ninja else 'make'),
""]
result = [
"IRPF90= irpf90", "IRPF90FLAGS= %s" % irpf90_flags,
"BUILD_SYSTEM= %s" % ('ninja' if ninja else 'make'), ""
]
# Export all the env variable used by irpf90
result += ['.EXPORT_ALL_VARIABLES:',
'',
'\n'.join("{0} = {1}".format(k, v) for k, v in sorted(d_flags.iteritems())),
'',
'\n'.join("{0} = {1}".format(k, ' '.join(v)) for k, v in sorted(d_var.iteritems())),
'']
result += [
'.EXPORT_ALL_VARIABLES:', '', '\n'.join("{0} = {1}".format(k, v)
for k, v in sorted(d_flags.iteritems())), '',
'\n'.join("{0} = {1}".format(k, ' '.join(v)) for k, v in sorted(d_var.iteritems())), ''
]
result += [ r'# Dark magic below modify with caution!',
r'# "You are Not Expected to Understand This"',
r"# .",
r"# /^\ .",
r'# /\ "V",',
r"# /__\ I O o",
r"# //..\\ I .",
r"# \].`[/ I",
r"# /l\/j\ (] . O",
r"# /. ~~ ,\/I .",
r"# \\L__j^\/I o",
r"# \/--v} I o .",
r"# | | I _________",
r"# | | I c(` ')o",
r"# | l I \. ,/",
r"# _/j L l\_! _//^---^\\_",
r""]
result += [
r'# Dark magic below modify with caution!', r'# "You are Not Expected to Understand This"',
r"# .", r"# /^\ .", r'# /\ "V",',
r"# /__\ I O o", r"# //..\\ I .", r"# \].`[/ I",
r"# /l\/j\ (] . O", r"# /. ~~ ,\/I .", r"# \\L__j^\/I o",
r"# \/--v} I o .", r"# | | I _________", r"# | | I c(` ')o",
r"# | l I \. ,/", r"# _/j L l\_! _//^---^\\_", r""
]
result += ["",
"ifeq ($(BUILD_SYSTEM),ninja)",
"\tBUILD_FILE=IRPF90_temp/build.ninja",
"\tIRPF90FLAGS += -j",
"else ifeq ($(BUILD_SYSTEM),make)",
"\tBUILD_FILE=IRPF90_temp/build.make",
"\tBUILD_SYSTEM += -j",
"else",
"DUMMY:",
"\t$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')",
"endif"]
result += [
"", "ifeq ($(BUILD_SYSTEM),ninja)", "\tBUILD_FILE=IRPF90_temp/build.ninja",
"\tIRPF90FLAGS += -j", "else ifeq ($(BUILD_SYSTEM),make)",
"\tBUILD_FILE=IRPF90_temp/build.make", "\tBUILD_SYSTEM += -j", "else", "DUMMY:",
"\t$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')", "endif"
]
result += ["",
"define run_and_touch",
result += [
"", "define run_and_touch",
" $(BUILD_SYSTEM) -C $(dir $(1) ) -f $(notdir $(1) ) $(addprefix $(CURDIR)/, $(2)) && touch $(2)",
"endef",
"",
"EXE := $(shell egrep -ri '^\s*program' *.irp.f | cut -d'.' -f1)",
"",
".PHONY: all",
"",
"all: $(BUILD_FILE)",
"\t$(call run_and_touch, $<, $(EXE))",
"",
".NOTPARALLEL: $(EXE)",
"$(EXE): $(BUILD_FILE)",
"\t$(call run_and_touch, $<, $(EXE))",
"endef", "", "EXE := $(shell egrep -ri '^\s*program' *.irp.f | cut -d'.' -f1)", "",
".PHONY: all", "", "all: $(BUILD_FILE)", "\t$(call run_and_touch, $<, $(EXE))", "",
".NOTPARALLEL: $(EXE)", "$(EXE): $(BUILD_FILE)", "\t$(call run_and_touch, $<, $(EXE))",
"$(BUILD_FILE): $(shell find . -maxdepth 2 -path ./IRPF90_temp -prune -o -name '*.irp.f' -print)",
"\t$(IRPF90) $(IRPF90FLAGS)",
"",
"clean:",
'\trm -f -- $(BUILD_FILE) $(EXE)'
"\t$(IRPF90) $(IRPF90FLAGS)", "", "clean:", '\trm -f -- $(BUILD_FILE) $(EXE)'
'\t$(shell find IRPF90_temp -type f \\( -name "*.o" -o -name "*.mod" -name "*.a" \\) -delete;)',
"veryclean: clean",
"\trm -rf IRPF90_temp/ IRPF90_man/ irpf90_entities dist tags"]
"veryclean: clean", "\trm -rf IRPF90_temp/ IRPF90_man/ irpf90_entities dist tags"
]
import util
data = '%s\n' % '\n'.join(result)
util.lazy_write_file('Makefile', data, conservative=True)
def create_make_all_clean(l_main):
#
'''Create the ALL and CLEAN target of Makefile
@ -373,16 +338,15 @@ def create_make_all_clean(l_main):
l_executable = ' '.join(dress(t.filename, in_root=True) for t in l_main)
output = [".PHONY : all",
"all: {l_executable}",
"",
".PHONY: clean",
"clean:",
output = [
".PHONY : all", "all: {l_executable}", "", ".PHONY: clean", "clean:",
'\tfind . -type f \( -name "*.o" -o -name "*.mod" \) -delete; rm -f {l_executable} --'
""]
""
]
return ['\n'.join(output).format(**locals())]
def create_var_and_rule(d_flags, ninja):
output = ['\n'.join("{0} = {1}".format(k, v) for k, v in d_flags.iteritems())]
@ -392,33 +356,21 @@ def create_var_and_rule(d_flags, ninja):
# Rules
t = [
"rule compile_fortran_{irp_id}",
" command = $FC $FCFLAGS -c $in -o $out",
" description = F : $short_in -> $short_out",
"",
"rule compile_c_{irp_id}",
"rule compile_fortran_{irp_id}", " command = $FC $FCFLAGS -c $in -o $out",
" description = F : $short_in -> $short_out", "", "rule compile_c_{irp_id}",
" command = $CC $CFLAGS -c $in -o $out",
" description = C : $short_in -> $short_out",
"",
"rule compile_cxx_{irp_id}",
" description = C : $short_in -> $short_out", "", "rule compile_cxx_{irp_id}",
" command = $CXX $CXXFLAGS -c $in -o $out",
" description = C++ : $short_in -> $short_out",
"",
"rule archive_{irp_id}",
" command = $AR cr $out $in",
" description = Archive: $short_out",
"",
"rule link_{irp_id}",
" command = $FC $FCFLAGS $in $LIB -o $out",
" description = Link: $short_out",
""
" description = C++ : $short_in -> $short_out", "", "rule archive_{irp_id}",
" command = $AR cr $out $in", " description = Archive: $short_out", "",
"rule link_{irp_id}", " command = $FC $FCFLAGS $in $LIB -o $out",
" description = Link: $short_out", ""
]
output += ['\n'.join(t).format(irp_id=irpf90_t.irp_id, **d_flags)]
return output
# Environment variables
d_default = {
@ -430,7 +382,8 @@ d_default = {
"CFLAGS": "-O2",
"CXX": "g++",
"CXXFLAGS": "-O2",
"LIB": ""}
"LIB": ""
}
d_flags = dict()
for k, v in d_default.iteritems():
@ -446,6 +399,7 @@ for k in ['SRC', 'OBJ']:
def create_generalmakefile(ninja):
create_makefile(d_flags, d_var, include_dir, ninja)
def run(d_module, ninja):
#(Dict[str,Module],bool) -> str
"""Wrote the ninja file needed to compile the program
@ -485,7 +439,7 @@ def run(d_module, ninja):
l_irp_sup_o = ["irp_touches.irp.o"]
l_irp_sup_s = ["irp_touches.irp.F90"]
if command_line.do_assert:
if command_line.do_debug or command_line.do_assert:
l_irp_sup_o += ["irp_stack.irp.o"]
l_irp_sup_s += ["irp_stack.irp.F90"]

View File

@ -27,6 +27,7 @@
from command_line import command_line
import irpf90_t
def run():
template = """
program codelet_%(name)s
@ -66,4 +67,3 @@ end
from util import lazy_write_file
lazy_write_file(filename, template % locals())

View File

@ -33,31 +33,56 @@ import re
description = "IRPF90 Fortran preprocessor."
options = {}
options['a'] = ['assert', 'Activates ASSERT statements. If absent, remove ASSERT statements.', 0]
options['c'] = [ 'codelet' , 'entity:NMAX or entity:precondition:NMAX : Generate a codelet to profile a provider running NMAX times', 1 ]
options['c'] = [
'codelet',
'entity:NMAX or entity:precondition:NMAX : Generate a codelet to profile a provider running NMAX times',
1
]
options['C'] = ['coarray', 'All providers are coarrays', 0]
options['d'] = [ 'debug' , 'Activates debug. The name of the current subroutine/function/provider will be printed on the standard output when entering or exiting a routine, as well as the CPU time passed inside the routine.', 0 ]
options['d'] = [
'debug',
'Activates debug. The name of the current subroutine/function/provider will be printed on the standard output when entering or exiting a routine, as well as the CPU time passed inside the routine.',
0
]
options['D'] = ['define', 'Defines a variable identified by the IRP_IF statements.', 1]
options['g'] = ['profile', 'Activates profiling of the code.', 0]
options['h'] = ['help', 'Print this help', 0]
options['I'] = ['include', 'Include directory', 1]
options['j'] = ['ninja', 'Use Ninja instead of make', 0]
options['i'] = [ 'init' , 'Initialize current directory. Creates a default Makefile and the temporary working directories.', 0 ]
options['l'] = [ 'align' , 'Align arrays using compiler directives and sets the $IRP_ALIGN variable. For example, --align=32 aligns all arrays on a 32 byte boundary.', 1 ]
options['i'] = [
'init',
'Initialize current directory. Creates a default Makefile and the temporary working directories.',
0
]
options['l'] = [
'align',
'Align arrays using compiler directives and sets the $IRP_ALIGN variable. For example, --align=32 aligns all arrays on a 32 byte boundary.',
1
]
options['m'] = ['memory', 'Print memory allocations/deallocations.', 0]
options['n'] = ['inline', '<all|providers|builders> : Force inlining of providers or builders', 1]
options['o'] = ['checkopt', 'Shows where optimization may be required', 0]
options['p'] = [ 'preprocess' , 'Prints a preprocessed file to standard output. Useful for debugging files containing shell scripts.', 1 ]
options['p'] = [
'preprocess',
'Prints a preprocessed file to standard output. Useful for debugging files containing shell scripts.',
1
]
options['r'] = ['no_directives', 'Ignore all compiler directives !DEC$ and !DIR$', 0]
options['s'] = [ 'substitute' , 'Substitute values in do loops for generating specific optimized code.', 1 ]
options['t'] = [ 'touch' , 'Display which entities are touched when touching the variable given as an argument.', 1 ]
options['s'] = [
'substitute', 'Substitute values in do loops for generating specific optimized code.', 1
]
options['t'] = [
'touch', 'Display which entities are touched when touching the variable given as an argument.',
1
]
options['v'] = ['version', 'Prints version of irpf90', 0]
options['w'] = ['warnings', 'Activate Warnings', 0]
options['z'] = ['openmp', 'Activate for OpenMP code', 0]
options['G'] = ['graph', 'Print the dependecy-graph of the entities (dots format)', 0]
options['T'] = ['Task', 'Auto-parallelism ', 0]
class CommandLine(object):
class CommandLine(object):
def __init__(self):
global options
self._opts = None
@ -186,6 +211,7 @@ Options:
sys.exit(2)
return self._opts
opts = property(fget=opts)
t = """
@ -205,7 +231,8 @@ do_$LONG = property(fget=do_$LONG)
@irpy.lazy_property
def do_run(self):
return not(any( (self.do_version, self.do_help, self.do_preprocess, self.do_touch, self.do_init)))
return not (any(
(self.do_version, self.do_help, self.do_preprocess, self.do_touch, self.do_init)))
# @irpy.lazy_property
# def do_Task(self):
@ -213,17 +240,20 @@ do_$LONG = property(fget=do_$LONG)
command_line = CommandLine()
def print_options():
keys = options.keys()
keys.sort()
import subprocess
for k in keys:
description = options[k][1]
p1 = subprocess.Popen(["fold", "-s", "-w", "40"],stdout=subprocess.PIPE,stdin=subprocess.PIPE)
p1 = subprocess.Popen(
["fold", "-s", "-w", "40"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
description = p1.communicate(description)[0]
description = description.replace('\n', '\n'.ljust(27))
print("-%s, --%s" % (k, options[k][0])).ljust(25), description + '\n'
print "\n"
if __name__ == '__main__':
print_options()

View File

@ -30,6 +30,7 @@ from irpf90_t import mandir
from util import parmap, build_dim, lazy_write_file
import os
def do_print_short(entity):
assert type(entity) == Entity
str_ = "{0:<35} : {1:<30} :: {2:<25} {3}".format(entity.prototype.filename[0],
@ -107,7 +108,6 @@ def do_print(entity, d_entity):
lazy_write_file("%s%s.l" % (mandir, name), '%s\n' % str_)
######################################################################
def do_print_subroutines(sub):
assert type(sub) == Routine
@ -164,8 +164,8 @@ def run(d_entity, d_routine):
l_subs = d_routine.values()
l_data_to_write = [("%s.l" % os.path.join(mandir, s.name), do_print_subroutines(s)) for s in l_subs]
l_data_to_write = [("%s.l" % os.path.join(mandir, s.name), do_print_subroutines(s))
for s in l_subs]
def worker(l):
filename, text = l

View File

@ -1,41 +0,0 @@
#!/usr/bin/env python
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
# the Implicit Reference to Parameters (IRP) method.
# Copyright (C) 2009 Anthony SCEMAMA
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Anthony Scemama
# LCPQ - IRSAMC - CNRS
# Universite Paul Sabatier
# 118, route de Narbonne
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import os
to_remove = """__init__.py cython_setup.py version.py command_line.py""".split()
ext_modules = []
for f in os.listdir('.') if f.emswith(".py") and not f in to_remove:
module = f.split('.')[0]
ext_modules.append(Extension(module,list(f)))
setup(name = 'IRPF90 extensions',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules)

View File

@ -30,6 +30,7 @@ from command_line import command_line
import sys
from lib.manager import irpy
class Entity(object):
'''All lines between BEGIN_PROVIDER and END_PROVIDER included
@ -168,13 +169,18 @@ class Entity(object):
from util import ashes_env
name = self.name
d_template= {'name':name,
d_template = {
'name': name,
'fmodule': self.fmodule,
'same_as': self.same_as,
'do_debug': command_line.do_debug,
'children': mangled(self.needs, self.d_entity),
'group_entity': [{'name':n,'dim':build_dim(self.cm_d_variable[n].dim,colons=True)} for n in self.l_name]}
'group_entity': [{
'name': n,
'dim': build_dim(
self.cm_d_variable[n].dim, colons=True)
} for n in self.l_name]
}
return ashes_env('io.f90', d_template).split('\n')
@ -303,8 +309,10 @@ class Entity(object):
'name': self.name,
'type': self.type,
'main': self.is_main,
'dim': build_dim(self.dim,colons=True),
'protected': '\n'.join(self.allocater+self.builder) if self.is_protected else False}
'dim': build_dim(
self.dim, colons=True),
'protected': '\n'.join(self.allocater + self.builder) if self.is_protected else False
}
return d_template
############################################################
@ -340,8 +348,11 @@ class Entity(object):
return {
'name': self.name,
'l_module': [n for n in build_use(self.parents + [self.name], self.d_entity,use=False)],
'l_ancestor': [n for n in mangled(self.parents, self.d_entity)]}
'l_module':
[n for n in build_use(
self.parents + [self.name], self.d_entity, use=False)],
'l_ancestor': [n for n in mangled(self.parents, self.d_entity)]
}
##########################################################
@ -379,6 +390,8 @@ class Entity(object):
l_module = [x for x in build_use([self.name] + self.to_provide, self.d_entity, use=False)]
l_children = [x for x in mangled(self.to_provide, self.d_entity)]
l_entity = [self.d_entity[n] for n in self.l_name]
l = ashes_env.render('provider.f90', {
'name': name,
'l_module': l_module,
@ -388,14 +401,15 @@ class Entity(object):
'do_task': command_line.do_Task,
'do_corray': command_line.do_coarray,
'dim': ','.join(self.dim),
'l_entity': [{
'name': i.name,
'dim': ','.join(i.dim)
} for i in l_entity]
})
return [i for i in l.split('\n') if i.strip()]
@irpy.lazy_property
def allocater(self):
if not self.is_main:
return []
from util import mangled
import util
@ -404,22 +418,21 @@ class Entity(object):
if self.is_protected:
l_module.remove(self.fmodule)
l_dim = [{'name': name, 'rank': i + 1, 'value': dimsize(k)} for i, k in enumerate(self.dim)]
l = ashes_env.render('allocater.f90', {
'name': name,
'l_module': l_module,
'do_debug': command_line.do_debug,
'do_corray': command_line.do_coarray,
'do_memory': command_line.do_memory,
'dim': ','.join(self.dim),
'l_dim': l_dim
})
return [i for i in l.split('\n') if i.strip()]
##########################################################
@irpy.lazy_property
def builder(self):
if not self.is_main:
@ -458,7 +471,6 @@ class Entity(object):
text += map(lambda x: ([], Simple_line(line.i, x, line.filename)),
build_call_provide(vars, self.d_entity))
# ~#~#~#~#~#
# Create the subroutine.
# ~#~#~#~#~#

View File

@ -1,260 +0,0 @@
#!/usr/bin/env python
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
# the Implicit Reference to Parameters (IRP) method.
# Copyright (C) 2009 Anthony SCEMAMA
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Anthony Scemama
# LCPQ - IRSAMC - CNRS
# Universite Paul Sabatier
# 118, route de Narbonne
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
import util
from command_line import command_line
do_assert = command_line.do_assert
do_debug = command_line.do_debug
do_openmp = command_line.do_openmp
do_memory = command_line.do_memory
import irpf90_t
FILENAME = irpf90_t.irpdir+"irp_stack.irp.F90"
def create():
txt = """
module irp_stack_mod
integer, parameter :: STACKMAX=1000
character*(128),allocatable :: irp_stack(:,:)
double precision,allocatable :: irp_cpu(:,:)
integer,allocatable :: stack_index(:)
logical :: alloc = .False.
integer :: nthread
character*(128) :: white = ''
end module
subroutine irp_enter(irp_where)
use irp_stack_mod
integer :: ithread
character*(*) :: irp_where
"""
if not do_openmp:
txt += """
ithread = 0
"""
else:
txt += """
integer, external :: omp_get_thread_num
integer, external :: omp_get_num_threads
ithread = omp_get_thread_num()
"""
txt += "$1"
if do_memory:
txt+="""
if (.not.alloc) then
"""
if do_openmp:
txt += """
!$OMP PARALLEL
!$OMP SINGLE
nthread = omp_get_num_threads()
!$OMP END SINGLE
!$OMP END PARALLEL
"""
else:
txt += """
nthread = 1
"""
txt += """
print *, 'Allocating irp_stack(',STACKMAX,',',0:nthread,')'
print *, 'Allocating irp_cpu(',STACKMAX,',',0:nthread,')'
print *, 'Allocating stack_index(',0:nthread,')'
endif"""
txt +="""
$2
end subroutine
subroutine irp_enter_f(irp_where)
use irp_stack_mod
integer :: ithread
character*(*) :: irp_where
"""
if do_openmp:
txt += """
integer, external :: omp_get_thread_num
integer, external :: omp_get_num_threads
ithread = omp_get_thread_num()
"""
else:
txt += """
ithread = 0
"""
txt += """
$1
"""
if do_memory:
txt+="""
if (.not.alloc) then
"""
if do_openmp:
txt += """
!$OMP PARALLEL
!$OMP SINGLE
nthread = omp_get_num_threads()
!$OMP END SINGLE
!$OMP END PARALLEL
"""
else:
txt += """
nthread = 1
"""
txt +="""
print *, 'Allocating irp_stack(',STACKMAX,',',0:nthread,')'
print *, 'Allocating irp_cpu(',STACKMAX,',',0:nthread,')'
print *, 'Allocating stack_index(',0:nthread,')'
endif
"""
txt += """
$2
end subroutine
subroutine irp_leave (irp_where)
use irp_stack_mod
character*(*) :: irp_where
integer :: ithread
double precision :: cpu
"""
if do_openmp:
txt += """
integer, external :: omp_get_thread_num
ithread = omp_get_thread_num()
"""
else:
txt += """
ithread = 0
"""
txt += """
$3
$4
end subroutine
"""
# $1
if do_assert or do_debug:
s = """
if (.not.alloc) then
"""
if do_openmp:
s += """
!$OMP PARALLEL
!$OMP SINGLE
nthread = omp_get_num_threads()
!$OMP END SINGLE
!$OMP END PARALLEL
!$OMP CRITICAL
if (.not.alloc) then
allocate(irp_stack(0:STACKMAX,0:nthread))
allocate(irp_cpu(0:STACKMAX,0:nthread))
allocate(stack_index(0:nthread))
stack_index = 0
alloc = .True.
endif
!$OMP END CRITICAL
endif
stack_index(ithread) = min(stack_index(ithread)+1,STACKMAX)
irp_stack(stack_index(ithread),ithread) = irp_where"""
else:
s += """
nthread = 1
if (.not.alloc) then
allocate(irp_stack(0:STACKMAX,1))
allocate(irp_cpu(0:STACKMAX,1))
allocate(stack_index(2))
stack_index = 0
alloc = .True.
endif
endif
stack_index(1) = min(stack_index(1)+1,STACKMAX)
irp_stack(stack_index(1),1) = irp_where"""
if do_memory:
txt+="""
print *, 'Allocating irp_stack(',STACKMAX,','0:nthread,')'
print *, 'Allocating irp_cpu(',STACKMAX,','0:nthread,')'
print *, 'Allocating stack_index(',0:nthread,')'"""
else:
s = ""
txt = txt.replace("$1",s)
# $2
if do_debug:
txt = txt.replace("$2","""
print *, ithread, ':', white(1:stack_index(ithread))//'-> ', trim(irp_where)
call cpu_time(irp_cpu(stack_index(ithread),ithread))""")
else:
txt = txt.replace("$2","")
# $3
if do_debug:
txt = txt.replace("$3","""
call cpu_time(cpu)
print *, ithread, ':', white(1:stack_index(ithread))//'<- ', &
trim(irp_stack(stack_index(ithread),ithread)), &
cpu-irp_cpu(stack_index(ithread),ithread)""")
else:
txt = txt.replace("$3","")
# $4
if do_debug or do_assert:
txt = txt.replace("$4","""
stack_index(ithread) = max(0,stack_index(ithread)-1)""")
else:
txt = txt.replace("$4","")
txt += """
subroutine irp_trace
use irp_stack_mod
integer :: ithread
integer :: i
"""
if do_openmp:
txt += """
!$ integer, external :: omp_get_thread_num
!$ ithread = omp_get_thread_num()
"""
else:
txt += """
ithread = 0
"""
txt += """
if (.not.alloc) return
print *, 'Stack trace: ', ithread
print *, '-------------------------'
do i=1,stack_index(ithread)
print *, trim(irp_stack(i,ithread))
enddo
print *, '-------------------------'
end subroutine
"""
util.lazy_write_file(FILENAME,txt)

View File

@ -35,6 +35,7 @@ except:
from command_line import command_line
from irpy_files import Irpy_comm_world
def main():
vim.install()
@ -54,7 +55,6 @@ def main():
comm_world = Irpy_comm_world()
if command_line.do_graph:
# Create a dot reprenstion of the dependency graph.
# Merge inside a subgraph the Entity provided together
@ -67,8 +67,6 @@ def main():
print ' %s -> { %s } ' % (e.name, ' '.join(e.needs))
print '}'
def print_subgraph(l_tuple, name, color):
for i, s in enumerate(l_tuple):
print ' subgraph cluster_%s_%s {' % (name, i)
@ -107,7 +105,6 @@ def main():
l_node_uniq = (l_main_usr | l_main_head_dummy) - s_exculde_dummy
#~=~=~=~=
# Create All edge
#~=~=~=~=
@ -116,7 +113,6 @@ def main():
for e in l_node_uniq:
d_need[e.name] = set(e.needs)
#~=~=~=~=
# Create All edge
#~=~=~=~=
@ -147,7 +143,6 @@ def main():
print ' }'
return
if command_line.do_preprocess:
for filename, text in comm_world.preprocessed_text:
if filename in command_line.preprocessed:
@ -180,6 +175,9 @@ def main():
comm_world.create_touches()
comm_world.create_man()
if command_line.do_debug or command_line.do_assert:
comm_world.create_stack()
if command_line.do_profile:
import profile
profile.run(comm_world.d_entity)
@ -187,5 +185,6 @@ def main():
if command_line.do_openmp:
comm_world.create_lock()
if __name__ == '__main__':
main()

View File

@ -24,7 +24,6 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
import sys
import re
@ -32,84 +31,104 @@ LENMAX = 70
tabn = 2
tab = " " * tabn
class Grep(object):
re_begin_program = re.compile(r"^\s*program\s", flags=re.I)
def begin_program(self, string):
return re.match(self.re_begin_program, string) is not None
re_end_program = re.compile(r"\s*(end\s*!?$|end\s*program)", flags=re.I)
def end_program(self, string):
return re.match(self.re_end_program, string) is not None
re_begin_subroutine = re.compile(r"^\s*(recursive)?\s*subroutine\s", flags=re.I)
def begin_subroutine(self, string):
return re.match(self.re_begin_subroutine, string) is not None
re_end_subroutine = re.compile(r"\s*(end\s*!?$|end\s*subroutine)", flags=re.I)
def end_subroutine(self, string):
return re.match(self.re_end_subroutine, string) is not None
re_begin_function = re.compile(r"^.*function\s+.*\(", flags=re.I)
def begin_function(self, string):
return re.match(self.re_begin_function, string) is not None
re_end_function = re.compile(r"\s*(end\s*!?$|end\s*function)", flags=re.I)
def end_function(self, string):
return re.match(self.re_end_function, string) is not None
re_begin_provider = re.compile(r"^\s*&?begin_provider\s", flags=re.I)
def begin_provider(self, string):
return re.match(self.re_begin_provider, string) is not None
re_end_provider = re.compile(r"^\s*end_provider\s*(!.*)?$", flags=re.I)
def end_provider(self, string):
return re.match(self.re_end_provider, string) is not None
re_begin_do = re.compile(r"^\s*do\s+", flags=re.I)
def begin_do(self, string):
return re.match(self.re_begin_do, string) is not None
re_end_do = re.compile(r"^\s*end\s*do\s*(!.*)?$", flags=re.I)
def end_do(self, string):
return re.match(self.re_end_do, string) is not None
re_begin_if = re.compile(r"^\s*if(\(|\s+).*(&|then)\s*(!.*)?$", flags=re.I)
def begin_if(self, string):
return re.match(self.re_begin_if, string) is not None
re_else = re.compile(r"^\s*else", flags=re.I)
def xelse(self, string):
return re.match(self.re_else, string) is not None
re_end_if = re.compile(r"^\s*end\s*if\s*(!.*)?$", flags=re.I)
def end_if(self, string):
return re.match(self.re_end_if, string) is not None
re_begin_select = re.compile(r"^\s*select\s*case", flags=re.I)
def begin_select(self, string):
return re.match(self.re_begin_select, string) is not None
re_case = re.compile(r"^\s*case\s*\(", flags=re.I)
def case(self, string):
return re.match(self.re_case, string) is not None
re_end_select = re.compile(r"^\s*end\s*select\s*(!.*)?$", flags=re.I)
def end_select(self, string):
return re.match(self.re_end_select, string) is not None
re_continuation = re.compile(r"^\s*\S+.*&")
def continuation(self, string):
return re.match(self.re_continuation, string) is not None
re_declaration = re.compile(r"^.*::.*$")
def declaration(self, string):
return re.match(self.re_declaration, string) is not None
grep = Grep()
class indent(object):
class indent(object):
def __init__(self):
"""Run the program"""
self.run()
@ -135,6 +154,7 @@ class indent(object):
except:
self._filename = None
return self._filename
filename = property(fget=get_filename)
def get_text(self):
@ -147,6 +167,7 @@ class indent(object):
else:
self._text = sys.stdin.read().splitlines()
return self._text
text = property(fget=get_text)
def indentlevel(self, line):
@ -269,4 +290,3 @@ def main():
if __name__ == '__main__':
main()

View File

@ -24,7 +24,6 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
irpdir = "IRPF90_temp/"
mandir = "IRPF90_man/"
@ -35,6 +34,7 @@ irp_id = abs(crc32(os.getcwd()))
from lib.manager import irpy
from util import logger
class Line(object):
def __init__(self, i, text, filename):
self.i = i
@ -48,8 +48,8 @@ class Line(object):
def __repr__(self):
return "%20s:%5d : %s (%s)" % (type(self).__name__, self.i, self.text, self.filename)
class LineWithName(Line):
class LineWithName(Line):
@irpy.lazy_property
def subname(self):
buf = self.lower
@ -65,19 +65,19 @@ class LineWithName(Line):
sys.exit(1)
return l_name.pop()
l_type = [
'Empty_line', 'Simple_line', "Declaration", "Continue", "Begin_provider",
"Cont_provider", "End_provider", "Begin_doc", "Doc", "End_doc",
"Begin_shell", "End_shell", "Begin_template", "End_template", "Subst",
"Assert", "Touch", "SoftTouch", "Irp_read", "Irp_write", "Irp_If",
"Irp_Else", "Irp_Endif", "Openmp", "Directive", "Use", "Do", "Enddo", "If",
"Elseif", "Else", "Endif", "Select", "Case", "End_select", "Provide", "NoDep", "Return", "Include",
"Implicit", "Free", "End", "Provide_all","Contains",'Type','End_module','Interface','End_interface',
'Where','Elsewhere','Endwhere']
'Empty_line', 'Simple_line', "Declaration", "Continue", "Begin_provider", "Cont_provider",
"End_provider", "Begin_doc", "Doc", "End_doc", "Begin_shell", "End_shell", "Begin_template",
"End_template", "Subst", "Assert", "Touch", "SoftTouch", "Irp_read", "Irp_write", "Irp_If",
"Irp_Else", "Irp_Endif", "Openmp", "Directive", "Use", "Do", "Enddo", "If", "Elseif", "Else",
"Endif", "Select", "Case", "End_select", "Provide", "NoDep", "Return", "Include", "Implicit",
"Free", "End", "Provide_all", "Contains", 'Type', 'End_module', 'Interface', 'End_interface',
'Where', 'Elsewhere', 'Endwhere'
]
for t in l_type:
globals()[t] = type(t, (Line, ), {})
for t in ['Subroutine', 'Function', 'Program', 'Call', 'Module']:
globals()[t] = type(t, (LineWithName, ), {})

View File

@ -24,7 +24,6 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
import os
import sys

View File

@ -10,6 +10,7 @@ import sys
from command_line import command_line
class Irpy_comm_world(object):
'''Maestro.'''
@ -114,8 +115,8 @@ class Irpy_comm_world(object):
l_duplicate = [x for x in l_ent if l_ent.count(x) > 1]
if l_duplicate:
from util import logger
logger.error('You have duplicate PROVIDER: %s' % ' '.join(
[e.name for e in l_duplicate]))
logger.error('You have duplicate PROVIDER: %s' %
' '.join([e.name for e in l_duplicate]))
import sys
sys.exit(1)
@ -290,8 +291,16 @@ class Irpy_comm_world(object):
lazy_write_file(filename, '%s\n' % text)
def create_stack(self):
import irp_stack
irp_stack.create()
from util import lazy_write_file
from util import ashes_env
str_ = ashes_env.render('irp_stack.F90', {
'do_debug': command_line.do_debug,
'do_openmp': command_line.do_openmp,
'do_memory': command_line.do_memory
})
filename = os.path.join(irpf90_t.irpdir, 'irp_stack.irp.F90')
lazy_write_file(filename, str_)
def create_buildfile(self, ninja):
import build_file

View File

@ -30,6 +30,7 @@ import preprocessed_text
from util import *
from entity import Entity
def put_info(text, filename):
lenmax = 80 - len(filename)
@ -43,14 +44,13 @@ def put_info(text, filename):
class Fmodule(object):
header = [ "! -*- F90 -*-",
"!",
"!-----------------------------------------------!",
header = [
"! -*- F90 -*-", "!", "!-----------------------------------------------!",
"! This file was generated with the irpf90 tool. !",
"! !",
"! DO NOT MODIFY IT BY HAND !",
"!-----------------------------------------------!",
""]
"!-----------------------------------------------!", ""
]
def __init__(self, text, filename, d_variable):
self.text = put_info(text, filename)
@ -77,11 +77,14 @@ class Fmodule(object):
if self.use or self.dec or self.l_entity:
d_template = {'name' : self.name,
'use':list(self.use),'usr_declaration':list(self.dec),
d_template = {
'name': self.name,
'use': list(self.use),
'usr_declaration': list(self.dec),
'irp_declaration': [e.d_header for e in self.l_entity],
'coarray': command_line.coarray,
'align': False if command_line.align == 1 else command_line.align}
'align': False if command_line.align == 1 else command_line.align
}
return [i for i in ashes_env.render('module.f90', d_template).split('\n') if i]
else:
return []
@ -116,7 +119,6 @@ class Fmodule(object):
@irpy.lazy_property
def residual_text_use_dec(self):
def remove_providers(text):
result = []
inside = False
@ -143,12 +145,12 @@ class Fmodule(object):
result.append((vars, line))
continue
if type(line) in [Subroutine, Function, Program]:
#Deep copy...
variable_list = list(vars)
elif type(line) == End:
result += [([], Use(line.i, x, line.filename)) for x in build_use(variable_list, self.d_all_variable)]
result += [([], Use(line.i, x, line.filename))
for x in build_use(variable_list, self.d_all_variable)]
else:
variable_list += vars
@ -178,7 +180,6 @@ class Fmodule(object):
elif type(line) == Declaration:
dec.append((vars, line))
if isinstance(line, (End, End_interface, End_module)):
inside += -1
@ -192,7 +193,8 @@ class Fmodule(object):
result = modify_functions(result)
from collections import namedtuple
Residual_text_use_dec = namedtuple('Residual_text_use_dec', ['use', 'module', 'dec', 'result'])
Residual_text_use_dec = namedtuple('Residual_text_use_dec',
['use', 'module', 'dec', 'result'])
return Residual_text_use_dec(*extract_use_dec_text(result))
@ -241,7 +243,6 @@ class Fmodule(object):
result += map(lambda x: ([], Simple_line(line.i, x, line.filename)),
build_call_provide(vars, self.d_all_variable))
from parsed_text import move_to_top_list, move_interface
move_to_top_list(result, [Declaration, Implicit, Use])
move_interface(result)
@ -250,14 +251,16 @@ class Fmodule(object):
@irpy.lazy_property
def needed_modules(self):
l = set(x.split(',only').pop(0).split()[1] for x in self.generated_text + self.head + self.residual_text if x.lstrip().startswith("use "))
l = set(
x.split(',only').pop(0).split()[1]
for x in self.generated_text + self.head + self.residual_text
if x.lstrip().startswith("use "))
if self.name in l:
l.remove(self.name)
return l
@irpy.lazy_property
def needed_modules_irp(self):
return [i for i in self.needed_modules if i.endswith("_mod")]
@ -265,5 +268,3 @@ class Fmodule(object):
@irpy.lazy_property
def needed_modules_usr(self):
return [i for i in self.needed_modules if not i.endswith("_mod")]

View File

@ -71,6 +71,7 @@ def check_touch(variables, line, vars, main_vars):
import sys
sys.exit(1)
from collections import namedtuple
Parsed_text = namedtuple('Parsed_text', ['varlist', 'line'])
@ -157,8 +158,9 @@ def get_parsed_text(filename, text, variables, subroutines, vtuple):
def fun(x):
if x not in variables:
error.fail(line, "Variable %s unknown" % (x, ))
return Parsed_text(
[], Simple_line(line.i, " %s_is_built = .True." % (x, ), line.filename))
return Parsed_text([],
Simple_line(line.i, " %s_is_built = .True." %
(x, ), line.filename))
result += map(fun, main_vars[:-1])
if type(line) == SoftTouch:
@ -206,6 +208,7 @@ def get_parsed_text(filename, text, variables, subroutines, vtuple):
return (filename, result)
######################################################################
def move_to_top_list(text, it):
# ( List[ List[Entity], Line], Iterator)
@ -291,7 +294,8 @@ def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Funct
# Get the begin of the insert
i_insert = []
for begin in i_begin:
i_insert.append(next(i+1 for i in range(begin,-1,-1) if isinstance(parsed_text[i][1], s_type)))
i_insert.append(
next(i + 1 for i in range(begin, -1, -1) if isinstance(parsed_text[i][1], s_type)))
# Do the insert and the delete in one passe
for insert, begin, end in zip(i_insert, i_begin, i_end):
@ -300,6 +304,7 @@ def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Funct
padding = end - begin
parsed_text[begin + padding:end + padding] = []
######################################################################
def build_sub_needs(parsed_text, d_subroutine):
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]], Dict[str:Sub]) -> None
@ -311,10 +316,14 @@ def build_sub_needs(parsed_text, d_subroutine):
l_buffer = []
for _, text in parsed_text:
l_begin = [ i for i, (_, line) in enumerate(text) if isinstance(line, (Subroutine, Function, Program))]
l_begin = [
i for i, (_, line) in enumerate(text)
if isinstance(line, (Subroutine, Function, Program))
]
l_end = [i for i, (_, line) in enumerate(text) if isinstance(line, End)]
l_buffer += [(d_subroutine[text[b].line.subname], text[b + 1:e]) for b, e in zip(l_begin, l_end) if not isinstance(text[b].line, Program)]
l_buffer += [(d_subroutine[text[b].line.subname], text[b + 1:e])
for b, e in zip(l_begin, l_end) if not isinstance(text[b].line, Program)]
for sub, text in l_buffer:
sub.needs = set(v for vs, _ in text for v in vs)
@ -347,7 +356,6 @@ def raise_entity(text):
skip_interface = False
lvl = 0
for i, (e, line) in enumerate(text):
type_ = type(line)
@ -383,6 +391,7 @@ def raise_entity(text):
assert (lvl == 0)
def move_variables(parsed_text):
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]]
'''Move variables into the top of the declaraiton.
@ -390,7 +399,6 @@ def move_variables(parsed_text):
This need to be optimised to handle the fact that we can have multi-provider
'''
def func(filename, text):
result = []
append = result.append
@ -554,7 +562,6 @@ def build_needs(parsed_text, subroutines, stuple, variables):
entity.needs = uniquify(l_needs)
# Now do the Other entity
for v in variables:
main = variables[v].same_as
@ -612,4 +619,3 @@ def perform_loop_substitutions(parsed_text):
append((vars, line))
main_result.append((filename, result))
return main_result

View File

@ -102,6 +102,7 @@ simple_dict = {
"endwhere": Endwhere,
}
def get_canonized_text(text_lower):
text_canonized = text_lower
@ -150,13 +151,11 @@ def get_type(i, filename, line, line_lower, line_lower_canonized, is_doc):
type_ = simple_dict[firstword]
return [type_(i, line, filename)], is_doc
#label do-loop (outer: do i=1,sze)
reg_do_lab = ur":\s+do\s+"
if re.search(reg_do_lab, line_lower):
return [Do(i, line, filename)], is_doc
lower_line = line_lower.strip()[1:]
if len(lower_line) <= 3:
@ -216,9 +215,14 @@ def save_and_execute(irpdir, scriptname, code, interpreter):
# Execute shell
import util
try:
text = util.check_output('PYTHONPATH=$PYTHONPATH:. %s %s' % (interpreter, irpdir_scriptname), shell=True, bufsize=-1, cwd=os.path.join(irpdir,'..'))
text = util.check_output(
'PYTHONPATH=$PYTHONPATH:. %s %s' % (interpreter, irpdir_scriptname),
shell=True,
bufsize=-1,
cwd=os.path.join(irpdir, '..'))
except:
util.logger.error("Something wrong append with embeded '%s' script: %s"% (interpreter, irpdir_scriptname))
util.logger.error("Something wrong append with embeded '%s' script: %s" %
(interpreter, irpdir_scriptname))
import sys
sys.exit(1)
@ -233,7 +237,6 @@ def execute_shell(text):
# (List[Line]) -> List[Line]
'''Execute the embedded shell scripts'''
l_begin = [i for i, line in enumerate(text) if isinstance(line, Begin_shell)]
l_end = [i for i, line in enumerate(text) if isinstance(line, End_shell)]
l_output = []
@ -243,6 +246,7 @@ def execute_shell(text):
# ~=~=~=~
from util import logger
import sys
def fail(l, a, b):
logger.error("%s In Begin_Shell, %s '%s'" % (l, a, b))
sys.exit(1)
@ -343,7 +347,11 @@ def execute_templates(text):
for v in variables:
script += " t0 = t0.replace('%s',d['%s'])\n" % (v, v)
script += " print t0\n"
result += save_and_execute(irpdir, scriptname="%s_template_%d" % (line.filename, line.i), code=script,interpreter="python")
result += save_and_execute(
irpdir,
scriptname="%s_template_%d" % (line.filename, line.i),
code=script,
interpreter="python")
else:
subst += line.text + '\n'
@ -435,7 +443,6 @@ def remove_comments(text, form):
return str_
if form == Free_form:
for line in text:
if type(line) in [Openmp, Doc, Directive]:
@ -547,7 +554,7 @@ def irp_simple_statements(text):
def process_return(line):
assert type(line) == Return
if command_line.do_assert or command_line.do_debug:
if command_line.do_debug:
newline = Simple_line(line.i, " call irp_leave(irp_here)", line.filename)
result = [newline, line]
else:
@ -603,7 +610,7 @@ def irp_simple_statements(text):
def process_end(line):
'''Add irp_leave if necessary'''
if command_line.do_assert or command_line.do_debug:
if command_line.do_debug:
i = line.i
f = line.filename
result = [Simple_line(i, " call irp_leave(irp_here)", f), line]
@ -618,7 +625,11 @@ def irp_simple_statements(text):
buffer = line.lower.translate(trans).split(',')
if len(buffer) < 2:
error.fail(line, "Error in Begin_provider statement")
import sys
print line
print "Error in Begin_provider statement"
sys.exit(1)
varname = buffer[1].strip()
length = len(varname)
i = line.i
@ -627,7 +638,7 @@ def irp_simple_statements(text):
Begin_provider(i, line.text, (f, varname)),
Declaration(i, " character*(%d) :: irp_here = '%s'" % (length, varname), f)
]
if command_line.do_assert or command_line.do_debug:
if command_line.do_debug:
result += [Simple_line(i, " call irp_enter(irp_here)", f), ]
return result
@ -647,10 +658,12 @@ def irp_simple_statements(text):
length = len(subname)
i = line.i
f = line.filename
result = [ line, Declaration(i, " character*(%d) :: irp_here = '%s'" % (length, subname), f)]
result = [
line, Declaration(i, " character*(%d) :: irp_here = '%s'" % (length, subname), f)
]
if command_line.do_assert or command_line.do_debug:
result += [Simple_line(i, " call irp_enter_f(irp_here)", f), ]
if command_line.do_debug:
result += [Simple_line(i, " call irp_enter_routine(irp_here)", f), ]
return result
def process_function(line):
@ -662,8 +675,8 @@ def irp_simple_statements(text):
result = [
line, Declaration(i, " character*(%d) :: irp_here = '%s'" % (length, subname), f)
]
if command_line.do_assert or command_line.do_debug:
result += [Simple_line(i, " call irp_enter_f(irp_here)", f), ]
if command_line.do_debug:
result += [Simple_line(i, " call irp_enter_routine(irp_here)", f), ]
return result
def process_program(line):
@ -680,6 +693,8 @@ def irp_simple_statements(text):
# Need to choose between lazy lock or are big full initialization
# if command_line.do_openmp:
# temp += [Simple_line(0, " call irp_init_locks_%s()" % (irp_id), line.filename)]
if command_line.do_debug or command_line.do_assert:
temp += [Simple_line(0, " CALL irp_stack_init", line.filename)]
temp += [Call(0, " call %s" % (program_name), line.filename)]
if command_line.do_profile:
@ -712,7 +727,6 @@ def irp_simple_statements(text):
Program: process_program,
}
result = []
for line in text:
buffer = [line]
@ -762,7 +776,8 @@ def process_old_style_do(text):
return
from util import logger
logger.error(text[begin], "(%s) Old-style do loops should end with 'continue' or 'end do'" % text[begin])
logger.error(text[begin], "(%s) Old-style do loops should end with 'continue' or 'end do'" %
text[begin])
from util import sys
sys.exit(1)
@ -847,13 +862,15 @@ def check_begin_end(raw_text):
Maybe more of one 'x' statement in defined cause in 'ifdef/else/endif' statement.
'''
d_block = {Enddo: [Do],
d_block = {
Enddo: [Do],
Endif: [If],
End_provider: [Begin_provider],
End_doc: [Begin_doc],
End: [Program, Subroutine, Function],
End_module: [Module],
End_interface: [Interface]}
End_interface: [Interface]
}
from collections import defaultdict
d_type = defaultdict(list)
@ -868,15 +885,18 @@ def check_begin_end(raw_text):
if n_end != n_begin:
if n_end > n_begin:
logger.error("You have more close statement than open statement (%s) (%s)",line.filename,t_end)
logger.error("You have more close statement than open statement (%s) (%s)",
line.filename, t_end)
else:
logger.error('You have more end statement than open statenemt for (%s) (%s)' % (line.filename, t_end))
logger.error('You have more end statement than open statenemt for (%s) (%s)' %
(line.filename, t_end))
for i in zip([l for i in l_begin for l in d_type[i]], d_type[t_end]):
logger.debug(i)
sys.exit(1)
######################################################################
def remove_ifdefs(text):
assert type(text) == list
@ -967,7 +987,8 @@ class Preprocess_text(object):
result = []
is_doc = False
for i, (l, ll, llc) in enumerate(zip(self.lines, self.lines_lower, self.lines_lower_canonized)):
for i, (l, ll,
llc) in enumerate(zip(self.lines, self.lines_lower, self.lines_lower_canonized)):
line, is_doc = get_type(i + 1, self.filename, l, ll, llc, is_doc)
result += line
return result
@ -994,6 +1015,5 @@ class Preprocess_text(object):
return result
if __name__ == '__main__':
debug()

View File

@ -24,7 +24,6 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
rdtsc = """
#ifdef __i386
double irp_rdtsc_(void) {
@ -47,12 +46,14 @@ import os
import threading
from irpf90_t import irpdir
def build_rdtsc():
filename = irpdir + "irp_rdtsc.c"
file = open(filename, 'w')
file.write(rdtsc)
file.close()
def build_module(variables):
data = """
module irp_timer
@ -169,7 +170,7 @@ end
file.write(data)
file.close()
def run(d_entity):
build_module(d_entity)
build_rdtsc()

View File

@ -24,34 +24,18 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
import re
re_comment = re.compile(r"^([^'!]*)('[^']*'[^']*)*!")
re_decl = re.compile( "".join( [ r"^\ *",
r"(integer[(::)?\* ,]+",
r"|double *precision[(::)?\* ,]+",
r"|logical[(::)?\* ,]+",
r"|character[(::)?\* ,]+",
r"|real[(::)?\* ,]+",
r"|dimension[(::)?\* ,]+",
r"|parameter[(::)?\* ,]+",
r"|data */",
r"|allocatable *(::)?",
r"|common */",
r"|namelist */",
r"|save */",
r"|complex[(::)?\* ,]+",
r"|intrinsic *(::)?",
r"|external *(::)?",
r"|equivalence *(::)?",
r"|type",
r"|endtype",
r")[^=(]"
re_decl = re.compile("".join([
r"^\ *", r"(integer[(::)?\* ,]+", r"|double *precision[(::)?\* ,]+", r"|logical[(::)?\* ,]+",
r"|character[(::)?\* ,]+", r"|real[(::)?\* ,]+", r"|dimension[(::)?\* ,]+",
r"|parameter[(::)?\* ,]+", r"|data */", r"|allocatable *(::)?", r"|common */", r"|namelist */",
r"|save */", r"|complex[(::)?\* ,]+", r"|intrinsic *(::)?", r"|external *(::)?",
r"|equivalence *(::)?", r"|type", r"|endtype", r")[^=(]"
]))
re_test = re.compile(r"\( *(.*)(\.[a-zA-Z]*\.|[<>]=?|[=/]=)([^=]*)\)")
re_string = re.compile(r"'.*?'")

View File

@ -24,18 +24,17 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
from irpf90_t import *
from util import logger
from lib.manager import irpy
class Routine(object):
'''
A collection of list corresponding of a Routine (Subroutine, or function)
'''
############################################################
def __init__(self, text):
assert type(text) == list
@ -51,6 +50,7 @@ class Routine(object):
raise AttributeError
############################################################
@irpy.lazy_property
def name(self):
'''Name is lowercase'''
@ -78,7 +78,8 @@ class Routine(object):
############################################################
@irpy.lazy_property
def touches_my_self(self):
return set(x for line in self.text for x in line.text.split()[1:] if isinstance(line,(Touch, SoftTouch)))
return set(x for line in self.text for x in line.text.split()[1:]
if isinstance(line, (Touch, SoftTouch)))
@irpy.lazy_property_mutable
def touches_ancestor(self):
@ -97,4 +98,6 @@ class Routine(object):
############################################################
@irpy.lazy_property
def calls(self):
return set(line.text.split('(',1)[0].split()[1].lower() for line in self.text if isinstance(line,Call))
return set(
line.text.split('(', 1)[0].split()[1].lower() for line in self.text
if isinstance(line, Call))

View File

@ -7,7 +7,7 @@ SUBROUTINE irp_finalize_{id}
{#entity_array}
IF (ALLOCATED({name})) THEN
{name_root}_is_built = .FALSE.
! DEALLOCATE({name})
DEALLOCATE({name})
ENDIF
{/entity_array}
END SUBROUTINE irp_finalize_{id}

View File

@ -24,7 +24,7 @@ SUBROUTINE irp_lock_{.}(set)
CALL omp_unset_lock({.}_lock)
ENDIF
{?do_debug} CALL irp_leach(irp_here) {/do_debug}
{?do_debug} CALL irp_leave(irp_here) {/do_debug}
END SUBROUTINE irp_lock_{.}
{/entity}

151
src/templates/irp_stack.f90 Normal file
View File

@ -0,0 +1,151 @@
MODULE irp_stack_mod
INTEGER, PARAMETER :: STACKMAX=1000
CHARACTER*(128) ,allocatable :: irp_stack(:,:)
DOUBLE PRECISION ,allocatable :: irp_cpu(:,:)
INTEGER ,allocatable :: stack_index(:)
INTEGER :: nthread
CHARACTER*(128) :: white = ''
END MODULE
SUBROUTINE irp_stack_init
USE irp_stack_mod
IMPLICIT NONE
INTEGER :: ithread
{?do_openmp}
INTEGER, EXTERNAL :: omp_get_thread_num
INTEGER, EXTERNAL :: omp_get_max_threads
{/do_openmp}
INTEGER :: ierr
{^do_openmp}
ithread = 0
{:else}
ithread = omp_get_thread_num()
{/do_openmp}
{^do_openmp} !$OMP CRITICAL {/do_openmp}
IF (.NOT.ALLOCATED(stack_index) ) THEN
{^do_openmp}
nthread = 1
{:else}
nthread = omp_get_max_threads()
{/do_openmp}
{?do_memory}
print *, 'Allocating irp_stack(0:',STACKMAX,',0:',nthread,')'
print *, 'Allocating irp_cpu(0:',STACKMAX,',0:',nthread,')'
print *, 'Allocating stack_index(0:',nthread,')'
{/do_memory}
ALLOCATE ( irp_stack(0:STACKMAX, 0:nthread), &
irp_cpu(0:STACKMAX, 0:nthread), &
stack_index(0:nthread) )
IF (ierr /=0 ) THEN
print*, 'Failed Allocating irp_stack, irp_cpu, stack_index'
ENDIF
stack_index = 0
END IF
END SUBROUTINE
SUBROUTINE irp_enter_routine(irp_where)
USE irp_stack_mod
IMPLICIT NONE
CHARACTER*(*), INTENT(in) :: irp_where
INTEGER :: ithread
REAL :: cpu
{?do_openmp}
INTEGER, EXTERNAL :: omp_get_thread_num
{/do_openmp}
{^do_openmp}
ithread = 0
{:else}
ithread = omp_get_thread_num()
{/do_openmp}
stack_index(ithread) = min(stack_index(ithread)+1,STACKMAX)
irp_stack(stack_index(ithread),ithread) = irp_where
END SUBROUTINE irp_enter_routine
SUBROUTINE irp_enter(irp_where)
USE irp_stack_mod
IMPLICIT NONE
CHARACTER*(*), INTENT(in) :: irp_where
INTEGER :: ithread
{?do_openmp}
INTEGER, EXTERNAL :: omp_get_thread_num
{/do_openmp}
{^do_openmp}
ithread = 0
{:else}
ithread = omp_get_thread_num()
{/do_openmp}
print *, ithread, ':', white(1:stack_index(ithread))//'-> ', trim(irp_where)
CALL cpu_time(irp_cpu(stack_index(ithread),ithread))
END SUBROUTINE irp_enter
SUBROUTINE irp_leave(irp_where)
USE irp_stack_mod
IMPLICIT NONE
CHARACTER*(*), INTENT(in) :: irp_where
INTEGER :: ithread
REAL :: cpu
{?do_openmp}
INTEGER, EXTERNAL :: omp_get_thread_num
{/do_openmp}
{^do_openmp}
ithread = 0
{:else}
ithread = omp_get_thread_num()
{/do_openmp}
CALL cpu_time(cpu)
print *, ithread, ':', white(1:stack_index(ithread))//'<- ', &
trim(irp_stack(stack_index(ithread),ithread)), &
cpu - irp_cpu(stack_index(ithread),ithread)
stack_index(ithread) = max(0,stack_index(ithread)-1)
END SUBROUTINE irp_leave
SUBROUTINE irp_trace
USE irp_stack_mod
IMPLICIT NONE
INTEGER :: ithread
{?do_openmp}
INTEGER, EXTERNAL :: omp_get_thread_num
{/do_openmp}
INTEGER :: i
{^do_openmp}
ithread = 0
{:else}
ithread = omp_get_thread_num()
{/do_openmp}
print *, 'Stack trace: ', ithread
print *, '-------------------------'
DO i=1,stack_index(ithread)
print *, trim(irp_stack(i,ithread))
END DO
print *, '-------------------------'
END SUBROUTINE irp_trace

View File

@ -6,7 +6,6 @@
! DO NOT MODIFY IT BY HAND !
!-----------------------------------------------!
MODULE {name}
{#use}

View File

@ -29,15 +29,16 @@ SUBROUTINE provide_{name}
{@last} {?do_task}!$OMP END TASKGROUP{/do_task} {/last}
{/l_children_static}
{#l_entity}
{?dim} CALL allocate_{name} {/dim}
{/l_entity}
CALL bld_{name}
{?do_debug} CALL irp_enter(irp_here) {/do_debug}
{?do_openmp}
ENDIF
CALL irp_lock_{name}(.FALSE.)
{/do_openmp}
{?do_debug} CALL irp_leave(irp_here) {/do_debug}
END SUBROUTINE provide_{name}

View File

@ -1,69 +0,0 @@
SUBROUTINE write_{name}(irp_num)
USE {fmodule}
IMPLICIT NONE
CHARACTER*(*), INTENT(IN) :: irp_num
LOGICAL :: irp_is_open = .TRUE.
INTEGER :: irp_iunit = 9
{?do_debug}
CHARACTER*(7+{@size key=name/}),PARAMETER :: irp_here = 'writer_{name}'
{/do_debug}
{?do_debug} CALL irp_enter(irp_here) {/do_debug}
IF (.NOT.{same_as}_is_built) THEN
CALL provide_{same_as}
ENDIF
{children}
CALL write_{.}(irp_num)
{/children}
DO WHILE (irp_is_open)
irp_iunit = irp_inuit + 1
INQUIRE(UNIT=irp_inuit, OPENED=irp_is_open)
END DO
{#group_entity}
OPEN(UNIT=irp_inuit,file='irpf90_{name}_'//trim(irp_num),FROM='FORMATTED',STATUS='UNKNOWN',ACTION='WRITE')
WRITE(irp_inuit,*) {.}{dim}
CLOSE(irp_inuit)
{/group_entity}
{?do_debug} CALL irp_leave(irp_here) {/do_debug}
END SUBROUTINE write_{name}
SUBROUTINE read_{name}(irp_num)
USE {fmodule}
IMPLICIT NONE
CHARACTER*(*), INTENT(IN) :: irp_num
LOGICAL :: irp_is_open = .TRUE.
INTEGER :: irp_iunit = 9
{?do_debug}
CHARACTER*(5+{@size key=name/}),PARAMETER :: irp_here = 'read_{name}'
{/do_debug}
{?do_debug} CALL irp_enter(irp_here) {/do_debug}
DO WHILE (irp_is_open)
irp_iunit = irp_inuit + 1
INQUIRE(UNIT=irp_inuit, OPENED=irp_is_open)
END DO
{#group_entity}
OPEN(UNIT=irp_inuit,file='irpf90_{name}_'//trim(irp_num),FROM='FORMATTED',STATUS='UNKNOWN',ACTION='WRITE')
READ(irp_inuit,*) {name}{dim}
CLOSE(irp_inuit)
{/group_entity}
CALL touch_{name}
{?do_debug} CALL irp_leave(irp_here) {/do_debug}
END SUBROUTINE read_{name}

View File

@ -28,26 +28,36 @@ from irpf90_t import irp_id,irpdir
import os
from command_line import command_line
def create(modules, variables):
# (Dict[str,Module]. Dict[str, Variable]) -> None
'''Create the fortran90 finalize subroutine and the touched one'''
main_modules_name = [m.name for m in modules.values() if m.is_main]
d_template_finalize = {'id':irp_id,
d_template_finalize = {
'id': irp_id,
'use': [m.name for m in modules.values() if not m.is_main and m.has_irp_module],
'entity_array':
[{'name':e.name,'name_root':e.same_as} for e in variables.values() if e.fmodule not in main_modules_name and e.dim]}
d_template_touch = {'do_debug': command_line.do_debug,
'entity':[e.d_touche_template for e in variables.values() if e.fmodule not in main_modules_name]}
'entity_array': [{
'name': e.name,
'name_root': e.same_as
} for e in variables.values() if e.fmodule not in main_modules_name and e.dim]
}
d_template_touch = {
'do_debug': command_line.do_debug,
'entity': [
e.d_touche_template for e in variables.values()
if e.fmodule not in main_modules_name and e.d_touche_template
]
}
import util
str_out = util.ashes_env.render('touch.f90', d_template_touch) + util.ashes_env.render('finalize.f90', d_template_finalize)
str_out = util.ashes_env.render('touch.f90', d_template_touch) + util.ashes_env.render(
'finalize.f90', d_template_finalize)
filename = os.path.join(irpdir, 'irp_touches.irp.F90')
util.lazy_write_file(filename, '%s\n' % util.remove_empy_lines(str_out))
if __name__ == '__main__':
create()

View File

@ -24,7 +24,6 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
# ~#~#~#~#~#
# L o g e r
# ~#~#~#~#~#
@ -42,7 +41,6 @@ logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('Irpf90')
logger.setLevel(30)
# ~#~#~#~#~#
# A S H E S _ T E M P L A T E S
# ~#~#~#~#~#
@ -50,6 +48,7 @@ from lib.manager import ashes
import os
ashes_env = ashes.AshesEnv([os.path.join(os.path.dirname(__file__), 'templates')])
def remove_empy_lines(text):
return os.linesep.join([s for s in text.splitlines() if s.strip()])
@ -57,6 +56,7 @@ def remove_empy_lines(text):
# / / _ R E L A T E D
# ~#~#~#~#~#
def chunkify(l, n_chunk):
# (List[any], int) -> List [ List[any] ]
'''Split the list on n_chunk'''
@ -66,6 +66,8 @@ def chunkify(l,n_chunk):
import multiprocessing
def parmap(f, it, parallel=False):
# (Callable, Iterable, bool) -> List
'''Parallel version of the std map function
@ -110,12 +112,12 @@ def parmap(f, it, parallel=False):
# (aka 1 job by processor)
it_chunk = chunkify(l=it, n_chunk=nproc)
def F(chunk):
# (List[any]) -> (List[any])
'''Same as 'f' but for a chunck'''
return map(f, chunk)
q_in = multiprocessing.JoinableQueue()
q_out = multiprocessing.Queue()
# All the worker will sepuku after reseaving this message
@ -183,6 +185,8 @@ def parmap(f, it, parallel=False):
# ~#~#~#~#~#
import hashlib
import os
def cached_file(filename, text):
# (str,str) -> bool
'''Check if file locatte at filename containt the same data as text
@ -218,6 +222,7 @@ def lazy_write_file(filename, text, conservative=False,touch=False):
elif touch:
os.utime(filename, None)
def listdir(directory, abspath=False):
#(str, bool) -> List[str]
'''Replacement of the std:listdir but with the possibility to get the abosulte path'''
@ -228,6 +233,7 @@ def listdir(directory, abspath=False):
else:
return [os.path.abspath(os.path.join(directory, f)) for f in l_filename]
def check_output(*popenargs, **kwargs):
"""Run command with arguments and return its output as a byte string.
Backported from Python 2.7 as it's implemented as pure python on stdlib.
@ -256,7 +262,6 @@ def uniquify(l,sort=False):
# (Iter, bool) -> List[Any]
'''Uniquify a immutable iterable. Don't preserve the order. Or maybe.'''
#Be carefull that element in Iter can be unshable.
try:
r = list(set(l))
@ -269,11 +274,13 @@ def uniquify(l,sort=False):
else:
return sorted(r)
def OrderedUniqueList(l):
# (Iter, bool) -> List[Any]
'''Uniquify a immutable iterable. Don't preserve the order'''
return sorted(set(l))
def flatten(l_2d):
# (List [ Iter[Any] ]) -> List
'''Construct a copy of the 2d list collapsed into one dimension.
@ -326,11 +333,13 @@ def build_dim(l_dim, colons=False):
return "(%s)" % (",".join(l_dim_colons))
def mangled(l_ent, d_ent):
# (List, Dict[str,Entity]) -> list
'''Create a uniq list of providier (merge the multione) '''
return OrderedUniqueList(d_ent[name].same_as for name in l_ent)
def build_use(l_ent, d_ent, use=True):
# (List, Dict[str,Entity]) -> list
'''Contruct the fortran90 'use' statement for the list of entity'''
@ -348,13 +357,13 @@ def build_call_provide(l_ent, d_ent):
# Get the corect name (in the case of multiple provider line)
l_same_as = mangled(l_ent, d_ent)
def bld_f90(x):
return [ " if (.not.%s_is_built) then" % x,
" call provide_%s" % x,
" endif"]
return [" if (.not.%s_is_built) then" % x, " call provide_%s" % x, " endif"]
return flatten(map(bld_f90, l_same_as))
def che_merge(sets):
#(List[Set] -> List[Set]
"""Merge a list of set is they are not disjoint.
@ -364,7 +373,10 @@ def che_merge(sets):
results = []
upd, isd, pop = set.update, set.isdisjoint, sets.pop
while sets:
if not [upd(sets[0],pop(i)) for i in range(len(sets)-1,0,-1) if not isd(sets[0],sets[i])]:
if not [
upd(sets[0], pop(i)) for i in range(len(sets) - 1, 0, -1)
if not isd(sets[0], sets[i])
]:
results.append(pop(0))
return results
@ -372,11 +384,15 @@ def che_merge(sets):
def l_dummy_entity(d_entity):
# Dict[str:Entity] -> List[set]
from itertools import combinations
l_candidate_botom = [ (i,j) for i,j in combinations(d_entity.keys(),2) if d_entity[i].needs == d_entity[j].needs]
l_dummy = [set([i,j]) for i,j in l_candidate_botom if d_entity[i].needed_by == d_entity[j].needed_by]
l_candidate_botom = [(i, j) for i, j in combinations(d_entity.keys(), 2)
if d_entity[i].needs == d_entity[j].needs]
l_dummy = [
set([i, j]) for i, j in l_candidate_botom if d_entity[i].needed_by == d_entity[j].needed_by
]
return che_merge(l_dummy)
def split_l_set(l_set_org):
#(List[set] -> (List, Set)
'''Split the list of set into a list of Head and and the concetenad of all the tail

View File

@ -24,9 +24,9 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
import os
def install():
VIM = os.environ["HOME"] + "/.vim"
try:
@ -44,5 +44,6 @@ def install():
except:
pass
if __name__ == "__main__":
install()