10
0
mirror of https://gitlab.com/scemama/irpf90.git synced 2025-01-03 10:05:40 +01:00

Merge /home/scemama/Thomas/irpf90

This commit is contained in:
Anthony Scemama 2017-07-11 23:31:31 +02:00
commit f1ec5683c6
39 changed files with 4620 additions and 1647 deletions

View File

@ -1,21 +1,27 @@
IRPF90= irpf90 # make | ninja
IRPF90FLAGS= -I ./ -I input/ ##############
BUILD_SYSTEM= make
BUILD_SYSTEM= ninja
#######
IRPF90= ../bin/irpf90
IRPF90FLAGS= -I input --codelet=v:100
.EXPORT_ALL_VARIABLES: .EXPORT_ALL_VARIABLES:
AR = ar
CC = gcc
CFLAGS = -O2
CXX = g++
CXXFLAGS = -O2
FC = gfortran
FCFLAGS = -O2
LIB = LIB =
RANLIB = ranlib
OBJ =
SRC = SRC =
OBJ =
# Compiler ! Will be overwriten by the ENV one if avalaible.
FC =ifort
FCFLAGS ?= -O2
CC ?= gcc
CFLAGS ?= -O2
CXX ?= g++
CXXFLAGS ?= -O2
# Dark magic below modify with caution! # Dark magic below modify with caution!
# "You are Not Expected to Understand This" # "You are Not Expected to Understand This"
@ -32,13 +38,18 @@ SRC =
# | | I _________ # | | I _________
# | | I c(` ')o # | | I c(` ')o
# | l I \. ,/ # | l I \. ,/
# _/j L l\_! _//^---^\\_ # _/j L l\_! _// \\_
#Misc
AR ?=
RANLIB ?=
ifeq ($(BUILD_SYSTEM),ninja) # Variable need by IRPF90
BUILD_SYSTEM_stripped=$(strip $(BUILD_SYSTEM))
ifeq ($(BUILD_SYSTEM_stripped),ninja)
BUILD_FILE=IRPF90_temp/build.ninja BUILD_FILE=IRPF90_temp/build.ninja
IRPF90FLAGS += -j IRPF90FLAGS += -j
else ifeq ($(BUILD_SYSTEM),make) else ifeq ($(BUILD_SYSTEM_stripped),make)
BUILD_FILE=IRPF90_temp/build.make BUILD_FILE=IRPF90_temp/build.make
BUILD_SYSTEM += -j BUILD_SYSTEM += -j
else else
@ -46,24 +57,38 @@ DUMMY:
$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)') $(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')
endif endif
define run_and_touch # Actual Rule
$(BUILD_SYSTEM) -C $(dir $(1) ) -f $(notdir $(1) ) $(addprefix $(CURDIR)/, $(2)) && touch $(2) EXE := $(shell egrep -ri '^\s*program' *.irp.f | cut -d'.' -f1)
ARCH = $(addprefix $(CURDIR)/,IRPF90_temp/irpf90.a)
.PHONY: clean all
all: $(EXE)
define run
$(BUILD_SYSTEM_stripped) -C $(dir $(BUILD_FILE) ) -f $(notdir $(BUILD_FILE) ) $(1)
endef endef
EXE := $(shell egrep -r '^\s*program' *.irp.f | awk '{print $$2}') #We allow for the user to ask for 'relative' path
#But the IRPF90 build system use absolute path.
$(EXE): $(ARCH)
@printf "%b" "\033[0;32m Build $@...\033[m\n"
@$(call run, $(addprefix $(CURDIR)/, $@)) && touch $@
.PHONY: all
all: $(BUILD_FILE) .NOTPARALLEL: $(BUILD_FILE) $(ARCH)
$(call run_and_touch, $<, $(EXE))
$(ARCH): $(BUILD_FILE)
@printf "%b" "\033[0;32m Creating the archive...\033[m\n"
@$(call run, $@) && touch $@
.NOTPARALLEL: $(EXE)
$(EXE): $(BUILD_FILE)
$(call run_and_touch, $<, $(EXE))
$(BUILD_FILE): $(shell find . -maxdepth 2 -path ./IRPF90_temp -prune -o -name '*.irp.f' -print) $(BUILD_FILE): $(shell find . -maxdepth 2 -path ./IRPF90_temp -prune -o -name '*.irp.f' -print)
$(IRPF90) $(IRPF90FLAGS) @printf "%b" "\033[0;32m Running the IRPF90-compiler...\033[m\n"
@$(IRPF90) $(IRPF90FLAGS)
clean: clean:
rm -f -- $(BUILD_FILE) $(EXE) $(shell find IRPF90_temp -type f \( -name "*.o" -o -name "*.mod" -name "*.a" \) -delete;) rm -f -- $(BUILD_FILE) $(EXE)
veryclean: clean veryclean: clean
rm -rf IRPF90_temp/ IRPF90_man/ irpf90_entities dist tags rm -rf IRPF90_temp/ IRPF90_man/ irpf90_entities dist tags

View File

@ -1,6 +1,6 @@
program irp_example2 program irp_example2
print *, "Example 2" print *, "Example 2"
print *, 't = ', t print *, 'v = ', v
IRP_WRITE t IRP_WRITE t

View File

@ -1,28 +1,31 @@
BEGIN_PROVIDER [integer, t ] BEGIN_PROVIDER [integer, t ]
IMPLICIT NONE
t = u1+v+4 t = u1+v+4
END_PROVIDER END_PROVIDER
BEGIN_PROVIDER [integer,w] BEGIN_PROVIDER [integer,w]
IMPLICIT NONE
w = d5+3 w = d5+3
END_PROVIDER END_PROVIDER
BEGIN_PROVIDER [ integer, v ] BEGIN_PROVIDER [ integer, v ]
implicit none IMPLICIT NONE
v = u2+w+2 v = u2+w+2
END_PROVIDER END_PROVIDER
BEGIN_PROVIDER [ integer, u1 ] BEGIN_PROVIDER [ integer, u1 ]
IMPLICIT NONE
integer :: fu integer :: fu
u1 = fu(d1,d2) u1 = fu(d1,d2)
END_PROVIDER END_PROVIDER
BEGIN_PROVIDER [ integer, u2 ] BEGIN_PROVIDER [ integer, u2 ]
IMPLICIT NONE
integer :: fu integer :: fu
u2 = fu(d3,d4) u2 = fu(d3,d4)
!df
END_PROVIDER END_PROVIDER
integer function fu(x,y) INTEGER function fu(x,y)
integer :: x,y INTEGER, INTENT(in) :: x,y
fu = x+y+1 fu = x+y+1
end function END FUNCTION

View File

@ -36,6 +36,7 @@ irp_id = irpf90_t.irp_id
cwd = os.getcwd() cwd = os.getcwd()
def dress(f, in_root=False): def dress(f, in_root=False):
#(str,bool) -> str #(str,bool) -> str
""" Transfoms the filename into $PWD/IRPF90_temp/f """ Transfoms the filename into $PWD/IRPF90_temp/f
@ -65,9 +66,7 @@ def create_build_touches(l_irp_m, ninja):
result_ninja = '\n'.join([ result_ninja = '\n'.join([
"build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_modules_irp}", "build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_modules_irp}",
" short_in = {short_target_F90}", " short_in = {short_target_F90}", " short_out = {short_target_o}", ""
" short_out = {short_target_o}",
""
]) ])
result_make = '\n'.join([ 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) list_of_object = ' '.join(l_irp_o + l_usr_o_wo_main + l_ext_o + l_irp_sup_o)
result_ninja = '\n'.join([ result_ninja = '\n'.join(
"build {lib}: archive_{irp_id} {list_of_object}", ["build {lib}: archive_{irp_id} {list_of_object}", " short_out = {short_lib}", ""])
" short_out = {short_lib}",
""])
result_make = '\n'.join([ result_make = '\n'.join([
"{lib}: {list_of_object}", "{lib}: {list_of_object}", '\t@printf "Archive: {short_lib}\\n"', "\t@$(AR) cr $@ $^", ""
'\t@printf "Archive: {short_lib}\\n"', ])
"\t@$(AR) cr $@ $^", ""])
result = result_ninja if ninja else result_make result = result_ninja if ninja else result_make
return result.format(**locals()) 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) basename = os.path.basename(filename)
if basename != progname: if basename != progname:
from util import logger 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) target = dress(filename, in_root=True)
short_target = filename 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([ result_ninja = '\n'.join([
"build {target}: link_{irp_id} {target_o} {irp_lib} | {list_of_module}", "build {target}: link_{irp_id} {target_o} {irp_lib} | {list_of_module}",
" short_out = {short_target}", " short_out = {short_target}", ""
""]) ])
result_make = '\n'.join([ result_make = '\n'.join([
"{target}:{target_o} {irp_lib} | {list_of_module}", "{target}:{target_o} {irp_lib} | {list_of_module}", '\t@printf "Link: {short_target}\\n"',
'\t@printf "Link: {short_target}\\n"', "\t@$(FC) $^ $(LIB) -o $@", ""
"\t@$(FC) $^ $(LIB) -o $@", ])
""])
result = result_ninja if ninja else result_make 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 = [ l_build = [
"build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}", "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_in = {short_target_F90}", " short_out = {short_target}", ""
" short_out = {short_target}",
""
] ]
l_build_make = [ l_build_make = [
"{target_o}: {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}", "{target_o}: {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}",
'\t@printf "F: {short_target_F90} -> {short_target}\\n"', '\t@printf "F: {short_target_F90} -> {short_target}\\n"', "\t@$(FC) $(FCFLAGS) -c $^ -o $@",
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", "" ""
] ]
# No need of module when compiling the irp_module. # No need of module when compiling the irp_module.
if t.has_irp_module: if t.has_irp_module:
l_build += [ l_build += [
"build {target_module_o}: compile_fortran_{irp_id} {target_module_F90} | {list_of_includes} {list_of_modules} ", "build {target_module_o}: compile_fortran_{irp_id} {target_module_F90} | {list_of_includes} {list_of_modules} ",
" short_in = {short_target_module_F90}", " short_in = {short_target_module_F90}", " short_out = {short_target_module_o}", ""
" short_out = {short_target_module_o}",
""
] ]
l_build_make += [ l_build_make += [
@ -271,87 +263,35 @@ def create_build_remaining(f,ninja):
if extension.lower() in ['f', 'f90']: if extension.lower() in ['f', 'f90']:
result = ["build {target_o}: compile_fortran_{irp_id} {target_i}"] 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 $@", ""
]
elif extension.lower() in ['c']: elif extension.lower() in ['c']:
result = ["build {target_o}: compile_c_{irp_id} {target_i}"] result = ["build {target_o}: compile_c_{irp_id} {target_i}"]
elif extension.lower() in ['cxx', 'cpp']: elif extension.lower() in ['cxx', 'cpp']:
result = ["build {target_o}: compile_cxx_{irp_id} {target_i}"] result = ["build {target_o}: compile_cxx_{irp_id} {target_i}"]
result += [" short_in = {short_target_i}", " short_out = {short_target_o}", ""] result += [" short_in = {short_target_i}", " short_out = {short_target_o}", ""]
return '\n'.join(result).format(**locals())
result_final = result if ninja else result_make
return '\n'.join(result_final).format(**locals())
def create_makefile(d_flags, d_var, irpf90_flags, ninja=True): def create_makefile(d_flags, d_var, irpf90_flags, ninja=True):
result = ["IRPF90= irpf90", d = {'BUILD_SYSTEM': 'ninja' if ninja else 'make',
"IRPF90FLAGS= %s" % irpf90_flags, 'irpf90_flags': irpf90_flags}
"BUILD_SYSTEM= %s" % ('ninja' if ninja else 'make'),
""]
# Export all the env variable used by irpf90 d.update(d_flags)
result += ['.EXPORT_ALL_VARIABLES:', d.update(d_var)
'',
'\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 += ["",
"ifeq ($(BUILD_SYSTEM),ninja)",
"\tBUILD_FILE=IRPF90_temp/build.ninja",
"\tIRPF90FLAGS += -j",
"else ifeq ($(BUILD_SYSTEM),make)",
"\tBUILD_FILE=IRPF90_temp/build.make",
"else",
"DUMMY:",
"\t$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')",
"endif"]
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))",
"$(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$(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"]
import util import util
data = '%s\n' % '\n'.join(result) str_ = util.ashes_env.render('general.make', d)
util.lazy_write_file('Makefile',data,conservative=True) util.lazy_write_file('Makefile', str_, conservative=True)
def create_make_all_clean(l_main): def create_make_all_clean(l_main):
# #
@ -364,16 +304,15 @@ def create_make_all_clean(l_main):
l_executable = ' '.join(dress(t.filename, in_root=True) for t in l_main) l_executable = ' '.join(dress(t.filename, in_root=True) for t in l_main)
output = [".PHONY : all", output = [
"all: {l_executable}", ".PHONY : all", "all: {l_executable}", "", ".PHONY: clean", "clean:",
"",
".PHONY: clean",
"clean:",
'\tfind . -type f \( -name "*.o" -o -name "*.mod" \) -delete; rm -f {l_executable} --' '\tfind . -type f \( -name "*.o" -o -name "*.mod" \) -delete; rm -f {l_executable} --'
""] ""
]
return ['\n'.join(output).format(**locals())] return ['\n'.join(output).format(**locals())]
def create_var_and_rule(d_flags, ninja): def create_var_and_rule(d_flags, ninja):
output = ['\n'.join("{0} = {1}".format(k, v) for k, v in d_flags.iteritems())] output = ['\n'.join("{0} = {1}".format(k, v) for k, v in d_flags.iteritems())]
@ -383,33 +322,21 @@ def create_var_and_rule(d_flags, ninja):
# Rules # Rules
t = [ t = [
"rule compile_fortran_{irp_id}", "rule compile_fortran_{irp_id}", " command = $FC $FCFLAGS -c $in -o $out",
" command = $FC $FCFLAGS -c $in -o $out", " description = F : $short_in -> $short_out", "", "rule compile_c_{irp_id}",
" description = F : $short_in -> $short_out",
"",
"rule compile_c_{irp_id}",
" command = $CC $CFLAGS -c $in -o $out", " command = $CC $CFLAGS -c $in -o $out",
" description = C : $short_in -> $short_out", " description = C : $short_in -> $short_out", "", "rule compile_cxx_{irp_id}",
"",
"rule compile_cxx_{irp_id}",
" command = $CXX $CXXFLAGS -c $in -o $out", " command = $CXX $CXXFLAGS -c $in -o $out",
" description = C++ : $short_in -> $short_out", " description = C++ : $short_in -> $short_out", "", "rule archive_{irp_id}",
"", " command = $AR cr $out $in", " description = Archive: $short_out", "",
"rule archive_{irp_id}", "rule link_{irp_id}", " command = $FC $FCFLAGS $in $LIB -o $out",
" command = $AR cr $out $in", " description = Link: $short_out", ""
" 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)] output += ['\n'.join(t).format(irp_id=irpf90_t.irp_id, **d_flags)]
return output return output
# Environment variables # Environment variables
d_default = { d_default = {
@ -421,7 +348,8 @@ d_default = {
"CFLAGS": "-O2", "CFLAGS": "-O2",
"CXX": "g++", "CXX": "g++",
"CXXFLAGS": "-O2", "CXXFLAGS": "-O2",
"LIB": ""} "LIB": ""
}
d_flags = dict() d_flags = dict()
for k, v in d_default.iteritems(): for k, v in d_default.iteritems():
@ -437,6 +365,7 @@ for k in ['SRC', 'OBJ']:
def create_generalmakefile(ninja): def create_generalmakefile(ninja):
create_makefile(d_flags, d_var, include_dir, ninja) create_makefile(d_flags, d_var, include_dir, ninja)
def run(d_module, ninja): def run(d_module, ninja):
#(Dict[str,Module],bool) -> str #(Dict[str,Module],bool) -> str
"""Wrote the ninja file needed to compile the program """Wrote the ninja file needed to compile the program
@ -476,7 +405,7 @@ def run(d_module, ninja):
l_irp_sup_o = ["irp_touches.irp.o"] l_irp_sup_o = ["irp_touches.irp.o"]
l_irp_sup_s = ["irp_touches.irp.F90"] 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_o += ["irp_stack.irp.o"]
l_irp_sup_s += ["irp_stack.irp.F90"] l_irp_sup_s += ["irp_stack.irp.F90"]
@ -484,9 +413,13 @@ def run(d_module, ninja):
l_irp_sup_o += ["irp_locks.irp.o"] l_irp_sup_o += ["irp_locks.irp.o"]
l_irp_sup_s += ["irp_locks.irp.F90"] l_irp_sup_s += ["irp_locks.irp.F90"]
if command_line.do_profile or command_line.do_codelet:
l_irp_sup_o += ["irp_rdtsc.o"]
l_irp_sup_s += ["irp_rdtsc.c"]
if command_line.do_profile: if command_line.do_profile:
l_irp_sup_o += ["irp_profile.irp.o", "irp_rdtsc.o"] l_irp_sup_o += ["irp_profile.irp.o"]
l_irp_sup_s += ["irp_profile.irp.F90", "irp_rdtsc.c"] l_irp_sup_s += ["irp_profile.irp.F90"]
l_irp_sup_o = map(dress, l_irp_sup_o) l_irp_sup_o = map(dress, l_irp_sup_o)
l_irp_sup_s = map(dress, l_irp_sup_s) l_irp_sup_s = map(dress, l_irp_sup_s)

View File

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

View File

@ -24,11 +24,7 @@
# 31062 Toulouse Cedex 4 # 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr # scemama@irsamc.ups-tlse.fr
try: from lib.manager import irpy
import irpy
except:
import lib_irpy as irpy
import getopt, sys import getopt, sys
from version import version from version import version
@ -37,30 +33,56 @@ import re
description = "IRPF90 Fortran preprocessor." description = "IRPF90 Fortran preprocessor."
options = {} options = {}
options['a'] = ['assert', 'Activates ASSERT statements. If absent, remove ASSERT statements.', 0] 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['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['D'] = ['define', 'Defines a variable identified by the IRP_IF statements.', 1]
options['g'] = ['profile', 'Activates profiling of the code.', 0] options['g'] = ['profile', 'Activates profiling of the code.', 0]
options['h'] = ['help', 'Print this help', 0] options['h'] = ['help', 'Print this help', 0]
options['I'] = ['include', 'Include directory', 1] options['I'] = ['include', 'Include directory', 1]
options['j'] = ['ninja', 'Use Ninja instead of make', 0] 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['i'] = [
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 ] '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['m'] = ['memory', 'Print memory allocations/deallocations.', 0]
options['n'] = ['inline', '<all|providers|builders> : Force inlining of providers or builders', 1] options['n'] = ['inline', '<all|providers|builders> : Force inlining of providers or builders', 1]
options['o'] = ['checkopt', 'Shows where optimization may be required', 0] 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['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['s'] = [
options['t'] = [ 'touch' , 'Display which entities are touched when touching the variable given as an argument.', 1 ] '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['v'] = ['version', 'Prints version of irpf90', 0]
options['w'] = ['warnings', 'Activate Warnings', 0] options['w'] = ['warnings', 'Activate Warnings', 0]
options['z'] = ['openmp', 'Activate for OpenMP code', 0] options['z'] = ['openmp', 'Activate for OpenMP code', 0]
options['G'] = ['graph', 'Print the dependecy-graph of the entities (dots format)', 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): def __init__(self):
global options global options
self._opts = None self._opts = None
@ -77,15 +99,15 @@ class CommandLine(object):
@irpy.lazy_property @irpy.lazy_property
def include_dir(self): def include_dir(self):
self._include_dir = [] l = []
for o, a in self.opts: for o, a in self.opts:
if o in ["-I", '--' + options['I'][0]]: if o in ["-I", '--' + options['I'][0]]:
if len(a) < 1: if len(a) < 1:
print "Error: -I option needs a directory" print "Error: -I option needs a directory"
if a[-1] != '/': if a[-1] != '/':
a = a + '/' a = a + '/'
self._include_dir.append(a) l.append(a)
return self._include_dir return l
@irpy.lazy_property @irpy.lazy_property
def inline(self): def inline(self):
@ -189,6 +211,7 @@ Options:
sys.exit(2) sys.exit(2)
return self._opts return self._opts
opts = property(fget=opts) opts = property(fget=opts)
t = """ t = """
@ -208,22 +231,29 @@ do_$LONG = property(fget=do_$LONG)
@irpy.lazy_property @irpy.lazy_property
def do_run(self): 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):
# return True
command_line = CommandLine() command_line = CommandLine()
def print_options(): def print_options():
keys = options.keys() keys = options.keys()
keys.sort() keys.sort()
import subprocess import subprocess
for k in keys: for k in keys:
description = options[k][1] 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 = p1.communicate(description)[0]
description = description.replace('\n', '\n'.ljust(27)) description = description.replace('\n', '\n'.ljust(27))
print("-%s, --%s" % (k, options[k][0])).ljust(25), description + '\n' print("-%s, --%s" % (k, options[k][0])).ljust(25), description + '\n'
print "\n" print "\n"
if __name__ == '__main__': if __name__ == '__main__':
print_options() print_options()

View File

@ -30,6 +30,7 @@ from irpf90_t import mandir
from util import parmap, build_dim, lazy_write_file from util import parmap, build_dim, lazy_write_file
import os import os
def do_print_short(entity): def do_print_short(entity):
assert type(entity) == Entity assert type(entity) == Entity
str_ = "{0:<35} : {1:<30} :: {2:<25} {3}".format(entity.prototype.filename[0], str_ = "{0:<35} : {1:<30} :: {2:<25} {3}".format(entity.prototype.filename[0],
@ -56,7 +57,7 @@ def process_deps(l):
def process_types(entity_input, d_entity): def process_types(entity_input, d_entity):
assert type(entity_input) == Entity assert type(entity_input) == Entity
l_name = [entity_input.name] + entity_input.others_entity_name l_name = entity_input.l_name
l_entity = [d_entity[name] for name in l_name] l_entity = [d_entity[name] for name in l_name]
l = [ "{0}\t:: {1}\t{2}".format(entity.type, name, build_dim(entity.dim) ) l = [ "{0}\t:: {1}\t{2}".format(entity.type, name, build_dim(entity.dim) )
@ -107,7 +108,6 @@ def do_print(entity, d_entity):
lazy_write_file("%s%s.l" % (mandir, name), '%s\n' % str_) lazy_write_file("%s%s.l" % (mandir, name), '%s\n' % str_)
###################################################################### ######################################################################
def do_print_subroutines(sub): def do_print_subroutines(sub):
assert type(sub) == Routine assert type(sub) == Routine
@ -164,8 +164,8 @@ def run(d_entity, d_routine):
l_subs = d_routine.values() 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): def worker(l):
filename, text = l filename, text = l

View File

@ -28,10 +28,7 @@ from irpf90_t import *
from util import * from util import *
from command_line import command_line from command_line import command_line
import sys import sys
try: from lib.manager import irpy
import irpy
except:
import lib_irpy as irpy
class Entity(object): class Entity(object):
@ -64,7 +61,6 @@ class Entity(object):
self.comm_world = comm_world self.comm_world = comm_world
# ~ # ~ # ~ # ~ # ~ # ~
# G l o b a l P r o p e r t y # G l o b a l P r o p e r t y
# ~ # ~ # ~ # ~ # ~ # ~
@ -97,7 +93,6 @@ class Entity(object):
d[type(line)] += [(i, line)] d[type(line)] += [(i, line)]
return d return d
# ~ # ~ # ~ # ~ # ~ # ~
# M u l t i p l e P r o v i d e r H a n d l e r # M u l t i p l e P r o v i d e r H a n d l e r
# ~ # ~ # ~ # ~ # ~ # ~
@ -114,7 +109,6 @@ class Entity(object):
''' '''
return self.name == self.same_as return self.name == self.same_as
@irpy.lazy_property @irpy.lazy_property
def prototype(self): def prototype(self):
# () -> Line # () -> Line
@ -128,16 +122,20 @@ class Entity(object):
''' '''
d = self.d_type_lines d = self.d_type_lines
return next(line for _,line in d[Begin_provider]+d[Cont_provider] if line.filename[1] == self.name) return next(line for _, line in d[Begin_provider] + d[Cont_provider]
if line.filename[1] == self.name)
@irpy.lazy_property @irpy.lazy_property
def others_entity_name(self): def l_name(self):
# () -> List[str]
d = self.d_type_lines
return [line.filename[1] for _, line in d[Begin_provider] + d[Cont_provider]]
@irpy.lazy_property
def l_others_name(self):
# () -> List[str] # () -> List[str]
'''Extract the other entity-name defined''' '''Extract the other entity-name defined'''
d = self.d_type_lines return [name for name in self.l_name if not name == self.name]
return [line.filename[1] for _,line in d[Begin_provider]+d[Cont_provider] if not line.filename[1] == self.name]
@irpy.lazy_property @irpy.lazy_property
def doc(self): def doc(self):
@ -163,45 +161,36 @@ class Entity(object):
return any(self.d_entity[i].is_written for i in self.parents) return any(self.d_entity[i].is_written for i in self.parents)
@irpy.lazy_property @irpy.lazy_property
def writer(self): def io_er(self):
if not self.is_main: if not self.is_main:
result = [] result = []
else:
from util import mangled
from util import ashes_env
name = self.name name = self.name
result = [ \
"subroutine writer_%s(irp_num)"%(name), d_template = {
" use %s"%(self.fmodule), 'name': name,
" implicit none", 'fmodule': self.fmodule,
" character*(*), intent(in) :: irp_num", 'same_as': self.same_as,
" logical :: irp_is_open", 'do_debug': command_line.do_debug,
" integer :: irp_iunit" ] 'children': mangled(self.needs, self.d_entity),
if command_line.do_debug: 'group_entity': [{
length = len("writer_%s" % (self.name)) 'name': n,
result += [\ 'dim': build_dim(
" character*(%d) :: irp_here = 'writer_%s'"%(length,name), self.d_entity[n].dim, colons=True)
" call irp_enter(irp_here)" ] } for n in self.l_name]
result += [ \ }
" if (.not.%s_is_built) then"%(self.same_as),
" call provide_%s"%(self.same_as), return ashes_env.render('ioer.f90', d_template).split('!TOKEN_SPLIT')
" endif" ]
result += map(lambda x: " call writer_%s(irp_num)" % (x), self.needs) @irpy.lazy_property
result += [ \ def reader(self):
" irp_is_open = .True.", return self.io_er[1].split('\n')
" irp_iunit = 9",
" do while (irp_is_open)", @irpy.lazy_property
" irp_iunit = irp_iunit+1", def writer(self):
" inquire(unit=irp_iunit,opened=irp_is_open)", return self.io_er[0].split('\n')
" enddo" ]
for n in [name] + self.others_entity_name:
result += [\
" open(unit=irp_iunit,file='irpf90_%s_'//trim(irp_num),form='FORMATTED',status='UNKNOWN',action='WRITE')"%(n),
" write(irp_iunit,*) %s%s"%(n,build_dim(self.d_entity[n].dim,colons=True)),
" close(irp_iunit)" ]
if command_line.do_debug:
result.append(" call irp_leave(irp_here)")
result.append("end subroutine writer_%s" % (name))
result.append("")
return result
@irpy.lazy_property_mutable @irpy.lazy_property_mutable
def is_read(self): def is_read(self):
@ -209,43 +198,8 @@ class Entity(object):
return any(self.d_entity[i].is_read for i in self.parents) return any(self.d_entity[i].is_read for i in self.parents)
@irpy.lazy_property @irpy.lazy_property
def reader(self): def is_source_touch(self):
if not self.is_main: return (Touch in self.d_type_lines or SoftTouch in self.d_type_lines)
result = []
else:
name = self.name
result = [ \
"subroutine reader_%s(irp_num)"%(name),
" use %s"%(self.fmodule),
" implicit none",
" character*(*), intent(in) :: irp_num",
" logical :: irp_is_open",
" integer :: irp_iunit" ]
if command_line.do_debug:
length = len("reader_%s" % (self.name))
result += [\
" character*(%d) :: irp_here = 'reader_%s'"%(length,name),
" call irp_enter(irp_here)" ]
result += map(lambda x: " call reader_%s(irp_num)" % (x), self.needs)
result += [ \
" irp_is_open = .True.",
" irp_iunit = 9",
" do while (irp_is_open)",
" inquire(unit=irp_iunit,opened=irp_is_open)",
" enddo"]
for n in [name] + self.others:
result += [\
" open(unit=irp_iunit,file='irpf90_%s_'//trim(irp_num),form='FORMATTED',status='OLD',action='READ')"%(n),
" read(irp_iunit,*) %s%s"%(n,build_dim(self.cm_d_variable[n].dim,colons=True)),
" close(irp_iunit)" ]
result += [ \
" call touch_%s"%(name),
" %s_is_built = .True."%(name) ]
if command_line.do_debug:
result.append(" call irp_leave(irp_here)")
result.append("end subroutine reader_%s" % (name))
result.append("")
return result
@irpy.lazy_property_mutable @irpy.lazy_property_mutable
def is_self_touched(self): def is_self_touched(self):
@ -314,7 +268,6 @@ class Entity(object):
else: else:
return map(str.strip, x[1:-1].split(',')) return map(str.strip, x[1:-1].split(','))
@irpy.lazy_property @irpy.lazy_property
def allocate(self): def allocate(self):
# () -> List[Str] # () -> List[Str]
@ -323,11 +276,14 @@ class Entity(object):
return [] return []
else: else:
# We never go here # We never go here
return [var for var in self.others_entity_name + [self.name] if self.d_entity[var].dim] return [var for var in l_name if self.d_entity[var].dim]
# ~ # ~ # ~ # ~ # ~ # ~
# D e c l a r a t i o n # D e c l a r a t i o n
# ~ # ~ # ~ # ~ # ~ # ~
@irpy.lazy_property
def is_protected(self):
return self.text[0].lower.startswith('begin_provider_immu')
@irpy.lazy_property @irpy.lazy_property
def type(self): def type(self):
@ -346,29 +302,20 @@ class Entity(object):
return type_ return type_
@irpy.lazy_property @irpy.lazy_property
def header(self): def d_header(self):
# () -> List[str] # () -> List[str]
'''Compute all the code needed to inistanticant the entity''' '''Compute all the code needed to inistanticant the entity'''
import util
name = self.name d_template = {
str_ = " {type_} :: {name} {dim}".format(type_=self.type, name=name, dim=build_dim(self.dim, colons=True)) 'name': self.name,
'type': self.type,
if command_line.coarray: 'main': self.is_main,
if not self.dim: 'dim': build_dim(
str_ += " [*]" self.dim, colons=True),
else: 'protected': '\n'.join(self.allocater + self.builder) if self.is_protected else False
str_ += " [:]" }
return d_template
l = [str_]
if self.dim and command_line.align != '1':
l += [" !DIR$ ATTRIBUTES ALIGN: %s :: %s" % (command_line.align, name)]
if self.is_main:
l += [" logical :: %s_is_built = .False." % (name)]
return l
############################################################ ############################################################
@irpy.lazy_property @irpy.lazy_property
@ -391,92 +338,36 @@ class Entity(object):
# ~ # ~ # ~ # ~ # ~ # ~
@irpy.lazy_property @irpy.lazy_property
def toucher(self): def d_touche_template(self):
# () -> List[str] # () -> List[str]
'''Fabric the f90 routine who handle the cache invalidation''' '''Fabric the f90 routine who handle the cache invalidation'''
# Only one by EntityColleciton # Only one by EntityColleciton
if not self.is_main: if not self.is_main:
return [] return {}
parents = self.parents from util import mangled
name = self.name
result = ["subroutine touch_%s" % (name)] return {
'name': self.name,
result += build_use(parents+[name],self.d_entity) 'l_module':
result.append(" implicit none") [n for n in build_use(
self.parents + [self.name], self.d_entity, use=False)],
if command_line.do_debug: 'l_ancestor': [n for n in mangled(self.parents, self.d_entity)]
length = str(len("touch_%s" % (name))) }
result += [" character*(%s) :: irp_here = 'touch_%s'" % (length, name)]
result += [" call irp_enter(irp_here)"]
result += map(lambda x: " %s_is_built = .False." % (x), parents)
result.append(" %s_is_built = .True." % (name))
if command_line.do_debug:
result.append(" call irp_leave(irp_here)")
result.append("end subroutine touch_%s" % (name))
result.append("")
return result
########################################################## ##########################################################
@irpy.lazy_property
def locker(self):
if not command_line.do_openmp:
return []
name = self.name
result = ["subroutine irp_lock_%s(set)" % (name)]
result += [
" use omp_lib",
" implicit none",
" logical, intent(in) :: set",
" integer(kind=omp_nest_lock_kind),save :: %s_lock" % (name),
" integer,save :: ifirst",
]
if command_line.do_debug:
length = str(len("irp_lock_%s" % (name)))
result += [
" character*(%s) :: irp_here = 'irp_lock_%s'" % (length, name),
" call irp_enter(irp_here)"
]
result += [
" if (ifirst == 0) then",
" ifirst = 1",
" call omp_init_nest_lock(%s_lock)" % (name),
" endif",
" if (set) then",
" call omp_set_nest_lock(%s_lock)" % (name),
" else",
" call omp_unset_nest_lock(%s_lock)" % (name),
" endif",
]
if command_line.do_debug:
result.append(" call irp_leave(irp_here)")
result.append("end subroutine irp_lock_%s" % (name))
result.append("")
return result
##########################################################
@irpy.lazy_property @irpy.lazy_property
def free(self): def free(self):
# () -> List[ str ] # () -> List[ str ]
'''Compute an part of a subroutine used to free a variable''' '''Compute an part of a subroutine used to free a variable'''
name = self.name name = self.name
result = ["!", result = ["!", "! >>> FREE %s" % (name), " %s_is_built = .False." % (self.same_as)]
"! >>> FREE %s" % (name),
" %s_is_built = .False." % (self.same_as)]
if self.dim: if self.dim:
result += [ result += [" if (allocated(%s)) then" % (name), " deallocate (%s)" % (name)]
" if (allocated(%s)) then"%(name),
" deallocate (%s)"%(name)]
if command_line.do_memory: if command_line.do_memory:
result += " print *, 'Deallocating %s'" % (name) result += " print *, 'Deallocating %s'" % (name)
@ -494,130 +385,56 @@ class Entity(object):
if not self.is_main: if not self.is_main:
return [] return []
from util import mangled
import util
name = self.name name = self.name
same_as = self.same_as 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)]
def dimsize(x): l_entity = [self.d_entity[n] for n in self.l_name]
# (str) -> str
'''Compute the number of element in the array'''
try:
b0, b1 = x.split(':')
except ValueError:
return x
b0_is_digit = b0.replace('-', '').isdigit() l = ashes_env.render('provider.f90', {
b1_is_digit = b1.replace('-', '').isdigit() 'name': name,
'l_module': l_module,
'l_children_static': l_children,
'do_debug': command_line.do_debug,
'do_openmp': command_line.do_openmp,
'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):
from util import mangled
if b0_is_digit and b1_is_digit: import util
size = str(int(b1) - int(b0) + 1) name = self.name
elif b0_is_digit: l_module = [x for x in build_use([self.name] + self.to_provide, self.d_entity, use=False)]
size = "(%s) - (%d)" % (b1, int(b0) - 1) if self.is_protected:
elif b1_is_digit: l_module.remove(self.fmodule)
size = "(%d) - (%s)" % (int(b1) + 1, b0)
else:
size = "(%s) - (%s) + 1" % (b1, b0)
return size l_dim = [{'name': name, 'rank': i + 1, 'value': dimsize(k)} for i, k in enumerate(self.dim)]
def build_alloc(name): l = ashes_env.render('allocater.f90', {
'name': name,
var = self.d_entity[name] 'l_module': l_module,
if var.dim == []: 'do_debug': command_line.do_debug,
return [] 'do_corray': command_line.do_coarray,
'do_memory': command_line.do_memory,
from util import build_dim 'dim': ','.join(self.dim),
'l_dim': l_dim
def print_size(): })
return " " * 5 + "print *, ' size: {0}'".format(build_dim(var.dim)) return [i for i in l.split('\n') if i.strip()]
def check_dimensions():
l = ["(%s>0)" % dimsize(x) for x in var.dim]
str_ = ".and.".join(l)
return " if (%s) then" % (str_)
def dimensions_OK():
result = [" irp_dimensions_OK = .True."]
for i, k in enumerate(var.dim):
result.append(" irp_dimensions_OK = irp_dimensions_OK.AND.(SIZE(%s,%d)==(%s))"
% (name, i + 1, dimsize(k)))
return result
def do_allocate():
if command_line.coarray:
result = " allocate(%s(%s)[*],stat=irp_err)"
else:
result = " allocate(%s(%s),stat=irp_err)"
result = result % (name, ','.join(var.dim))
if command_line.do_memory:
tmp = "\n print *, %s, 'Allocating %s(%s)'"
d = ','.join(self.dim)
result += tmp % ('size(' + name + ')', name, d)
return result
result = [" if (allocated (%s) ) then" % (name)]
result += dimensions_OK()
result += [
" if (.not.irp_dimensions_OK) then", " deallocate(%s,stat=irp_err)" % (name),
" if (irp_err /= 0) then", " print *, irp_here//': Deallocation failed: %s'" %
(name), print_size(), " endif"
]
if command_line.do_memory:
result += [" print *, 'Deallocating %s'" % (name)]
result.append(check_dimensions())
result.append(do_allocate())
result += [\
" if (irp_err /= 0) then",
" print *, irp_here//': Allocation failed: %s'"%(name),
print_size(),
" endif",
" endif",
" endif",
" else" ]
result.append(check_dimensions())
result.append(do_allocate())
result += [
" if (irp_err /= 0) then", " print *, irp_here//': Allocation failed: %s'" %
(name), print_size(), " endif", " endif", " endif"
]
return result
result = []
if command_line.directives and command_line.inline in ["all", "providers"]:
result += ["!DEC$ ATTRIBUTES FORCEINLINE :: provide_%s" % (name)]
result += ["subroutine provide_%s" % (name)]
result += build_use([same_as] + self.to_provide, self.d_entity)
if command_line.do_openmp:
result += [" use omp_lib"]
result.append(" implicit none")
length = len("provide_%s" % (name))
result += [
" character*(%d) :: irp_here = 'provide_%s'" % (length, name),
" integer :: irp_err ",
" logical :: irp_dimensions_OK",
"!$ integer :: nthreads"
]
if command_line.do_openmp:
result.append(" call irp_lock_%s(.True.)" % (same_as))
if command_line.do_assert or command_line.do_debug:
result.append(" call irp_enter(irp_here)")
result += build_call_provide(self.to_provide, self.d_entity)
result += flatten(map(build_alloc, [self.same_as] + self.others_entity_name))
result += [
" if (.not.%s_is_built) then" % (same_as), " call bld_%s" % (same_as),
" %s_is_built = .True." % (same_as), ""
]
result += [" endif"]
if command_line.do_assert or command_line.do_debug:
result.append(" call irp_leave(irp_here)")
if command_line.do_openmp:
result.append(" call irp_lock_%s(.False.)" % (same_as))
result.append("end subroutine provide_%s" % (name))
result.append("")
return result
########################################################## ##########################################################
@irpy.lazy_property @irpy.lazy_property
def builder(self): def builder(self):
if not self.is_main: if not self.is_main:
@ -651,6 +468,7 @@ class Entity(object):
line_prototype.filename))) line_prototype.filename)))
for vars, line in ps_text[begin + 1:end]: for vars, line in ps_text[begin + 1:end]:
text.append((vars, line)) text.append((vars, line))
text += map(lambda x: ([], Simple_line(line.i, x, line.filename)), text += map(lambda x: ([], Simple_line(line.i, x, line.filename)),
build_call_provide(vars, self.d_entity)) build_call_provide(vars, self.d_entity))
@ -665,13 +483,19 @@ class Entity(object):
# Add the use statement # Add the use statement
result += ["subroutine bld_%s" % (self.name)] result += ["subroutine bld_%s" % (self.name)]
result += build_use([self.name] + self.needs, self.d_entity)
l_use = build_use([self.name] + self.needs, self.d_entity, use=False)
if self.is_protected:
l_use.remove(self.fmodule)
result += ['USE %s' % n for n in l_use]
import parsed_text import parsed_text
# Move the variable to top, and add the text # Move the variable to top, and add the text
parsed_text.move_to_top_list(text, [Declaration, Implicit, Use]) parsed_text.move_to_top_list(text, [Declaration, Implicit, Use])
result.extend( line.text for _,line in text if not isinstance(line, (Begin_doc, End_doc, Doc, Cont_provider))) result.extend(line.text for _, line in text
if not isinstance(line, (Begin_doc, End_doc, Doc, Cont_provider)))
if command_line.do_profile: if command_line.do_profile:
result += [ result += [
@ -689,6 +513,11 @@ class Entity(object):
#Set by parsed_text.build_needs(...) #Set by parsed_text.build_needs(...)
raise AttributeError raise AttributeError
@irpy.lazy_property_mutable
def needed_by(self):
#Set by parsed_text.build_needs(...)
return []
@irpy.lazy_property @irpy.lazy_property
def children(self): def children(self):
@ -708,16 +537,10 @@ class Entity(object):
########################################################## ##########################################################
@irpy.lazy_property @irpy.lazy_property
def parents(self): def parents(self):
if not self.is_main:
return []
result = [] result = []
for x in self.needed_by: for x in self.needed_by:
result.append(x) result.append(x)
try:
result += self.d_entity[x].parents result += self.d_entity[x].parents
except RuntimeError:
pass # Exception will be checked after
result = OrderedUniqueList(result) result = OrderedUniqueList(result)
if self.name in result: if self.name in result:

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 command_line import command_line
from irpy_files import Irpy_comm_world from irpy_files import Irpy_comm_world
def main(): def main():
vim.install() vim.install()
@ -55,16 +56,93 @@ def main():
comm_world = Irpy_comm_world() comm_world = Irpy_comm_world()
if command_line.do_graph: if command_line.do_graph:
# Create a dot reprenstion of the dependency graph.
# Merge inside a subgraph the Entity provided together
def print_full_diagram(l_entity):
l_entity_not_leaf = [e for e in l_entity if e.needs]
print 'digraph Full { '
for e in l_entity_not_leaf:
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)
print ' %s ' % ' '.join(s)
print ' color = %s ' % color
print ' }'
comm_world.t_filename_parsed_text # Initialize entity need. Dirty I know. comm_world.t_filename_parsed_text # Initialize entity need. Dirty I know.
print 'graph { ' print_full_diagram(comm_world.d_entity.values())
for name,entity in comm_world.d_entity.items():
if entity.needs: print 'digraph Compact { '
print ' {0} -> {1}'.format(name, ' '.join(entity.needs)) print ' graph [ordering="out" splines=true overlap=false];'
l_main_usr = set([entity for entity in comm_world.d_entity.values() if entity.is_main])
l_main_head_usr = set([entity for entity in l_main_usr if entity.l_others_name])
l_set_main_head_name = [set(e.l_name) for e in l_main_head_usr]
print_subgraph(l_set_main_head_name, 'usr', color='blue')
from util import l_dummy_entity
l_set_dummy_name = l_dummy_entity(comm_world.d_entity)
print_subgraph(l_set_dummy_name, 'dummy', color='red')
#~=~=~=~=
# Create List Node Uniq
#~=~=~=~=
from util import split_l_set, flatten
l_main_dummy_name, s_exculde_dummy_name = split_l_set(l_set_dummy_name)
l_name_dummy_name_flatten = flatten(l_set_dummy_name)
l_main_head_dummy = set([comm_world.d_entity[name] for name in l_name_dummy_name_flatten])
s_exculde_dummy = set([comm_world.d_entity[name] for name in s_exculde_dummy_name])
l_node_uniq = (l_main_usr | l_main_head_dummy) - s_exculde_dummy
#~=~=~=~=
# Create All edge
#~=~=~=~=
# We need to remove the spurious edge caused by the the dummy multiples providers
d_need = dict()
for e in l_node_uniq:
d_need[e.name] = set(e.needs)
#~=~=~=~=
# Create All edge
#~=~=~=~=
# Draw the eddge
# If a arrow if arriving into Multipliple provider and if it is bold this mean it use all the entity inside it.
from util import uniquify
l_set_multiple = uniquify(l_set_dummy_name + l_set_main_head_name)
l_name_usr = [e.name for e in l_main_head_usr]
for source, l_target in d_need.items():
if source in l_name_usr:
color = 'blue'
elif source in l_name_dummy_name_flatten:
color = 'red'
else:
color = 'black'
for s in l_set_multiple:
if s.issubset(l_target):
print ' %s -> %s [color="%s", penwidth=2]' % (source, sorted(s).pop(), color)
l_target = l_target - s
if l_target:
print ' %s -> { %s } [color="%s"]' % (source, ' '.join(l_target), color)
print ' }' print ' }'
return return
if command_line.do_preprocess: if command_line.do_preprocess:
for filename, text in comm_world.preprocessed_text: for filename, text in comm_world.preprocessed_text:
if filename in command_line.preprocessed: if filename in command_line.preprocessed:
@ -100,6 +178,9 @@ def main():
comm_world.create_touches() comm_world.create_touches()
comm_world.create_man() comm_world.create_man()
if command_line.do_debug or command_line.do_assert:
comm_world.create_stack()
if command_line.do_profile: if command_line.do_profile:
import profile import profile
profile.run(comm_world.d_entity) profile.run(comm_world.d_entity)
@ -107,5 +188,6 @@ def main():
if command_line.do_openmp: if command_line.do_openmp:
comm_world.create_lock() comm_world.create_lock()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

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

View File

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

View File

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

View File

@ -1,10 +1,8 @@
from util import parmap, lazy_write_file from util import parmap, lazy_write_file
from util import flatten, listdir from util import flatten, listdir
from util import logger
try: from lib.manager import irpy
import irpy
except:
import lib_irpy as irpy
import os import os
import irpf90_t import irpf90_t
@ -12,7 +10,6 @@ import sys
from command_line import command_line from command_line import command_line
from util import logger
class Irpy_comm_world(object): class Irpy_comm_world(object):
'''Maestro.''' '''Maestro.'''
@ -42,10 +39,8 @@ class Irpy_comm_world(object):
s_file_folder_all = set(flatten(listdir(path, abspath=True) for path in s_folder_abs)) s_file_folder_all = set(flatten(listdir(path, abspath=True) for path in s_folder_abs))
# Take everything! # Take everything!
s_file_folder = filter(lambda f: os.path.isfile(f) and not f.startswith("."), s_file_folder_all) s_file_folder = filter(lambda f: os.path.isfile(f) and not f.startswith("."),
s_file_folder_all)
s_file_tot = set(l_file) if l_file else set() s_file_tot = set(l_file) if l_file else set()
s_file_tot.update(s_file_folder) s_file_tot.update(s_file_folder)
@ -75,6 +70,7 @@ class Irpy_comm_world(object):
'''Tuple (filename, preprocessed_text)''' '''Tuple (filename, preprocessed_text)'''
from preprocessed_text import Preprocess_text from preprocessed_text import Preprocess_text
def worker_preprocess(filename): def worker_preprocess(filename):
return (filename, Preprocess_text(filename).preprocessed_text) return (filename, Preprocess_text(filename).preprocessed_text)
@ -107,20 +103,20 @@ class Irpy_comm_world(object):
l_end = [i for i, line in self.d_type_lines[End_provider]] l_end = [i for i, line in self.d_type_lines[End_provider]]
l_provider = [self.l_preprocessed_text[begin:end] for begin, end in zip(l_begin, l_end)] l_provider = [self.l_preprocessed_text[begin:end] for begin, end in zip(l_begin, l_end)]
l_ent = [] l_ent = []
for icount, buf in enumerate(l_provider): for icount, buf in enumerate(l_provider):
from functools import partial from functools import partial
Ent_part = partial(Entity, buf, icount, comm_world=self) Ent_part = partial(Entity, buf, icount, comm_world=self)
ent = Ent_part() ent = Ent_part()
l_ent += [ent] + [Ent_part(other) for other in ent.others_entity_name] l_ent += [ent] + [Ent_part(name) for name in ent.l_others_name]
# O(2) but who care # O(2) but who care
l_duplicate = [x for x in l_ent if l_ent.count(x) > 1] l_duplicate = [x for x in l_ent if l_ent.count(x) > 1]
if l_duplicate: if l_duplicate:
from util import logger 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 import sys
sys.exit(1) sys.exit(1)
@ -131,25 +127,32 @@ class Irpy_comm_world(object):
# #
# Second pass # Second pass
#
# Modify parameter of variables # Modify parameter of variables
# Touch Softouch # Touch Softouch
def find_variable(line): def find_variable(line):
from util import logger
import sys
l_var = line.lower.split()[1:] l_var = line.lower.split()[1:]
if len(l_var) < 1: if len(l_var) < 1:
error.fail(line, "Syntax error") logger.error("Syntax error: %s", line)
import sys
sys.exit(1)
if any(v for v in l_var if v not in d_ent): try:
error.fail(line, "Variable %s unknown" % (v, )) e = next(v for v in l_var if v not in d_ent)
except StopIteration:
pass
else:
logger.error("Entity %s unknown: %s" % (e, line))
import sys
sys.exit(1)
return l_var return l_var
d_modif = dict() d_modif = dict()
from irpf90_t import Touch, SoftTouch, Free from irpf90_t import Touch, SoftTouch, Free
from util import flatten from util import flatten
for cmd, l_type in [('is_self_touched', [Touch, SoftTouch]), for cmd, l_type in [('is_self_touched', [Touch, SoftTouch]), ('is_free', [Free])]:
('is_free', [Free])]:
l_line = flatten([self.d_type_lines[type_] for type_ in l_type]) l_line = flatten([self.d_type_lines[type_] for type_ in l_type])
l_name = flatten([find_variable(line) for _, line in l_line]) l_name = flatten([find_variable(line) for _, line in l_line])
@ -175,7 +178,6 @@ class Irpy_comm_world(object):
Routine is a collection of line between Subroutine / Function Routine is a collection of line between Subroutine / Function
''' '''
# ~#~#~#~#~# # ~#~#~#~#~#
# Create the dict # Create the dict
# ~#~#~#~#~# # ~#~#~#~#~#
@ -187,7 +189,9 @@ class Irpy_comm_world(object):
from routine import Routine from routine import Routine
text = self.l_preprocessed_text text = self.l_preprocessed_text
l_rou = [ Routine(text[b:e]) for b, e in zip(l_begin, l_end) if not isinstance(text[b], Program)] l_rou = [
Routine(text[b:e]) for b, e in zip(l_begin, l_end) if not isinstance(text[b], Program)
]
# Now we can create a dict and at it # Now we can create a dict and at it
d_rou = dict() d_rou = dict()
@ -228,14 +232,15 @@ class Irpy_comm_world(object):
import parsed_text import parsed_text
vtuple = [(v, s.same_as, s.regexp) for v, s in d_entity.iteritems()] vtuple = [(v, s.same_as, s.regexp) for v, s in d_entity.iteritems()]
def worker_parsed(filename_text): def worker_parsed(filename_text):
filename, text = filename_text filename, text = filename_text
return parsed_text.get_parsed_text(filename, text, d_entity, d_routine, vtuple) return parsed_text.get_parsed_text(filename, text, d_entity, d_routine, vtuple)
parsed_text_0 = parmap(worker_parsed, self.t_filename_preprocessed_text) parsed_text_0 = parmap(worker_parsed, self.t_filename_preprocessed_text)
from irpf90_t import NoDep, Declaration, Implicit, Use, Cont_provider from irpf90_t import NoDep, Declaration, Implicit, Use, Cont_provider
def moved_to_top_l(ptext): def moved_to_top_l(ptext):
l = [NoDep, Declaration, Implicit, Use, Cont_provider] l = [NoDep, Declaration, Implicit, Use, Cont_provider]
for _, text in ptext: for _, text in ptext:
@ -277,7 +282,7 @@ class Irpy_comm_world(object):
# Module data # Module data
if m.has_irp_module: if m.has_irp_module:
filename = os.path.join(irpdir, '%s.irp.module.F90' % m.filename) filename = os.path.join(irpdir, '%s.irp.module.F90' % m.filename)
text = '\n'.join(m.header + m.head) text = '\n'.join(m.head)
lazy_write_file(filename, '%s\n' % text) lazy_write_file(filename, '%s\n' % text)
# Subroutines # Subroutines
@ -286,8 +291,16 @@ class Irpy_comm_world(object):
lazy_write_file(filename, '%s\n' % text) lazy_write_file(filename, '%s\n' % text)
def create_stack(self): def create_stack(self):
import irp_stack from util import lazy_write_file
irp_stack.create() 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): def create_buildfile(self, ninja):
import build_file import build_file
@ -301,22 +314,10 @@ class Irpy_comm_world(object):
import create_man as c_man import create_man as c_man
c_man.run(self.d_entity, self.d_routine) c_man.run(self.d_entity, self.d_routine)
def create_lock(self): def create_lock(self):
from util import lazy_write_file from util import lazy_write_file
l = sorted(self.d_entity.keys()) from util import ashes_env
out = []
for v in l:
out += self.d_entity[v].locker
out += [ "subroutine irp_init_locks_%s()"%(irpf90_t.irp_id),
" implicit none" ]
for v in l:
out += [ " call irp_lock_%s(.True.)"%v ]
out += [ " call irp_lock_%s(.False.)"%v ]
out += [ "end subroutine", "" ]
str_ = ashes_env.render('irp_lock.f90', {'entity': sorted(self.d_entity)})
filename = os.path.join(irpf90_t.irpdir, 'irp_locks.irp.F90') filename = os.path.join(irpf90_t.irpdir, 'irp_locks.irp.F90')
lazy_write_file(filename, '\n'.join(out)) lazy_write_file(filename, str_)

0
src/lib/__init__.py Normal file
View File

BIN
src/lib/__init__.pyc Normal file

Binary file not shown.

10
src/lib/manager.py Normal file
View File

@ -0,0 +1,10 @@
try:
import irpy
except:
import static_irpy as irpy
try:
import ashes
except:
import static_ashes as ashes

BIN
src/lib/manager.pyc Normal file

Binary file not shown.

2602
src/lib/static_ashes.py Normal file

File diff suppressed because it is too large Load Diff

BIN
src/lib/static_ashes.pyc Normal file

Binary file not shown.

3
src/lib_irpy.py → src/lib/static_irpy.py Executable file → Normal file
View File

@ -1,4 +1,5 @@
#Handle the execution stack #!/usr/bin/python
from collections import defaultdict from collections import defaultdict
d_path = defaultdict(list) d_path = defaultdict(list)
d_last_caller = defaultdict(lambda: None) d_last_caller = defaultdict(lambda: None)

View File

@ -1,4 +1,4 @@
#!/unr/bin/env python #!/usr/bin/env python
# IRPF90 is a Fortran90 preprocessor written in Python for programming using # IRPF90 is a Fortran90 preprocessor written in Python for programming using
# the Implicit Reference to Parameters (IRP) method. # the Implicit Reference to Parameters (IRP) method.
# Copyright (C) 2009 Anthony SCEMAMA # Copyright (C) 2009 Anthony SCEMAMA
@ -30,6 +30,7 @@ import preprocessed_text
from util import * from util import *
from entity import Entity from entity import Entity
def put_info(text, filename): def put_info(text, filename):
lenmax = 80 - len(filename) lenmax = 80 - len(filename)
@ -43,14 +44,13 @@ def put_info(text, filename):
class Fmodule(object): class Fmodule(object):
header = [ "! -*- F90 -*-", header = [
"!", "! -*- F90 -*-", "!", "!-----------------------------------------------!",
"!-----------------------------------------------!",
"! This file was generated with the irpf90 tool. !", "! This file was generated with the irpf90 tool. !",
"! !", "! !",
"! DO NOT MODIFY IT BY HAND !", "! DO NOT MODIFY IT BY HAND !",
"!-----------------------------------------------!", "!-----------------------------------------------!", ""
""] ]
def __init__(self, text, filename, d_variable): def __init__(self, text, filename, d_variable):
self.text = put_info(text, filename) self.text = put_info(text, filename)
@ -74,19 +74,20 @@ class Fmodule(object):
@irpy.lazy_property @irpy.lazy_property
def head(self): def head(self):
'''The module who containt the declaration of the entity''' '''The module who containt the declaration of the entity'''
body = list(self.use)
body += list(self.dec)
body += [header for var in self.l_entity for header in var.header]
if self.use or self.dec or self.l_entity:
if body: d_template = {
result = ["module %s" % (self.name)] 'name': self.name,
result += body 'use': list(self.use),
result += ["end module %s" % (self.name)] '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
}
return [i for i in ashes_env.render('module.f90', d_template).split('\n') if i]
else: else:
result = [] return []
return result
@irpy.lazy_property @irpy.lazy_property
def has_irp_module(self): def has_irp_module(self):
@ -106,17 +107,17 @@ class Fmodule(object):
result = [] result = []
for var in self.l_entity: for var in self.l_entity:
result += var.provider result += var.provider
if not var.is_protected:
result += var.builder result += var.builder
result += var.allocater
if var.is_read: if var.is_read:
result += var.reader result += var.reader
if var.is_written: if var.is_written:
result += var.writer result += var.writer
return result return result
@irpy.lazy_property @irpy.lazy_property
def residual_text_use_dec(self): def residual_text_use_dec(self):
def remove_providers(text): def remove_providers(text):
result = [] result = []
inside = False inside = False
@ -143,12 +144,12 @@ class Fmodule(object):
result.append((vars, line)) result.append((vars, line))
continue continue
if type(line) in [Subroutine, Function, Program]: if type(line) in [Subroutine, Function, Program]:
#Deep copy... #Deep copy...
variable_list = list(vars) variable_list = list(vars)
elif type(line) == End: 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: else:
variable_list += vars variable_list += vars
@ -178,7 +179,6 @@ class Fmodule(object):
elif type(line) == Declaration: elif type(line) == Declaration:
dec.append((vars, line)) dec.append((vars, line))
if isinstance(line, (End, End_interface, End_module)): if isinstance(line, (End, End_interface, End_module)):
inside += -1 inside += -1
@ -192,7 +192,8 @@ class Fmodule(object):
result = modify_functions(result) result = modify_functions(result)
from collections import namedtuple 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)) return Residual_text_use_dec(*extract_use_dec_text(result))
@ -213,14 +214,14 @@ class Fmodule(object):
Because user can define F90 Type, we need to keep the correct order. Because user can define F90 Type, we need to keep the correct order.
Warning: Warning:
If we uniquify that can cause a problem with the type in guess. If we uniquify that can cause a problem.
```type toto ```TYPE toto
integer :: n INTEGER :: n
end type toto END TYPE toto
integer :: n INTEGER :: n
``` ```
Fix: Fix:
We need to support Type keyword. We need to support TYPE keyword.
''' '''
@ -241,7 +242,6 @@ class Fmodule(object):
result += map(lambda x: ([], Simple_line(line.i, x, line.filename)), result += map(lambda x: ([], Simple_line(line.i, x, line.filename)),
build_call_provide(vars, self.d_all_variable)) build_call_provide(vars, self.d_all_variable))
from parsed_text import move_to_top_list, move_interface from parsed_text import move_to_top_list, move_interface
move_to_top_list(result, [Declaration, Implicit, Use]) move_to_top_list(result, [Declaration, Implicit, Use])
move_interface(result) move_interface(result)
@ -250,14 +250,16 @@ class Fmodule(object):
@irpy.lazy_property @irpy.lazy_property
def needed_modules(self): 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: if self.name in l:
l.remove(self.name) l.remove(self.name)
return l return l
@irpy.lazy_property @irpy.lazy_property
def needed_modules_irp(self): def needed_modules_irp(self):
return [i for i in self.needed_modules if i.endswith("_mod")] return [i for i in self.needed_modules if i.endswith("_mod")]
@ -265,5 +267,3 @@ class Fmodule(object):
@irpy.lazy_property @irpy.lazy_property
def needed_modules_usr(self): def needed_modules_usr(self):
return [i for i in self.needed_modules if not i.endswith("_mod")] return [i for i in self.needed_modules if not i.endswith("_mod")]

View File

@ -34,7 +34,8 @@ regexps_re_string_sub = regexps.re_string.sub
def find_variables_in_line(line, vtuple): def find_variables_in_line(line, vtuple):
line_lower = regexps_re_string_sub('', line.lower) line_lower = regexps_re_string_sub('', line.lower)
return [same_as for v, same_as, regexp in vtuple if v in line_lower and regexp(line_lower)] #return [same_as for v,same_as, regexp in vtuple if v in line_lower and regexp(line_lower)]
return [v for v, same_as, regexp in vtuple if v in line_lower and regexp(line_lower)]
def find_funcs_in_line(line, stuple): def find_funcs_in_line(line, stuple):
@ -56,16 +57,19 @@ def check_touch(variables, line, vars, main_vars):
if main_var not in variables: if main_var not in variables:
error.fail(line, "Variable %s unknown" % (main_var, )) error.fail(line, "Variable %s unknown" % (main_var, ))
x = variables[main_var] x = variables[main_var]
return [main_var] + x.others_entity_name return [main_var] + x.l_others_name
all_others = uniquify(flatten(map(fun, main_vars))) all_others = uniquify(flatten(map(fun, main_vars)))
all_others.sort() all_others.sort()
vars.sort() vars.sort()
for x, y in zip(vars, all_others): for x, y in zip(vars, all_others):
if x != y: if x != y:
message = "The following entities should be touched:\n" message = "The following entities should be touched:"
message = "\n".join([message] + map(lambda x: "- %s" % (x, ), all_others)) message = "\n".join([message] + map(lambda x: "- %s" % (x, ), all_others))
error.fail(line, message) from util import logger
logger.error("%s (%s)" % (message, line))
import sys
sys.exit(1)
from collections import namedtuple from collections import namedtuple
@ -96,7 +100,8 @@ def get_parsed_text(filename, text, variables, subroutines, vtuple):
varlist.append(v) varlist.append(v)
variable_list = find_variables_in_line(line, vtuple) variable_list = find_variables_in_line(line, vtuple)
variable_list.remove(variables[v].same_as) variable_list.remove(v)
# variable_list.remove(variables[v].same_as)
append(Parsed_text(variable_list, line)) append(Parsed_text(variable_list, line))
@ -109,7 +114,9 @@ def get_parsed_text(filename, text, variables, subroutines, vtuple):
l = filter(lambda x: x not in varlist, l) l = filter(lambda x: x not in varlist, l)
for v in l: for v in l:
if v not in variables: if v not in variables:
error.fail(line, "Variable %s is unknown" % (v)) logger.error("Variable %s is unknown (%s)" % (v, line))
import sys
sys.exit(1)
append(Parsed_text(l, Provide(line.i, "", line.filename))) append(Parsed_text(l, Provide(line.i, "", line.filename)))
append(Parsed_text(l, Simple_line(line.i, "!%s" % (line.text), line.filename))) append(Parsed_text(l, Simple_line(line.i, "!%s" % (line.text), line.filename)))
@ -119,6 +126,8 @@ def get_parsed_text(filename, text, variables, subroutines, vtuple):
for v in l: for v in l:
if v not in variables: if v not in variables:
error.fail(line, "Variable %s is unknown" % (v)) error.fail(line, "Variable %s is unknown" % (v))
sys.exit(1)
l = map(lambda x: "-%s" % (x), l) l = map(lambda x: "-%s" % (x), l)
append(Parsed_text(l, Simple_line(line.i, "!%s" % (line.text), line.filename))) append(Parsed_text(l, Simple_line(line.i, "!%s" % (line.text), line.filename)))
elif type(line) in [Touch, SoftTouch]: elif type(line) in [Touch, SoftTouch]:
@ -149,8 +158,9 @@ def get_parsed_text(filename, text, variables, subroutines, vtuple):
def fun(x): def fun(x):
if x not in variables: if x not in variables:
error.fail(line, "Variable %s unknown" % (x, )) error.fail(line, "Variable %s unknown" % (x, ))
return Parsed_text( return Parsed_text([],
[], Simple_line(line.i, " %s_is_built = .True." % (x, ), line.filename)) Simple_line(line.i, " %s_is_built = .True." %
(x, ), line.filename))
result += map(fun, main_vars[:-1]) result += map(fun, main_vars[:-1])
if type(line) == SoftTouch: if type(line) == SoftTouch:
@ -198,6 +208,7 @@ def get_parsed_text(filename, text, variables, subroutines, vtuple):
return (filename, result) return (filename, result)
###################################################################### ######################################################################
def move_to_top_list(text, it): def move_to_top_list(text, it):
# ( List[ List[Entity], Line], Iterator) # ( List[ List[Entity], Line], Iterator)
@ -283,7 +294,8 @@ def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Funct
# Get the begin of the insert # Get the begin of the insert
i_insert = [] i_insert = []
for begin in i_begin: 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 # Do the insert and the delete in one passe
for insert, begin, end in zip(i_insert, i_begin, i_end): for insert, begin, end in zip(i_insert, i_begin, i_end):
@ -292,6 +304,7 @@ def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Funct
padding = end - begin padding = end - begin
parsed_text[begin + padding:end + padding] = [] parsed_text[begin + padding:end + padding] = []
###################################################################### ######################################################################
def build_sub_needs(parsed_text, d_subroutine): def build_sub_needs(parsed_text, d_subroutine):
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]], Dict[str:Sub]) -> None #(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]], Dict[str:Sub]) -> None
@ -303,10 +316,14 @@ def build_sub_needs(parsed_text, d_subroutine):
l_buffer = [] l_buffer = []
for _, text in parsed_text: 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_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: for sub, text in l_buffer:
sub.needs = set(v for vs, _ in text for v in vs) sub.needs = set(v for vs, _ in text for v in vs)
@ -329,10 +346,58 @@ def add_subroutine_needs(parsed_text, subroutines):
###################################################################### ######################################################################
def raise_entity(text):
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]]
'''Working progress'''
l_token = []
d_level_var = dict()
d_level_var[0] = []
skip_interface = False
lvl = 0
for i, (e, line) in enumerate(text):
type_ = type(line)
if type_ in [Interface, End_interface]:
skip_interface = not skip_interface
if skip_interface:
continue
if type_ in [Begin_provider, Program, Subroutine, Function, If]:
l_token.append(i)
lvl += 1
d_level_var[lvl] = e[:]
elif type_ in [End_provider, End, Endif]:
i = l_token.pop()
text[i] = (d_level_var[lvl], text[i][1])
lvl += -1
elif type_ in [Else, Elseif]:
i = l_token.pop()
text[i] = (d_level_var[lvl], text[i][1])
assert (type(text[i][1]) == If)
l_token.append(i)
d_level_var[lvl] = e[:]
else:
d_level_var[lvl] += e[:]
text[i] = ([], line)
assert (lvl == 0)
def move_variables(parsed_text): def move_variables(parsed_text):
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]] #(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]]
'''Move variables into the top of the declaraiton''' '''Move variables into the top of the declaraiton.
This need to be optimised to handle the fact that we can have multi-provider
'''
def func(filename, text): def func(filename, text):
result = [] result = []
@ -406,6 +471,10 @@ def move_variables(parsed_text):
result.reverse() result.reverse()
#print '@@@@@@@@@@@@@'
#for i in text:
# print i
# 2nd pass # 2nd pass
text = result text = result
result = [] result = []
@ -447,7 +516,14 @@ def move_variables(parsed_text):
main_result = [] main_result = []
for filename, text in parsed_text: for filename, text in parsed_text:
#for i in text:
# print i
main_result.append((filename, func(filename, text))) main_result.append((filename, func(filename, text)))
#print '==========='
#for i in main_result[-1][1]:
# print i
return main_result return main_result
@ -459,6 +535,7 @@ def build_needs(parsed_text, subroutines, stuple, variables):
# Needs and to_provide # Needs and to_provide
# ~#~#~#~#~# # ~#~#~#~#~#
# Loop of the main Entity
for filename, text in parsed_text: for filename, text in parsed_text:
l_begin = [i for i, (_, line) in enumerate(text) if isinstance(line, Begin_provider)] l_begin = [i for i, (_, line) in enumerate(text) if isinstance(line, Begin_provider)]
@ -485,6 +562,7 @@ def build_needs(parsed_text, subroutines, stuple, variables):
entity.needs = uniquify(l_needs) entity.needs = uniquify(l_needs)
# Now do the Other entity
for v in variables: for v in variables:
main = variables[v].same_as main = variables[v].same_as
if main != v: if main != v:
@ -492,25 +570,17 @@ def build_needs(parsed_text, subroutines, stuple, variables):
variables[v].to_provide = variables[main].to_provide variables[v].to_provide = variables[main].to_provide
# ~#~#~#~#~# # ~#~#~#~#~#
# Needs and to_provide # Needs_by
# ~#~#~#~#~# # ~#~#~#~#~#
from collections import defaultdict
for v in variables: d_needed_by = defaultdict(list)
variables[v].needed_by = [] for var in variables.values():
for v in variables:
main = variables[v].same_as
if main != v:
variables[v].needed_by = variables[main].needed_by
for v in variables:
var = variables[v]
if var.is_main:
for x in var.needs: for x in var.needs:
variables[x].needed_by.append(var.same_as) d_needed_by[x].append(var.name)
for v in variables: for v in d_needed_by:
var = variables[v] variables[v].needed_by = uniquify(d_needed_by[v])
var.needed_by = uniquify(var.needed_by)
###################################################################### ######################################################################
from command_line import command_line from command_line import command_line
@ -549,4 +619,3 @@ def perform_loop_substitutions(parsed_text):
append((vars, line)) append((vars, line))
main_result.append((filename, result)) main_result.append((filename, result))
return main_result return main_result

View File

@ -57,8 +57,11 @@ simple_dict = {
"subst": Subst, "subst": Subst,
"end_doc": End_doc, "end_doc": End_doc,
"begin_provider": Begin_provider, "begin_provider": Begin_provider,
"begin_provider_immutable": Begin_provider,
"&begin_provider": Cont_provider, "&begin_provider": Cont_provider,
"&begin_provider_immutable": Cont_provider,
"end_provider": End_provider, "end_provider": End_provider,
"end_provider_immutable": End_provider,
"assert": Assert, "assert": Assert,
"touch": Touch, "touch": Touch,
"soft_touch": SoftTouch, "soft_touch": SoftTouch,
@ -99,6 +102,7 @@ simple_dict = {
"endwhere": Endwhere, "endwhere": Endwhere,
} }
def get_canonized_text(text_lower): def get_canonized_text(text_lower):
text_canonized = text_lower text_canonized = text_lower
@ -147,13 +151,11 @@ def get_type(i, filename, line, line_lower, line_lower_canonized, is_doc):
type_ = simple_dict[firstword] type_ = simple_dict[firstword]
return [type_(i, line, filename)], is_doc return [type_(i, line, filename)], is_doc
#label do-loop (outer: do i=1,sze) #label do-loop (outer: do i=1,sze)
reg_do_lab = ur":\s+do\s+" reg_do_lab = ur":\s+do\s+"
if re.search(reg_do_lab, line_lower): if re.search(reg_do_lab, line_lower):
return [Do(i, line, filename)], is_doc return [Do(i, line, filename)], is_doc
lower_line = line_lower.strip()[1:] lower_line = line_lower.strip()[1:]
if len(lower_line) <= 3: if len(lower_line) <= 3:
@ -213,9 +215,14 @@ def save_and_execute(irpdir, scriptname, code, interpreter):
# Execute shell # Execute shell
import util import util
try: 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: 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 import sys
sys.exit(1) sys.exit(1)
@ -230,7 +237,6 @@ def execute_shell(text):
# (List[Line]) -> List[Line] # (List[Line]) -> List[Line]
'''Execute the embedded shell scripts''' '''Execute the embedded shell scripts'''
l_begin = [i for i, line in enumerate(text) if isinstance(line, Begin_shell)] 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_end = [i for i, line in enumerate(text) if isinstance(line, End_shell)]
l_output = [] l_output = []
@ -240,6 +246,7 @@ def execute_shell(text):
# ~=~=~=~ # ~=~=~=~
from util import logger from util import logger
import sys import sys
def fail(l, a, b): def fail(l, a, b):
logger.error("%s In Begin_Shell, %s '%s'" % (l, a, b)) logger.error("%s In Begin_Shell, %s '%s'" % (l, a, b))
sys.exit(1) sys.exit(1)
@ -340,7 +347,11 @@ def execute_templates(text):
for v in variables: for v in variables:
script += " t0 = t0.replace('%s',d['%s'])\n" % (v, v) script += " t0 = t0.replace('%s',d['%s'])\n" % (v, v)
script += " print t0\n" 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: else:
subst += line.text + '\n' subst += line.text + '\n'
@ -432,7 +443,6 @@ def remove_comments(text, form):
return str_ return str_
if form == Free_form: if form == Free_form:
for line in text: for line in text:
if type(line) in [Openmp, Doc, Directive]: if type(line) in [Openmp, Doc, Directive]:
@ -544,7 +554,7 @@ def irp_simple_statements(text):
def process_return(line): def process_return(line):
assert type(line) == Return 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) newline = Simple_line(line.i, " call irp_leave(irp_here)", line.filename)
result = [newline, line] result = [newline, line]
else: else:
@ -600,7 +610,7 @@ def irp_simple_statements(text):
def process_end(line): def process_end(line):
'''Add irp_leave if necessary''' '''Add irp_leave if necessary'''
if command_line.do_assert or command_line.do_debug: if command_line.do_debug:
i = line.i i = line.i
f = line.filename f = line.filename
result = [Simple_line(i, " call irp_leave(irp_here)", f), line] result = [Simple_line(i, " call irp_leave(irp_here)", f), line]
@ -615,7 +625,11 @@ def irp_simple_statements(text):
buffer = line.lower.translate(trans).split(',') buffer = line.lower.translate(trans).split(',')
if len(buffer) < 2: 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() varname = buffer[1].strip()
length = len(varname) length = len(varname)
i = line.i i = line.i
@ -624,7 +638,7 @@ def irp_simple_statements(text):
Begin_provider(i, line.text, (f, varname)), Begin_provider(i, line.text, (f, varname)),
Declaration(i, " character*(%d) :: irp_here = '%s'" % (length, varname), f) 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), ] result += [Simple_line(i, " call irp_enter(irp_here)", f), ]
return result return result
@ -644,10 +658,12 @@ def irp_simple_statements(text):
length = len(subname) length = len(subname)
i = line.i i = line.i
f = line.filename 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: if command_line.do_debug:
result += [Simple_line(i, " call irp_enter_f(irp_here)", f), ] result += [Simple_line(i, " call irp_enter_routine(irp_here)", f), ]
return result return result
def process_function(line): def process_function(line):
@ -659,27 +675,42 @@ def irp_simple_statements(text):
result = [ result = [
line, Declaration(i, " character*(%d) :: irp_here = '%s'" % (length, subname), f) line, Declaration(i, " character*(%d) :: irp_here = '%s'" % (length, subname), f)
] ]
if command_line.do_assert or command_line.do_debug: if command_line.do_debug:
result += [Simple_line(i, " call irp_enter_f(irp_here)", f), ] result += [Simple_line(i, " call irp_enter_routine(irp_here)", f), ]
return result return result
def process_program(line): def process_program(line):
assert type(line) == Program assert type(line) == Program
program_name = line.lower.split()[1] program_name = line.lower.split()[1]
temp = [Program(0, "program irp_program", program_name)] temp = [Program(0, "program irp_program", program_name)]
if command_line.do_Task:
for i in [" call omp_set_nested(.TRUE.)", "!$omp parallel", "!$omp single"]:
temp += [Simple_line(0, i, line.filename)]
if command_line.do_profile: if command_line.do_profile:
temp += [Simple_line(0, "call irp_init_timer()", line.filename)] temp += [Simple_line(0, "call irp_init_timer()", line.filename)]
if command_line.do_openmp: # Need to choose between lazy lock or are big full initialization
temp += [Simple_line(0, " call irp_init_locks_%s()" % (irp_id), line.filename)] # 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)] temp += [Call(0, " call %s" % (program_name), line.filename)]
if command_line.do_profile: if command_line.do_profile:
temp += [Simple_line(0, "call irp_print_timer()", line.filename)] temp += [Simple_line(0, "call irp_print_timer()", line.filename)]
temp += [Simple_line(0, " call irp_finalize_%s()" % (irp_id), line.filename)] temp += [Simple_line(0, " call irp_finalize_%s()" % (irp_id), line.filename)]
if command_line.do_Task:
for i in ["!$omp taskwait", "!$omp end single", "!$omp end parallel"]:
temp += [Simple_line(0, i, line.filename)]
temp += [End(0, "end program", line.filename)] temp += [End(0, "end program", line.filename)]
result = temp + process_subroutine( result = temp + process_subroutine(
Subroutine(line.i, "subroutine %s" % (program_name, ), line.filename)) Subroutine(line.i, "subroutine %s" % (program_name, ), line.filename))
return result return result
d = { d = {
@ -696,7 +727,6 @@ def irp_simple_statements(text):
Program: process_program, Program: process_program,
} }
result = [] result = []
for line in text: for line in text:
buffer = [line] buffer = [line]
@ -746,7 +776,8 @@ def process_old_style_do(text):
return return
from util import logger 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 from util import sys
sys.exit(1) sys.exit(1)
@ -831,13 +862,15 @@ def check_begin_end(raw_text):
Maybe more of one 'x' statement in defined cause in 'ifdef/else/endif' statement. Maybe more of one 'x' statement in defined cause in 'ifdef/else/endif' statement.
''' '''
d_block = {Enddo: [Do], d_block = {
Enddo: [Do],
Endif: [If], Endif: [If],
End_provider: [Begin_provider], End_provider: [Begin_provider],
End_doc: [Begin_doc], End_doc: [Begin_doc],
End: [Program, Subroutine, Function], End: [Program, Subroutine, Function],
End_module: [Module], End_module: [Module],
End_interface: [Interface]} End_interface: [Interface]
}
from collections import defaultdict from collections import defaultdict
d_type = defaultdict(list) d_type = defaultdict(list)
@ -852,15 +885,18 @@ def check_begin_end(raw_text):
if n_end != n_begin: if n_end != n_begin:
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: 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]): for i in zip([l for i in l_begin for l in d_type[i]], d_type[t_end]):
logger.debug(i) logger.debug(i)
sys.exit(1) sys.exit(1)
###################################################################### ######################################################################
def remove_ifdefs(text): def remove_ifdefs(text):
assert type(text) == list assert type(text) == list
@ -951,7 +987,8 @@ class Preprocess_text(object):
result = [] result = []
is_doc = False 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) line, is_doc = get_type(i + 1, self.filename, l, ll, llc, is_doc)
result += line result += line
return result return result
@ -978,6 +1015,5 @@ class Preprocess_text(object):
return result return result
if __name__ == '__main__': if __name__ == '__main__':
debug() debug()

View File

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

View File

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

View File

@ -24,22 +24,17 @@
# 31062 Toulouse Cedex 4 # 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr # scemama@irsamc.ups-tlse.fr
from irpf90_t import * from irpf90_t import *
from util import logger from util import logger
from lib.manager import irpy
try:
import irpy
except:
import lib_irpy as irpy
class Routine(object): class Routine(object):
''' '''
A collection of list corresponding of a Routine (Subroutine, or function) A collection of list corresponding of a Routine (Subroutine, or function)
''' '''
############################################################ ############################################################
def __init__(self, text): def __init__(self, text):
assert type(text) == list assert type(text) == list
@ -55,6 +50,7 @@ class Routine(object):
raise AttributeError raise AttributeError
############################################################ ############################################################
@irpy.lazy_property @irpy.lazy_property
def name(self): def name(self):
'''Name is lowercase''' '''Name is lowercase'''
@ -82,7 +78,8 @@ class Routine(object):
############################################################ ############################################################
@irpy.lazy_property @irpy.lazy_property
def touches_my_self(self): 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 @irpy.lazy_property_mutable
def touches_ancestor(self): def touches_ancestor(self):
@ -101,4 +98,6 @@ class Routine(object):
############################################################ ############################################################
@irpy.lazy_property @irpy.lazy_property
def calls(self): 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

@ -0,0 +1,50 @@
{?dim}
SUBROUTINE allocate_{name}
{#l_module}
USE {.}
{/l_module}
IMPLICIT NONE
CHARACTER*(9+{@size key=name/}),PARAMETER :: irp_here = 'allocate_{name}'
INTEGER :: irp_err
LOGICAL :: alloc
alloc = ALLOCATED({name})
IF ( alloc .AND.( &
{#l_dim}
( SIZE({name},{rank}) == {value} ) {@sep}.OR.{/sep} &
{/l_dim})) THEN
RETURN
ELSE IF (.NOT.alloc) THEN
GO TO 666
ELSE
{?do_memory} PRINT*, irp_here//': Deallocated {name}' {/do_memory}
DEALLOCATE({name},STAT=irp_err)
IF (irp_err /= 0) THEN
PRINT*, irp_here//': Deallocation failed: {name}'
PRINT*,' size: {dim}'
ENDIF
GO TO 666
ENDIF
666 CONTINUE
{?do_memory} PRINT*, irp_here//': Allocate {name} ({dim})'{/do_memory}
{^do_corray}
ALLOCATE({name} ({dim}), STAT=irp_err)
{:else}
ALLOCATE({name} ({dim}[*]), STAT=irp_err)
{/do_corray}
IF (irp_err /= 0) then
PRINT*, irp_here//': Allocation failed: {name}'
PRINT*,' size: {dim}'
ENDIF
END SUBROUTINE allocate_{name}
{/dim}

View File

@ -0,0 +1,13 @@
SUBROUTINE irp_finalize_{id}
{#use}
USE {.}
{/use}
IMPLICIT NONE
{#entity_array}
IF (ALLOCATED({name})) THEN
{name_root}_is_built = .FALSE.
DEALLOCATE({name})
ENDIF
{/entity_array}
END SUBROUTINE irp_finalize_{id}

View File

@ -0,0 +1,94 @@
# make | ninja
##############
BUILD_SYSTEM= {BUILD_SYSTEM}
#######
IRPF90= irpf90
IRPF90FLAGS= {irpf90_flags}
.EXPORT_ALL_VARIABLES:
LIB = {LIB}
SRC = {SRC}
OBJ = {OBJ}
# Compiler ! Will be overwriten by the ENV one if avalaible.
FC ?= {FC}
FCFLAGS ?= {FCFLAGS}
CC ?= {CC}
CFLAGS ?= {CFLAGS}
CXX ?= {CXX}
CXXFLAGS ?= {CXXFLAGS}
# Dark magic below modify with caution!
# "You are Not Expected to Understand This"
# .
# /^\ .
# /\ "V",
# /__\ I O o
# //..\\ I .
# \].`[/ I
# /l\/j\ (] . O
# /. ~~ ,\/I .
# \\L__j^\/I o
# \/--v} I o .
# | | I _________
# | | I c(` ')o
# | l I \. ,/
# _/j L l\_! _// \\_
#Misc
AR ?= {ar}
RANLIB ?= {ranlib}
# Variable need by IRPF90
BUILD_SYSTEM_stripped=$(strip $(BUILD_SYSTEM))
ifeq ($(BUILD_SYSTEM_stripped),ninja)
BUILD_FILE=IRPF90_temp/build.ninja
IRPF90FLAGS += -j
else ifeq ($(BUILD_SYSTEM_stripped),make)
BUILD_FILE=IRPF90_temp/build.make
BUILD_SYSTEM += -j
else
DUMMY:
$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')
endif
# Actual Rule
EXE := $(shell egrep -ri '^\s*program' *.irp.f | cut -d'.' -f1)
ARCH = $(addprefix $(CURDIR)/,IRPF90_temp/irpf90.a)
.PHONY: clean all
all: $(EXE)
define run
$(BUILD_SYSTEM_stripped) -C $(dir $(BUILD_FILE) ) -f $(notdir $(BUILD_FILE) ) $(1)
endef
#We allow for the user to ask for 'relative' path
#But the IRPF90 build system use absolute path.
$(EXE): $(ARCH)
@printf "%b" "\033[0;32m Build $@...\033[m\n"
@$(call run, $(addprefix $(CURDIR)/, $@)) && touch $@
.NOTPARALLEL: $(BUILD_FILE) $(ARCH)
$(ARCH): $(BUILD_FILE)
@printf "%b" "\033[0;32m Creating the archive...\033[m\n"
@$(call run, $@) && touch $@
$(BUILD_FILE): $(shell find . -maxdepth 2 -path ./IRPF90_temp -prune -o -name '*.irp.f' -print)
@printf "%b" "\033[0;32m Running the IRPF90-compiler...\033[m\n"
@$(IRPF90) $(IRPF90FLAGS)
clean:
rm -f -- $(BUILD_FILE) $(EXE)
veryclean: clean
rm -rf IRPF90_temp/ IRPF90_man/ irpf90_entities dist tags

71
src/templates/ioer.f90 Normal file
View File

@ -0,0 +1,71 @@
SUBROUTINE writer_{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 writer_{.}(irp_num)
{/children}
DO WHILE (irp_is_open)
irp_iunit = irp_iunit + 1
INQUIRE(UNIT=irp_iunit, OPENED=irp_is_open)
END DO
{#group_entity}
OPEN(UNIT=irp_iunit,file='irpf90_{name}_'//trim(irp_num),FORM='FORMATTED',STATUS='UNKNOWN',ACTION='WRITE')
WRITE(irp_iunit,*) {name}{dim}
CLOSE(irp_iunit)
{/group_entity}
{?do_debug} CALL irp_leave(irp_here) {/do_debug}
END SUBROUTINE writer_{name}
!TOKEN_SPLIT
SUBROUTINE reader_{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_iunit + 1
INQUIRE(UNIT=irp_iunit, OPENED=irp_is_open)
END DO
{#group_entity}
OPEN(UNIT=irp_iunit,file='irpf90_{name}_'//trim(irp_num),FORM='FORMATTED',STATUS='OLD',ACTION='READ')
READ(irp_iunit,*) {name}{dim}
CLOSE(irp_iunit)
{/group_entity}
CALL touch_{same_as}
{?do_debug} CALL irp_leave(irp_here) {/do_debug}
END SUBROUTINE reader_{name}

View File

@ -0,0 +1,31 @@
{#entity}
SUBROUTINE irp_lock_{.}(set)
USE omp_lib
IMPLICIT NONE
LOGICAL, INTENT(in) :: set
INTEGER(KIND=omp_lock_kind),SAVE :: {.}_lock
INTEGER, SAVE :: ifirst = 0
{?do_debug}
CHARACTER*(9+{@size key={.}/}),PARAMETER :: irp_here = 'irp_lock_{name}'
{/do_debug}
{?do_debug} CALL irp_enter(irp_here) {/do_debug}
IF (ifirst == 0) then
ifirst = 1
CALL omp_init_lock({.}_lock)
ENDIF
IF (set) THEN
CALL omp_set_lock({.}_lock)
ELSE
CALL omp_unset_lock({.}_lock)
ENDIF
{?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

39
src/templates/module.f90 Normal file
View File

@ -0,0 +1,39 @@
! -*- F90 -*-
!
!-----------------------------------------------!
! This file was generated with the irpf90 tool. !
! !
! DO NOT MODIFY IT BY HAND !
!-----------------------------------------------!
MODULE {name}
{#use}
USE {.}
{/use}
{#usr_declaration}
{.}
{/usr_declaration}
{#irp_declaration}
{^dim}
{type} {?protected}, PROTECTED {/protected} :: {name} {?coarray} [*] {/coarray}
{:else}
{?align} !DIR$ ATTRIBUTES ALIGN: {align} :: {name} {/align}
{type} {?protected}, PROTECTED {/protected} :: {name} {dim} {?coarray} [:] {/coarray}
{/dim}
{?main}
LOGICAL :: {name}_is_built = .FALSE.
{/main}
{/irp_declaration}
CONTAINS
{#irp_declaration}
{protected|s}
{/irp_declaration}
END MODULE {name}

View File

@ -0,0 +1,45 @@
{?inline}!DEC$ ATTRIBUTES FORCEINLINE :: provide_{name}{/inline}
SUBROUTINE provide_{name}
{#l_module}
USE {.}
{/l_module}
IMPLICIT NONE
{?do_debug}
CHARACTER*(8+{@size key=name/}),PARAMETER :: irp_here = 'provide_{name}'
{/do_debug}
{?do_debug} CALL irp_enter(irp_here) {/do_debug}
{?do_openmp}
CALL irp_lock_{name}(.TRUE.)
IF (.NOT.{name}_is_built) THEN
{/do_openmp}
{#l_children_static}
{@first} {?do_task}!$OMP TASKGROUP{/do_task} {/first}
{?do_openmp}!$OMP flush({.}_is_built){/do_openmp}
IF (.NOT.{.}_is_built) THEN
{?do_task}!$OMP TASK{/do_task}
CALL provide_{.}
{?do_task}!$OMP END TASK{/do_task}
ENDIF
{@last} {?do_task}!$OMP END TASKGROUP{/do_task} {/last}
{/l_children_static}
{#l_entity}
{?dim} CALL allocate_{name} {/dim}
{/l_entity}
CALL bld_{name}
{name}_is_built = .TRUE.
{?do_openmp}
ENDIF
CALL irp_lock_{name}(.FALSE.)
{/do_openmp}
{?do_debug} CALL irp_leave(irp_here) {/do_debug}
END SUBROUTINE provide_{name}

26
src/templates/touch.f90 Normal file
View File

@ -0,0 +1,26 @@
{#entity}
SUBROUTINE touch_{name}
{#l_module}
USE {.}
{/l_module}
IMPLICIT NONE
{?do_debug}
CHARACTER*(6+{@size key=name/}),PARAMETER :: irp_here = 'touch_{name}'
{/do_debug}
{?do_debug} CALL irp_enter(irp_here) {/do_debug}
{#l_ancestor}
{.}_is_built = .FALSE.
{/l_ancestor}
{name}_is_built = .TRUE.
{?do_debug} CALL irp_leave(irp_here) {/do_debug}
END SUBROUTINE touch_{name}
{/entity}

View File

@ -26,40 +26,38 @@
from irpf90_t import irp_id, irpdir from irpf90_t import irp_id, irpdir
import os import os
from util import lazy_write_file from command_line import command_line
def create(modules, variables): def create(modules, variables):
# (Dict[str,Module]. Dict[str, Variable]) -> None # (Dict[str,Module]. Dict[str, Variable]) -> None
'''Create the fortran90 finalize subroutine and the touched one''' '''Create the fortran90 finalize subroutine and the touched one'''
finalize = "subroutine irp_finalize_%s\n"%(irp_id)
for m in filter(lambda x: not modules[x].is_main and modules[x].has_irp_module, modules):
finalize += " use %s\n"%(modules[m].name)
main_modules_name = [m.name for m in modules.values() if m.is_main] main_modules_name = [m.name for m in modules.values() if m.is_main]
out = [] d_template_finalize = {
for v,var in variables.iteritems(): '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]
}
if var.fmodule not in main_modules_name: d_template_touch = {
#if var.is_self_touched: 'do_debug': command_line.do_debug,
out += var.toucher 'entity': [
if var.dim: e.d_touche_template for e in variables.values()
finalize += " if (allocated(%s)) then\n"%v if e.fmodule not in main_modules_name and e.d_touche_template
finalize += " %s_is_built = .False.\n"%var.same_as ]
finalize += " deallocate(%s)\n"%v }
finalize += " endif\n" import util
str_out = util.ashes_env.render('touch.f90', d_template_touch) + util.ashes_env.render(
finalize += "end\n" 'finalize.f90', d_template_finalize)
if out:
out = map(lambda x: "%s\n"%(x),out)
out += finalize
filename = os.path.join(irpdir, 'irp_touches.irp.F90') filename = os.path.join(irpdir, 'irp_touches.irp.F90')
lazy_write_file(filename,''.join(out)) util.lazy_write_file(filename, '%s\n' % util.remove_empy_lines(str_out))
if __name__ == '__main__': if __name__ == '__main__':
create() create()

View File

@ -24,7 +24,6 @@
# 31062 Toulouse Cedex 4 # 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr # scemama@irsamc.ups-tlse.fr
# ~#~#~#~#~# # ~#~#~#~#~#
# L o g e r # L o g e r
# ~#~#~#~#~# # ~#~#~#~#~#
@ -42,10 +41,22 @@ logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('Irpf90') logger = logging.getLogger('Irpf90')
logger.setLevel(30) logger.setLevel(30)
# ~#~#~#~#~#
# A S H E S _ T E M P L A T E S
# ~#~#~#~#~#
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()])
# ~#~#~#~#~# # ~#~#~#~#~#
# / / _ R E L A T E D # / / _ R E L A T E D
# ~#~#~#~#~# # ~#~#~#~#~#
def chunkify(l, n_chunk): def chunkify(l, n_chunk):
# (List[any], int) -> List [ List[any] ] # (List[any], int) -> List [ List[any] ]
'''Split the list on n_chunk''' '''Split the list on n_chunk'''
@ -55,6 +66,8 @@ def chunkify(l,n_chunk):
import multiprocessing import multiprocessing
def parmap(f, it, parallel=False): def parmap(f, it, parallel=False):
# (Callable, Iterable, bool) -> List # (Callable, Iterable, bool) -> List
'''Parallel version of the std map function '''Parallel version of the std map function
@ -99,12 +112,12 @@ def parmap(f, it, parallel=False):
# (aka 1 job by processor) # (aka 1 job by processor)
it_chunk = chunkify(l=it, n_chunk=nproc) it_chunk = chunkify(l=it, n_chunk=nproc)
def F(chunk): def F(chunk):
# (List[any]) -> (List[any]) # (List[any]) -> (List[any])
'''Same as 'f' but for a chunck''' '''Same as 'f' but for a chunck'''
return map(f, chunk) return map(f, chunk)
q_in = multiprocessing.JoinableQueue() q_in = multiprocessing.JoinableQueue()
q_out = multiprocessing.Queue() q_out = multiprocessing.Queue()
# All the worker will sepuku after reseaving this message # All the worker will sepuku after reseaving this message
@ -172,6 +185,8 @@ def parmap(f, it, parallel=False):
# ~#~#~#~#~# # ~#~#~#~#~#
import hashlib import hashlib
import os import os
def cached_file(filename, text): def cached_file(filename, text):
# (str,str) -> bool # (str,str) -> bool
'''Check if file locatte at filename containt the same data as text '''Check if file locatte at filename containt the same data as text
@ -207,6 +222,7 @@ def lazy_write_file(filename, text, conservative=False,touch=False):
elif touch: elif touch:
os.utime(filename, None) os.utime(filename, None)
def listdir(directory, abspath=False): def listdir(directory, abspath=False):
#(str, bool) -> List[str] #(str, bool) -> List[str]
'''Replacement of the std:listdir but with the possibility to get the abosulte path''' '''Replacement of the std:listdir but with the possibility to get the abosulte path'''
@ -217,6 +233,7 @@ def listdir(directory, abspath=False):
else: else:
return [os.path.abspath(os.path.join(directory, f)) for f in l_filename] return [os.path.abspath(os.path.join(directory, f)) for f in l_filename]
def check_output(*popenargs, **kwargs): def check_output(*popenargs, **kwargs):
"""Run command with arguments and return its output as a byte string. """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. Backported from Python 2.7 as it's implemented as pure python on stdlib.
@ -243,20 +260,29 @@ def check_output(*popenargs, **kwargs):
def uniquify(l, sort=False): def uniquify(l, sort=False):
# (Iter, bool) -> List[Any] # (Iter, bool) -> List[Any]
'''Uniquify a immutable iterable. Don't preserve the order''' '''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)) r = list(set(l))
except TypeError:
used = list()
r = [x for x in l if x not in used and (used.append(x) or True)]
if not sort: if not sort:
return r return r
else: else:
return sorted(r) return sorted(r)
def OrderedUniqueList(l): def OrderedUniqueList(l):
# (Iter, bool) -> List[Any] # (Iter, bool) -> List[Any]
'''Uniquify a immutable iterable. Don't preserve the order''' '''Uniquify a immutable iterable. Don't preserve the order'''
return sorted(set(l)) return sorted(set(l))
def flatten(l_2d): def flatten(l_2d):
# (List [ List[Any] ]) -> List # (List [ Iter[Any] ]) -> List
'''Construct a copy of the 2d list collapsed into one dimension. '''Construct a copy of the 2d list collapsed into one dimension.
Note: Note:
@ -269,6 +295,28 @@ def flatten(l_2d):
# ~#~#~#~#~# # ~#~#~#~#~#
# I R P _ R E L A T E D # I R P _ R E L A T E D
# ~#~#~#~#~# # ~#~#~#~#~#
def dimsize(x):
# (str) -> str
'''Compute the number of element in the array'''
try:
b0, b1 = x.split(':')
except ValueError:
return x
b0_is_digit = b0.replace('-', '').isdigit()
b1_is_digit = b1.replace('-', '').isdigit()
if b0_is_digit and b1_is_digit:
size = str(int(b1) - int(b0) + 1)
elif b0_is_digit:
size = "(%s) - (%d)" % (b1, int(b0) - 1)
elif b1_is_digit:
size = "(%d) - (%s)" % (int(b1) + 1, b0)
else:
size = "(%s) - (%s) + 1" % (b1, b0)
return size
def build_dim(l_dim, colons=False): def build_dim(l_dim, colons=False):
# (List[str],bool) -> str # (List[str],bool) -> str
'''Contruct a valid fortran90 array dimension code from a list dimension '''Contruct a valid fortran90 array dimension code from a list dimension
@ -286,20 +334,71 @@ def build_dim(l_dim, colons=False):
return "(%s)" % (",".join(l_dim_colons)) return "(%s)" % (",".join(l_dim_colons))
def build_use(l_ent, d_ent): 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 # (List, Dict[str,Entity]) -> list
'''Contruct the fortran90 'use' statement for the list of entity''' '''Contruct the fortran90 'use' statement for the list of entity'''
return OrderedUniqueList(" use %s" % d_ent[x].fmodule for x in l_ent)
l_name = OrderedUniqueList(d_ent[x].fmodule for x in l_ent)
if not use:
return l_name
else:
return [" use %s" % n for n in l_name]
def build_call_provide(l_ent, d_ent): def build_call_provide(l_ent, d_ent):
# (List, Dict[str,Entity]) -> list # (List, Dict[str,Entity]) -> list
'''Construct the fortran 90 call the provider needed by the list of entity''' '''Construct the fortran 90 call the provider needed by the list of entity'''
def fun(x):
return [ " if (.not.%s_is_built) then" % x,
" call provide_%s" % x,
" endif"]
# Get the corect name (in the case of multiple provider line) # Get the corect name (in the case of multiple provider line)
l_same_as = OrderedUniqueList(d_ent[x].same_as for x in l_ent) l_same_as = mangled(l_ent, d_ent)
return flatten(map(fun, l_same_as))
def bld_f90(x):
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.
Note:
This will destry 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])
]:
results.append(pop(0))
return results
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
]
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
Note: Head and Tail a not defined in set. Head in one element of the set, and tail the rest.
'''
l_set = [set(s) for s in l_set_org]
l_main = [s.pop() for s in l_set]
return l_main, set(flatten(l_set))

View File

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