mirror of
https://gitlab.com/scemama/irpf90.git
synced 2024-12-22 04:13:33 +01:00
commit
dd2afebb0d
@ -1,13 +1,69 @@
|
||||
IRPF90 = python ../src/irpf90.py -I input -a -d
|
||||
FC = ifort
|
||||
FCFLAGS= -O2
|
||||
NINJA =
|
||||
IRPF90= irpf90
|
||||
IRPF90FLAGS= -I ./ -I input/
|
||||
BUILD_SYSTEM= make
|
||||
|
||||
SRC=
|
||||
OBJ=
|
||||
LIB=
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
|
||||
include irpf90.make
|
||||
AR = ar
|
||||
CC = gcc
|
||||
CFLAGS = -O2
|
||||
CXX = g++
|
||||
CXXFLAGS = -O2
|
||||
FC = gfortran
|
||||
FCFLAGS = -O2
|
||||
LIB =
|
||||
RANLIB = ranlib
|
||||
|
||||
irpf90.make: $(wildcard *.irp.f)
|
||||
$(IRPF90)
|
||||
OBJ =
|
||||
SRC =
|
||||
|
||||
# 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\_! _//^---^\\_
|
||||
|
||||
|
||||
ifeq ($(BUILD_SYSTEM),ninja)
|
||||
BUILD_FILE=IRPF90_temp/build.ninja
|
||||
IRPF90FLAGS += -j
|
||||
else ifeq ($(BUILD_SYSTEM),make)
|
||||
BUILD_FILE=IRPF90_temp/build.make
|
||||
BUILD_SYSTEM += -j
|
||||
else
|
||||
DUMMY:
|
||||
$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')
|
||||
endif
|
||||
|
||||
define run_and_touch
|
||||
$(BUILD_SYSTEM) -C $(dir $(1) ) -f $(notdir $(1) ) $(addprefix $(CURDIR)/, $(2)) && touch $(2)
|
||||
endef
|
||||
|
||||
EXE := $(shell egrep -r '^\s*program' *.irp.f | awk '{print $$2}')
|
||||
|
||||
.PHONY: all
|
||||
|
||||
all: $(BUILD_FILE)
|
||||
$(call run_and_touch, $<, $(EXE))
|
||||
|
||||
.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)
|
||||
$(IRPF90) $(IRPF90FLAGS)
|
||||
|
||||
clean:
|
||||
rm -f -- $(BUILD_FILE) $(EXE) $(shell find IRPF90_temp -type f \( -name "*.o" -o -name "*.mod" -name "*.a" \) -delete;)
|
||||
veryclean: clean
|
||||
rm -rf IRPF90_temp/ IRPF90_man/ irpf90_entities dist tags
|
||||
|
@ -1,12 +1,8 @@
|
||||
program irp_example1
|
||||
! integer :: x(W)
|
||||
BEGIN_SHELL [ /bin/bash ]
|
||||
echo print *, \'Compiled by `whoami` on `date`\'
|
||||
echo print *, \'$FC $FCFLAGS\'
|
||||
echo print *, \'$IRPF90\'
|
||||
END_SHELL
|
||||
print *, 't = ', t
|
||||
|
||||
print *, 'v=', v
|
||||
! print *, u2
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
BEGIN_PROVIDER [ integer, t ]
|
||||
BEGIN_PROVIDER [integer, t ]
|
||||
t = u1+v+4
|
||||
END_PROVIDER
|
||||
|
||||
@ -7,6 +7,7 @@ BEGIN_PROVIDER [integer,w]
|
||||
END_PROVIDER
|
||||
|
||||
BEGIN_PROVIDER [ integer, v ]
|
||||
implicit none
|
||||
v = u2+w+2
|
||||
END_PROVIDER
|
||||
|
||||
@ -18,6 +19,7 @@ END_PROVIDER
|
||||
BEGIN_PROVIDER [ integer, u2 ]
|
||||
integer :: fu
|
||||
u2 = fu(d3,d4)
|
||||
!df
|
||||
END_PROVIDER
|
||||
|
||||
integer function fu(x,y)
|
||||
|
3
src/.style.yapf
Normal file
3
src/.style.yapf
Normal file
@ -0,0 +1,3 @@
|
||||
[style]
|
||||
based_on_style = pep8
|
||||
COLUMN_LIMIT = 100
|
537
src/build_file.py
Normal file
537
src/build_file.py
Normal file
@ -0,0 +1,537 @@
|
||||
#!/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 os, sys
|
||||
import irpf90_t
|
||||
from command_line import command_line
|
||||
|
||||
from os.path import basename
|
||||
|
||||
irpdir = irpf90_t.irpdir
|
||||
mandir = irpf90_t.mandir
|
||||
irp_id = irpf90_t.irp_id
|
||||
|
||||
cwd = os.getcwd()
|
||||
|
||||
def dress(f, in_root=False):
|
||||
#(str,bool) -> str
|
||||
""" Transfoms the filename into $PWD/IRPF90_temp/f
|
||||
|
||||
Note:
|
||||
In root=True resurn $PWD/f
|
||||
"""
|
||||
|
||||
pwd = os.getcwd()
|
||||
if in_root:
|
||||
result = os.path.join(pwd, f)
|
||||
else:
|
||||
result = os.path.join(pwd, irpdir, f)
|
||||
return os.path.normpath(result)
|
||||
|
||||
|
||||
def create_build_touches(l_irp_m, ninja):
|
||||
|
||||
irp_id = irpf90_t.irp_id
|
||||
name = "irp_touches"
|
||||
short_target_o = "%s.irp.o" % name
|
||||
short_target_F90 = "%s.irp.F90" % name
|
||||
target_o = dress(short_target_o)
|
||||
target_F90 = dress(short_target_F90)
|
||||
|
||||
list_of_modules_irp = ' '.join(l_irp_m)
|
||||
|
||||
result_ninja = '\n'.join([
|
||||
"build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_modules_irp}",
|
||||
" short_in = {short_target_F90}",
|
||||
" short_out = {short_target_o}",
|
||||
""
|
||||
])
|
||||
|
||||
result_make = '\n'.join([
|
||||
"{target_o}: {target_F90} | {list_of_modules_irp}",
|
||||
'\t@printf "F: {short_target_F90} -> {short_target_o}\\n"',
|
||||
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", ""
|
||||
])
|
||||
|
||||
result = result_ninja if ninja else result_make
|
||||
|
||||
return result.format(**locals())
|
||||
|
||||
|
||||
def create_build_archive(l_irp_o, l_usr_o_wo_main, l_ext_o, l_irp_sup_o, ninja=True):
|
||||
# (List[str] * 6 ) -> str
|
||||
"""Create the build command for the irp_touches.o file and the irpf90.a library.
|
||||
|
||||
- the touch file need all the irp_module.
|
||||
- the archive file need all the object.
|
||||
|
||||
"""
|
||||
|
||||
irp_id = irpf90_t.irp_id
|
||||
short_lib = "irpf90.a"
|
||||
lib = dress(short_lib)
|
||||
|
||||
list_of_object = ' '.join(l_irp_o + l_usr_o_wo_main + l_ext_o + l_irp_sup_o)
|
||||
|
||||
result_ninja = '\n'.join([
|
||||
"build {lib}: archive_{irp_id} {list_of_object}",
|
||||
" short_out = {short_lib}",
|
||||
""])
|
||||
|
||||
result_make = '\n'.join([
|
||||
"{lib}: {list_of_object}",
|
||||
'\t@printf "Archive: {short_lib}\\n"',
|
||||
"\t@$(AR) cr $@ $^", ""])
|
||||
|
||||
result = result_ninja if ninja else result_make
|
||||
return result.format(**locals())
|
||||
|
||||
|
||||
def create_build_link(t, l_irp_m, l_usr_m, l_ext_m, ninja=True):
|
||||
# (Module, List[str], List[str]) -> str
|
||||
""" Create the build command who will link the .o file into the target executable
|
||||
|
||||
To link we need the .o file corresponding to the target, and the ar lib.
|
||||
"""
|
||||
|
||||
irp_id = irpf90_t.irp_id
|
||||
|
||||
filename = t.filename
|
||||
progname = t.prog_name
|
||||
|
||||
basename = os.path.basename(filename)
|
||||
if basename != progname:
|
||||
from util import logger
|
||||
logger.info('program-name `{0}` != file-name `{1}` (using file-name for now...)'.format(progname,basename))
|
||||
|
||||
target = dress(filename, in_root=True)
|
||||
short_target = filename
|
||||
short_target_o = "%s.irp.o" % filename
|
||||
|
||||
target_o = dress(short_target_o)
|
||||
|
||||
list_of_module = ' '.join(l_irp_m + l_usr_m + l_ext_m)
|
||||
irp_lib = dress("irpf90.a")
|
||||
|
||||
result_ninja = '\n'.join([
|
||||
"build {target}: link_{irp_id} {target_o} {irp_lib} | {list_of_module}",
|
||||
" short_out = {short_target}",
|
||||
""])
|
||||
|
||||
result_make = '\n'.join([
|
||||
"{target}:{target_o} {irp_lib} | {list_of_module}",
|
||||
'\t@printf "Link: {short_target}\\n"',
|
||||
"\t@$(FC) $^ $(LIB) -o $@",
|
||||
""])
|
||||
|
||||
result = result_ninja if ninja else result_make
|
||||
|
||||
return result.format(**locals())
|
||||
|
||||
|
||||
def create_build_compile(t, l_module, l_ext_modfile=[], ninja=True):
|
||||
# (Module, List[Module], List[str], bool) -> str
|
||||
"""Create the build command for the module t.
|
||||
|
||||
- The module can produce a .MOD file
|
||||
- The module can Need another .MOD file.
|
||||
This .MOD file can be produced by:
|
||||
1) a file generated by IRP_F90 preprocessor.
|
||||
2) a file defined by the user but a .irp.f90 file.
|
||||
3) a file not handle at all by IRPF90.
|
||||
|
||||
- The fortran90 file maybe created by the Python module need no dependency.
|
||||
|
||||
"""
|
||||
|
||||
irp_id = irpf90_t.irp_id
|
||||
name = t.filename
|
||||
|
||||
short_target = name
|
||||
target = dress(name, in_root=True)
|
||||
|
||||
short_target_o = "%s.irp.o" % name
|
||||
short_target_F90 = "%s.irp.F90" % name
|
||||
|
||||
target_o = dress(short_target_o)
|
||||
target_F90 = dress(short_target_F90)
|
||||
|
||||
# Here is the hack. We don't check MOD files, but the associated .o.
|
||||
# MOD name are not part of the standart.
|
||||
|
||||
needed_modules = [dress(x, in_root=True) for x in l_ext_modfile]
|
||||
|
||||
# Expensive and stupid. We can create a dict to do the loockup only once
|
||||
for m in t.needed_modules_usr:
|
||||
# m is name
|
||||
for x in l_module:
|
||||
if m in x.gen_mod and x.filename != t.filename:
|
||||
needed_modules.append("%s.irp.o" % x.filename)
|
||||
|
||||
from util import uniquify
|
||||
needed_modules = uniquify(needed_modules)
|
||||
|
||||
needed_modules_irp = [
|
||||
"%s.irp.module.o" % (x.filename) for x in l_module if x.name in t.needed_modules_irp
|
||||
]
|
||||
|
||||
if t.has_irp_module:
|
||||
short_target_module_F90 = "%s.irp.module.F90" % name
|
||||
short_target_module_o = "%s.irp.module.o" % name
|
||||
|
||||
target_module_o = dress(short_target_module_o)
|
||||
target_module_F90 = dress(short_target_module_F90)
|
||||
needed_modules_irp += [target_module_o]
|
||||
|
||||
list_of_modules = ' '.join(map(dress, needed_modules))
|
||||
list_of_modules_irp = ' '.join(map(dress, needed_modules_irp))
|
||||
|
||||
inline_include = True
|
||||
if not inline_include:
|
||||
#Wrong name, this not work!
|
||||
#list_of_includes = ' '.join(map(lambda x: dress(x, in_root=True), t.includes))
|
||||
raise NotImplemented
|
||||
else:
|
||||
#The include have already by included
|
||||
list_of_includes = ' '
|
||||
|
||||
l_build = [
|
||||
"build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}",
|
||||
" short_in = {short_target_F90}",
|
||||
" short_out = {short_target}",
|
||||
""
|
||||
]
|
||||
|
||||
l_build_make = [
|
||||
"{target_o}: {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}",
|
||||
'\t@printf "F: {short_target_F90} -> {short_target}\\n"',
|
||||
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", ""
|
||||
]
|
||||
|
||||
# No need of module when compiling the irp_module.
|
||||
if t.has_irp_module:
|
||||
l_build += [
|
||||
"build {target_module_o}: compile_fortran_{irp_id} {target_module_F90} | {list_of_includes} {list_of_modules} ",
|
||||
" short_in = {short_target_module_F90}",
|
||||
" short_out = {short_target_module_o}",
|
||||
""
|
||||
]
|
||||
|
||||
l_build_make += [
|
||||
"{target_module_o}: {target_module_F90} | {list_of_includes} {list_of_modules}",
|
||||
'\t@printf "F: {short_target_module_F90} -> {short_target_module_o}\\n"',
|
||||
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", ""
|
||||
]
|
||||
|
||||
l_cur = l_build if ninja else l_build_make
|
||||
return '\n'.join(l_cur).format(**locals())
|
||||
|
||||
|
||||
def create_build_remaining(f,ninja):
|
||||
"""
|
||||
Create the build command for the remaining file f. f is a file name (str).
|
||||
"""
|
||||
|
||||
irp_id = irpf90_t.irp_id
|
||||
|
||||
t, extension = f.rsplit('.', 1)
|
||||
t1 = dress(t, in_root=True)
|
||||
t2 = dress(t, in_root=False)
|
||||
target_i = f
|
||||
target_o = "%s.o" % t
|
||||
|
||||
if not target_o.startswith(os.path.join(cwd, irpdir)):
|
||||
target_o = target_o.replace(cwd, os.path.join(cwd, irpdir))
|
||||
|
||||
short_target_o = os.path.split(target_o)[1]
|
||||
short_target_i = os.path.split(target_i)[1]
|
||||
|
||||
if extension.lower() in ['f', 'f90']:
|
||||
result = ["build {target_o}: compile_fortran_{irp_id} {target_i}"]
|
||||
elif extension.lower() in ['c']:
|
||||
result = ["build {target_o}: compile_c_{irp_id} {target_i}"]
|
||||
elif extension.lower() in ['cxx', 'cpp']:
|
||||
result = ["build {target_o}: compile_cxx_{irp_id} {target_i}"]
|
||||
|
||||
result += [" short_in = {short_target_i}", " short_out = {short_target_o}", ""]
|
||||
return '\n'.join(result).format(**locals())
|
||||
|
||||
|
||||
def create_makefile(d_flags,d_var,irpf90_flags,ninja=True):
|
||||
|
||||
result = ["IRPF90= irpf90",
|
||||
"IRPF90FLAGS= %s" % irpf90_flags,
|
||||
"BUILD_SYSTEM= %s" % ('ninja' if ninja else 'make'),
|
||||
""]
|
||||
|
||||
# Export all the env variable used by irpf90
|
||||
result += ['.EXPORT_ALL_VARIABLES:',
|
||||
'',
|
||||
'\n'.join("{0} = {1}".format(k, v) for k, v in sorted(d_flags.iteritems())),
|
||||
'',
|
||||
'\n'.join("{0} = {1}".format(k, ' '.join(v)) for k, v in sorted(d_var.iteritems())),
|
||||
'']
|
||||
|
||||
result += [ r'# Dark magic below modify with caution!',
|
||||
r'# "You are Not Expected to Understand This"',
|
||||
r"# .",
|
||||
r"# /^\ .",
|
||||
r'# /\ "V",',
|
||||
r"# /__\ I O o",
|
||||
r"# //..\\ I .",
|
||||
r"# \].`[/ I",
|
||||
r"# /l\/j\ (] . O",
|
||||
r"# /. ~~ ,\/I .",
|
||||
r"# \\L__j^\/I o",
|
||||
r"# \/--v} I o .",
|
||||
r"# | | I _________",
|
||||
r"# | | I c(` ')o",
|
||||
r"# | l I \. ,/",
|
||||
r"# _/j L l\_! _//^---^\\_",
|
||||
r""]
|
||||
|
||||
result += ["",
|
||||
"ifeq ($(BUILD_SYSTEM),ninja)",
|
||||
"\tBUILD_FILE=IRPF90_temp/build.ninja",
|
||||
"\tIRPF90FLAGS += -j",
|
||||
"else ifeq ($(BUILD_SYSTEM),make)",
|
||||
"\tBUILD_FILE=IRPF90_temp/build.make",
|
||||
"\tBUILD_SYSTEM += -j",
|
||||
"else",
|
||||
"DUMMY:",
|
||||
"\t$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')",
|
||||
"endif"]
|
||||
|
||||
result += ["",
|
||||
"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
|
||||
data = '%s\n' % '\n'.join(result)
|
||||
util.lazy_write_file('Makefile',data,conservative=True)
|
||||
|
||||
def create_make_all_clean(l_main):
|
||||
#
|
||||
'''Create the ALL and CLEAN target of Makefile
|
||||
|
||||
Note: Portability doesn't mater. -delete is maybe not posix
|
||||
but -exec rm {} + is far more ugly!
|
||||
|
||||
'''
|
||||
|
||||
l_executable =' '.join(dress( t.filename, in_root=True) for t in l_main)
|
||||
|
||||
output = [".PHONY : all",
|
||||
"all: {l_executable}",
|
||||
"",
|
||||
".PHONY: clean",
|
||||
"clean:",
|
||||
'\tfind . -type f \( -name "*.o" -o -name "*.mod" \) -delete; rm -f {l_executable} --'
|
||||
""]
|
||||
|
||||
return [ '\n'.join(output).format(**locals())]
|
||||
|
||||
def create_var_and_rule(d_flags, ninja):
|
||||
|
||||
output = ['\n'.join("{0} = {1}".format(k, v) for k, v in d_flags.iteritems())]
|
||||
|
||||
if ninja:
|
||||
output += ["builddir = %s" % os.path.join(cwd, irpdir)]
|
||||
|
||||
# Rules
|
||||
t = [
|
||||
"rule compile_fortran_{irp_id}",
|
||||
" command = $FC $FCFLAGS -c $in -o $out",
|
||||
" description = F : $short_in -> $short_out",
|
||||
"",
|
||||
"rule compile_c_{irp_id}",
|
||||
" command = $CC $CFLAGS -c $in -o $out",
|
||||
" description = C : $short_in -> $short_out",
|
||||
"",
|
||||
"rule compile_cxx_{irp_id}",
|
||||
" command = $CXX $CXXFLAGS -c $in -o $out",
|
||||
" description = C++ : $short_in -> $short_out",
|
||||
"",
|
||||
"rule archive_{irp_id}",
|
||||
" command = $AR cr $out $in",
|
||||
" description = Archive: $short_out",
|
||||
"",
|
||||
"rule link_{irp_id}",
|
||||
" command = $FC $FCFLAGS $in $LIB -o $out",
|
||||
" description = Link: $short_out",
|
||||
""
|
||||
]
|
||||
|
||||
output += ['\n'.join(t).format(irp_id=irpf90_t.irp_id, **d_flags)]
|
||||
|
||||
return output
|
||||
|
||||
|
||||
# Environment variables
|
||||
|
||||
d_default = {
|
||||
"FC": "gfortran",
|
||||
"FCFLAGS": "-O2",
|
||||
"AR": "ar",
|
||||
"RANLIB": " ranlib",
|
||||
"CC": "gcc",
|
||||
"CFLAGS": "-O2",
|
||||
"CXX": "g++",
|
||||
"CXXFLAGS": "-O2",
|
||||
"LIB": ""}
|
||||
|
||||
d_flags = dict()
|
||||
for k, v in d_default.iteritems():
|
||||
d_flags[k] = os.environ[k] if k in os.environ else v
|
||||
|
||||
include_dir = ' ' + ' '.join(["-I %s" % (i) for i in command_line.include_dir])
|
||||
|
||||
d_var = dict()
|
||||
for k in ['SRC', 'OBJ']:
|
||||
d_var[k] = os.environ[k].split() if k in os.environ else []
|
||||
|
||||
|
||||
def create_generalmakefile(ninja):
|
||||
create_makefile(d_flags,d_var, include_dir,ninja)
|
||||
|
||||
def run(d_module, ninja):
|
||||
#(Dict[str,Module],bool) -> str
|
||||
"""Wrote the ninja file needed to compile the program
|
||||
|
||||
Note:
|
||||
- FC,AR,CC,CXX,LIB, FCFLAGS, CFLAGS, CXXFLAGS are compiler enviroment read
|
||||
- SRC,OBJ: Are the not irp.f file defined by the user
|
||||
"""
|
||||
|
||||
# Add required flags
|
||||
|
||||
for k in ['FCFLAGS', 'CFLAGS', 'CXXFLAGS']:
|
||||
d_flags[k] += include_dir
|
||||
|
||||
# Each python module can produce one or two .F90/.o file and maybe one .MOD file:
|
||||
#
|
||||
# No usr defined module and no IRP-F90 provider declaration:
|
||||
# - One .F90 - No .MOD file
|
||||
# Usr defined module AND no IRP-F90 provider:
|
||||
# - One .F90 - One. MOD file
|
||||
# No usr define module AND IRP-F90 provider:
|
||||
# - Two .F90 - One. MOD file
|
||||
|
||||
# Each python module can depend of different module:
|
||||
# - IRP created one
|
||||
# - usr declared
|
||||
# - external (don't know by IRP)
|
||||
|
||||
# Each python module can need 3 type of .MOD file
|
||||
l_mod = list(d_module.values())
|
||||
|
||||
# Modules that are not targets
|
||||
l_mod_no_main = filter(lambda m: not m.is_main, l_mod)
|
||||
l_mod_main = filter(lambda m: m.is_main, l_mod)
|
||||
|
||||
# List irp supl object/source files
|
||||
l_irp_sup_o = ["irp_touches.irp.o"]
|
||||
l_irp_sup_s = ["irp_touches.irp.F90"]
|
||||
|
||||
if command_line.do_assert:
|
||||
l_irp_sup_o += ["irp_stack.irp.o"]
|
||||
l_irp_sup_s += ["irp_stack.irp.F90"]
|
||||
|
||||
if command_line.do_openmp:
|
||||
l_irp_sup_o += ["irp_locks.irp.o"]
|
||||
l_irp_sup_s += ["irp_locks.irp.F90"]
|
||||
|
||||
if command_line.do_profile:
|
||||
l_irp_sup_o += ["irp_profile.irp.o", "irp_rdtsc.o"]
|
||||
l_irp_sup_s += ["irp_profile.irp.F90", "irp_rdtsc.c"]
|
||||
|
||||
l_irp_sup_o = map(dress, l_irp_sup_o)
|
||||
l_irp_sup_s = map(dress, l_irp_sup_s)
|
||||
|
||||
# List of extrernal object/source file
|
||||
l_ext_o = l_ext_m = map(lambda x: dress(x, in_root=True), d_var['OBJ'])
|
||||
l_ext_s = map(lambda x: dress(x, in_root=True), d_var['SRC'])
|
||||
|
||||
# List of object create by the IRP-F90
|
||||
l_irp_o = l_irp_m = map(dress,
|
||||
["%s.irp.module.o" % (m.filename) for m in l_mod if m.has_irp_module])
|
||||
|
||||
# List of object create by the USR. Maybe he have a module, maybe not.
|
||||
l_usr_o_wo_main = map(dress, ["%s.irp.o" % (m.filename) for m in l_mod_no_main])
|
||||
l_usr_m = map(dress, ["%s.irp.o" % (m.filename) for m in l_mod if m.needed_modules_usr])
|
||||
|
||||
#-=~=~=
|
||||
# O U T P U T
|
||||
#~=~=~=
|
||||
|
||||
output = create_var_and_rule(d_flags, ninja)
|
||||
if not ninja:
|
||||
output += create_make_all_clean(l_mod_main)
|
||||
|
||||
# Create all the .irp.F90 -> .o
|
||||
for m in l_mod:
|
||||
output.append(create_build_compile(m, l_mod, l_ext_m, ninja))
|
||||
|
||||
output.append(create_build_touches(l_irp_m,ninja))
|
||||
# All the objects. Kind of, only need usr without main for the static library
|
||||
output.append(create_build_archive(l_irp_o, l_usr_o_wo_main, l_ext_o, l_irp_sup_o, ninja))
|
||||
|
||||
for i in l_mod_main:
|
||||
# All the mod (overshoot)
|
||||
output.append(create_build_link(i, l_irp_m, l_usr_m, l_ext_m, ninja))
|
||||
|
||||
# Remaining files
|
||||
for i in l_irp_sup_s[1:]+l_ext_s:
|
||||
output.append(create_build_remaining(i, ninja))
|
||||
|
||||
filename = os.path.join(irpdir, "build.ninja" if ninja else "build.make")
|
||||
|
||||
data = '%s\n' % '\n\n'.join(output)
|
||||
import util
|
||||
util.lazy_write_file(filename,data,touch=True)
|
||||
|
||||
return
|
@ -1,73 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
|
||||
# the Implicit Reference to Parameters (IRP) method.
|
||||
# Copyright (C) 2009 Anthony SCEMAMA
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Anthony Scemama
|
||||
# LCPQ - IRSAMC - CNRS
|
||||
# Universite Paul Sabatier
|
||||
# 118, route de Narbonne
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from irpf90_t import *
|
||||
from util import *
|
||||
from variables import variables
|
||||
from modules import modules
|
||||
|
||||
CHECKPOINT_UNIT_NUMBER=63
|
||||
|
||||
FILENAME=irpdir+'irp_checkpoint.irp.F90'
|
||||
|
||||
def create():
|
||||
out_write = [ "subroutine irp_checkpoint_write" ]
|
||||
l = variables.keys()
|
||||
l.sort
|
||||
main_modules = filter(lambda x: modules[x].is_main, modules)
|
||||
for m in filter(lambda x: not modules[x].is_main, modules):
|
||||
out_write += [ " use %s"%(modules[m].name) ]
|
||||
out_write += [ " implicit none" ]
|
||||
out_write += [ " integer, parameter :: iunit = %d"%(CHECKPOINT_UNIT_NUMBER) ]
|
||||
out_write += [ " open(unit=%d,file='irp_checkpoint.dat',status='UNKNOWN',action='WRITE')"%(CHECKPOINT_UNIT_NUMBER) ]
|
||||
for v in l:
|
||||
var = variables[v]
|
||||
if var.is_main:
|
||||
out_write += [ " if (%s_is_built) then"%(v) ]
|
||||
for w in [v]+var.others:
|
||||
d = variables[w].dim
|
||||
if d == []:
|
||||
out_write += [ " write(iunit,*) '%s', 0"%(w) ]
|
||||
else:
|
||||
out_write += [ " write(iunit, *) '%s', %d"%(w, len(d)),
|
||||
" write(iunit, *) %s"%(",".join(
|
||||
[ "size(%s,%d)"%(w,i+1) for i in range(len(d)) ] ))
|
||||
]
|
||||
out_write += [ " write(iunit,*) %s"%(w) ]
|
||||
out_write += [ " endif" ]
|
||||
out_write += [ " close(%d)"%(CHECKPOINT_UNIT_NUMBER) ]
|
||||
out_write += [ "end" ]
|
||||
|
||||
out = '\n'.join(out_write)
|
||||
if not same_file(FILENAME,out):
|
||||
file = open(FILENAME,'w')
|
||||
file.writelines(out)
|
||||
file.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
create()
|
||||
|
@ -63,8 +63,7 @@ end
|
||||
precondition = ""
|
||||
else:
|
||||
precondition = "PROVIDE "+precondition
|
||||
file = open(filename,'w')
|
||||
file.write(template%locals())
|
||||
file.close()
|
||||
|
||||
|
||||
from util import lazy_write_file
|
||||
lazy_write_file(filename,template%locals())
|
||||
|
||||
|
@ -24,6 +24,11 @@
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
try:
|
||||
import irpy
|
||||
except:
|
||||
import lib_irpy as irpy
|
||||
|
||||
|
||||
import getopt, sys
|
||||
from version import version
|
||||
@ -52,6 +57,7 @@ options['t'] = [ 'touch' , 'Display which entities are touched when touch
|
||||
options['v'] = [ 'version' , 'Prints version of irpf90', 0 ]
|
||||
options['w'] = [ 'warnings' , 'Activate Warnings', 0 ]
|
||||
options['z'] = [ 'openmp' , 'Activate for OpenMP code', 0 ]
|
||||
options['G'] = [ 'graph' , 'Print the dependecy-graph of the entities (dots format)', 0 ]
|
||||
|
||||
class CommandLine(object):
|
||||
|
||||
@ -61,17 +67,16 @@ class CommandLine(object):
|
||||
self.argv = list(sys.argv)
|
||||
self.executable_name = self.argv[0]
|
||||
|
||||
@irpy.lazy_property
|
||||
def defined(self):
|
||||
if '_defined' not in self.__dict__:
|
||||
self._defined = []
|
||||
for o,a in self.opts:
|
||||
if o in [ "-D", '--'+options['D'][0] ]:
|
||||
self._defined.append(a)
|
||||
return self._defined
|
||||
defined = property(fget=defined)
|
||||
return [ a for o,a in self.opts if o in [ "-D", '--'+options['D'][0] ] ]
|
||||
|
||||
@irpy.lazy_property
|
||||
def graph(self):
|
||||
return next((a.split() for o,a in self.opts if o in ["-G", '--'+options['G'][0] ]),[])
|
||||
|
||||
@irpy.lazy_property
|
||||
def include_dir(self):
|
||||
if '_include_dir' not in self.__dict__:
|
||||
self._include_dir = []
|
||||
for o,a in self.opts:
|
||||
if o in [ "-I", '--'+options['I'][0] ]:
|
||||
@ -80,41 +85,32 @@ class CommandLine(object):
|
||||
if a[-1] != '/':
|
||||
a = a+'/'
|
||||
self._include_dir.append(a)
|
||||
return self._include_dir
|
||||
include_dir = property(fget=include_dir)
|
||||
|
||||
return self._include_dir
|
||||
|
||||
@irpy.lazy_property
|
||||
def inline(self):
|
||||
if '_inline' not in self.__dict__:
|
||||
self._inline = ""
|
||||
for o,a in self.opts:
|
||||
if o in [ "-n", '--'+options['n'][0] ]:
|
||||
self._inline = a
|
||||
break
|
||||
return self._inline
|
||||
inline = property(fget=inline)
|
||||
return next( (a for o,a in self.opts if o in [ "-n", '--'+options['n'][0] ]),'')
|
||||
|
||||
@irpy.lazy_property
|
||||
def substituted(self):
|
||||
if '_substituted' not in self.__dict__:
|
||||
self._substituted = {}
|
||||
for o,a in self.opts:
|
||||
if o in [ "-s", '--'+options['s'][0] ]:
|
||||
k, v = a.split(':')
|
||||
v_re = re.compile(r"(\W)(%s)(\W.*$|$)"%k.strip())
|
||||
self._substituted[k] = [v, v_re]
|
||||
return self._substituted
|
||||
substituted = property(fget=substituted)
|
||||
return self._substituted
|
||||
|
||||
@irpy.lazy_property
|
||||
def codelet(self):
|
||||
if '_codelet' not in self.__dict__:
|
||||
self._codelet = []
|
||||
for o,a in self.opts:
|
||||
if o in [ "-c", '--'+options['c'][0] ]:
|
||||
buffer = a.split(':')
|
||||
filename = 'codelet_'+buffer[0]+'.irp.f'
|
||||
if len(buffer) == 2:
|
||||
self._codelet = [buffer[0], int(buffer[1]), None, filename]
|
||||
return [buffer[0], int(buffer[1]), None, filename]
|
||||
elif len(buffer) == 3:
|
||||
self._codelet = [buffer[0], int(buffer[2]), buffer[1], filename]
|
||||
return [buffer[0], int(buffer[2]), buffer[1], filename]
|
||||
else:
|
||||
print """
|
||||
Error in codelet definition. Use:
|
||||
@ -123,80 +119,38 @@ or
|
||||
--codelet=provider:precondition:NMAX
|
||||
"""
|
||||
sys.exit(1)
|
||||
return self._codelet
|
||||
codelet = property(fget=codelet)
|
||||
|
||||
def preprocessed(self):
|
||||
if '_preprocessed' not in self.__dict__:
|
||||
self._preprocessed = []
|
||||
for o,a in self.opts:
|
||||
if o in [ "-p", '--'+options['p'][0] ]:
|
||||
self._preprocessed.append(a)
|
||||
return self._preprocessed
|
||||
preprocessed = property(fget=preprocessed)
|
||||
@irpy.lazy_property
|
||||
def preprocessed(self):
|
||||
return [a for o,a in self.ops if o in [ "-p", '--'+options['p'][0] ] ]
|
||||
|
||||
@irpy.lazy_property
|
||||
def touched(self):
|
||||
if '_touched' not in self.__dict__:
|
||||
self._touched = []
|
||||
for o,a in self.opts:
|
||||
if o in [ "-t", '--'+options['t'][0] ]:
|
||||
self._touched.append(a.lower())
|
||||
return self._touched
|
||||
touched = property(fget=touched)
|
||||
return [a for o,a in self.ops if o in [ "-t", '--'+options['t'][0] ] ]
|
||||
|
||||
@irpy.lazy_property
|
||||
def align(self):
|
||||
if '_align' not in self.__dict__:
|
||||
self._align = '1'
|
||||
for o,a in self.opts:
|
||||
if o in [ "-l", '--'+options['l'][0] ]:
|
||||
self._align = a
|
||||
return self._align
|
||||
align = property(fget=align)
|
||||
return next( (a for o,a in self.opts if o in [ "-l", '--'+options['l'][0] ]),'1')
|
||||
|
||||
@irpy.lazy_property
|
||||
def coarray(self):
|
||||
if '_coarray' not in self.__dict__:
|
||||
self._coarray = False
|
||||
for o,a in self.opts:
|
||||
if o in [ "-C", '--'+options['C'][0] ]:
|
||||
self._coarray = True
|
||||
return self._coarray
|
||||
coarray = property(fget=coarray)
|
||||
return any(o for o,a in self.opts if o in [ "-C", '--'+options['C'][0] ])
|
||||
|
||||
@irpy.lazy_property
|
||||
def warnings(self):
|
||||
if '_warnings' not in self.__dict__:
|
||||
self._warnings= False
|
||||
for o,a in self.opts:
|
||||
if o in [ "-w", '--'+options['w'][0] ]:
|
||||
self._warnings= True
|
||||
return self._warnings
|
||||
do_warnings = property(fget=warnings)
|
||||
return any(o for o,a in self.opts if o in [ "-W", '--'+options['W'][0] ])
|
||||
|
||||
@irpy.lazy_property
|
||||
def openmp(self):
|
||||
if '_openmp' not in self.__dict__:
|
||||
self._openmp = False
|
||||
for o,a in self.opts:
|
||||
if o in [ "-z", '--'+options['z'][0] ]:
|
||||
self._openmp = True
|
||||
return self._openmp
|
||||
do_openmp = property(fget=openmp)
|
||||
return any(o for o,a in self.opts if o in [ "-z", '--'+options['z'][0] ])
|
||||
|
||||
@irpy.lazy_property
|
||||
def ninja(self):
|
||||
if '_ninja' not in self.__dict__:
|
||||
self._ninja = False
|
||||
for o,a in self.opts:
|
||||
if o in [ "-j", '--'+options['j'][0] ]:
|
||||
self._ninja = True
|
||||
return self._ninja
|
||||
do_ninja = property(fget=ninja)
|
||||
return any(o for o,a in self.opts if o in [ "-j", '--'+options['j'][0] ])
|
||||
|
||||
@irpy.lazy_property
|
||||
def directives(self):
|
||||
if '_directives' not in self.__dict__:
|
||||
self._directives = True
|
||||
for o,a in self.opts:
|
||||
if o in [ "-r", '--'+options['r'][0] ]:
|
||||
self._directives = False
|
||||
return self._directives
|
||||
directives = property(fget=directives)
|
||||
return not(any(o for o,a in self.opts if o in [ "-r", '--'+options['r'][0] ]))
|
||||
|
||||
def usage(self):
|
||||
t = """
|
||||
@ -251,17 +205,10 @@ do_$LONG = property(fget=do_$LONG)
|
||||
for short in options:
|
||||
long = options[short][0]
|
||||
exec t.replace("$LONG",long).replace("$SHORT",short) #in locals()
|
||||
|
||||
|
||||
@irpy.lazy_property
|
||||
def do_run(self):
|
||||
if '_do_run' not in self.__dict__:
|
||||
self._do_run = not ( \
|
||||
self.do_version or \
|
||||
self.do_help or \
|
||||
self.do_preprocess or \
|
||||
self.do_touch or \
|
||||
self.do_init )
|
||||
return self._do_run
|
||||
do_run = property(fget=do_run)
|
||||
return not(any( (self.do_version, self.do_help, self.do_preprocess, self.do_touch, self.do_init)))
|
||||
|
||||
|
||||
command_line = CommandLine()
|
||||
|
@ -24,166 +24,171 @@
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
from entity import Entity
|
||||
from routine import Routine
|
||||
from irpf90_t import mandir
|
||||
from util import parmap, build_dim,lazy_write_file
|
||||
import os
|
||||
|
||||
from variable import Variable
|
||||
from variables import variables
|
||||
from subroutine import Sub
|
||||
from subroutines import subroutines
|
||||
from irpf90_t import *
|
||||
from util import *
|
||||
def do_print_short(entity):
|
||||
assert type(entity) == Entity
|
||||
str_ = "{0:<35} : {1:<30} :: {2:<25} {3}".format(entity.prototype.filename[0],
|
||||
entity.type,
|
||||
entity.name,
|
||||
build_dim(entity.dim)) # yapf: disable
|
||||
return [str_]
|
||||
|
||||
|
||||
def do_print_short(file,var):
|
||||
assert type(var) == Variable
|
||||
print >>file, "%s : %s :: %s %s"%( \
|
||||
var.line.filename[0].ljust(35),
|
||||
var.type.ljust(30),
|
||||
var.name.ljust(25),
|
||||
build_dim(var.dim) )
|
||||
|
||||
######################################################################
|
||||
def process_doc(file,line):
|
||||
assert type(line) == str
|
||||
line = line.strip()
|
||||
if line == "":
|
||||
line = ".br"
|
||||
print >>file, line
|
||||
def process_doc(line):
|
||||
assert type(line) == str
|
||||
line = line.strip()
|
||||
return [line if line else ".br"]
|
||||
|
||||
|
||||
######################################################################
|
||||
def process_deps(file,l):
|
||||
assert type(l) == list
|
||||
for v in l:
|
||||
print >>file, "%s\n.br"%(v,)
|
||||
def process_deps(l):
|
||||
assert isinstance(l, (list, set))
|
||||
return ['%s\n.br' % v for v in sorted(l)]
|
||||
|
||||
|
||||
######################################################################
|
||||
def process_types(file,var):
|
||||
assert type(var) == Variable
|
||||
vars = [var.name] + var.others
|
||||
for var in vars:
|
||||
name = var
|
||||
var = variables[var]
|
||||
Type = var.type
|
||||
dim = build_dim(var.dim)
|
||||
print >>file, "%s\t:: %s\t%s"%(Type,name,dim)
|
||||
def process_types(entity_input, d_entity):
|
||||
assert type(entity_input) == Entity
|
||||
|
||||
l_name = [entity_input.name] + entity_input.others_entity_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) )
|
||||
for name,entity in zip(l_name,l_entity) ] # yapf: disable
|
||||
|
||||
return l
|
||||
|
||||
|
||||
######################################################################
|
||||
def do_print(var):
|
||||
assert type(var) == Variable
|
||||
filename = var.line.filename[0]
|
||||
name = var.name
|
||||
file = open("%s%s.l"%(mandir,var.name), "w")
|
||||
print >>file, '.TH "IRPF90 entities" l %s "IRPF90 entities" %s'%(name,name)
|
||||
if var.same_as != var.name:
|
||||
var = variables[var.same_as]
|
||||
print >>file, ".SH Declaration"
|
||||
print >>file, ".nf"
|
||||
process_types(file,var)
|
||||
print >>file, ".ni"
|
||||
if var.doc != []:
|
||||
print >>file, ".SH Description"
|
||||
for l in var.doc:
|
||||
process_doc(file,l)
|
||||
print >>file, ".SH File\n.P"
|
||||
print >>file, filename
|
||||
if var.needs != []:
|
||||
var.needs.sort()
|
||||
print >>file, ".SH Needs"
|
||||
process_deps(file,var.needs)
|
||||
if var.needed_by != []:
|
||||
var.needed_by.sort()
|
||||
print >>file, ".SH Needed by"
|
||||
process_deps(file,var.needed_by)
|
||||
print >>file, ".SH Instability factor"
|
||||
fo = len(var.children)
|
||||
fi = len(var.parents)
|
||||
print >>file, "%5.1f %%"%(100.* (fi / (fi+fo+.000001) ))
|
||||
print >>file, ".br"
|
||||
file.close()
|
||||
def do_print(entity, d_entity):
|
||||
assert type(entity) == Entity
|
||||
filename = entity.prototype.filename[0]
|
||||
name = entity.name
|
||||
|
||||
l_data = []
|
||||
|
||||
l_data.append('.TH "IRPF90 entities" l {0} "IRPF90 entities" {0}'.format(name))
|
||||
|
||||
if entity.same_as != entity.name:
|
||||
entity = d_entity[entity.same_as]
|
||||
l_data.extend([".SH Declaration", ".nf"])
|
||||
l_data += process_types(entity, d_entity)
|
||||
|
||||
l_data.append(".ni")
|
||||
|
||||
if entity.doc:
|
||||
l_data.append(".SH Description")
|
||||
for l in entity.doc:
|
||||
l_data += process_doc(l)
|
||||
|
||||
l_data.append(".SH File\n.P")
|
||||
l_data.append(filename)
|
||||
|
||||
if entity.needs:
|
||||
l_data.append(".SH Needs")
|
||||
l_data += process_deps(entity.needs)
|
||||
|
||||
if entity.needed_by:
|
||||
l_data.append(".SH Needed by")
|
||||
l_data += process_deps(entity.needed_by)
|
||||
|
||||
l_data.append(".SH Instability factor")
|
||||
fo = len(entity.children)
|
||||
fi = len(entity.parents)
|
||||
l_data.append("%5.1f %%" % (100. * (fi / (fi + fo + .000001))))
|
||||
l_data.append(".br")
|
||||
str_ = '\n'.join(l_data)
|
||||
lazy_write_file("%s%s.l" % (mandir, name), '%s\n' % str_)
|
||||
|
||||
|
||||
######################################################################
|
||||
def process_declaration_subroutine(file, sub):
|
||||
print >>file, sub.line.text.split('!')[0].strip()
|
||||
|
||||
# for line in sub.text:
|
||||
######################################################################
|
||||
def do_print_subroutines(sub):
|
||||
assert type(sub) == Sub
|
||||
filename = sub.line.filename
|
||||
name = sub.name
|
||||
file = open("%s%s.l"%(mandir,sub.name), "w")
|
||||
print >>file, '.TH "IRPF90 entities" l %s "IRPF90 entities" %s'%(name,name)
|
||||
print >>file, ".SH Declaration"
|
||||
print >>file, ".nf"
|
||||
process_declaration_subroutine(file,sub)
|
||||
print >>file, ".ni"
|
||||
if sub.doc != []:
|
||||
print >>file, ".SH Description"
|
||||
for l in sub.doc:
|
||||
process_doc(file,l)
|
||||
print >>file, ".SH File\n.P"
|
||||
print >>file, filename
|
||||
if sub.needs != []:
|
||||
sub.needs.sort()
|
||||
print >>file, ".SH Needs"
|
||||
process_deps(file,sub.needs)
|
||||
if sub.called_by != []:
|
||||
sub.called_by.sort()
|
||||
print >>file, ".SH Called by"
|
||||
process_deps(file,sub.called_by)
|
||||
if sub.calls != []:
|
||||
sub.calls.sort()
|
||||
print >>file, ".SH Calls"
|
||||
process_deps(file,sub.calls)
|
||||
if sub.touches != []:
|
||||
sub.touches.sort()
|
||||
print >>file, ".SH Touches"
|
||||
process_deps(file,sub.touches)
|
||||
print >>file, ".SH Instability factor"
|
||||
fo = len(sub.needs)+len(sub.calls)+len(sub.touches)
|
||||
fi = len(sub.called_by)
|
||||
print >>file, "%5.1f %%"%(100.* (fi / (fi+fo+.000001) ))
|
||||
print >>file, ".br"
|
||||
file.close()
|
||||
assert type(sub) == Routine
|
||||
filename = sub.prototype.filename
|
||||
name = sub.name
|
||||
l_data = []
|
||||
|
||||
l_data.append('.TH "IRPF90 entities" l {0} "IRPF90 entities" {0}'.format(name))
|
||||
l_data.append(".SH Declaration")
|
||||
l_data.append(".nf")
|
||||
l_data += [sub.prototype.text]
|
||||
l_data.append(".ni")
|
||||
if sub.doc:
|
||||
l_data.append(".SH Description")
|
||||
for l in sub.doc:
|
||||
l_data += process_doc(l)
|
||||
l_data.append(".SH File\n.P")
|
||||
|
||||
l_data.append(filename)
|
||||
if sub.needs:
|
||||
l_data.append(".SH Needs")
|
||||
l_data += process_deps(sub.needs)
|
||||
|
||||
if sub.called_by:
|
||||
l_data.append(".SH Called by")
|
||||
l_data += process_deps(sub.called_by)
|
||||
|
||||
if sub.calls:
|
||||
l_data.append(".SH Calls")
|
||||
l_data += process_deps(sub.calls)
|
||||
|
||||
if sub.touches:
|
||||
l_data.append(".SH Touches")
|
||||
l_data += process_deps(sub.touches)
|
||||
|
||||
l_data.append(".SH Instability factor")
|
||||
fo = len(sub.needs) + len(sub.calls) + len(sub.touches)
|
||||
fi = len(sub.called_by)
|
||||
l_data.append("%5.1f %%" % (100. * (fi / (fi + fo + .000001))))
|
||||
l_data.append(".br")
|
||||
|
||||
str_ = '\n'.join(l_data)
|
||||
|
||||
return '%s\n' % str_
|
||||
|
||||
#lazy_write_file(filename="%s.l" % os.path.join(mandir, name), text='%s\n' % str_)
|
||||
|
||||
|
||||
######################################################################
|
||||
def run():
|
||||
import parsed_text
|
||||
import os,sys
|
||||
pid1 = os.fork()
|
||||
if pid1 == 0:
|
||||
for v in variables.values():
|
||||
do_print(v)
|
||||
for s in subroutines.values():
|
||||
do_print_subroutines(s)
|
||||
sys.exit(0)
|
||||
def run(d_entity, d_routine):
|
||||
|
||||
for v in d_entity.values():
|
||||
do_print(v, d_entity)
|
||||
|
||||
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]
|
||||
|
||||
|
||||
def worker(l):
|
||||
filename, text = l
|
||||
lazy_write_file(filename, text)
|
||||
|
||||
parmap(worker, l_data_to_write)
|
||||
|
||||
pid2 = os.fork()
|
||||
if pid2 == 0:
|
||||
tags = []
|
||||
l = variables.keys()
|
||||
file = open("irpf90_entities","w")
|
||||
l.sort()
|
||||
for v in l:
|
||||
do_print_short(file,variables[v])
|
||||
line = variables[v].line
|
||||
# tags.append( '%s\t%s\t/%s/;"\n'%(v,line.filename[0],line.text.split('!')[0].strip()) )
|
||||
tags.append( '%s\t%s\t%d\n'%(v,line.filename[0],line.i) )
|
||||
file.close()
|
||||
l = subroutines.keys()
|
||||
for v in l:
|
||||
line = subroutines[v].line
|
||||
# tags.append('%s\t%s\t/%s/;"\n'%(v,line.filename,line.text.split('!')[0].strip()))
|
||||
tags.append('%s\t%s\t%d\n'%(v,line.filename,line.i))
|
||||
tags.sort()
|
||||
file = open("tags","w")
|
||||
for line in tags:
|
||||
file.write(line)
|
||||
file.close()
|
||||
sys.exit(0)
|
||||
|
||||
os.waitpid(pid1,0)
|
||||
os.waitpid(pid2,0)
|
||||
for v in d_entity.keys():
|
||||
line = d_entity[v].prototype
|
||||
tags.append('%s\t%s\t%d\n' % (v, line.filename[0], line.i))
|
||||
|
||||
for v in d_routine.keys():
|
||||
line = d_routine[v].prototype
|
||||
tags.append('%s\t%s\t%d\n' % (v, line.filename, line.i))
|
||||
|
||||
lazy_write_file("tags", ''.join(sorted(tags)))
|
||||
|
||||
l_data = [e for k, v in sorted(d_entity.items()) for e in do_print_short(v)]
|
||||
str_ = '\n'.join(l_data)
|
||||
lazy_write_file(filename="irpf90_entities", text='%s\n' % str_)
|
||||
|
||||
######################################################################
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
run()
|
||||
|
@ -32,21 +32,10 @@ import os
|
||||
to_remove = """__init__.py cython_setup.py version.py command_line.py""".split()
|
||||
ext_modules = []
|
||||
|
||||
files = os.listdir('.')
|
||||
for file in to_remove:
|
||||
files.remove(file)
|
||||
|
||||
for file in files:
|
||||
if file.endswith(".py"):
|
||||
module = file.split('.')[0]
|
||||
ext_modules += [ Extension(module,[file]) ]
|
||||
|
||||
setup(
|
||||
name = 'IRPF90 extensions',
|
||||
cmdclass = {'build_ext': build_ext},
|
||||
ext_modules = ext_modules
|
||||
)
|
||||
|
||||
|
||||
|
||||
for f in os.listdir('.') if f.emswith(".py") and not f in to_remove:
|
||||
module = f.split('.')[0]
|
||||
ext_modules.append(Extension(module,list(f)))
|
||||
|
||||
setup(name = 'IRPF90 extensions',
|
||||
cmdclass = {'build_ext': build_ext},
|
||||
ext_modules = ext_modules)
|
||||
|
726
src/entity.py
Normal file
726
src/entity.py
Normal file
@ -0,0 +1,726 @@
|
||||
#!/usr/bin/env python
|
||||
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
|
||||
# the Implicit Reference to Parameters (IRP) method.
|
||||
# Copyright (C) 2009 Anthony SCEMAMA
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Anthony Scemama
|
||||
# LCPQ - IRSAMC - CNRS
|
||||
# Universite Paul Sabatier
|
||||
# 118, route de Narbonne
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
from irpf90_t import *
|
||||
from util import *
|
||||
from command_line import command_line
|
||||
import sys
|
||||
try:
|
||||
import irpy
|
||||
except:
|
||||
import lib_irpy as irpy
|
||||
|
||||
|
||||
class Entity(object):
|
||||
'''All lines between BEGIN_PROVIDER and END_PROVIDER included
|
||||
|
||||
Note: Those lines can define multiple Provider, one need to pick one.
|
||||
'''
|
||||
|
||||
############################################################
|
||||
def __init__(self, text, label, name=None, comm_world=None):
|
||||
# (list[str], str, int, Irpy_comm_world)
|
||||
'''Instantiate the object.
|
||||
|
||||
Args:
|
||||
text: List of lines between BEGIN_PROVIDER and END_PROVIDER included
|
||||
int: An unique int id (usefull when profilling)
|
||||
name: The name of the provider defined after the chosen BEGIN_PROVIDER statement
|
||||
comm_world: A object to communicate we the external world.
|
||||
'''
|
||||
|
||||
assert type(text) == list
|
||||
assert len(text) > 0
|
||||
assert type(text[0]) == Begin_provider
|
||||
|
||||
self.label = label
|
||||
self.text = text
|
||||
|
||||
self.same_as = text[0].filename[1]
|
||||
self.name = name if name else self.same_as
|
||||
|
||||
self.comm_world = comm_world
|
||||
|
||||
|
||||
# ~ # ~ # ~
|
||||
# G l o b a l P r o p e r t y
|
||||
# ~ # ~ # ~
|
||||
@irpy.lazy_property
|
||||
def d_entity(self):
|
||||
# () -> Dict[str,Entity]
|
||||
'''Create an alias to the global dictionary of Entity.
|
||||
|
||||
Note: Be aware of the possiblity of Cyclic Dependency.
|
||||
'''
|
||||
return self.comm_world.d_entity
|
||||
|
||||
@irpy.lazy_property
|
||||
def cm_t_filename_parsed_text(self):
|
||||
# () -> Tuple[str, Parsed_text]
|
||||
'''Create an alias to the global tuple for parsed text
|
||||
|
||||
Note: self.comm_world.t_filename_parsed_text need d_entity.
|
||||
Be aware of the possibility of Cyclic Dependency
|
||||
'''
|
||||
return self.comm_world.t_filename_parsed_text
|
||||
|
||||
@irpy.lazy_property
|
||||
def d_type_lines(self):
|
||||
# () -> Dict[Line, Tuple[int,Line] ]
|
||||
'''Contruct a mapping table between the type of the line and the possition'''
|
||||
from collections import defaultdict
|
||||
d = defaultdict(list)
|
||||
for i, line in enumerate(self.text):
|
||||
d[type(line)] += [(i, line)]
|
||||
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
|
||||
# ~ # ~ # ~
|
||||
@irpy.lazy_property
|
||||
def is_main(self):
|
||||
# () -> bool
|
||||
'''Check if this Entity is the main one
|
||||
|
||||
Exemple:
|
||||
BEGIN_PROVIDER [pi, double precision] &
|
||||
BEGIN_PROVIDER [e, double preision]
|
||||
|
||||
return True for 'pi' and False for 'e'
|
||||
'''
|
||||
return self.name == self.same_as
|
||||
|
||||
|
||||
@irpy.lazy_property
|
||||
def prototype(self):
|
||||
# () -> Line
|
||||
'''Find the declaration statement associated with the name of the provider
|
||||
|
||||
Exemple:
|
||||
BEGIN_PROVIDER [pi, double precision] &
|
||||
BEGIN_PROVIDER [e, double preision]
|
||||
|
||||
if self.name == e, will return BEGIN_PROVIDER [e, double preision]
|
||||
'''
|
||||
|
||||
d = self.d_type_lines
|
||||
return next(line for _,line in d[Begin_provider]+d[Cont_provider] if line.filename[1] == self.name)
|
||||
|
||||
|
||||
@irpy.lazy_property
|
||||
def others_entity_name(self):
|
||||
# () -> List[str]
|
||||
'''Extract the other entity-name defined'''
|
||||
d = self.d_type_lines
|
||||
return [line.filename[1] for _,line in d[Begin_provider]+d[Cont_provider] if not line.filename[1] == self.name]
|
||||
|
||||
|
||||
@irpy.lazy_property
|
||||
def doc(self):
|
||||
# () -> List[str]
|
||||
doc = [line.text.lstrip()[1:] for _,line in self.d_type_lines[Doc]]
|
||||
if not doc:
|
||||
logger.warning("Entity '%s' is not documented" % (self.name))
|
||||
return doc
|
||||
|
||||
@irpy.lazy_property
|
||||
def documented(self):
|
||||
#() -> bool
|
||||
return bool(self.doc)
|
||||
|
||||
# ~ # ~ # ~
|
||||
# T o u c h / R E A D / W R O T E
|
||||
# ~ # ~ # ~
|
||||
|
||||
@irpy.lazy_property_mutable
|
||||
def is_written(self):
|
||||
#() -> bool
|
||||
'''Check if it will be written on disk'''
|
||||
return any(self.d_entity[i].is_written for i in self.parents)
|
||||
|
||||
@irpy.lazy_property
|
||||
def writer(self):
|
||||
if not self.is_main:
|
||||
result = []
|
||||
else:
|
||||
name = self.name
|
||||
result = [ \
|
||||
"subroutine writer_%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("writer_%s" % (self.name))
|
||||
result += [\
|
||||
" character*(%d) :: irp_here = 'writer_%s'"%(length,name),
|
||||
" call irp_enter(irp_here)" ]
|
||||
result += [ \
|
||||
" if (.not.%s_is_built) then"%(self.same_as),
|
||||
" call provide_%s"%(self.same_as),
|
||||
" endif" ]
|
||||
result += map(lambda x: " call writer_%s(irp_num)" % (x), self.needs)
|
||||
result += [ \
|
||||
" irp_is_open = .True.",
|
||||
" irp_iunit = 9",
|
||||
" do while (irp_is_open)",
|
||||
" irp_iunit = irp_iunit+1",
|
||||
" inquire(unit=irp_iunit,opened=irp_is_open)",
|
||||
" 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
|
||||
def is_read(self):
|
||||
'''Check if it will be read from disk'''
|
||||
return any(self.d_entity[i].is_read for i in self.parents)
|
||||
|
||||
@irpy.lazy_property
|
||||
def reader(self):
|
||||
if not self.is_main:
|
||||
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
|
||||
def is_self_touched(self):
|
||||
'''Cehck if it will be modified (touch)'''
|
||||
return False
|
||||
|
||||
@irpy.lazy_property
|
||||
def is_touched(self):
|
||||
'''If any of the children is touched, the entity is touched'''
|
||||
if self.is_self_touched or any(self.d_entity[i].is_touched for i in self.children):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
# ~ # ~ # ~
|
||||
# INCLUDE, USE, CALL
|
||||
# ~ # ~ # ~
|
||||
|
||||
@irpy.lazy_property
|
||||
def includes(self):
|
||||
# () -> str
|
||||
'''Extract the name of include who need be to be include in this Entity'''
|
||||
return [line.filename for _,line in self.d_type_lines[Include]]
|
||||
|
||||
@irpy.lazy_property
|
||||
def uses(self):
|
||||
'''Extract the name of module who are used in this Entity'''
|
||||
return [line.filename for _,line in self.d_type_lines[Use]]
|
||||
|
||||
@irpy.lazy_property
|
||||
def calls(self):
|
||||
'''Extract the name ofthe function called by the entity'''
|
||||
|
||||
def extract_name(line):
|
||||
return line.text.split('(', 1)[0].split()[1].lower()
|
||||
|
||||
return [extract_name(line) for _,line in self.d_type_lines[Call] ]
|
||||
|
||||
# ~ # ~ # ~
|
||||
# Array Dimension
|
||||
# ~ # ~ # ~
|
||||
|
||||
@irpy.lazy_property
|
||||
def dim(self):
|
||||
# () -> List[str]
|
||||
'''Extract the dimension of the needed array in a form of list of variable name
|
||||
|
||||
Exemple:
|
||||
BEGIN_PROVIDER [real, ao_num ]
|
||||
-> []
|
||||
|
||||
BEGIN_PROVIDER [ real, ao_oneD_p, (ao_num) ]
|
||||
-> ['ao_num']
|
||||
|
||||
BEGIN_PROVIDER [ real, ao_oneD_prim_p, (ao_num,ao_prim_num_max) ]
|
||||
-> ['ao_num', 'ao_prim_num_max']
|
||||
'''
|
||||
|
||||
line = self.prototype.text.split('!')[0]
|
||||
buffer = line.replace(']', '').split(',', 2)
|
||||
|
||||
try:
|
||||
x = buffer[2].strip()
|
||||
except IndexError:
|
||||
return []
|
||||
else:
|
||||
return map(str.strip, x[1:-1].split(','))
|
||||
|
||||
|
||||
@irpy.lazy_property
|
||||
def allocate(self):
|
||||
# () -> List[Str]
|
||||
'''Return a list of name of entity who are array and main'''
|
||||
if not self.is_main:
|
||||
return []
|
||||
else:
|
||||
# We never go here
|
||||
return [var for var in self.others_entity_name + [self.name] if self.d_entity[var].dim]
|
||||
|
||||
# ~ # ~ # ~
|
||||
# D e c l a r a t i o n
|
||||
# ~ # ~ # ~
|
||||
|
||||
@irpy.lazy_property
|
||||
def type(self):
|
||||
# () -> str
|
||||
'''Compute the fortran type code of the entity'''
|
||||
|
||||
type_ = self.prototype.text.split(',')[0].split('[')[1].strip()
|
||||
|
||||
if not type_:
|
||||
logger.error( "Error in definition of %s." % (self.name))
|
||||
sys.exit(1)
|
||||
|
||||
if self.dim:
|
||||
return "%s, allocatable" % (type_)
|
||||
else:
|
||||
return type_
|
||||
|
||||
@irpy.lazy_property
|
||||
def header(self):
|
||||
# () -> List[str]
|
||||
'''Compute all the code needed to inistanticant the entity'''
|
||||
|
||||
|
||||
name = self.name
|
||||
str_ = " {type_} :: {name} {dim}".format(type_=self.type, name=name, dim=build_dim(self.dim, colons=True))
|
||||
|
||||
if command_line.coarray:
|
||||
if not self.dim:
|
||||
str_ += " [*]"
|
||||
else:
|
||||
str_ += " [:]"
|
||||
|
||||
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
|
||||
def fmodule(self):
|
||||
# () -> str
|
||||
'''Contruct the name of the module who will contain the entity'''
|
||||
name = self.prototype.filename[0].replace('/', '__').split('.irp.f')[0]
|
||||
return '%s_mod' % name
|
||||
|
||||
############################################################
|
||||
@irpy.lazy_property
|
||||
def regexp(self):
|
||||
# () -> Regex
|
||||
'''Compile a regex targeted to 'search' the name of this entity'''
|
||||
import re
|
||||
return re.compile(r"([^a-z0-9'\"_]|^)%s([^a-z0-9_]|$)" % (self.name), re.I).search
|
||||
|
||||
# ~ # ~ # ~
|
||||
# F o r t r a n 9 0 G e n e r a t i o n
|
||||
# ~ # ~ # ~
|
||||
|
||||
@irpy.lazy_property
|
||||
def toucher(self):
|
||||
# () -> List[str]
|
||||
'''Fabric the f90 routine who handle the cache invalidation'''
|
||||
|
||||
# Only one by EntityColleciton
|
||||
if not self.is_main:
|
||||
return []
|
||||
|
||||
parents = self.parents
|
||||
name = self.name
|
||||
|
||||
result = ["subroutine touch_%s" % (name)]
|
||||
|
||||
result += build_use(parents+[name],self.d_entity)
|
||||
result.append(" implicit none")
|
||||
|
||||
if command_line.do_debug:
|
||||
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
|
||||
def free(self):
|
||||
# () -> List[ str ]
|
||||
'''Compute an part of a subroutine used to free a variable'''
|
||||
|
||||
name = self.name
|
||||
result = ["!",
|
||||
"! >>> FREE %s" % (name),
|
||||
" %s_is_built = .False." % (self.same_as)]
|
||||
|
||||
if self.dim:
|
||||
result += [
|
||||
" if (allocated(%s)) then"%(name),
|
||||
" deallocate (%s)"%(name)]
|
||||
if command_line.do_memory:
|
||||
result += " print *, 'Deallocating %s'"%(name)
|
||||
|
||||
result += [" endif"]
|
||||
|
||||
result.append("! <<< END FREE")
|
||||
return result
|
||||
|
||||
##########################################################
|
||||
@irpy.lazy_property
|
||||
def provider(self):
|
||||
# () -> List[str]
|
||||
'''Create the fortran90 code for the EntityCollection'''
|
||||
|
||||
if not self.is_main:
|
||||
return []
|
||||
|
||||
name = self.name
|
||||
same_as = self.same_as
|
||||
|
||||
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_alloc(name):
|
||||
|
||||
var = self.d_entity[name]
|
||||
if var.dim == []:
|
||||
return []
|
||||
|
||||
from util import build_dim
|
||||
|
||||
def print_size():
|
||||
return " " * 5 + "print *, ' size: {0}'".format(build_dim(var.dim))
|
||||
|
||||
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
|
||||
def builder(self):
|
||||
if not self.is_main:
|
||||
return []
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# Get the raw text for the builder
|
||||
# ~#~#~#~#~#
|
||||
|
||||
#Next return the first element of the iterator
|
||||
ps_text = next(text for filename, text in self.cm_t_filename_parsed_text
|
||||
if self.prototype.filename[0].startswith(filename))
|
||||
begin = next(i for i, (_, line) in enumerate(ps_text)
|
||||
if isinstance(line, Begin_provider) if line.filename[1] == self.same_as)
|
||||
end = next(begin + i for i, (_, line) in enumerate(ps_text[begin:])
|
||||
if isinstance(line, End_provider))
|
||||
|
||||
# Now we now that the text is betern ps_text[begin:end]
|
||||
_, line_prototype = ps_text[begin]
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# Aded the call to the provider
|
||||
# ~#~#~#~#~#
|
||||
|
||||
text = []
|
||||
if command_line.do_profile:
|
||||
text.append(([], Declaration(line_prototype.i,
|
||||
" double precision :: irp_rdtsc, irp_rdtsc1, irp_rdtsc2",
|
||||
line_prototype.filename)))
|
||||
text.append(([], Simple_line(line_prototype.i, " irp_rdtsc1 = irp_rdtsc()",
|
||||
line_prototype.filename)))
|
||||
|
||||
for vars, line in ps_text[begin + 1:end]:
|
||||
text.append((vars, line))
|
||||
text += map(lambda x: ([], Simple_line(line.i, x, line.filename)),
|
||||
build_call_provide(vars, self.d_entity))
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# Create the subroutine.
|
||||
# ~#~#~#~#~#
|
||||
|
||||
result = []
|
||||
if command_line.directives and command_line.inline in ["all", "builders"]:
|
||||
result += ["!DEC$ ATTRIBUTES INLINE :: bld_%s" % (same_as)]
|
||||
|
||||
# Add the use statement
|
||||
result += ["subroutine bld_%s" % (self.name)]
|
||||
result += build_use([self.name] + self.needs, self.d_entity)
|
||||
|
||||
import parsed_text
|
||||
# Move the variable to top, and add the text
|
||||
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)))
|
||||
|
||||
if command_line.do_profile:
|
||||
result += [
|
||||
" irp_rdtsc2 = irp_rdtsc()",
|
||||
" call irp_set_timer(%d,(irp_rdtsc2-irp_rdtsc1))" % self.label
|
||||
]
|
||||
#Close
|
||||
result.append("end subroutine bld_%s" % (self.name))
|
||||
|
||||
return result
|
||||
|
||||
##########################################################
|
||||
@irpy.lazy_property_mutable
|
||||
def needs(self):
|
||||
#Set by parsed_text.build_needs(...)
|
||||
raise AttributeError
|
||||
|
||||
@irpy.lazy_property
|
||||
def children(self):
|
||||
|
||||
result = []
|
||||
for x in self.needs:
|
||||
result.append(x)
|
||||
try:
|
||||
result += self.d_entity[x].children
|
||||
except RuntimeError:
|
||||
pass # Exception will be checked after
|
||||
|
||||
result = OrderedUniqueList(result)
|
||||
if self.name in result:
|
||||
error.fail(self.prototype, "Cyclic dependencies:\n%s" % (str(result)))
|
||||
return result
|
||||
|
||||
##########################################################
|
||||
@irpy.lazy_property
|
||||
def parents(self):
|
||||
if not self.is_main:
|
||||
return []
|
||||
|
||||
result = []
|
||||
for x in self.needed_by:
|
||||
result.append(x)
|
||||
try:
|
||||
result += self.d_entity[x].parents
|
||||
except RuntimeError:
|
||||
pass # Exception will be checked after
|
||||
|
||||
result = OrderedUniqueList(result)
|
||||
if self.name in result:
|
||||
error.fail(self.prototype, "Cyclic dependencies:\n%s" % (str(self._parents)))
|
||||
|
||||
return result
|
66
src/error.py
66
src/error.py
@ -1,66 +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 sys
|
||||
from irpf90_t import *
|
||||
from command_line import command_line
|
||||
do_warnings = command_line.do_warnings
|
||||
|
||||
######################################################################
|
||||
def fail(line,message):
|
||||
print """
|
||||
Error:
|
||||
-----
|
||||
"""
|
||||
print message, '\n'
|
||||
if line is not None:
|
||||
assert isinstance(line,Line)
|
||||
print "file %s ; line %d :\n %s"%(line.filename,line.i,line.text)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
######################################################################
|
||||
def warn(line,message):
|
||||
if not command_line.do_warnings:
|
||||
return
|
||||
if line is not None:
|
||||
assert isinstance(line,Line)
|
||||
print """
|
||||
Warning:
|
||||
-------
|
||||
"""
|
||||
print message, '\n'
|
||||
print "file %s, line %d:\n %s"%(line.filename,line.i,line.text)
|
||||
else:
|
||||
print "Warning: %s"%(message)
|
||||
|
||||
|
||||
######################################################################
|
||||
if __name__ == '__main__':
|
||||
line = Empty_line(3,"empty", "testfile")
|
||||
fail(line, "Message")
|
||||
|
89
src/init.py
89
src/init.py
@ -1,89 +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 os
|
||||
|
||||
import util
|
||||
import makefile
|
||||
import irpf90_t
|
||||
from command_line import command_line
|
||||
|
||||
initialized = False
|
||||
|
||||
|
||||
def init():
|
||||
|
||||
global initialized
|
||||
if initialized:
|
||||
return
|
||||
|
||||
# Create directories
|
||||
for dir in [ irpf90_t.irpdir, irpf90_t.mandir ]:
|
||||
try:
|
||||
wd = os.getcwd()
|
||||
os.chdir(dir)
|
||||
os.chdir(wd)
|
||||
except OSError:
|
||||
os.mkdir(dir)
|
||||
|
||||
for dir in command_line.include_dir:
|
||||
dir = irpf90_t.irpdir+dir
|
||||
try:
|
||||
wd = os.getcwd()
|
||||
os.chdir(dir)
|
||||
os.chdir(wd)
|
||||
except OSError:
|
||||
os.mkdir(dir)
|
||||
|
||||
# Create makefile
|
||||
makefile.create()
|
||||
|
||||
# Copy current files in the irpdir
|
||||
for dir in ['./']+command_line.include_dir:
|
||||
try:
|
||||
os.stat(dir)
|
||||
except:
|
||||
print dir,'not in dir'
|
||||
continue
|
||||
for filename in os.listdir(dir):
|
||||
filename = dir+filename
|
||||
if not filename.startswith(".") and not os.path.isdir(filename):
|
||||
try:
|
||||
file = open(filename,"r")
|
||||
except IOError:
|
||||
if command_line.do_warnings:
|
||||
print "Warning : Unable to read file %s."%(filename)
|
||||
else:
|
||||
buffer = file.read()
|
||||
file.close()
|
||||
if not util.same_file(irpf90_t.irpdir+filename,buffer):
|
||||
file = open(irpf90_t.irpdir+filename,"w")
|
||||
file.write(buffer)
|
||||
file.close()
|
||||
|
||||
initialized = True
|
||||
|
@ -253,13 +253,8 @@ subroutine irp_trace
|
||||
enddo
|
||||
print *, '-------------------------'
|
||||
end subroutine
|
||||
|
||||
"""
|
||||
|
||||
txt = txt.split('\n')
|
||||
txt = map(lambda x: x+"\n",txt)
|
||||
if not util.same_file(FILENAME, txt):
|
||||
file = open(FILENAME,'w')
|
||||
file.writelines(txt)
|
||||
file.close()
|
||||
|
||||
util.lazy_write_file(FILENAME,txt)
|
||||
|
||||
|
131
src/irpf90.py
131
src/irpf90.py
@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#cscs /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
|
||||
@ -25,95 +24,85 @@
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
|
||||
import vim
|
||||
import os,sys
|
||||
import os, sys
|
||||
try:
|
||||
wd = os.path.abspath(os.path.dirname(__file__))
|
||||
sys.path.insert(0,(wd+"/../src/"))
|
||||
wd = os.path.abspath(os.path.dirname(__file__))
|
||||
sys.path.insert(0, (wd + "/../src/"))
|
||||
except:
|
||||
pass
|
||||
sys.setcheckinterval(1000)
|
||||
pass
|
||||
|
||||
from command_line import command_line
|
||||
from irpy_files import Irpy_comm_world
|
||||
|
||||
def main():
|
||||
|
||||
vim.install()
|
||||
vim.install()
|
||||
|
||||
if command_line.do_help:
|
||||
command_line.usage()
|
||||
if command_line.do_help:
|
||||
command_line.usage()
|
||||
return
|
||||
if command_line.do_version:
|
||||
from version import version
|
||||
print version
|
||||
return
|
||||
|
||||
if command_line.do_version:
|
||||
from version import version
|
||||
print version
|
||||
if command_line.do_init:
|
||||
from build_file import create_generalmakefile
|
||||
create_generalmakefile(command_line.do_ninja)
|
||||
return
|
||||
|
||||
from init import init
|
||||
if command_line.do_init:
|
||||
init()
|
||||
comm_world = Irpy_comm_world()
|
||||
|
||||
if command_line.do_preprocess:
|
||||
init()
|
||||
from preprocessed_text import preprocessed_text
|
||||
for filename,text in preprocessed_text:
|
||||
if filename in command_line.preprocessed:
|
||||
for line in text:
|
||||
print line.text
|
||||
if command_line.do_graph:
|
||||
comm_world.t_filename_parsed_text # Initialize entity need. Dirty I know.
|
||||
|
||||
print 'graph { '
|
||||
for name,entity in comm_world.d_entity.items():
|
||||
if entity.needs:
|
||||
print ' {0} -> {1}'.format(name, ' '.join(entity.needs))
|
||||
print '}'
|
||||
return
|
||||
|
||||
|
||||
if command_line.do_touch:
|
||||
from variables import variables
|
||||
for var in command_line.touched:
|
||||
if var not in variables:
|
||||
print "%s is not an IRP entity"%(var,)
|
||||
else:
|
||||
print "Touching %s invalidates the following entities:"%(var,)
|
||||
parents = variables[var].parents
|
||||
parents.sort()
|
||||
for x in parents:
|
||||
print "- %s"%(x,)
|
||||
if command_line.do_preprocess:
|
||||
for filename, text in comm_world.preprocessed_text:
|
||||
if filename in command_line.preprocessed:
|
||||
for line in text:
|
||||
print line.text
|
||||
return
|
||||
|
||||
if command_line.do_codelet:
|
||||
import profile
|
||||
profile.build_rdtsc()
|
||||
import codelet
|
||||
codelet.run()
|
||||
if command_line.do_touch:
|
||||
for var in command_line.touched:
|
||||
if var not in comm_world.d_entity:
|
||||
print "%s is not an IRP entity" % var
|
||||
else:
|
||||
print "Touching %s invalidates the following entities:" % var
|
||||
for x in sorted(d_entity[var].parents):
|
||||
print "- %s" % (x, )
|
||||
return
|
||||
|
||||
if not command_line.do_run:
|
||||
return
|
||||
if command_line.do_codelet:
|
||||
import profile
|
||||
profile.build_rdtsc()
|
||||
import codelet
|
||||
codelet.run()
|
||||
|
||||
init()
|
||||
if not command_line.do_run:
|
||||
return
|
||||
|
||||
import irp_stack
|
||||
irp_stack.create()
|
||||
comm_world.create_buildfile(command_line.do_ninja)
|
||||
comm_world.write_modules()
|
||||
|
||||
comm_world.create_touches()
|
||||
comm_world.create_man()
|
||||
|
||||
import makefile
|
||||
makefile.create()
|
||||
if command_line.do_profile:
|
||||
import profile
|
||||
profile.run(comm_world.d_entity)
|
||||
|
||||
from modules import modules, write_module
|
||||
for m in modules.keys():
|
||||
write_module(modules[m])
|
||||
|
||||
makefile.run()
|
||||
|
||||
import touches
|
||||
touches.create()
|
||||
|
||||
# import checkpoint
|
||||
# checkpoint.create()
|
||||
|
||||
import create_man
|
||||
create_man.run()
|
||||
|
||||
if command_line.do_profile:
|
||||
import profile
|
||||
profile.run()
|
||||
|
||||
if command_line.do_openmp:
|
||||
import locks
|
||||
locks.create()
|
||||
if command_line.do_openmp:
|
||||
comm_world.create_lock()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
main()
|
||||
|
408
src/irpf90_t.py
408
src/irpf90_t.py
@ -24,385 +24,63 @@
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
import os
|
||||
from zlib import crc32
|
||||
|
||||
irpdir = "IRPF90_temp/"
|
||||
mandir = "IRPF90_man/"
|
||||
|
||||
from zlib import crc32
|
||||
import os
|
||||
irp_id = abs(crc32(os.getcwd()))
|
||||
|
||||
try:
|
||||
import irpy
|
||||
except:
|
||||
import lib_irpy as irpy
|
||||
|
||||
|
||||
class Line(object):
|
||||
def __init__(self,i,text,filename):
|
||||
self.i = i
|
||||
self._text = None
|
||||
self.filename = filename
|
||||
self._lower = None
|
||||
self.set_text(text)
|
||||
def __init__(self, i, text, filename):
|
||||
self.i = i
|
||||
self.text = text
|
||||
self.filename = filename
|
||||
|
||||
def get_text(self):
|
||||
return self._text
|
||||
|
||||
def set_text(self,value):
|
||||
self._text = value
|
||||
self._lower = value.lower()
|
||||
@irpy.lazy_property
|
||||
def lower(self):
|
||||
return self.text.lower()
|
||||
|
||||
def get_lower(self):
|
||||
return self._lower
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s (%s)" % (type(self).__name__, self.i, self.text, self.filename)
|
||||
|
||||
text = property(fget=get_text, fset=set_text)
|
||||
lower = property(fget=get_lower)
|
||||
class LineWithName(Line):
|
||||
|
||||
class Empty_line(Line):
|
||||
str="Empty_line"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Empty_line",self.i,self.text)
|
||||
@irpy.lazy_property
|
||||
def subname(self):
|
||||
buf = self.lower
|
||||
if not buf.endswith(')'):
|
||||
buf += "()"
|
||||
|
||||
class Simple_line(Line):
|
||||
str="Simple_line"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Simple_line",self.i,self.text)
|
||||
l_buf = buf.split('(')
|
||||
l_name = l_buf[0].split()
|
||||
|
||||
class Declaration(Line):
|
||||
str="Declaration"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Declaration",self.i,self.text)
|
||||
|
||||
class Continue(Line):
|
||||
str="Continue"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Continue",self.i,self.text)
|
||||
|
||||
class Begin_provider(Line):
|
||||
str="Begin_provider"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Begin_provider",self.i,self.text)
|
||||
|
||||
class Cont_provider(Line):
|
||||
str="Cont_provider"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Cont_provider",self.i,self.text)
|
||||
|
||||
class End_provider(Line):
|
||||
str="End_provider"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("End_provider",self.i,self.text)
|
||||
|
||||
class Begin_doc(Line):
|
||||
str="Begin_doc"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Begin_doc",self.i,self.text)
|
||||
|
||||
class Doc(Line):
|
||||
str="Doc"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Doc",self.i,self.text)
|
||||
|
||||
class End_doc(Line):
|
||||
str="End_doc"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("End_doc",self.i,self.text)
|
||||
|
||||
class Begin_shell(Line):
|
||||
str="Begin_shell"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Begin_shell",self.i,self.text)
|
||||
|
||||
class End_shell(Line):
|
||||
str="End_shell"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("End_shell",self.i,self.text)
|
||||
|
||||
class Begin_template(Line):
|
||||
str="Begin_template"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Begin_template",self.i,self.text)
|
||||
|
||||
class End_template(Line):
|
||||
str="End_template"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("End_template",self.i,self.text)
|
||||
|
||||
class Subst(Line):
|
||||
str="Subst"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Subst",self.i,self.text)
|
||||
|
||||
class Assert(Line):
|
||||
str="Assert"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Assert",self.i,self.text)
|
||||
|
||||
class Touch(Line):
|
||||
str="Touch"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Touch",self.i,self.text)
|
||||
|
||||
class SoftTouch(Touch):
|
||||
str="SoftTouch"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("SoftTouch",self.i,self.text)
|
||||
|
||||
class Irp_read(Line):
|
||||
str="Irp_read"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Irp_read",self.i,self.text)
|
||||
|
||||
class Irp_write(Line):
|
||||
str="Irp_write"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Irp_write",self.i,self.text)
|
||||
|
||||
class Irp_If(Line):
|
||||
str="Irp_If"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Irp_If",self.i,self.text)
|
||||
|
||||
class Irp_Else(Line):
|
||||
str="Irp_Else"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Irp_Else",self.i,self.text)
|
||||
|
||||
class Irp_Endif(Line):
|
||||
str="Irp_Endif"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Irp_Endif",self.i,self.text)
|
||||
|
||||
class Openmp(Line):
|
||||
str="Openmp"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Openmp",self.i,self.text)
|
||||
|
||||
class Directive(Line):
|
||||
str="Directive"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Directive",self.i,self.text)
|
||||
|
||||
class Use(Line):
|
||||
str="Use"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Use",self.i,self.text)
|
||||
|
||||
class Do(Line):
|
||||
str="Do"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Do",self.i,self.text)
|
||||
|
||||
class Enddo (Line):
|
||||
str="Enddo"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Enddo",self.i,self.text)
|
||||
|
||||
class If(Line):
|
||||
str="If"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("If",self.i,self.text)
|
||||
|
||||
class Elseif(Line):
|
||||
str="Elseif"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Elseif",self.i,self.text)
|
||||
|
||||
class Else(Line):
|
||||
str="Else"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Else",self.i,self.text)
|
||||
|
||||
class Endif(Line):
|
||||
str="Endif"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Endif",self.i,self.text)
|
||||
|
||||
class Select(Line):
|
||||
str="Select"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Select",self.i,self.text)
|
||||
|
||||
class Case(Line):
|
||||
str="Case"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Case",self.i,self.text)
|
||||
|
||||
class End_select(Line):
|
||||
str="End_select"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("End_select",self.i,self.text)
|
||||
|
||||
class Program(Line):
|
||||
str="Program"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Program",self.i,self.text)
|
||||
|
||||
class Subroutine(Line):
|
||||
str="Subroutine"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Subroutine",self.i,self.text)
|
||||
|
||||
class Function(Line):
|
||||
str="Function"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Function",self.i,self.text)
|
||||
|
||||
class Call(Line):
|
||||
str="Call"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Call",self.i,self.text)
|
||||
|
||||
class Provide(Line):
|
||||
str="Provide"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Provide",self.i,self.text)
|
||||
|
||||
class NoDep(Line):
|
||||
str="NoDep"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("NoDep",self.i,self.text)
|
||||
|
||||
class Return (Line):
|
||||
str="Return"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Return",self.i,self.text)
|
||||
|
||||
class Include(Line):
|
||||
str="Include"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Include",self.i,self.text)
|
||||
|
||||
class Implicit (Line):
|
||||
str="Implicit"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Implicit",self.i,self.text)
|
||||
|
||||
class Free(Line):
|
||||
str="Free"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Free",self.i,self.text)
|
||||
|
||||
class End(Line):
|
||||
str="End"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("End",self.i,self.text)
|
||||
|
||||
class Provide_all (Line):
|
||||
str="Provide_all"
|
||||
def __init__(self,i,text,filename):
|
||||
Line.__init__(self,i,text,filename)
|
||||
def __repr__(self):
|
||||
return "%20s:%5d : %s"%("Provide_all",self.i,self.text)
|
||||
|
||||
|
||||
######################################################################
|
||||
|
||||
def create_irpf90_files():
|
||||
result = []
|
||||
from command_line import command_line
|
||||
import os
|
||||
def is_irpf90_file(filename):
|
||||
return filename.endswith(".irp.f") and not filename.startswith('.')
|
||||
result = filter ( is_irpf90_file, os.listdir(os.getcwd()) )
|
||||
for dir in command_line.include_dir:
|
||||
try:
|
||||
os.stat(dir)
|
||||
result += map(lambda x: dir+x, filter ( is_irpf90_file, os.listdir(dir) ) )
|
||||
except:
|
||||
continue
|
||||
if command_line.do_codelet:
|
||||
result += [command_line.codelet[3]]
|
||||
return result
|
||||
irpf90_files = create_irpf90_files()
|
||||
if len(l_name) < 2:
|
||||
import loger
|
||||
logger.error("Syntax Error: %s" % line)
|
||||
sys.exit(1)
|
||||
return l_name.pop()
|
||||
|
||||
l_type = [
|
||||
'Empty_line', 'Simple_line', "Declaration", "Continue", "Begin_provider",
|
||||
"Cont_provider", "End_provider", "Begin_doc", "Doc", "End_doc",
|
||||
"Begin_shell", "End_shell", "Begin_template", "End_template", "Subst",
|
||||
"Assert", "Touch", "SoftTouch", "Irp_read", "Irp_write", "Irp_If",
|
||||
"Irp_Else", "Irp_Endif", "Openmp", "Directive", "Use", "Do", "Enddo", "If",
|
||||
"Elseif", "Else", "Endif", "Select", "Case", "End_select", "Provide", "NoDep", "Return", "Include",
|
||||
"Implicit", "Free", "End", "Provide_all","Contains",'Type','End_module','Interface','End_interface',
|
||||
'Where','Elsewhere','Endwhere']
|
||||
|
||||
for t in l_type:
|
||||
globals()[t] = type(t, (Line, ), {})
|
||||
|
||||
for t in ['Subroutine', 'Function', 'Program', 'Call','Module']:
|
||||
globals()[t] = type(t, (LineWithName, ), {})
|
||||
|
||||
|
@ -28,12 +28,13 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
wd = os.path.abspath(os.path.dirname(__file__))
|
||||
from irpf90_t import mandir
|
||||
filename = sys.argv[1].lower()+".l"
|
||||
if filename not in os.listdir(mandir):
|
||||
print "%s does not exist"%(sys.argv[1])
|
||||
sys.exit(-1)
|
||||
|
||||
os.system("man ./"+mandir+sys.argv[1].lower()+".l")
|
||||
if __name__ == "__main__":
|
||||
from irpf90_t import mandir
|
||||
entity = sys.argv[1].lower()
|
||||
|
||||
filename = '%s.l'% entity
|
||||
if filename not in os.listdir(mandir):
|
||||
print "Error: `%s` does not exist"% entity
|
||||
sys.exit(-1)
|
||||
|
||||
os.system("man %s" % os.path.join(mandir,filename))
|
||||
|
322
src/irpy_files.py
Normal file
322
src/irpy_files.py
Normal file
@ -0,0 +1,322 @@
|
||||
from util import parmap,lazy_write_file
|
||||
from util import flatten, listdir
|
||||
|
||||
try:
|
||||
import irpy
|
||||
except:
|
||||
import lib_irpy as irpy
|
||||
|
||||
import os
|
||||
import irpf90_t
|
||||
import sys
|
||||
|
||||
from command_line import command_line
|
||||
|
||||
from util import logger
|
||||
|
||||
class Irpy_comm_world(object):
|
||||
'''Maestro.'''
|
||||
|
||||
def __init__(self,l_dir=None, l_file=None):
|
||||
# (Iter, Iter) -> None
|
||||
|
||||
# Create directories
|
||||
from itertools import ifilterfalse
|
||||
i_folder = ifilterfalse(os.path.exists, (irpf90_t.irpdir, irpf90_t.mandir))
|
||||
map(os.mkdir,i_folder)
|
||||
|
||||
# List file
|
||||
|
||||
l_dir =l_dir if l_dir else (command_line.include_dir+['.'])
|
||||
l_not_dir = [d for d in l_dir if not (os.path.exists(d) and os.path.isdir(d))]
|
||||
if l_not_dir:
|
||||
logger.error('Try to include no existing directory: [%s]' % ','.join(l_not_dir))
|
||||
sys.exit(1)
|
||||
|
||||
# Create folder in IRPDIR
|
||||
i_folder = ifilterfalse(os.path.exists, (os.path.join(irpf90_t.irpdir,d) for d in l_dir))
|
||||
map(os.mkdir, i_folder)
|
||||
|
||||
s_folder_abs = set(os.path.abspath(path) for path in l_dir)
|
||||
|
||||
s_file_folder_all = set(flatten(listdir(path,abspath=True) for path in s_folder_abs))
|
||||
|
||||
# Take everything!
|
||||
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.update(s_file_folder)
|
||||
|
||||
s_file_rel = set(os.path.relpath(f,self.cwd) for f in s_file_tot)
|
||||
|
||||
# Lazy Copy file
|
||||
for f in s_file_rel:
|
||||
src = os.path.join(self.cwd,f)
|
||||
text_ref = open(src, 'rb').read()
|
||||
|
||||
dest = os.path.join(self.cwd,irpf90_t.irpdir, f)
|
||||
lazy_write_file(dest, text_ref)
|
||||
|
||||
if command_line.do_codelet:
|
||||
s_file_tot.update(command_line.codelet[3])
|
||||
|
||||
# No filter the irpf90 file
|
||||
self.irpf90_files_ordered=sorted(filter(lambda f: f.endswith(".irp.f") ,s_file_rel))
|
||||
|
||||
@irpy.lazy_property
|
||||
def cwd(self):
|
||||
return os.getcwd()
|
||||
|
||||
@irpy.lazy_property
|
||||
def t_filename_preprocessed_text(self):
|
||||
'''Tuple (filename, preprocessed_text)'''
|
||||
|
||||
from preprocessed_text import Preprocess_text
|
||||
def worker_preprocess(filename):
|
||||
return (filename, Preprocess_text(filename).preprocessed_text)
|
||||
|
||||
return parmap(worker_preprocess, self.irpf90_files_ordered)
|
||||
|
||||
@irpy.lazy_property
|
||||
def l_preprocessed_text(self):
|
||||
# (None) -> List[Line]
|
||||
'''List preprocessed_text'''
|
||||
|
||||
return [line for _, text in self.t_filename_preprocessed_text for line in text]
|
||||
|
||||
@irpy.lazy_property
|
||||
def d_type_lines(self):
|
||||
|
||||
from collections import defaultdict
|
||||
d = defaultdict(list)
|
||||
for i, line in enumerate(self.l_preprocessed_text):
|
||||
d[type(line)] += [(i, line)]
|
||||
return d
|
||||
|
||||
@irpy.lazy_property
|
||||
def d_entity(self):
|
||||
# None -> Dict[Str,Entity]
|
||||
'''And entity is a collection of line between BEGIN_PROVIDER and END_PROVIDER '''
|
||||
from irpf90_t import Begin_provider, End_provider
|
||||
from entity import Entity
|
||||
|
||||
l_begin = [i for i, line in self.d_type_lines[Begin_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_ent = []
|
||||
for icount, buf in enumerate(l_provider):
|
||||
from functools import partial
|
||||
Ent_part = partial(Entity,buf,icount,comm_world=self)
|
||||
|
||||
ent = Ent_part()
|
||||
l_ent += [ent] + [Ent_part(other) for other in ent.others_entity_name]
|
||||
|
||||
# O(2) but who care
|
||||
l_duplicate = [x for x in l_ent if l_ent.count(x) > 1]
|
||||
if l_duplicate:
|
||||
from util import logger
|
||||
logger.error('You have duplicate PROVIDER: %s' % ' '.join([e.name for e in l_duplicate]))
|
||||
import sys
|
||||
sys.exit(1)
|
||||
|
||||
# Python 2.6 Don't allow list comprehesion
|
||||
d_ent = dict()
|
||||
for e in l_ent:
|
||||
d_ent[e.name] = e
|
||||
|
||||
#
|
||||
# Second pass
|
||||
#
|
||||
# Modify parameter of variables
|
||||
|
||||
# Touch Softouch
|
||||
def find_variable(line):
|
||||
l_var = line.lower.split()[1:]
|
||||
if len(l_var) < 1:
|
||||
error.fail(line, "Syntax error")
|
||||
|
||||
if any(v for v in l_var if v not in d_ent):
|
||||
error.fail(line, "Variable %s unknown" % (v, ))
|
||||
return l_var
|
||||
|
||||
|
||||
d_modif = dict()
|
||||
from irpf90_t import Touch, SoftTouch, Free
|
||||
from util import flatten
|
||||
for cmd, l_type in [('is_self_touched', [Touch, SoftTouch]),
|
||||
('is_free', [Free])]:
|
||||
|
||||
l_line = flatten( [self.d_type_lines[type_] for type_ in l_type])
|
||||
l_name = flatten( [find_variable(line) for _, line in l_line])
|
||||
d_modif[cmd] = l_name
|
||||
|
||||
# Read and Write
|
||||
from irpf90_t import Irp_read, Irp_write
|
||||
for cmd, type_ in [('is_read', Irp_read), ('is_written', Irp_write)]:
|
||||
l_name = [line.filename for _, line in self.d_type_lines[type_]]
|
||||
d_modif[cmd] = l_name
|
||||
|
||||
#Do the modifcation
|
||||
for cmd, l_name in d_modif.items():
|
||||
for name in l_name:
|
||||
setattr(d_ent[name], cmd, True)
|
||||
|
||||
return d_ent
|
||||
|
||||
@irpy.lazy_property_mutable
|
||||
def d_routine(self):
|
||||
'''
|
||||
Dictionnary name -> Routine object.
|
||||
Routine is a collection of line between Subroutine / Function
|
||||
'''
|
||||
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# Create the dict
|
||||
# ~#~#~#~#~#
|
||||
|
||||
from irpf90_t import Subroutine, Function, Program, End
|
||||
d_type = self.d_type_lines
|
||||
l_begin = sorted(i for type_ in (Subroutine, Function, Program) for i, _ in d_type[type_])
|
||||
l_end = [i for i, _ in d_type[End]]
|
||||
|
||||
from routine import Routine
|
||||
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)]
|
||||
|
||||
# Now we can create a dict and at it
|
||||
d_rou = dict()
|
||||
for s in l_rou:
|
||||
d_rou[s.name] = s
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# Finish the initialization of the routine
|
||||
# ~#~#~#~#~#
|
||||
|
||||
from collections import defaultdict
|
||||
d_called_by = defaultdict(set)
|
||||
|
||||
for entity in self.d_entity.values():
|
||||
name = entity.name
|
||||
if entity.same_as == name:
|
||||
for x in entity.calls:
|
||||
d_called_by[x].add(name)
|
||||
|
||||
from util import uniquify
|
||||
for routine in d_rou.values():
|
||||
for x in routine.calls:
|
||||
d_called_by[x].add(routine.name)
|
||||
|
||||
for routine in d_rou.values():
|
||||
routine.called_by = sorted(d_called_by[routine.name])
|
||||
|
||||
l_set = [d_rou[name].touches_my_self for name in routine.calls if name in d_rou]
|
||||
routine.touches_ancestor = set().union(*l_set)
|
||||
|
||||
return d_rou
|
||||
|
||||
@irpy.lazy_property
|
||||
def t_filename_parsed_text(self):
|
||||
'''(filename,parsed_text)'''
|
||||
d_entity = self.d_entity
|
||||
d_routine = self.d_routine
|
||||
|
||||
import parsed_text
|
||||
vtuple = [(v, s.same_as, s.regexp) for v, s in d_entity.iteritems()]
|
||||
def worker_parsed(filename_text):
|
||||
filename, text = filename_text
|
||||
return parsed_text.get_parsed_text(filename, text, d_entity, d_routine, vtuple)
|
||||
|
||||
parsed_text_0 = parmap(worker_parsed, self.t_filename_preprocessed_text)
|
||||
|
||||
|
||||
from irpf90_t import NoDep,Declaration,Implicit,Use,Cont_provider
|
||||
def moved_to_top_l(ptext):
|
||||
l = [NoDep, Declaration, Implicit, Use, Cont_provider]
|
||||
for _, text in ptext:
|
||||
parsed_text.move_to_top_list(text, l)
|
||||
|
||||
#Touch routine
|
||||
parsed_text.build_sub_needs(parsed_text_0, d_routine)
|
||||
moved_to_top_l(parsed_text_0)
|
||||
|
||||
parsed_text_1 = parsed_text.add_subroutine_needs(parsed_text_0, d_routine)
|
||||
parsed_text_1 = parsed_text.move_variables(parsed_text_1)
|
||||
|
||||
moved_to_top_l(parsed_text_1)
|
||||
|
||||
parsed_text.check_opt(parsed_text_1)
|
||||
parsed_text_1 = parsed_text.perform_loop_substitutions(parsed_text_1)
|
||||
|
||||
#touch entity
|
||||
stuple = [(s, v.regexp) for s, v in d_routine.iteritems() if v.is_function]
|
||||
parsed_text.build_needs(parsed_text_1, d_routine, stuple,d_entity)
|
||||
|
||||
return parsed_text_1
|
||||
|
||||
@irpy.lazy_property
|
||||
def d_module(self):
|
||||
from module import Fmodule
|
||||
result = dict()
|
||||
for filename, text in self.t_filename_parsed_text:
|
||||
result[filename] = Fmodule(text, filename,self.d_entity)
|
||||
|
||||
return result
|
||||
|
||||
def write_modules(self):
|
||||
from irpf90_t import irpdir
|
||||
from util import lazy_write_file
|
||||
import os
|
||||
|
||||
for m in self.d_module.values():
|
||||
# Module data
|
||||
if m.has_irp_module:
|
||||
filename = os.path.join(irpdir, '%s.irp.module.F90' % m.filename)
|
||||
text = '\n'.join(m.header + m.head)
|
||||
lazy_write_file(filename, '%s\n' % text)
|
||||
|
||||
# Subroutines
|
||||
filename = os.path.join(irpdir, '%s.irp.F90' % m.filename)
|
||||
text = '\n'.join(m.header + m.generated_text + m.residual_text)
|
||||
lazy_write_file(filename, '%s\n' % text)
|
||||
|
||||
def create_stack(self):
|
||||
import irp_stack
|
||||
irp_stack.create()
|
||||
|
||||
def create_buildfile(self,ninja):
|
||||
import build_file
|
||||
build_file.run(self.d_module,ninja)
|
||||
|
||||
def create_touches(self):
|
||||
import touches
|
||||
touches.create(self.d_module, self.d_entity)
|
||||
|
||||
def create_man(self):
|
||||
import create_man as c_man
|
||||
c_man.run(self.d_entity, self.d_routine)
|
||||
|
||||
|
||||
def create_lock(self):
|
||||
from util import lazy_write_file
|
||||
l = sorted(self.d_entity.keys())
|
||||
|
||||
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", "" ]
|
||||
|
||||
filename = os.path.join(irpf90_t.irpdir,'irp_locks.irp.F90')
|
||||
lazy_write_file(filename, '\n'.join(out))
|
||||
|
160
src/lib_irpy.py
Executable file
160
src/lib_irpy.py
Executable file
@ -0,0 +1,160 @@
|
||||
#Handle the execution stack
|
||||
from collections import defaultdict
|
||||
d_path = defaultdict(list)
|
||||
d_last_caller = defaultdict(lambda: None)
|
||||
|
||||
def genealogy(obj, _node, direction,degree_max=100):
|
||||
"""Return the genealogy of a _node.
|
||||
Direction is $parents or $children, recurse accordingly"""
|
||||
|
||||
def sap(_node, direction, visited=set(), degree=0):
|
||||
|
||||
visited.add(_node)
|
||||
try:
|
||||
s = getattr(obj, "{0}_{1}".format(_node, direction))
|
||||
except AttributeError:
|
||||
s = set()
|
||||
|
||||
for next_ in s - visited:
|
||||
|
||||
if degree < degree_max:
|
||||
sap(next_, direction, visited, degree+1)
|
||||
|
||||
return visited
|
||||
|
||||
s = sap(_node, direction) - set([_node])
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def addattr(obj, name, value):
|
||||
try:
|
||||
s = getattr(obj, name)
|
||||
except AttributeError:
|
||||
setattr(obj, name, set([value]))
|
||||
else:
|
||||
setattr(obj, name, s | set([value]))
|
||||
|
||||
def removeattr(obj, name, value):
|
||||
try:
|
||||
s = getattr(obj, name)
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
setattr(obj, name, s - set([value]))
|
||||
|
||||
|
||||
# _
|
||||
# | \ _ _ _ ._ _. _|_ _ ._
|
||||
# |_/ (/_ (_ (_) | (_| |_ (_) |
|
||||
#
|
||||
class lazy_property(object):
|
||||
"""
|
||||
My little Property
|
||||
My little Property
|
||||
My little Property... friend
|
||||
"""
|
||||
|
||||
def __init__(self, provider, init_node=False, immutable=True):
|
||||
"""Provider: If a function who will be used to compute the node
|
||||
init_node: If the name of the node
|
||||
immutable: If immutable is set you cannot set the node"""
|
||||
|
||||
self.provider = provider
|
||||
self.init_node = init_node
|
||||
self.immutable = immutable
|
||||
|
||||
if not self.init_node:
|
||||
name = provider.__name__
|
||||
else:
|
||||
name = self.init_node
|
||||
|
||||
#Kind of human readable identifier
|
||||
self._node = "_%s_%s" % (name, id(provider))
|
||||
|
||||
def __get__(self, obj, objtype):
|
||||
"Get the value of the node and handle the genealogy"
|
||||
|
||||
_node = self._node
|
||||
|
||||
if d_path[obj]:
|
||||
_caller = d_path[obj][-1]
|
||||
if _caller != d_last_caller[obj]:
|
||||
addattr(obj, "%s_parents" % _node, _caller)
|
||||
addattr(obj, "%s_children" % _caller, _node)
|
||||
d_last_caller[obj] = _caller
|
||||
|
||||
#Wanted: value. Cached or Computed
|
||||
try:
|
||||
value = getattr(obj, _node)
|
||||
except AttributeError:
|
||||
|
||||
d_path[obj].append(_node)
|
||||
|
||||
value = self.provider(obj)
|
||||
setattr(obj, _node, value)
|
||||
|
||||
d_path[obj].pop()
|
||||
|
||||
return value
|
||||
|
||||
def __set__(self, obj, value):
|
||||
"""Set the value of the node
|
||||
But wait, init_node are "gradual typed" variable! Youpi!
|
||||
Idea borrowed from the-worst-programming-language-ever (http://bit.ly/13tc6XW)
|
||||
"""
|
||||
|
||||
_node = self._node
|
||||
|
||||
if not self.init_node:
|
||||
|
||||
if self.immutable:
|
||||
raise AttributeError("Immutable Node {0}".format(self._node))
|
||||
|
||||
#Set the new value
|
||||
setattr(obj, _node, value)
|
||||
|
||||
#Node ancestor need to be recompute is asked
|
||||
for _parent in genealogy(obj, _node, "parents"):
|
||||
if hasattr(obj, _parent): delattr(obj, _parent)
|
||||
|
||||
#Node abandoned her children,
|
||||
for _child in genealogy(obj, _node, "children",degree_max=1):
|
||||
removeattr(obj, "%s_parents" % _child, _node)
|
||||
|
||||
#Indeed node is now a leaf
|
||||
setattr(obj, "%s_children" % _node, set())
|
||||
|
||||
else:
|
||||
setattr(obj, _node, value)
|
||||
self.init_node = False
|
||||
|
||||
|
||||
def lazy_property_mutable(provider):
|
||||
"Return a lazy_property mutable"
|
||||
return lazy_property(provider=provider, immutable=False)
|
||||
|
||||
|
||||
def lazy_property_leaves(mutables=(), immutables=()):
|
||||
"Set to properties for the __init__ method"
|
||||
|
||||
def leaf_decorator(func):
|
||||
def func_wrapper(self, *args, **kwargs):
|
||||
|
||||
for node in set(immutables) | set(mutables):
|
||||
|
||||
def provider(self):
|
||||
return getattr(self, "_%s" % node)
|
||||
|
||||
p = lazy_property(provider=provider,
|
||||
init_node=node,
|
||||
immutable=node in immutables)
|
||||
|
||||
#If this ugly? Yeah... Is this an issue? I don't really know
|
||||
setattr(self.__class__, node, p)
|
||||
|
||||
return func(self, *args, **kwargs)
|
||||
|
||||
return func_wrapper
|
||||
|
||||
return leaf_decorator
|
58
src/locks.py
58
src/locks.py
@ -1,58 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
|
||||
# the Implicit Reference to Parameters (IRP) method.
|
||||
# Copyright (C) 2009 Anthony SCEMAMA
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Anthony Scemama
|
||||
# LCPQ - IRSAMC - CNRS
|
||||
# Universite Paul Sabatier
|
||||
# 118, route de Narbonne
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from command_line import command_line
|
||||
|
||||
from irpf90_t import *
|
||||
from util import *
|
||||
from variables import variables
|
||||
FILENAME=irpdir+'irp_locks.irp.F90'
|
||||
|
||||
def create():
|
||||
out = []
|
||||
l = variables.keys()
|
||||
l.sort
|
||||
for v in l:
|
||||
var = variables[v]
|
||||
out += var.locker
|
||||
|
||||
out += [
|
||||
"subroutine irp_init_locks_%s()"%(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" ]
|
||||
out = map(lambda x: "%s\n"%(x),out)
|
||||
if not same_file(FILENAME,out):
|
||||
file = open(FILENAME,'w')
|
||||
file.writelines(out)
|
||||
file.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
create()
|
||||
|
204
src/makefile.py
204
src/makefile.py
@ -1,204 +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 os,sys
|
||||
import irpf90_t
|
||||
from command_line import command_line
|
||||
irpdir = irpf90_t.irpdir
|
||||
mandir = irpf90_t.mandir
|
||||
|
||||
FILENAME = "Makefile"
|
||||
FILENAME_GITIGNORE = ".gitignore"
|
||||
IRPF90_MAKE = "irpf90.make"
|
||||
|
||||
######################################################################
|
||||
def create():
|
||||
has_makefile = True
|
||||
try:
|
||||
file = open(FILENAME,"r")
|
||||
except IOError:
|
||||
has_makefile = False
|
||||
if has_makefile:
|
||||
return
|
||||
file = open(FILENAME,"w")
|
||||
t = """IRPF90 = irpf90 #-a -d
|
||||
FC = gfortran
|
||||
FCFLAGS= -O2 -ffree-line-length-none -I .
|
||||
NINJA = ninja
|
||||
AR = ar
|
||||
RANLIB = ranlib
|
||||
|
||||
SRC=
|
||||
OBJ=
|
||||
LIB=
|
||||
|
||||
-include %s
|
||||
export
|
||||
|
||||
%s: $(filter-out %s%%, $(wildcard */*.irp.f)) $(wildcard *.irp.f) $(wildcard *.inc.f) Makefile
|
||||
\t$(IRPF90)
|
||||
"""%(IRPF90_MAKE,IRPF90_MAKE,irpdir)
|
||||
file.write(t)
|
||||
file.close()
|
||||
create_gitignore()
|
||||
|
||||
######################################################################
|
||||
def create_gitignore():
|
||||
has_makefile = True
|
||||
try:
|
||||
file = open(FILENAME_GITIGNORE,"r")
|
||||
except IOError:
|
||||
has_makefile = False
|
||||
if has_makefile:
|
||||
return
|
||||
file = open(FILENAME_GITIGNORE,"w")
|
||||
t = "\n".join([ irpdir, mandir, IRPF90_MAKE, 'irpf90_entities', 'tags' ])
|
||||
file.write(t)
|
||||
file.close()
|
||||
|
||||
######################################################################
|
||||
def run_ninja():
|
||||
import ninja
|
||||
ninja.run()
|
||||
|
||||
######################################################################
|
||||
def run_make():
|
||||
from modules import modules
|
||||
mod = []
|
||||
for m in modules.values():
|
||||
mod.append(m)
|
||||
|
||||
file = open(IRPF90_MAKE,'w')
|
||||
result = ""
|
||||
result += "FC+=-I %s "%(irpdir)
|
||||
for i in command_line.include_dir:
|
||||
result += "-I %s%s "%(irpdir,i)
|
||||
result += "\n"
|
||||
result += "SRC += %sirp_stack.irp.F90"%(irpdir)
|
||||
result += " %sirp_touches.irp.F90"%(irpdir)
|
||||
# result += " %sirp_checkpoint.irp.F90"%(irpdir)
|
||||
if command_line.do_openmp:
|
||||
result += " %sirp_locks.irp.F90"%(irpdir)
|
||||
if command_line.do_profile:
|
||||
result += " %sirp_profile.irp.F90"%(irpdir)
|
||||
for m in mod:
|
||||
result += " %s%s.irp.F90"%(irpdir,m.filename)
|
||||
result += " %s%s.irp.module.F90"%(irpdir,m.filename)
|
||||
print >>file, result
|
||||
|
||||
result = "OBJ_IRP = %sirp_stack.irp.o "%(irpdir)
|
||||
for m in mod:
|
||||
if not m.is_main:
|
||||
result += " %s%s.irp.o"%(irpdir,m.filename)
|
||||
result += " %s%s.irp.module.o"%(irpdir,m.filename)
|
||||
print >>file, result
|
||||
|
||||
print >>file, "OBJ1 = $(OBJ_IRP) $(OBJ) %sirp_touches.irp.o "%(irpdir),
|
||||
# print >>file, " %sirp_checkpoint.irp.o"%(irpdir),
|
||||
if command_line.do_profile:
|
||||
print >>file, " %sirp_profile.irp.o"%(irpdir), " irp_rdtsc.o",
|
||||
if command_line.do_codelet:
|
||||
print >>file, " irp_rdtsc.o",
|
||||
if command_line.do_openmp:
|
||||
print >>file, " %sirp_locks.irp.o"%(irpdir)
|
||||
else:
|
||||
print >>file, ""
|
||||
|
||||
all = filter(lambda x: modules[x].is_main, modules)
|
||||
all = map(lambda x: x[:-6], all)
|
||||
all_o = map(lambda x: "%s.irp.module.o %s.irp.o"%(x,x), all)
|
||||
print >>file, "ALL = %s"%(" ".join(all))
|
||||
print >>file, "ALL_OBJ = %s"%(" ".join(all_o))
|
||||
print >>file, "ALL_OBJ1 = $(patsubst %%, %s%%,$(notdir $(ALL_OBJ)))"%(irpdir)
|
||||
print >>file, "all:$(ALL)"
|
||||
print >>file, "\t@$(MAKE) -s move"
|
||||
# print >>file, "ifdef USE_IRPF90_A"
|
||||
for m in mod:
|
||||
if m.is_main:
|
||||
exe = m.filename
|
||||
print >>file, "%s: %s%s.irp.o %s%s.irp.module.o IRPF90_temp/irpf90.a"%(exe,irpdir,exe,irpdir,exe)
|
||||
print >>file, "\t$(FC) -o $@ %s$@.irp.o %s$@.irp.module.o IRPF90_temp/irpf90.a $(LIB)"%(irpdir,irpdir)
|
||||
print >>file, "\t@$(MAKE) -s move"
|
||||
# print >>file, "else"
|
||||
# for m in mod:
|
||||
# if m.is_main:
|
||||
# exe = m.filename
|
||||
# print >>file, "%s: %s%s.irp.o %s%s.irp.module.o $(OBJ1)"%(exe,irpdir,exe,irpdir,exe)
|
||||
# print >>file, "\t$(FC) -o $@ %s$@.irp.o %s$@.irp.module.o $(OBJ1) $(LIB)"%(irpdir,irpdir)
|
||||
# print >>file, "\t@$(MAKE) -s move"
|
||||
# print >>file, "endif"
|
||||
|
||||
buffer = ""
|
||||
for m in mod:
|
||||
filename = "%s%s.irp.o: $(OBJ) %s%s.irp.module.o"%(irpdir,m.filename,irpdir,m.filename)
|
||||
needed_modules = filter( lambda x: modules[x].name in m.needed_modules, modules )
|
||||
needed_files = map(lambda x: modules[x].filename, needed_modules)
|
||||
mds = map (lambda x: " %s%s.irp.module.o"%(irpdir,x),needed_files)
|
||||
print >>file, filename," ".join(mds)," ".join(m.includes)
|
||||
if not m.is_main:
|
||||
buffer += "\t - @echo '"+filename+" ".join(mds)+"' >> %sdist_Makefile\n"%(irpdir)
|
||||
# print >>file, "%sirp_touches.irp.o %sirp_checkpoint.irp.o: $(OBJ) "%(irpdir,irpdir),
|
||||
print >>file, "%sirp_touches.irp.o: $(OBJ) "%(irpdir),
|
||||
mds = filter(lambda x: not x.is_main,mod)
|
||||
mds = map(lambda x: " %s%s.irp.o %s%s.irp.o"%(irpdir,x.filename,irpdir,x.filename),mds)
|
||||
print >>file," ".join(mds)
|
||||
if command_line.do_profile:
|
||||
print >>file, "%sirp_profile.irp.o:"%(irpdir),
|
||||
print >>file," ".join(mds)
|
||||
if command_line.do_openmp:
|
||||
print >>file, "%sirp_locks.irp.o:"%(irpdir),
|
||||
print >>file," ".join(mds)
|
||||
|
||||
|
||||
for dir in [ irpdir ] + map(lambda x: irpdir+x, command_line.include_dir):
|
||||
print >>file, dir+"%.irp.module.o: $(OBJ) "+dir+"%.irp.module.F90"
|
||||
print >>file, "\t$(FC) $(FCFLAGS) -c "+dir+"$*.irp.module.F90 -o "+dir+"$*.irp.module.o"
|
||||
print >>file, dir+"%.irp.o: $(OBJ) "+dir+"%.irp.module.o "+dir+"%.irp.F90"
|
||||
print >>file, "\t$(FC) $(FCFLAGS) -c "+dir+"$*.irp.F90 -o "+dir+"$*.irp.o"
|
||||
print >>file, dir+"%.irp.o: $(OBJ) "+dir+"%.irp.F90"
|
||||
print >>file, "\t$(FC) $(FCFLAGS) -c "+dir+"$*.irp.F90 -o "+dir+"$*.irp.o"
|
||||
print >>file, dir+"%.o: %.F90"
|
||||
print >>file, "\t$(FC) $(FCFLAGS) -c $*.F90 -o "+dir+"$*.o"
|
||||
print >>file, dir+"%.o: %.f90\n\t$(FC) $(FCFLAGS) -c $*.f90 -o "+dir+"$*.o"
|
||||
print >>file, dir+"%.o: %.f\n\t$(FC) $(FCFLAGS) -c $*.f -o "+dir+"$*.o"
|
||||
print >>file, dir+"%.o: %.F\n\t$(FC) $(FCFLAGS) -c $*.F -o "+dir+"$*.o"
|
||||
print >>file, dir+"%.irp.F90: "+IRPF90_MAKE+"\n"
|
||||
print >>file, "move:\n\t@mv -f *.mod IRPF90_temp/ 2> /dev/null | DO_NOTHING=\n"
|
||||
print >>file, "IRPF90_temp/irpf90.a: $(OBJ) $(OBJ1)\n\t$(AR) crf IRPF90_temp/irpf90.a $(OBJ1)\n"
|
||||
print >>file, "clean:\n\trm -rf $(EXE) $(OBJ1) IRPF90_temp/irpf90.a $(ALL_OBJ1) $(ALL)\n"
|
||||
print >>file, "veryclean:\n\t- $(MAKE) clean\n"
|
||||
print >>file, "\t- rm -rf "+irpdir+" "+mandir+" "+IRPF90_MAKE+" irpf90_entities dist tags\n"
|
||||
|
||||
file.close()
|
||||
|
||||
######################################################################
|
||||
def run():
|
||||
if command_line.do_ninja:
|
||||
run_ninja()
|
||||
else:
|
||||
run_make()
|
||||
|
394
src/module.py
394
src/module.py
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/unr/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
|
||||
@ -24,204 +24,246 @@
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from irpf90_t import *
|
||||
from variable import *
|
||||
from variables import variables
|
||||
from command_line import command_line
|
||||
import preprocessed_text
|
||||
from util import *
|
||||
from entity import Entity
|
||||
|
||||
def put_info(text, filename):
|
||||
|
||||
lenmax = 80 - len(filename)
|
||||
format_ = "%" + str(lenmax) + "s ! %s:%4s"
|
||||
|
||||
str_ = '{text:{width}} ! {filename}:{i:4}'
|
||||
for _, line in text:
|
||||
line.text = str_.format(text=line.text,filename=line.filename,i=line.i,width=lenmax)
|
||||
return text
|
||||
|
||||
|
||||
class Fmodule(object):
|
||||
|
||||
header = \
|
||||
[ "! -*- F90 -*-",
|
||||
"!",
|
||||
"!-----------------------------------------------!",
|
||||
"! This file was generated with the irpf90 tool. !",
|
||||
"! !",
|
||||
"! DO NOT MODIFY IT BY HAND !",
|
||||
"!-----------------------------------------------!",
|
||||
"" ]
|
||||
header = [ "! -*- F90 -*-",
|
||||
"!",
|
||||
"!-----------------------------------------------!",
|
||||
"! This file was generated with the irpf90 tool. !",
|
||||
"! !",
|
||||
"! DO NOT MODIFY IT BY HAND !",
|
||||
"!-----------------------------------------------!",
|
||||
""]
|
||||
|
||||
def __init__(self,text,filename):
|
||||
self.text = put_info(text,filename)
|
||||
self.filename = filename[:-6]
|
||||
self.name = "%s_mod"%(self.filename).replace('/','__').replace('.','Dot')
|
||||
def __init__(self, text, filename, d_variable):
|
||||
self.text = put_info(text, filename)
|
||||
self.filename = filename[:-6]
|
||||
self.name = "%s_mod" % (self.filename).replace('/', '__').replace('.', 'Dot')
|
||||
self.d_all_variable = d_variable
|
||||
|
||||
def is_main(self):
|
||||
if '_is_main' not in self.__dict__:
|
||||
self._is_main = self.prog_name is not None
|
||||
return self._is_main
|
||||
is_main = property(is_main)
|
||||
@irpy.lazy_property
|
||||
def prog_name(self):
|
||||
l = [line.filename for _, line in self.text if isinstance(line, Program)]
|
||||
return l.pop() if l else None
|
||||
|
||||
def prog_name(self):
|
||||
if '_prog_name' not in self.__dict__:
|
||||
buffer = filter(lambda x: type(x[1]) == Program,self.text)
|
||||
if buffer == []:
|
||||
self._prog_name = None
|
||||
else:
|
||||
self._prog_name = buffer[0][1].filename
|
||||
return self._prog_name
|
||||
prog_name = property(prog_name)
|
||||
@irpy.lazy_property
|
||||
def is_main(self):
|
||||
return self.prog_name is not None
|
||||
|
||||
def variables(self):
|
||||
if '_variables' not in self.__dict__:
|
||||
from variables import variables
|
||||
name = self.name
|
||||
self._variables = filter(lambda x: variables[x].fmodule == name, variables)
|
||||
return self._variables
|
||||
variables = property(variables)
|
||||
@irpy.lazy_property
|
||||
def l_entity(self):
|
||||
return [value for value in self.d_all_variable.values() if value.fmodule == self.name]
|
||||
|
||||
@irpy.lazy_property
|
||||
def head(self):
|
||||
'''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]
|
||||
|
||||
|
||||
def head(self):
|
||||
if '_head' not in self.__dict__:
|
||||
result = [ "module %s"%(self.name) ]
|
||||
result += self.use
|
||||
result += self.dec
|
||||
result += flatten( map(lambda x: variables[x].header,self.variables) )
|
||||
result.append( "end module %s"%(self.name) )
|
||||
self._head = result
|
||||
return self._head
|
||||
head = property(head)
|
||||
if body:
|
||||
result = ["module %s" % (self.name)]
|
||||
result += body
|
||||
result += ["end module %s" % (self.name)]
|
||||
else:
|
||||
result = []
|
||||
|
||||
def needed_vars(self):
|
||||
if '_needed_vars' not in self.__dict__:
|
||||
result = map(lambda x: variables[x].needs,self.variables)
|
||||
result = make_single ( flatten(result) )
|
||||
self._needed_vars = result
|
||||
return self._needed_vars
|
||||
needed_vars = property(needed_vars)
|
||||
return result
|
||||
|
||||
def includes(self):
|
||||
if '_includes' not in self.__dict__:
|
||||
buffer = []
|
||||
for v in self.needed_vars:
|
||||
buffer += variables[v].includes
|
||||
self._includes = make_single(buffer)
|
||||
return self._includes
|
||||
includes = property(includes)
|
||||
@irpy.lazy_property
|
||||
def has_irp_module(self):
|
||||
return bool(self.head)
|
||||
|
||||
def generated_text(self):
|
||||
if '_generated_text' not in self.__dict__:
|
||||
result = []
|
||||
for var in self.variables:
|
||||
var = variables[var]
|
||||
result += var.provider
|
||||
result += var.builder
|
||||
if var.is_read:
|
||||
result += var.reader
|
||||
if var.is_written:
|
||||
result += var.writer
|
||||
self._generated_text = result
|
||||
return self._generated_text
|
||||
generated_text = property(generated_text)
|
||||
@irpy.lazy_property
|
||||
def needed_vars(self):
|
||||
return set(n for var in self.l_entity for n in var.needs)
|
||||
|
||||
def residual_text(self):
|
||||
if '_residual_text' not in self.__dict__:
|
||||
from variables import build_use, call_provides
|
||||
from parsed_text import move_to_top
|
||||
def remove_providers(text):
|
||||
@irpy.lazy_property
|
||||
def includes(self):
|
||||
return set(i for var in self.needed_vars for i in self.d_all_variable[var].includes)
|
||||
|
||||
@irpy.lazy_property
|
||||
def generated_text(self):
|
||||
'Routine genereraed by the IRPF90. provide, build, ...'
|
||||
result = []
|
||||
inside = False
|
||||
for vars,line in text:
|
||||
if type(line) == Begin_provider:
|
||||
inside = True
|
||||
if not inside:
|
||||
result.append( (vars,line) )
|
||||
if type(line) == End_provider:
|
||||
for var in self.l_entity:
|
||||
result += var.provider
|
||||
result += var.builder
|
||||
if var.is_read:
|
||||
result += var.reader
|
||||
if var.is_written:
|
||||
result += var.writer
|
||||
|
||||
return result
|
||||
|
||||
@irpy.lazy_property
|
||||
def residual_text_use_dec(self):
|
||||
|
||||
def remove_providers(text):
|
||||
result = []
|
||||
inside = False
|
||||
return result
|
||||
|
||||
def modify_functions(text):
|
||||
for vars, line in text:
|
||||
if type(line) == Begin_provider:
|
||||
inside = True
|
||||
if not inside:
|
||||
result.append((vars, line))
|
||||
if type(line) == End_provider:
|
||||
inside = False
|
||||
return result
|
||||
|
||||
def modify_functions(text):
|
||||
|
||||
result = []
|
||||
variable_list = []
|
||||
skip_interface = False
|
||||
for vars, line in text:
|
||||
if type(line) in [Interface, End_interface]:
|
||||
skip_interface = not skip_interface
|
||||
|
||||
if skip_interface:
|
||||
result.append((vars, line))
|
||||
continue
|
||||
|
||||
|
||||
if type(line) in [Subroutine, Function, Program]:
|
||||
#Deep copy...
|
||||
variable_list = list(vars)
|
||||
elif type(line) == End:
|
||||
result += [([], Use(line.i, x, line.filename)) for x in build_use(variable_list, self.d_all_variable)]
|
||||
else:
|
||||
variable_list += vars
|
||||
|
||||
result.append((vars, line))
|
||||
return result
|
||||
|
||||
def extract_use_dec_text(text):
|
||||
# (List[ Tuple(Entity,Line) ]) -> (List[ Tuple(Entity,Line),List[ Tuple(Entity,Line),List[ Tuple(Entity,Line))
|
||||
'''Extract the global declaration statement and module use form the declaration of function. '''
|
||||
|
||||
inside = 0
|
||||
result,dec,use,module = [],[],[],[]
|
||||
|
||||
for vars, line in text:
|
||||
|
||||
if isinstance(line, (Subroutine, Function, Program,Interface,Module)):
|
||||
inside += 1
|
||||
|
||||
if type(line) == Module:
|
||||
module.append((vars,line))
|
||||
|
||||
if inside:
|
||||
result.append((vars, line))
|
||||
else:
|
||||
if type(line) == Use:
|
||||
use.append((vars, line))
|
||||
elif type(line) == Declaration:
|
||||
dec.append((vars, line))
|
||||
|
||||
|
||||
if isinstance(line,(End,End_interface,End_module)):
|
||||
inside += -1
|
||||
|
||||
if inside:
|
||||
print 'Something wrong append'
|
||||
sys.exit(1)
|
||||
|
||||
return use, module, dec, result
|
||||
|
||||
result = remove_providers(self.text)
|
||||
result = modify_functions(result)
|
||||
|
||||
from collections import namedtuple
|
||||
Residual_text_use_dec = namedtuple('Residual_text_use_dec', ['use', 'module', 'dec', 'result'])
|
||||
|
||||
return Residual_text_use_dec(*extract_use_dec_text(result))
|
||||
|
||||
@irpy.lazy_property
|
||||
def use(self):
|
||||
return set(" %s" % line.text for _, line in self.residual_text_use_dec.use)
|
||||
|
||||
@irpy.lazy_property
|
||||
def gen_mod(self):
|
||||
'''List of module generated by the user in this module...'''
|
||||
return set("%s" % line.subname for _, line in self.residual_text_use_dec.module)
|
||||
|
||||
@irpy.lazy_property
|
||||
def dec(self):
|
||||
'''The declaration of this module
|
||||
|
||||
Note:
|
||||
Because user can define F90 Type, we need to keep the correct order.
|
||||
|
||||
Warning:
|
||||
If we uniquify that can cause a problem with the type in guess.
|
||||
```type toto
|
||||
integer :: n
|
||||
end type toto
|
||||
integer :: n
|
||||
```
|
||||
Fix:
|
||||
We need to support Type keyword.
|
||||
|
||||
'''
|
||||
|
||||
l = [" %s" % line.text for _, line in self.residual_text_use_dec.dec]
|
||||
from util import uniquify
|
||||
if len(l) != len(uniquify(l)):
|
||||
raise NotImplementedError
|
||||
|
||||
return l
|
||||
|
||||
@irpy.lazy_property
|
||||
def residual_text(self):
|
||||
'''Not the generated function (build, provide, touch, etc.)'''
|
||||
|
||||
result = []
|
||||
variable_list = []
|
||||
for vars,line in text:
|
||||
if type(line) in [ Subroutine, Function ]:
|
||||
variable_list = list(vars)
|
||||
elif type(line) == End:
|
||||
result += map(lambda x: ([],Use(line.i,x,line.filename)), build_use(variable_list))
|
||||
else:
|
||||
variable_list += vars
|
||||
result.append( (vars,line) )
|
||||
return result
|
||||
|
||||
def extract_use_dec_text(text):
|
||||
inside = False
|
||||
result = []
|
||||
dec = []
|
||||
use = []
|
||||
for vars,line in text:
|
||||
if type(line) in [ Subroutine, Function, Program]:
|
||||
inside = True
|
||||
if inside:
|
||||
result.append( (vars,line) )
|
||||
else:
|
||||
if type(line) == Use:
|
||||
use.append( (vars,line) )
|
||||
elif type(line) == Declaration:
|
||||
dec.append( (vars,line) )
|
||||
if type(line) == End:
|
||||
inside = False
|
||||
return use, dec, result
|
||||
|
||||
def provide_variables(text):
|
||||
result = []
|
||||
for vars,line in text:
|
||||
result.append( ([],line) )
|
||||
result += map(lambda x: ([],Simple_line(line.i,x,line.filename)), call_provides(vars))
|
||||
return result
|
||||
|
||||
result = remove_providers(self.text)
|
||||
result = modify_functions(result)
|
||||
use,dec,result = extract_use_dec_text(result)
|
||||
self._use = make_single(map(lambda x: " "+x[1].text, use))
|
||||
self._dec = map(lambda x: " "+x[1].text, dec)
|
||||
# self._dec = make_single(map(lambda x: " "+x[1].text, dec))
|
||||
result = provide_variables(result)
|
||||
result = move_to_top(result,Declaration)
|
||||
result = move_to_top(result,Implicit)
|
||||
result = move_to_top(result,Use)
|
||||
result = map(lambda x: x[1], result)
|
||||
result = map(lambda x: x.text, result)
|
||||
self._residual_text = result
|
||||
return self._residual_text
|
||||
residual_text = property(residual_text)
|
||||
|
||||
def use(self):
|
||||
if '_use' not in self.__dict__:
|
||||
self.residual_text
|
||||
return self._use
|
||||
use = property(use)
|
||||
|
||||
def dec(self):
|
||||
if '_dec' not in self.__dict__:
|
||||
self.residual_text
|
||||
return self._dec
|
||||
dec = property(dec)
|
||||
for vars, line in self.residual_text_use_dec.result:
|
||||
result.append(([], line))
|
||||
result += map(lambda x: ([], Simple_line(line.i, x, line.filename)),
|
||||
build_call_provide(vars, self.d_all_variable))
|
||||
|
||||
|
||||
def needed_modules(self):
|
||||
if '_needed_modules' not in self.__dict__:
|
||||
buffer = filter(lambda x: x.lstrip().startswith("use "), \
|
||||
self.generated_text+self.head+self.residual_text)
|
||||
buffer = map(lambda x: x.split()[1], buffer)
|
||||
buffer = filter(lambda x: x.endswith("_mod"),buffer )
|
||||
self._needed_modules = make_single(buffer)
|
||||
if self.name in self._needed_modules:
|
||||
self._needed_modules.remove(self.name)
|
||||
return self._needed_modules
|
||||
needed_modules = property(needed_modules)
|
||||
from parsed_text import move_to_top_list, move_interface
|
||||
move_to_top_list(result, [Declaration, Implicit, Use])
|
||||
move_interface(result)
|
||||
|
||||
######################################################################
|
||||
return [line.text for _, line in result]
|
||||
|
||||
@irpy.lazy_property
|
||||
def needed_modules(self):
|
||||
l = set(x.split(',only').pop(0).split()[1] for x in self.generated_text + self.head + self.residual_text if x.lstrip().startswith("use "))
|
||||
|
||||
if self.name in l:
|
||||
l.remove(self.name)
|
||||
|
||||
return l
|
||||
|
||||
|
||||
@irpy.lazy_property
|
||||
def needed_modules_irp(self):
|
||||
return [i for i in self.needed_modules if i.endswith("_mod")]
|
||||
|
||||
@irpy.lazy_property
|
||||
def needed_modules_usr(self):
|
||||
return [i for i in self.needed_modules if not i.endswith("_mod")]
|
||||
|
||||
if __name__ == '__main__':
|
||||
from parsed_text import parsed_text
|
||||
for filename, text in parsed_text:
|
||||
if filename == 'vmc_step.irp.f':
|
||||
x = Fmodule(text,filename)
|
||||
break
|
||||
for line in x.head:
|
||||
print line
|
||||
print x.includes
|
||||
|
||||
|
@ -1,68 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
|
||||
# the Implicit Reference to Parameters (IRP) method.
|
||||
# Copyright (C) 2009 Anthony SCEMAMA
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Anthony Scemama
|
||||
# LCPQ - IRSAMC - CNRS
|
||||
# Universite Paul Sabatier
|
||||
# 118, route de Narbonne
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from irpf90_t import *
|
||||
from parsed_text import parsed_text
|
||||
from module import Fmodule
|
||||
from util import *
|
||||
|
||||
######################################################################
|
||||
def create_modules():
|
||||
result = {}
|
||||
for filename,text in parsed_text:
|
||||
result[filename] = Fmodule(text,filename)
|
||||
return result
|
||||
|
||||
modules = create_modules()
|
||||
|
||||
######################################################################
|
||||
def write_module(m):
|
||||
# Module data
|
||||
filename = irpdir+m.filename+".irp.module.F90"
|
||||
text = m.header + m.head
|
||||
text = map(lambda x: "%s\n"%(x),text)
|
||||
if not same_file(filename,text):
|
||||
# print filename
|
||||
file = open(filename,"w")
|
||||
file.writelines(text)
|
||||
file.close()
|
||||
|
||||
# Subroutines
|
||||
filename = irpdir+m.filename+".irp.F90"
|
||||
text = m.header + m.generated_text + m.residual_text
|
||||
text = map(lambda x: "%s\n"%(x),text)
|
||||
if not same_file(filename,text):
|
||||
# print filename
|
||||
file = open(filename,"w")
|
||||
file.writelines(text)
|
||||
file.close()
|
||||
|
||||
######################################################################
|
||||
if __name__ == '__main__':
|
||||
write_module(modules['psi.irp.f'])
|
||||
|
||||
|
408
src/ninja.py
408
src/ninja.py
@ -1,408 +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 os,sys
|
||||
import irpf90_t
|
||||
from command_line import command_line
|
||||
from modules import modules
|
||||
irpdir = irpf90_t.irpdir
|
||||
mandir = irpf90_t.mandir
|
||||
irp_id = irpf90_t.irp_id
|
||||
|
||||
FILENAME = os.path.join(irpdir,"build.ninja")
|
||||
|
||||
cwd = os.getcwd()
|
||||
|
||||
PRINT_WIDTH=50
|
||||
|
||||
def dress(f,in_root=False):
|
||||
"""
|
||||
Transfoms the filename f into $PWD/IRPF90_temp/f
|
||||
"""
|
||||
if in_root:
|
||||
result = os.path.join(cwd,f)
|
||||
else:
|
||||
result = os.path.join(cwd,irpdir,f)
|
||||
return os.path.normpath(result)
|
||||
|
||||
|
||||
def create_build_touches(list_of_other_o):
|
||||
"""
|
||||
Create the build command for the irp_touches.o file and the irpf90.a library.
|
||||
"""
|
||||
name = "irp_touches"
|
||||
short_lib = "irpf90.a"
|
||||
short_target_o = "%s.irp.o"%name
|
||||
short_target_F90 = "%s.irp.F90"%name
|
||||
lib = dress(short_lib)
|
||||
target_o = dress(short_target_o)
|
||||
target_F90 = dress(short_target_F90)
|
||||
|
||||
needed_modules = [ "%s.irp.module.o"%(modules[x].filename) for x in modules ]
|
||||
|
||||
list_of_modules = map(dress, needed_modules) + list_of_other_o
|
||||
list_of_modules = ' '.join(list_of_modules)
|
||||
|
||||
result = '\n'.join(
|
||||
[
|
||||
"build {target_o}: compile_touches_{id} {target_F90} | {list_of_modules}",
|
||||
" short_in = {short_target_F90}",
|
||||
" short_out = {short_target_o}",
|
||||
"",
|
||||
"build {lib}: link_lib_{id} {target_o} {list_of_modules}",
|
||||
" short_out = {short_lib}",
|
||||
"",
|
||||
] )
|
||||
|
||||
result = result.format(
|
||||
id = irp_id ,
|
||||
lib = lib ,
|
||||
list_of_modules = list_of_modules ,
|
||||
short_lib = short_lib ,
|
||||
short_target_F90 = os.path.split(target_F90)[1] ,
|
||||
short_target_o = os.path.split(target_o)[1] ,
|
||||
target_F90 = target_F90 ,
|
||||
target_o = target_o
|
||||
)
|
||||
return result
|
||||
|
||||
def create_build_target(t,list_of_other_o):
|
||||
"""
|
||||
Create the build command for the target module t. t is a Fmodule object.
|
||||
"""
|
||||
name = t.filename
|
||||
|
||||
irp_lib = dress("irpf90.a")
|
||||
target = dress(name,in_root=True)
|
||||
short_target_o = "%s.irp.o"%name
|
||||
short_target_F90 = "%s.irp.F90"%name
|
||||
short_target_module_F90 = "%s.irp.module.F90"%name
|
||||
short_target_module_o = "%s.irp.module.o"%name
|
||||
target_o = dress(short_target_o)
|
||||
target_F90 = dress(short_target_F90)
|
||||
target_module_o = dress(short_target_module_o)
|
||||
target_module_F90 = dress(short_target_module_F90)
|
||||
|
||||
needed_modules = [ "%s.irp.module.o"%(modules[x].filename) for x in modules \
|
||||
if modules[x].name in t.needed_modules ] + [ target_module_o ]
|
||||
|
||||
list_of_o = [ target_o, target_module_o, irp_lib ]
|
||||
list_of_o = ' '.join(list_of_o)
|
||||
|
||||
list_of_modules = map(dress, needed_modules) + list_of_other_o
|
||||
list_of_modules = ' '.join(list_of_modules)
|
||||
|
||||
list_of_includes = ' '.join(map(lambda x: dress(x,in_root=True), t.includes))
|
||||
|
||||
result = '\n'.join(
|
||||
[ "build {target}: link_{id} {list_of_o}",
|
||||
" short_out = {short_target}",
|
||||
"",
|
||||
"build {target_o}: compile_fortran_{id} {target_F90} | {list_of_modules} {list_of_includes}",
|
||||
" short_in = {short_target_F90}",
|
||||
" short_out = {short_target_o}",
|
||||
"",
|
||||
"build {target_module_o}: compile_fortran_{id} {target_module_F90}",
|
||||
" short_in = {short_target_module_F90}",
|
||||
" short_out = {short_target_module_o}",
|
||||
"",
|
||||
] )
|
||||
|
||||
result = result.format(
|
||||
id = irp_id ,
|
||||
list_of_includes = list_of_includes ,
|
||||
list_of_modules = list_of_modules ,
|
||||
list_of_o = list_of_o ,
|
||||
short_target_F90 = os.path.split(target_F90)[1] ,
|
||||
short_target_module_F90 = os.path.split(target_module_F90)[1] ,
|
||||
short_target_module_o = os.path.split(target_module_o)[1] ,
|
||||
short_target = name ,
|
||||
short_target_o = os.path.split(target_o)[1] ,
|
||||
target_F90 = target_F90 ,
|
||||
target_module_F90 = target_module_F90 ,
|
||||
target_module_o = target_module_o ,
|
||||
target_o = target_o ,
|
||||
target = target
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def create_build_non_target(t,list_of_other_o):
|
||||
"""
|
||||
Create the build command for the non-target module t. t is a Fmodule object.
|
||||
"""
|
||||
name = t.filename
|
||||
|
||||
target = dress(name,in_root=True)
|
||||
short_target_o = "%s.irp.o"%name
|
||||
short_target_F90 = "%s.irp.F90"%name
|
||||
short_target_module_F90 = "%s.irp.module.F90"%name
|
||||
short_target_module_o = "%s.irp.module.o"%name
|
||||
target_o = dress(short_target_o)
|
||||
target_F90 = dress(short_target_F90)
|
||||
target_module_o = dress(short_target_module_o)
|
||||
target_module_F90 = dress(short_target_module_F90)
|
||||
|
||||
needed_modules = [ "%s.irp.module.o"%(modules[x].filename) for x in modules \
|
||||
if modules[x].name in t.needed_modules ] + [ target_module_o ]
|
||||
|
||||
list_of_modules = map(dress, needed_modules)
|
||||
list_of_modules = ' '.join(list_of_modules)
|
||||
list_of_externals = ' '.join([ dress(x,in_root=True) for x in list_of_other_o ])
|
||||
list_of_includes = ' '.join(map(lambda x: dress(x,in_root=True), t.includes))
|
||||
|
||||
result = '\n'.join(
|
||||
[
|
||||
"build {target_o}: compile_fortran_{id} {target_F90} | {list_of_modules} {list_of_externals}",
|
||||
" short_in = {short_target_F90}",
|
||||
" short_out = {short_target}",
|
||||
"",
|
||||
"build {target_module_o}: compile_fortran_{id} {target_module_F90} | {list_of_externals} {list_of_includes}",
|
||||
" short_in = {short_target_F90}",
|
||||
" short_out = {short_target_o}",
|
||||
"",
|
||||
] )
|
||||
|
||||
result = result.format(
|
||||
id = irp_id ,
|
||||
list_of_externals = list_of_externals ,
|
||||
list_of_includes = list_of_includes ,
|
||||
list_of_modules = list_of_modules ,
|
||||
short_target_F90 = os.path.split(target_F90)[1] ,
|
||||
short_target = name ,
|
||||
short_target_o = os.path.split(target_o)[1] ,
|
||||
target_F90 = target_F90 ,
|
||||
target_module_F90 = target_module_F90 ,
|
||||
target_module_o = target_module_o ,
|
||||
target_o = target_o
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def create_build_remaining(f):
|
||||
"""
|
||||
Create the build command for the remaining file f. f is a file name (str).
|
||||
"""
|
||||
t, extension = f.rsplit('.',1)
|
||||
t1 = dress(t,in_root=True)
|
||||
t2 = dress(t,in_root=False)
|
||||
target_i = f
|
||||
target_o = "%s.o"%t
|
||||
if not target_o.startswith(os.path.join(cwd,irpdir)):
|
||||
target_o = target_o.replace(cwd,os.path.join(cwd,irpdir))
|
||||
|
||||
if extension.lower() in [ 'f', 'f90' ]:
|
||||
result = [ "build {target_o}: compile_fortran_{id} {target_i}" ]
|
||||
elif extension.lower() in [ 'c' ]:
|
||||
result = [ "build {target_o}: compile_c_{id} {target_i}" ]
|
||||
elif extension.lower() in [ 'cxx', 'cpp' ]:
|
||||
result = [ "build {target_o}: compile_cxx_{id} {target_i}" ]
|
||||
|
||||
result += [ " short_in = {short_target_i}",
|
||||
" short_out = {short_target_o}", "" ]
|
||||
result = '\n'.join(result).format(
|
||||
target_o = target_o,
|
||||
target_i = target_i,
|
||||
short_target_o = os.path.split(target_o)[1],
|
||||
short_target_i = os.path.split(target_i)[1],
|
||||
id = irp_id
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def create_irpf90_make(targets):
|
||||
targets = ' '.join(targets)
|
||||
result = """NINJA += -C {0}
|
||||
|
||||
TARGETS={1}
|
||||
|
||||
.PHONY: all clean veryclean
|
||||
|
||||
all:
|
||||
$(NINJA)
|
||||
|
||||
$(TARGETS):
|
||||
$(NINJA) $(PWD)/$@
|
||||
|
||||
clean:
|
||||
$(NINJA) -t clean
|
||||
|
||||
veryclean: clean
|
||||
rm -rf IRPF90_temp/ IRPF90_man/ irpf90.make irpf90_entities dist tags
|
||||
|
||||
""".format(irpdir, targets)
|
||||
|
||||
import makefile
|
||||
with open(makefile.IRPF90_MAKE,'w') as file:
|
||||
file.write(result)
|
||||
|
||||
|
||||
def run():
|
||||
|
||||
output = [ "builddir = %s"%os.path.join(cwd,irpdir) ]
|
||||
|
||||
# Environment variables
|
||||
|
||||
try: FC = os.environ["FC"]
|
||||
except KeyError: FC="gfortran -ffree-line-length-none"
|
||||
|
||||
try: AR = os.environ["AR"]
|
||||
except KeyError: AR="ar"
|
||||
|
||||
try: CC = os.environ["CC"]
|
||||
except KeyError: CC="gcc"
|
||||
|
||||
try: CXX = os.environ["CXX"]
|
||||
except KeyError: CXX="g++"
|
||||
|
||||
includes = [ "-I %s"%(i) for i in command_line.include_dir ]
|
||||
|
||||
FC += " "+' '.join(includes)
|
||||
CC += " "+' '.join(includes)
|
||||
CXX += " "+' '.join(includes)
|
||||
|
||||
try: SRC = os.environ["SRC"].split()
|
||||
except KeyError: SRC=[]
|
||||
|
||||
try: OBJ = os.environ["OBJ"].split()
|
||||
except KeyError: OBJ=[]
|
||||
|
||||
try: LIB = os.environ["LIB"].split()
|
||||
except KeyError: LIB=[]
|
||||
|
||||
try: FCFLAGS = os.environ["FCFLAGS"].split()
|
||||
except KeyError: FCFLAGS = [ "-O2" ]
|
||||
|
||||
try: CFLAGS = os.environ["CFLAGS"].split()
|
||||
except KeyError: CFLAGS = [ "-O2" ]
|
||||
|
||||
try: CXXFLAGS = os.environ["CXXFLAGS"].split()
|
||||
except KeyError: CXXFLAGS = [ "-O2" ]
|
||||
|
||||
FCFLAGS = ' '.join(FCFLAGS)
|
||||
CFLAGS = ' '.join(CFLAGS)
|
||||
CXXFLAGS = ' '.join(CXXFLAGS)
|
||||
LIB = ' '.join(LIB)
|
||||
|
||||
# Rules
|
||||
|
||||
t = [ "rule compile_fortran_{id}",
|
||||
" command = {FC} {FCFLAGS} -c $in -o $out",
|
||||
" description = F : $short_in -> $short_out",
|
||||
"",
|
||||
"rule compile_touches_{id}",
|
||||
" command = {FC} -c $in -o $out",
|
||||
" description = F : $short_in -> $short_out",
|
||||
"",
|
||||
"",
|
||||
"rule compile_c_{id}" ,
|
||||
" command = {CC} {CFLAGS} -c $in -o $out",
|
||||
" description = C : $short_in -> $short_out",
|
||||
"",
|
||||
"rule compile_cxx_{id}",
|
||||
" command = {CXX} {CXXFLAGS} -c $in -o $out",
|
||||
" description = C++ : $short_in -> $short_out",
|
||||
"",
|
||||
"rule link_lib_{id}",
|
||||
" command = {AR} crf $out $in" ,
|
||||
" description = Link: $short_out",
|
||||
"",
|
||||
"rule link_{id}",
|
||||
" command = {FC} $in {LIB} -o $out" ,
|
||||
" description = Link: $short_out"]
|
||||
|
||||
output += [ '\n'.join(t).format(id=irp_id, FC=FC, FCFLAGS=FCFLAGS, LIB=LIB, CXX=CXX, CXXFLAGS=CXXFLAGS, CC=CC, CFLAGS=CFLAGS, AR=AR) ]
|
||||
|
||||
|
||||
# All modules : list of Fmodule objects
|
||||
|
||||
l_mod = list( modules.values() )
|
||||
|
||||
|
||||
# Modules that are not targets
|
||||
|
||||
l_non_targets = [ x for x in l_mod if not x.is_main ]
|
||||
|
||||
|
||||
|
||||
|
||||
# Common object/source files
|
||||
|
||||
l_common_o = [ "irp_touches.irp.o" ] + \
|
||||
[ "{0}.irp.o".format(x.filename) for x in l_non_targets ] + \
|
||||
[ "{0}.irp.module.o".format(x.filename) for x in l_non_targets ]
|
||||
|
||||
|
||||
l_common_s = []
|
||||
|
||||
if command_line.do_assert:
|
||||
l_common_o += [ "irp_stack.irp.o" ]
|
||||
l_common_s += [ "irp_stack.irp.F90" ]
|
||||
|
||||
if command_line.do_openmp:
|
||||
l_common_o += [ "irp_locks.irp.o" ]
|
||||
l_common_s += [ "irp_locks.irp.F90" ]
|
||||
|
||||
if command_line.do_profile:
|
||||
l_common_o += [ "irp_profile.irp.o", "irp_rdtsc.o" ]
|
||||
l_common_s += [ "irp_profile.irp.F90", "irp_rdtsc.c" ]
|
||||
|
||||
l_common_o = map(dress,l_common_o) + map(lambda x: dress(x,in_root=True), OBJ)
|
||||
l_common_s = map(dress,l_common_s) + map(lambda x: dress(x,in_root=True), SRC)
|
||||
|
||||
|
||||
# IRP_touches
|
||||
output.append(create_build_touches(l_common_o[1:]))
|
||||
|
||||
# All targets : list of Fmodule objects
|
||||
|
||||
l_targets = [ x for x in l_mod if x.is_main ]
|
||||
|
||||
|
||||
# Create lines
|
||||
|
||||
for i in l_non_targets:
|
||||
output.append (create_build_non_target(i,OBJ))
|
||||
|
||||
for i in l_targets:
|
||||
output.append(create_build_target(i, l_common_o))
|
||||
|
||||
# Remaining files
|
||||
for i in l_common_s:
|
||||
output.append(create_build_remaining(i))
|
||||
|
||||
|
||||
with open(FILENAME,'w') as f:
|
||||
f.write('\n\n'.join(output))
|
||||
f.write('\n')
|
||||
|
||||
create_irpf90_make([ x.filename for x in l_targets ] + [ os.path.join(irpdir,'irpf90.a') ] )
|
||||
|
||||
return
|
||||
|
||||
|
@ -24,526 +24,529 @@
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from util import *
|
||||
from irpf90_t import *
|
||||
from variables import variables
|
||||
from preprocessed_text import preprocessed_text
|
||||
from subroutines import subroutines
|
||||
import regexps, re
|
||||
import error
|
||||
|
||||
vtuple = map(lambda v: (v, variables[v].same_as, variables[v].regexp), variables.keys())
|
||||
stuple = map(lambda s: (s, subroutines[s].regexp), subroutines.keys())
|
||||
stuple = filter(lambda s: subroutines[s[0]].is_function, stuple)
|
||||
re_string_sub = regexps.re_string.sub
|
||||
|
||||
regexps_re_string_sub = regexps.re_string.sub
|
||||
def find_variables_in_line(line):
|
||||
assert isinstance(line,Line)
|
||||
result = []
|
||||
sub_done = False
|
||||
buffer = line.lower
|
||||
ap = result.append
|
||||
for v,same_as,regexp in vtuple:
|
||||
if v in buffer:
|
||||
if not sub_done:
|
||||
buffer = regexps_re_string_sub('',buffer)
|
||||
sub_done = True
|
||||
if regexp.search(buffer) is not None:
|
||||
ap(same_as)
|
||||
return result
|
||||
|
||||
def find_funcs_in_line(line):
|
||||
assert isinstance(line,Line)
|
||||
result = []
|
||||
append = result.append
|
||||
sub_done = False
|
||||
buffer = line.lower
|
||||
for s,regexp in stuple:
|
||||
if s in buffer:
|
||||
if regexp.search(buffer) is not None:
|
||||
append(s)
|
||||
return result
|
||||
|
||||
def find_variables_in_line(line, vtuple):
|
||||
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)]
|
||||
|
||||
|
||||
def find_funcs_in_line(line, stuple):
|
||||
assert isinstance(line, Line)
|
||||
line_lower = line.lower
|
||||
result = [s for s, regexp in stuple if s in line_lower and regexp.search(line_lower)]
|
||||
return result
|
||||
|
||||
|
||||
def find_subroutine_in_line(line):
|
||||
assert type(line) == Call
|
||||
buffer = line.text.split('(')[0]
|
||||
buffer = buffer.split()[1].lower()
|
||||
return buffer
|
||||
assert type(line) == Call
|
||||
buffer = line.text.split('(')[0]
|
||||
buffer = buffer.split()[1].lower()
|
||||
return buffer
|
||||
|
||||
|
||||
def check_touch(variables, line, vars, main_vars):
|
||||
def fun(main_var):
|
||||
if main_var not in variables:
|
||||
error.fail(line, "Variable %s unknown" % (main_var, ))
|
||||
x = variables[main_var]
|
||||
return [main_var] + x.others_entity_name
|
||||
|
||||
all_others = uniquify(flatten(map(fun, main_vars)))
|
||||
all_others.sort()
|
||||
vars.sort()
|
||||
for x, y in zip(vars, all_others):
|
||||
if x != y:
|
||||
message = "The following entities should be touched:\n"
|
||||
message = "\n".join([message] + map(lambda x: "- %s" % (x, ), all_others))
|
||||
error.fail(line, message)
|
||||
|
||||
|
||||
from collections import namedtuple
|
||||
Parsed_text = namedtuple('Parsed_text', ['varlist', 'line'])
|
||||
|
||||
def check_touch(line,vars,main_vars):
|
||||
def fun(main_var):
|
||||
if main_var not in variables:
|
||||
error.fail(line,"Variable %s unknown"%(main_var,))
|
||||
x = variables[main_var]
|
||||
return [main_var]+x.others
|
||||
all_others = make_single(flatten( map(fun,main_vars) ))
|
||||
all_others.sort()
|
||||
vars.sort()
|
||||
for x,y in zip(vars,all_others):
|
||||
if x != y:
|
||||
message = "The following entities should be touched:\n"
|
||||
message = "\n".join([message]+map(lambda x: "- %s"%(x,),all_others))
|
||||
error.fail(line,message)
|
||||
|
||||
################################################################################
|
||||
def update_variables():
|
||||
for filename,text in preprocessed_text:
|
||||
|
||||
for line in filter(lambda x: type(x) in [ Touch, SoftTouch ], text):
|
||||
vars = line.lower.split()
|
||||
if len(vars) < 2:
|
||||
error.fail(line,"Syntax error")
|
||||
for v in vars[1:]:
|
||||
if v not in variables:
|
||||
error.fail(line,"Variable %s unknown"%(v,))
|
||||
variables[v]._is_touched = True
|
||||
|
||||
for line in filter(lambda x: type(x) == Free,text):
|
||||
vars = line.lower.split()
|
||||
if len(vars) < 2:
|
||||
error.fail(line,"Syntax error")
|
||||
for v in vars[1:]:
|
||||
if v not in variables:
|
||||
error.fail(line,"Variable %s unknown"%(v,))
|
||||
variables[v].is_freed = True
|
||||
|
||||
for line in filter(lambda x: type(x) == Irp_read,text):
|
||||
variables[line.filename]._is_read = True
|
||||
|
||||
for line in filter(lambda x: type (x) == Irp_write,text):
|
||||
variables[line.filename]._is_written = True
|
||||
|
||||
################################################################################
|
||||
|
||||
def get_parsed_text():
|
||||
def func(filename, text):
|
||||
def get_parsed_text(filename, text, variables, subroutines, vtuple):
|
||||
varlist = []
|
||||
result = []
|
||||
append = result.append
|
||||
for line in text: #filter(
|
||||
# lambda x: type(x) not in [ Doc, Begin_doc, End_doc ],
|
||||
# text):
|
||||
if type(line) in [ \
|
||||
Empty_line,
|
||||
Continue,
|
||||
Return,
|
||||
Begin_shell,
|
||||
End_shell,
|
||||
Openmp,
|
||||
Directive,
|
||||
Use,
|
||||
Enddo,
|
||||
End_select,
|
||||
Endif,
|
||||
Implicit,
|
||||
Program,
|
||||
Subroutine,
|
||||
Function,
|
||||
End,
|
||||
]:
|
||||
append( ([],line) )
|
||||
elif type(line) in [ Begin_provider, Cont_provider ]:
|
||||
if type(line) == Begin_provider:
|
||||
varlist = []
|
||||
buffer = map(strip,line.lower.replace(']','').split(','))
|
||||
assert len(buffer) > 1
|
||||
v = buffer[1]
|
||||
varlist.append(v)
|
||||
variable_list = find_variables_in_line(line)
|
||||
try:
|
||||
variable_list.remove(variables[v].same_as)
|
||||
except ValueError:
|
||||
print v, variables[v].same_as
|
||||
raise
|
||||
append( (variable_list,line) )
|
||||
elif type(line) == End_provider:
|
||||
varlist = []
|
||||
append( ([],line) )
|
||||
elif type(line) == Provide:
|
||||
l = line.lower.split()[1:]
|
||||
l = filter(lambda x: x not in varlist, l)
|
||||
for v in l:
|
||||
if v not in variables:
|
||||
error.fail(line,"Variable %s is unknown"%(v))
|
||||
append( (l,Provide(line.i,"",line.filename)) )
|
||||
append( (l,Simple_line(line.i,"!%s"%(line.text),line.filename)) )
|
||||
elif type(line) == NoDep:
|
||||
l = line.lower.split()[1:]
|
||||
for v in l:
|
||||
if v not in variables:
|
||||
error.fail(line,"Variable %s is unknown"%(v))
|
||||
l = map(lambda x: "-%s"%(x), l)
|
||||
append( (l,Simple_line(line.i,"!%s"%(line.text),line.filename)) )
|
||||
elif type(line) in [ Touch, SoftTouch ]:
|
||||
vars = line.lower.split()
|
||||
if len(vars) < 2:
|
||||
error.fail(line,"Syntax error")
|
||||
vars = vars[1:]
|
||||
def fun(x):
|
||||
main = variables[x].same_as
|
||||
return main
|
||||
main_vars = make_single( map(fun, vars) )
|
||||
check_touch(line,vars,main_vars)
|
||||
txt = " ".join(vars)
|
||||
append ( (vars,Simple_line(line.i,"!",line.filename)) )
|
||||
append ( ([],Simple_line(line.i,"! >>> TOUCH %s"%(txt,),line.filename)) )
|
||||
def fun(x):
|
||||
if x not in variables:
|
||||
error.fail(line,"Variable %s unknown"%(x,))
|
||||
return [ ([],Simple_line(line.i," call touch_%s"%(x,),line.filename)),
|
||||
([],Use(line.i," use %s"%(variables[x].fmodule), line.filename)) ]
|
||||
result += flatten(map( fun, main_vars ))
|
||||
def fun(x):
|
||||
if x not in variables:
|
||||
error.fail(line,"Variable %s unknown"%(x,))
|
||||
return ([],Simple_line(line.i," %s_is_built = .True."%(x,),line.filename))
|
||||
result += map( fun, main_vars[:-1] )
|
||||
if type(line) == SoftTouch:
|
||||
append ( ([],Simple_line(line.i,"! <<< END TOUCH (Soft)",line.filename)) )
|
||||
|
||||
for i, line in enumerate(text):
|
||||
|
||||
tmp_result = []
|
||||
if isinstance(line,
|
||||
(Empty_line, Continue, Return, Begin_shell, End_shell, Openmp, Directive, Use,
|
||||
Enddo, End_select, Endif, End, Implicit, Program, Subroutine, Function)):
|
||||
|
||||
append(Parsed_text([], line))
|
||||
|
||||
elif isinstance(line, (Begin_provider, Cont_provider)):
|
||||
|
||||
if isinstance(line, (Begin_provider)):
|
||||
varlist = []
|
||||
|
||||
v = line.lower.replace(']', '').split(',')[1].strip()
|
||||
varlist.append(v)
|
||||
|
||||
variable_list = find_variables_in_line(line, vtuple)
|
||||
variable_list.remove(variables[v].same_as)
|
||||
|
||||
append(Parsed_text(variable_list, line))
|
||||
|
||||
elif type(line) == End_provider:
|
||||
varlist = []
|
||||
append(Parsed_text([], line))
|
||||
|
||||
elif type(line) == Provide:
|
||||
l = line.lower.split()[1:]
|
||||
l = filter(lambda x: x not in varlist, l)
|
||||
for v in l:
|
||||
if v not in variables:
|
||||
error.fail(line, "Variable %s is unknown" % (v))
|
||||
|
||||
append(Parsed_text(l, Provide(line.i, "", line.filename)))
|
||||
append(Parsed_text(l, Simple_line(line.i, "!%s" % (line.text), line.filename)))
|
||||
|
||||
elif type(line) == NoDep:
|
||||
l = line.lower.split()[1:]
|
||||
for v in l:
|
||||
if v not in variables:
|
||||
error.fail(line, "Variable %s is unknown" % (v))
|
||||
l = map(lambda x: "-%s" % (x), l)
|
||||
append(Parsed_text(l, Simple_line(line.i, "!%s" % (line.text), line.filename)))
|
||||
elif type(line) in [Touch, SoftTouch]:
|
||||
|
||||
vars = line.lower.split()
|
||||
if len(vars) < 2:
|
||||
error.fail(line, "Syntax error")
|
||||
vars = vars[1:]
|
||||
|
||||
main_vars = uniquify([variables[x].same_as for x in vars])
|
||||
|
||||
check_touch(variables, line, vars, main_vars)
|
||||
|
||||
txt = " ".join(vars)
|
||||
append(Parsed_text(vars, Simple_line(line.i, "!", line.filename)))
|
||||
append(Parsed_text([], Simple_line(line.i, "! >>> TOUCH %s" % (txt, ), line.filename)))
|
||||
|
||||
def fun(x):
|
||||
if x not in variables:
|
||||
error.fail(line, "Variable %s unknown" % (x, ))
|
||||
return [
|
||||
Parsed_text([], Simple_line(line.i, " call touch_%s" % (x, ), line.filename)),
|
||||
Parsed_text([], Use(line.i, " use %s" % (variables[x].fmodule), line.filename))
|
||||
]
|
||||
|
||||
result += flatten(map(fun, main_vars))
|
||||
|
||||
def fun(x):
|
||||
if x not in variables:
|
||||
error.fail(line, "Variable %s unknown" % (x, ))
|
||||
return Parsed_text(
|
||||
[], Simple_line(line.i, " %s_is_built = .True." % (x, ), line.filename))
|
||||
|
||||
result += map(fun, main_vars[:-1])
|
||||
if type(line) == SoftTouch:
|
||||
append(
|
||||
Parsed_text([], Simple_line(line.i, "! <<< END TOUCH (Soft)", line.filename)))
|
||||
else:
|
||||
append(Parsed_text([], Provide_all(line.i, "! <<< END TOUCH", line.filename)))
|
||||
|
||||
elif type(line) == Call:
|
||||
l = find_variables_in_line(line, vtuple)
|
||||
l = filter(lambda x: x not in varlist, l)
|
||||
sub = find_subroutine_in_line(line)
|
||||
|
||||
if sub not in subroutines:
|
||||
t = Simple_line
|
||||
append(Parsed_text(l, Simple_line(line.i, line.text, line.filename)))
|
||||
else:
|
||||
append((l, line))
|
||||
if subroutines[sub].touches != []:
|
||||
append(Parsed_text([], Provide_all(line.i, "", line.filename)))
|
||||
|
||||
elif type(line) == Free:
|
||||
vars = line.lower.split()
|
||||
vars = vars[1:]
|
||||
append(Parsed_text([], Simple_line(line.i, "!%s" % (line.text), line.filename)))
|
||||
use = map(lambda x: " use %s" % (variables[x].fmodule), vars)
|
||||
for var in vars:
|
||||
result += map(lambda x: Parsed_text([], Use(line.i, x, line.filename)),
|
||||
uniquify(use))
|
||||
result += map(lambda x: Parsed_text([], Simple_line(line.i, x, line.filename)),
|
||||
variables[var].free)
|
||||
|
||||
elif type(line) == Irp_read:
|
||||
append(Parsed_text([], Simple_line(line.i, "!%s" % (line.text), line.filename)))
|
||||
|
||||
elif type(line) == Irp_write:
|
||||
append(Parsed_text([], Simple_line(line.i, "!%s" % (line.text), line.filename)))
|
||||
|
||||
elif type(line) in [Begin_doc, End_doc, Doc]:
|
||||
pass
|
||||
else:
|
||||
append ( ([],Provide_all(line.i,"! <<< END TOUCH",line.filename)) )
|
||||
elif type(line) == Call:
|
||||
l = find_variables_in_line(line)
|
||||
l = filter(lambda x: x not in varlist, l)
|
||||
sub = find_subroutine_in_line(line)
|
||||
if sub not in subroutines:
|
||||
t = Simple_line
|
||||
append( (l,Simple_line(line.i,line.text,line.filename)) )
|
||||
else:
|
||||
append( (l,line) )
|
||||
if subroutines[sub].touches != []:
|
||||
append( ([],Provide_all(line.i,"",line.filename)) )
|
||||
elif type(line) == Free:
|
||||
vars = line.lower.split()
|
||||
vars = vars[1:]
|
||||
append( ([],Simple_line(line.i,"!%s"%(line.text),line.filename)) )
|
||||
use = map(lambda x: " use %s"%(variables[x].fmodule),vars)
|
||||
for var in vars:
|
||||
result += map(lambda x: ([],Use(line.i,x,line.filename)),
|
||||
make_single(use))
|
||||
result += map(lambda x: ([],Simple_line(line.i,x,line.filename)),
|
||||
variables[var].free)
|
||||
elif type(line) == Irp_read:
|
||||
append( ([],Simple_line(line.i,"!%s"%(line.text),line.filename)) )
|
||||
elif type(line) == Irp_write:
|
||||
append( ([],Simple_line(line.i,"!%s"%(line.text),line.filename)) )
|
||||
elif type(line) in [ Begin_doc, End_doc, Doc ]:
|
||||
pass
|
||||
else:
|
||||
l = find_variables_in_line(line)
|
||||
l = filter(lambda x: x not in varlist, l)
|
||||
append( (l,line) )
|
||||
return result
|
||||
|
||||
#main_result = []
|
||||
#for filename,text in preprocessed_text:
|
||||
# main_result.append( (filename, func(filename,text)) )
|
||||
#return main_result
|
||||
return parallel_loop(func,preprocessed_text)
|
||||
|
||||
update_variables()
|
||||
parsed_text = get_parsed_text()
|
||||
l = find_variables_in_line(line, vtuple)
|
||||
l = filter(lambda x: x not in varlist, l)
|
||||
append(Parsed_text(l, line))
|
||||
|
||||
return (filename, result)
|
||||
|
||||
######################################################################
|
||||
def move_to_top_list(text, it):
|
||||
# ( List[ List[Entity], Line], Iterator)
|
||||
'''Move the all the element of List[ List[Entity], Line] of Line's Type containt in IT are the top of text.
|
||||
|
||||
def move_to_top(text,t):
|
||||
assert type(text) == list
|
||||
assert t in [ NoDep, Declaration, Implicit, Use, Cont_provider ]
|
||||
Note:
|
||||
- The permutation neeed to be done following `it` order
|
||||
- We can have `nested` subroutine / Function. (Because of interface)
|
||||
- This function is called way to much. Is need to be efficient
|
||||
- This function is Unpure
|
||||
- One pass over `text`
|
||||
|
||||
inside = False
|
||||
for i in range(len(text)):
|
||||
vars, line = text[i]
|
||||
if type(line) in [ Begin_provider, Program, Subroutine, Function ]:
|
||||
begin = i
|
||||
inside = True
|
||||
elif type(line) in [ End_provider, End ]:
|
||||
inside = False
|
||||
elif type(line) == t:
|
||||
if inside:
|
||||
text.pop(i)
|
||||
begin += 1
|
||||
text.insert(begin,(vars,line))
|
||||
|
||||
return text
|
||||
NB:
|
||||
- I am not really proud of the Sentinel value for the deleted,
|
||||
but I waste already so much time on more cleaver but not working solution...
|
||||
'''
|
||||
|
||||
result = []
|
||||
for filename,text in parsed_text:
|
||||
text = move_to_top(text,NoDep)
|
||||
text = move_to_top(text,Declaration)
|
||||
text = move_to_top(text,Implicit)
|
||||
text = move_to_top(text,Use)
|
||||
text = move_to_top(text,Cont_provider)
|
||||
result.append ( (filename,text) )
|
||||
parsed_text = result
|
||||
assert set(it).issubset([NoDep, Declaration, Implicit, Use, Cont_provider])
|
||||
|
||||
# ~ # ~ # ~
|
||||
# G e t P e r m u t a t i o n
|
||||
# ~ # ~ # ~
|
||||
|
||||
from collections import defaultdict
|
||||
d_permutation = defaultdict(list)
|
||||
# Type:List(begin, Line)
|
||||
# We will insert the Line at begin position later on
|
||||
|
||||
l_begin = []
|
||||
|
||||
for i, (l_var, line) in enumerate(text):
|
||||
t = type(line)
|
||||
|
||||
if t in [Begin_provider, Module,Program, Subroutine, Function]:
|
||||
l_begin.append(i)
|
||||
elif t in [End_provider, End]:
|
||||
l_begin.pop()
|
||||
|
||||
elif l_begin and t in it:
|
||||
d_permutation[t].append( (l_begin[-1], [l_var, line]) )
|
||||
# Put the sentinel, will be deleted after the insertion
|
||||
text[i] = None
|
||||
|
||||
# ~ # ~ # ~
|
||||
# O r d e r t h e m
|
||||
# ~ # ~ # ~
|
||||
# We need to do the permutation in the correct order
|
||||
d_insert = defaultdict(list)
|
||||
for t in reversed(it):
|
||||
for begin, tline in d_permutation[t]:
|
||||
d_insert[begin].append(tline)
|
||||
|
||||
# ~ # ~ # ~
|
||||
# D o t h e m
|
||||
# ~ # ~ # ~
|
||||
# Because idx are sorted, it's easy to do the insert part of the move
|
||||
# Just pad each insert by the number of precedent insert
|
||||
padding = 0
|
||||
for idx in sorted(d_insert.keys()):
|
||||
for tline in d_insert[idx]:
|
||||
text.insert(idx + padding + 1, tline)
|
||||
padding += 1
|
||||
|
||||
# Now do the Delete part of the move. Fortunatly we put a sentinel to know the line to delete
|
||||
for i in reversed(xrange(len(text))):
|
||||
if text[i] is None:
|
||||
del text[i]
|
||||
|
||||
|
||||
def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Function,Module)):
|
||||
# ( List[ List[Entity], Line], Iterator)
|
||||
'''Move everything containt into 'interface' below the first instance of s_type who preced it
|
||||
|
||||
Note:
|
||||
= This function is unpur
|
||||
'''
|
||||
|
||||
# Get the born of the interface
|
||||
i_begin = [ i for i, (_, line) in enumerate(parsed_text) if isinstance(line,Interface) ]
|
||||
i_end = [ i+1 for i, (_, line) in enumerate(parsed_text) if isinstance(line,End_interface) ]
|
||||
|
||||
# Get the begin of the insert
|
||||
i_insert = []
|
||||
for begin in i_begin:
|
||||
i_insert.append(next(i+1 for i in range(begin,-1,-1) if isinstance(parsed_text[i][1], s_type)))
|
||||
|
||||
# Do the insert and the delete in one passe
|
||||
for insert, begin, end in zip(i_insert,i_begin,i_end):
|
||||
parsed_text[insert:insert] = parsed_text[begin:end]
|
||||
|
||||
padding = end-begin
|
||||
parsed_text[begin+padding:end+padding] = []
|
||||
|
||||
######################################################################
|
||||
def build_sub_needs():
|
||||
# Needs
|
||||
for filename, text in parsed_text:
|
||||
sub = None
|
||||
in_program = False
|
||||
for vars,line in text:
|
||||
if type(line) in [ Subroutine, Function ]:
|
||||
subname = find_subname(line)
|
||||
sub = subroutines[subname]
|
||||
sub._needs = []
|
||||
sub._to_provide = []
|
||||
elif type(line) == End:
|
||||
if not in_program:
|
||||
sub._needs = make_single(sub._needs)
|
||||
sub._to_provide = make_single(sub._to_provide)
|
||||
sub = None
|
||||
elif type(line) == Program:
|
||||
in_program = True
|
||||
if sub is not None:
|
||||
if type(line) == Declaration:
|
||||
sub._to_provide += vars
|
||||
sub._needs += vars
|
||||
def build_sub_needs(parsed_text, d_subroutine):
|
||||
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]], Dict[str:Sub]) -> None
|
||||
'''Set the needs, and provides arguements of Routine present in parsed_text
|
||||
|
||||
Note:
|
||||
This function is unpure
|
||||
'''
|
||||
|
||||
build_sub_needs()
|
||||
l_buffer = []
|
||||
for _, text in parsed_text:
|
||||
l_begin = [ i for i, (_, line) in enumerate(text) if isinstance(line, (Subroutine, Function, Program))]
|
||||
l_end = [i for i, (_, line) in enumerate(text) if isinstance(line, End)]
|
||||
|
||||
l_buffer += [(d_subroutine[text[b].line.subname], text[b + 1:e]) for b, e in zip(l_begin, l_end) if not isinstance(text[b].line, Program)]
|
||||
|
||||
for sub, text in l_buffer:
|
||||
sub.needs = set(v for vs, _ in text for v in vs)
|
||||
sub.to_provide = set(v for vs, line in text for v in vs if isinstance(line, Declaration))
|
||||
|
||||
#####################################################################
|
||||
|
||||
def add_subroutine_needs():
|
||||
main_result = []
|
||||
for filename, text in parsed_text:
|
||||
result = []
|
||||
append = result.append
|
||||
for vars,line in text:
|
||||
if type(line) == Call:
|
||||
subname = find_subname(line)
|
||||
vars += subroutines[subname].to_provide
|
||||
append( (vars,line) )
|
||||
main_result.append( (filename, result) )
|
||||
return main_result
|
||||
|
||||
parsed_text = add_subroutine_needs()
|
||||
def add_subroutine_needs(parsed_text, subroutines):
|
||||
main_result = []
|
||||
for filename, text in parsed_text:
|
||||
result = []
|
||||
append = result.append
|
||||
for vars, line in text:
|
||||
if type(line) == Call:
|
||||
vars += subroutines[line.subname].to_provide
|
||||
append((vars, line))
|
||||
main_result.append((filename, result))
|
||||
return main_result
|
||||
|
||||
|
||||
######################################################################
|
||||
def move_variables():
|
||||
def move_variables(parsed_text):
|
||||
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]]
|
||||
'''Move variables into the top of the declaraiton'''
|
||||
|
||||
def func(filename, text):
|
||||
result = []
|
||||
append = result.append
|
||||
# 1st pass
|
||||
varlist = []
|
||||
ifvars = []
|
||||
elsevars = []
|
||||
old_varlist = []
|
||||
old_ifvars = []
|
||||
old_elsevars = []
|
||||
revtext = list(text)
|
||||
revtext.reverse()
|
||||
try:
|
||||
for vars,line in revtext:
|
||||
if type(line) in [ End_provider,End ]:
|
||||
varlist = []
|
||||
append( ([],line) )
|
||||
elif type(line) in [ Endif, End_select ]:
|
||||
old_ifvars.append( list(ifvars) )
|
||||
old_elsevars.append( list(elsevars) )
|
||||
old_varlist.append( list(varlist) )
|
||||
varlist = []
|
||||
append( ([],line) )
|
||||
elif type(line) == Else:
|
||||
elsevars += list(varlist)
|
||||
append( (varlist,line) )
|
||||
varlist = []
|
||||
elif type(line) in [ Elseif, Case ]:
|
||||
ifvars += list(varlist)
|
||||
append( (varlist,line) )
|
||||
if vars != []:
|
||||
varlist = old_varlist.pop()
|
||||
varlist += vars
|
||||
old_varlist.append( list(varlist) )
|
||||
varlist = []
|
||||
elif type(line) in [ If, Select ]:
|
||||
ifvars += list(varlist)
|
||||
append( (varlist,line) )
|
||||
vars += filter(lambda x: x in elsevars, ifvars)
|
||||
ifvars = old_ifvars.pop()
|
||||
elsevars = old_elsevars.pop()
|
||||
varlist = old_varlist.pop() + vars
|
||||
elif type(line) in [ Begin_provider, Program, Subroutine, Function ]:
|
||||
varlist += vars
|
||||
append( (varlist,line) )
|
||||
if old_varlist != [] \
|
||||
or old_ifvars != [] \
|
||||
or old_elsevars != []:
|
||||
error.fail(line,"End if missing")
|
||||
varlist = []
|
||||
elif type(line) in (Provide,Provide_all):
|
||||
append( (vars,line) )
|
||||
else:
|
||||
varlist += vars
|
||||
append( ([],line) )
|
||||
except:
|
||||
error.fail(line,"Unable to parse file")
|
||||
|
||||
def func(filename, text):
|
||||
result = []
|
||||
append = result.append
|
||||
# 1st pass
|
||||
varlist = []
|
||||
ifvars = []
|
||||
elsevars = []
|
||||
old_varlist = []
|
||||
old_ifvars = []
|
||||
old_elsevars = []
|
||||
revtext = list(text)
|
||||
revtext.reverse()
|
||||
|
||||
skip_interface = False
|
||||
try:
|
||||
for vars, line in revtext:
|
||||
if type(line) in [Interface, End_interface]:
|
||||
skip_interface = not skip_interface
|
||||
|
||||
if skip_interface:
|
||||
append(([], line))
|
||||
continue
|
||||
|
||||
result.reverse()
|
||||
if type(line) in [End_provider, End]:
|
||||
varlist = []
|
||||
append(([], line))
|
||||
elif type(line) in [Endif, End_select]:
|
||||
old_ifvars.append(list(ifvars))
|
||||
old_elsevars.append(list(elsevars))
|
||||
old_varlist.append(list(varlist))
|
||||
varlist = []
|
||||
append(([], line))
|
||||
elif type(line) == Else:
|
||||
elsevars += list(varlist)
|
||||
append((varlist, line))
|
||||
varlist = []
|
||||
elif type(line) in [Elseif, Case]:
|
||||
ifvars += list(varlist)
|
||||
append((varlist, line))
|
||||
if vars != []:
|
||||
varlist = old_varlist.pop()
|
||||
varlist += vars
|
||||
old_varlist.append(list(varlist))
|
||||
varlist = []
|
||||
elif type(line) in [If, Select]:
|
||||
ifvars += list(varlist)
|
||||
append((varlist, line))
|
||||
vars += filter(lambda x: x in elsevars, ifvars)
|
||||
ifvars = old_ifvars.pop()
|
||||
elsevars = old_elsevars.pop()
|
||||
varlist = old_varlist.pop() + vars
|
||||
elif type(line) in [Begin_provider, Program, Subroutine, Function]:
|
||||
varlist += vars
|
||||
append((varlist, line))
|
||||
if old_varlist != [] \
|
||||
or old_ifvars != [] \
|
||||
or old_elsevars != []:
|
||||
error.fail(line, "End if missing")
|
||||
varlist = []
|
||||
elif type(line) in (Provide, Provide_all):
|
||||
append((vars, line))
|
||||
else:
|
||||
varlist += vars
|
||||
append(([], line))
|
||||
except:
|
||||
from util import logger
|
||||
logger.error("Unable to parse file %s", line)
|
||||
import sys
|
||||
sys.exit(1)
|
||||
|
||||
# 2nd pass
|
||||
text = result
|
||||
result = []
|
||||
append = result.append
|
||||
old_varlist = []
|
||||
varlist = []
|
||||
try:
|
||||
for vars,line in text:
|
||||
if vars != []:
|
||||
vars = make_single(vars)
|
||||
if type(line) in [ Begin_provider, Program, Subroutine, Function ]:
|
||||
varlist = list(vars)
|
||||
elif type(line) in [ If, Select ]:
|
||||
old_varlist.append(varlist)
|
||||
vars = filter(lambda x: x not in varlist,vars)
|
||||
varlist = make_single(varlist + vars)
|
||||
assert old_varlist is not varlist
|
||||
elif type(line) in [ Elseif, Else, Case ]:
|
||||
varlist = old_varlist.pop()
|
||||
old_varlist.append(varlist)
|
||||
vars = filter(lambda x: x not in varlist,vars)
|
||||
varlist = make_single(varlist + vars)
|
||||
assert old_varlist is not varlist
|
||||
elif type(line) in [ Endif, End_select ]:
|
||||
varlist = old_varlist.pop()
|
||||
elif type(line) == Provide_all:
|
||||
vars += varlist
|
||||
elif type(line) in [ End_provider, End ]:
|
||||
assert old_varlist == []
|
||||
varlist = []
|
||||
for v in vars[:]:
|
||||
if v[0] == '-':
|
||||
vars.remove(v)
|
||||
vars.remove(v[1:])
|
||||
result.append( (vars,line) )
|
||||
except:
|
||||
error.fail(line,"Unable to parse file")
|
||||
return result
|
||||
result.reverse()
|
||||
|
||||
main_result = []
|
||||
for filename,text in parsed_text:
|
||||
main_result.append( (filename, func(filename,text)) )
|
||||
return main_result
|
||||
#return parallel_loop(func,parsed_text)
|
||||
# 2nd pass
|
||||
text = result
|
||||
result = []
|
||||
append = result.append
|
||||
old_varlist = []
|
||||
varlist = []
|
||||
try:
|
||||
for vars, line in text:
|
||||
if vars:
|
||||
vars = uniquify(vars)
|
||||
if type(line) in [Begin_provider, Program, Subroutine, Function]:
|
||||
varlist = list(vars)
|
||||
elif type(line) in [If, Select]:
|
||||
old_varlist.append(varlist)
|
||||
vars = filter(lambda x: x not in varlist, vars)
|
||||
varlist = uniquify(varlist + vars)
|
||||
assert old_varlist is not varlist
|
||||
elif type(line) in [Elseif, Else, Case]:
|
||||
varlist = old_varlist.pop()
|
||||
old_varlist.append(varlist)
|
||||
vars = filter(lambda x: x not in varlist, vars)
|
||||
varlist = uniquify(varlist + vars)
|
||||
assert old_varlist is not varlist
|
||||
elif type(line) in [Endif, End_select]:
|
||||
varlist = old_varlist.pop()
|
||||
elif type(line) == Provide_all:
|
||||
vars += varlist
|
||||
elif type(line) in [End_provider, End]:
|
||||
assert old_varlist == []
|
||||
varlist = []
|
||||
for v in vars[:]:
|
||||
if v[0] == '-':
|
||||
vars.remove(v)
|
||||
vars.remove(v[1:])
|
||||
result.append((vars, line))
|
||||
except:
|
||||
error.fail(line, "Unable to parse file")
|
||||
return result
|
||||
|
||||
main_result = []
|
||||
for filename, text in parsed_text:
|
||||
main_result.append((filename, func(filename, text)))
|
||||
return main_result
|
||||
|
||||
parsed_text = move_variables()
|
||||
|
||||
######################################################################
|
||||
def build_needs():
|
||||
# Needs
|
||||
for filename, text in parsed_text:
|
||||
var = None
|
||||
for vars,line in text:
|
||||
if type(line) == Begin_provider:
|
||||
buffer = map(strip,line.lower.replace(']',',').split(','))
|
||||
var = variables[buffer[1]]
|
||||
var.needs = []
|
||||
var.to_provide = vars
|
||||
elif type(line) == End_provider:
|
||||
var.needs = make_single(var.needs)
|
||||
var.to_provide = make_single(var.to_provide)
|
||||
var = None
|
||||
if var is not None:
|
||||
var.needs += vars
|
||||
if type(line) == Call:
|
||||
subname = find_subname(line)
|
||||
var.needs += subroutines[subname].needs
|
||||
elif type(line) in [ \
|
||||
Simple_line, Assert,
|
||||
Do , If,
|
||||
Elseif , Select,
|
||||
]:
|
||||
funcs = find_funcs_in_line(line)
|
||||
for f in funcs:
|
||||
var.needs += subroutines[f].needs
|
||||
for v in variables:
|
||||
main = variables[v].same_as
|
||||
if main != v:
|
||||
variables[v].needs = variables[main].needs
|
||||
variables[v].to_provide = variables[main].to_provide
|
||||
def build_needs(parsed_text, subroutines, stuple, variables):
|
||||
'out: variable'
|
||||
|
||||
# Needed_by
|
||||
for v in variables:
|
||||
variables[v].needed_by = []
|
||||
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:
|
||||
variables[x].needed_by.append(var.same_as)
|
||||
for v in variables:
|
||||
var = variables[v]
|
||||
var.needed_by = make_single(var.needed_by)
|
||||
# ~#~#~#~#~#
|
||||
# Needs and to_provide
|
||||
# ~#~#~#~#~#
|
||||
|
||||
for filename, text in parsed_text:
|
||||
|
||||
build_needs()
|
||||
l_begin = [i for i, (_, line) in enumerate(text) if isinstance(line, Begin_provider)]
|
||||
l_end = [i for i, (_, line) in enumerate(text) if isinstance(line, End_provider)]
|
||||
|
||||
result = []
|
||||
for filename,text in parsed_text:
|
||||
text = move_to_top(text,NoDep)
|
||||
text = move_to_top(text,Declaration)
|
||||
text = move_to_top(text,Implicit)
|
||||
text = move_to_top(text,Use)
|
||||
text = move_to_top(text,Cont_provider)
|
||||
result.append ( (filename,text) )
|
||||
parsed_text = result
|
||||
for start, end in zip(l_begin, l_end):
|
||||
l_vars_start, line_start = text[start]
|
||||
|
||||
name = map(str.strip, line_start.lower.replace(']', ',').split(','))[1]
|
||||
entity = variables[name]
|
||||
|
||||
entity.to_provide = uniquify(l_vars_start)
|
||||
|
||||
l_needs = []
|
||||
for vars, line in text[start:end]:
|
||||
l_needs += vars
|
||||
|
||||
if type(line) == Call:
|
||||
l_needs += subroutines[line.subname].needs
|
||||
elif type(line) in [Simple_line, Assert, Do, If, Elseif, Select]:
|
||||
funcs = find_funcs_in_line(line, stuple)
|
||||
for f in funcs:
|
||||
l_needs += subroutines[f].needs
|
||||
|
||||
entity.needs = uniquify(l_needs)
|
||||
|
||||
for v in variables:
|
||||
main = variables[v].same_as
|
||||
if main != v:
|
||||
variables[v].needs = variables[main].needs
|
||||
variables[v].to_provide = variables[main].to_provide
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# Needs and to_provide
|
||||
# ~#~#~#~#~#
|
||||
|
||||
for v in variables:
|
||||
variables[v].needed_by = []
|
||||
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:
|
||||
variables[x].needed_by.append(var.same_as)
|
||||
|
||||
for v in variables:
|
||||
var = variables[v]
|
||||
var.needed_by = uniquify(var.needed_by)
|
||||
|
||||
######################################################################
|
||||
from command_line import command_line
|
||||
|
||||
def check_opt():
|
||||
if not command_line.do_checkopt:
|
||||
return
|
||||
|
||||
for filename, text in parsed_text:
|
||||
do_level = 0
|
||||
for vars,line in text:
|
||||
if not type(line) == Provide_all:
|
||||
if do_level > 0 and vars != []:
|
||||
print "Optimization: %s line %d"%(line.filename,line.i)
|
||||
for v in vars:
|
||||
print " PROVIDE ",v
|
||||
if type(line) == Do:
|
||||
do_level += 1
|
||||
elif type(line) == Enddo:
|
||||
do_level -= 1
|
||||
check_opt()
|
||||
def check_opt(parsed_text):
|
||||
if not command_line.do_checkopt:
|
||||
return
|
||||
|
||||
for filename, text in parsed_text:
|
||||
do_level = 0
|
||||
for vars, line in text:
|
||||
if not type(line) == Provide_all:
|
||||
if do_level > 0 and vars != []:
|
||||
print "Optimization: %s line %d" % (line.filename, line.i)
|
||||
for v in vars:
|
||||
print " PROVIDE ", v
|
||||
if type(line) == Do:
|
||||
do_level += 1
|
||||
elif type(line) == Enddo:
|
||||
do_level -= 1
|
||||
|
||||
|
||||
######################################################################
|
||||
def perform_loop_substitutions():
|
||||
main_result = []
|
||||
for filename, text in parsed_text:
|
||||
result = []
|
||||
append = result.append
|
||||
for vars,line in text:
|
||||
if type(line) in [ Do, If, Elseif ] :
|
||||
for k,v in command_line.substituted.items():
|
||||
reg = v[1]
|
||||
while reg.search(line.text) is not None:
|
||||
line.text = re.sub(reg,r'\1%s\3', line.text,count=1)%v[0]
|
||||
append( (vars,line) )
|
||||
main_result.append( (filename, result) )
|
||||
return main_result
|
||||
def perform_loop_substitutions(parsed_text):
|
||||
main_result = []
|
||||
for filename, text in parsed_text:
|
||||
result = []
|
||||
append = result.append
|
||||
for vars, line in text:
|
||||
if type(line) in [Do, If, Elseif]:
|
||||
for k, v in command_line.substituted.items():
|
||||
reg = v[1]
|
||||
while reg.search(line.text) is not None:
|
||||
line.text = re.sub(reg, r'\1%s\3', line.text, count=1) % v[0]
|
||||
append((vars, line))
|
||||
main_result.append((filename, result))
|
||||
return main_result
|
||||
|
||||
parsed_text = perform_loop_substitutions()
|
||||
|
||||
######################################################################
|
||||
if __name__ == '__main__':
|
||||
for i in range(len(parsed_text)):
|
||||
if parsed_text[i][0] == sys.argv[1]:
|
||||
print '!-------- %s -----------'%(parsed_text[i][0])
|
||||
for line in parsed_text[i][1]:
|
||||
print line[1]
|
||||
print line[0], line[1].filename
|
||||
#for i in subroutines:
|
||||
# print i, subroutines[i].needs, subroutines[i].to_provide
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -52,15 +52,8 @@ def build_rdtsc():
|
||||
file = open(filename,'w')
|
||||
file.write(rdtsc)
|
||||
file.close()
|
||||
# def t():
|
||||
# p = subprocess.Popen(["gcc","-O2",filename,"-c","-o","irp_rdtsc.o"])
|
||||
# p.communicate()
|
||||
# os.remove(filename)
|
||||
#
|
||||
# threading.Thread(target=t).start()
|
||||
|
||||
def build_module():
|
||||
from variables import variables
|
||||
def build_module(variables):
|
||||
data = """
|
||||
module irp_timer
|
||||
double precision :: irp_profile(3,%(n)d)
|
||||
@ -176,9 +169,7 @@ end
|
||||
file.write(data)
|
||||
file.close()
|
||||
|
||||
def run():
|
||||
build_module()
|
||||
def run(d_entity):
|
||||
build_module(d_entity)
|
||||
build_rdtsc()
|
||||
|
||||
if __name__ == "__main__":
|
||||
build_rdtsc()
|
||||
|
@ -47,7 +47,7 @@ re_decl = re.compile( "".join( [ r"^\ *",
|
||||
r"|external *(::)?",
|
||||
r"|equivalence *(::)?",
|
||||
r"|type",
|
||||
r"|end ?type",
|
||||
r"|endtype",
|
||||
r")[^=(]"
|
||||
] ) )
|
||||
|
||||
|
104
src/routine.py
Normal file
104
src/routine.py
Normal file
@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python
|
||||
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
|
||||
# the Implicit Reference to Parameters (IRP) method.
|
||||
# Copyright (C) 2009 Anthony SCEMAMA
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Anthony Scemama
|
||||
# LCPQ - IRSAMC - CNRS
|
||||
# Universite Paul Sabatier
|
||||
# 118, route de Narbonne
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from irpf90_t import *
|
||||
|
||||
from util import logger
|
||||
|
||||
try:
|
||||
import irpy
|
||||
except:
|
||||
import lib_irpy as irpy
|
||||
|
||||
class Routine(object):
|
||||
'''
|
||||
A collection of list corresponding of a Routine (Subroutine, or function)
|
||||
'''
|
||||
|
||||
|
||||
############################################################
|
||||
def __init__(self,text):
|
||||
assert type(text) == list
|
||||
assert len(text) > 0
|
||||
|
||||
self.text = text
|
||||
self.prototype = self.text[0]
|
||||
assert isinstance(self.prototype, (Subroutine, Function))
|
||||
|
||||
############################################################
|
||||
@irpy.lazy_property_mutable
|
||||
def called_by(self):
|
||||
raise AttributeError
|
||||
|
||||
############################################################
|
||||
@irpy.lazy_property
|
||||
def name(self):
|
||||
'''Name is lowercase'''
|
||||
return self.prototype.subname
|
||||
|
||||
############################################################
|
||||
@irpy.lazy_property
|
||||
def is_function(self):
|
||||
return "function" in self.prototype.lower
|
||||
|
||||
############################################################
|
||||
@irpy.lazy_property
|
||||
def is_subroutine(self):
|
||||
return "subroutine" in self.prototype.lower
|
||||
|
||||
############################################################
|
||||
@irpy.lazy_property
|
||||
def doc(self):
|
||||
|
||||
l_doc = [ l for l in self.text if isinstance(l,Doc) ]
|
||||
if not l_doc:
|
||||
logger.info("Subroutine '%s' is not documented"%(self.name))
|
||||
return [l.text.lstrip()[1:] for l in l_doc]
|
||||
|
||||
############################################################
|
||||
@irpy.lazy_property
|
||||
def touches_my_self(self):
|
||||
return set(x for line in self.text for x in line.text.split()[1:] if isinstance(line,(Touch, SoftTouch)))
|
||||
|
||||
@irpy.lazy_property_mutable
|
||||
def touches_ancestor(self):
|
||||
raise AttributeError
|
||||
|
||||
@irpy.lazy_property
|
||||
def touches(self):
|
||||
return list(self.touches_my_self.union(self.touches_ancestor))
|
||||
|
||||
############################################################
|
||||
@irpy.lazy_property
|
||||
def regexp(self):
|
||||
import re
|
||||
return re.compile(r"([^a-z0-9'\"_]|^)%s([^a-z0-9_]|$)"%(self.name),re.I)
|
||||
|
||||
############################################################
|
||||
@irpy.lazy_property
|
||||
def calls(self):
|
||||
return set(line.text.split('(',1)[0].split()[1].lower() for line in self.text if isinstance(line,Call))
|
@ -1,131 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
|
||||
# the Implicit Reference to Parameters (IRP) method.
|
||||
# Copyright (C) 2009 Anthony SCEMAMA
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Anthony Scemama
|
||||
# LCPQ - IRSAMC - CNRS
|
||||
# Universite Paul Sabatier
|
||||
# 118, route de Narbonne
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from irpf90_t import *
|
||||
from util import *
|
||||
import error
|
||||
|
||||
class Sub(object):
|
||||
|
||||
############################################################
|
||||
def __init__(self,text):
|
||||
assert type(text) == list
|
||||
assert len(text) > 0
|
||||
assert type(text[0]) in [Subroutine, Function]
|
||||
self.text = text
|
||||
self.called_by = []
|
||||
|
||||
############################################################
|
||||
def name(self):
|
||||
'''Name is lowercase'''
|
||||
if '_name' not in self.__dict__:
|
||||
self._name = find_subname(self.line)
|
||||
return self._name
|
||||
name = property(name)
|
||||
|
||||
############################################################
|
||||
def is_function(self):
|
||||
if '_is_function' not in self.__dict__:
|
||||
self._is_function = "function" in self.line.lower
|
||||
return self._is_function
|
||||
is_function = property(is_function)
|
||||
|
||||
############################################################
|
||||
def doc(self):
|
||||
if '_doc' not in self.__dict__:
|
||||
def f(l): return
|
||||
buffer = filter(lambda l:type(l) == Doc, self.text)
|
||||
self._doc = map(lambda l: l.text.lstrip()[1:], buffer)
|
||||
if buffer == []:
|
||||
error.warn(None,"Subroutine %s is not documented"%(self.name))
|
||||
return self._doc
|
||||
doc = property(doc)
|
||||
|
||||
############################################################
|
||||
def line(self):
|
||||
if '_line' not in self.__dict__:
|
||||
self._line = self.text[0]
|
||||
return self._line
|
||||
line = property(line)
|
||||
|
||||
############################################################
|
||||
def touches(self):
|
||||
if '_touches' not in self.__dict__:
|
||||
from subroutines import subroutines
|
||||
self._touches = []
|
||||
for line in filter(lambda x: type(x) in [Touch, SoftTouch],self.text):
|
||||
self._touches += line.text.split()[1:]
|
||||
for sub in self.calls:
|
||||
if sub in subroutines:
|
||||
self._touches += subroutines[sub].touches
|
||||
self._touches = make_single(self._touches)
|
||||
return self._touches
|
||||
touches = property(touches)
|
||||
|
||||
############################################################
|
||||
def needs(self):
|
||||
if '_needs' not in self.__dict__:
|
||||
import parsed_text
|
||||
self._needs = make_single(self._needs)
|
||||
return self._needs
|
||||
needs = property(needs)
|
||||
|
||||
############################################################
|
||||
def to_provide(self):
|
||||
if '_to_provide' not in self.__dict__:
|
||||
import parsed_text
|
||||
return self._to_provide
|
||||
to_provide = property(to_provide)
|
||||
|
||||
############################################################
|
||||
def regexp(self):
|
||||
if '_regexp' not in self.__dict__:
|
||||
import re
|
||||
self._regexp = re.compile( \
|
||||
r"([^a-z0-9'\"_]|^)%s([^a-z0-9_]|$)"%(self.name),re.I)
|
||||
return self._regexp
|
||||
regexp = property(regexp)
|
||||
|
||||
############################################################
|
||||
def calls(self):
|
||||
if '_calls' not in self.__dict__:
|
||||
buffer = filter(lambda x: type(x) == Call,self.text)
|
||||
self._calls = []
|
||||
for line in buffer:
|
||||
sub = line.text.split('(',1)[0].split()[1].lower()
|
||||
self._calls.append(sub)
|
||||
self._calls = make_single(self._calls)
|
||||
return self._calls
|
||||
calls = property(calls)
|
||||
|
||||
######################################################################
|
||||
if __name__ == '__main__':
|
||||
from preprocessed_text import preprocessed_text
|
||||
from variables import variables
|
||||
from subroutines import subroutines
|
||||
print map(lambda x: variables[x].needs, subroutines['full_ci'].needs)
|
||||
print subroutines['full_ci'].calls
|
@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
|
||||
# the Implicit Reference to Parameters (IRP) method.
|
||||
# Copyright (C) 2009 Anthony SCEMAMA
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Anthony Scemama
|
||||
# LCPQ - IRSAMC - CNRS
|
||||
# Universite Paul Sabatier
|
||||
# 118, route de Narbonne
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from util import *
|
||||
from subroutine import *
|
||||
from variables import variables
|
||||
from variable import Variable
|
||||
from irpf90_t import *
|
||||
|
||||
def create_subroutines():
|
||||
from preprocessed_text import preprocessed_text
|
||||
result = {}
|
||||
for filename, text in preprocessed_text:
|
||||
buffer = []
|
||||
inside = False
|
||||
for line in text:
|
||||
if type(line) in [ Subroutine, Function ]:
|
||||
inside = True
|
||||
if inside:
|
||||
buffer.append(line)
|
||||
if isinstance(line,End):
|
||||
if inside:
|
||||
v = Sub(buffer)
|
||||
result[v.name] = v
|
||||
buffer = []
|
||||
inside = False
|
||||
return result
|
||||
|
||||
def create_called_by(subs,vars):
|
||||
for s in subs.values() + vars.values():
|
||||
if type(s) == Variable and s.same_as != s.name:
|
||||
continue
|
||||
for x in s.calls:
|
||||
try:
|
||||
subs[x].called_by.append(s.name)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
for s in subs.values():
|
||||
s.called_by = make_single(s.called_by)
|
||||
s.called_by.sort()
|
||||
|
||||
subroutines = create_subroutines()
|
||||
create_called_by(subroutines,variables)
|
||||
|
||||
if __name__ == '__main__':
|
||||
for v in subroutines.keys():
|
||||
print v
|
@ -24,50 +24,42 @@
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
from irpf90_t import irp_id,irpdir
|
||||
import os
|
||||
from util import lazy_write_file
|
||||
|
||||
from irpf90_t import *
|
||||
from util import *
|
||||
from variables import variables
|
||||
from modules import modules
|
||||
def create(modules,variables):
|
||||
# (Dict[str,Module]. Dict[str, Variable]) -> None
|
||||
'''Create the fortran90 finalize subroutine and the touched one'''
|
||||
|
||||
FILENAME=irpdir+'irp_touches.irp.F90'
|
||||
|
||||
def create():
|
||||
out = []
|
||||
l = variables.keys()
|
||||
l.sort
|
||||
main_modules = filter(lambda x: modules[x].is_main, modules)
|
||||
|
||||
finalize = "subroutine irp_finalize_%s\n"%(irp_id)
|
||||
for m in filter(lambda x: not modules[x].is_main, modules):
|
||||
finalize += " use %s\n"%(modules[m].name)
|
||||
for v in l:
|
||||
var = variables[v]
|
||||
var_in_main = False
|
||||
for m in main_modules:
|
||||
if var.fmodule == modules[m].name:
|
||||
var_in_main = True
|
||||
break
|
||||
if not var_in_main:
|
||||
if var.is_touched:
|
||||
out += var.toucher
|
||||
if var.dim != []:
|
||||
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]
|
||||
|
||||
out = []
|
||||
for v,var in variables.iteritems():
|
||||
|
||||
if var.fmodule not in main_modules_name:
|
||||
#if var.is_self_touched:
|
||||
out += var.toucher
|
||||
if var.dim:
|
||||
finalize += " if (allocated(%s)) then\n"%v
|
||||
finalize += " %s_is_built = .False.\n"%var.same_as
|
||||
finalize += " deallocate(%s)\n"%v
|
||||
finalize += " endif\n"
|
||||
|
||||
finalize += "end\n"
|
||||
|
||||
|
||||
if out != []:
|
||||
if out:
|
||||
out = map(lambda x: "%s\n"%(x),out)
|
||||
|
||||
out += finalize
|
||||
|
||||
if not same_file(FILENAME,out):
|
||||
file = open(FILENAME,'w')
|
||||
file.writelines(out)
|
||||
file.close()
|
||||
|
||||
filename=os.path.join(irpdir,'irp_touches.irp.F90')
|
||||
lazy_write_file(filename,''.join(out))
|
||||
|
||||
if __name__ == '__main__':
|
||||
create()
|
||||
|
||||
|
413
src/util.py
413
src/util.py
@ -24,169 +24,282 @@
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# L o g e r
|
||||
# ~#~#~#~#~#
|
||||
'''
|
||||
Level Numeric value
|
||||
CRITICAL 50
|
||||
ERROR 40
|
||||
WARNING 30
|
||||
INFO 20
|
||||
DEBUG 10
|
||||
NOTSET 0
|
||||
'''
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger('Irpf90')
|
||||
logger.setLevel(30)
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# / / _ R E L A T E D
|
||||
# ~#~#~#~#~#
|
||||
|
||||
def chunkify(l,n_chunk):
|
||||
# (List[any], int) -> List [ List[any] ]
|
||||
'''Split the list on n_chunk'''
|
||||
len_ = len(l)
|
||||
n = max(1, len_ / n_chunk )
|
||||
return [ l[i:i + n] for i in xrange(0, len_, n) ]
|
||||
|
||||
|
||||
import multiprocessing
|
||||
def parmap(f, it, parallel=False):
|
||||
# (Callable, Iterable, bool) -> List
|
||||
'''Parallel version of the std map function
|
||||
|
||||
The parallel flag is set to togle the // execusion
|
||||
|
||||
Note:
|
||||
- We try to use the Mulprocesses map is possible else we use our own
|
||||
- The order of the sequence if concerved
|
||||
- Will use all the processesor possible
|
||||
- We return a List
|
||||
- The traceback is loose if an error occur but a Exception is raise.
|
||||
'''
|
||||
|
||||
if not parallel:
|
||||
return map(f, it)
|
||||
|
||||
nproc = multiprocessing.cpu_count()
|
||||
|
||||
# ~!~!~!
|
||||
# Parallelisation STD
|
||||
# ~!~!~
|
||||
|
||||
# This 'hang' on Travis and I don't know why...
|
||||
# https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled
|
||||
#from cPickle import PicklingError
|
||||
#try:
|
||||
# p = multiprocessing.Pool(nproc)
|
||||
# l_res = p.map(f, it,nproc)
|
||||
#except PicklingError:
|
||||
# pass
|
||||
#else:
|
||||
# return l_res
|
||||
|
||||
# ~!~!~!
|
||||
# Parallelisation By Us
|
||||
# ~!~!~
|
||||
|
||||
# To optimize the // performance,
|
||||
# we merge the task into chunk
|
||||
# In this implementation, we minimizise the communication
|
||||
# (aka 1 job by processor)
|
||||
|
||||
it_chunk = chunkify(l=it,n_chunk=nproc)
|
||||
def F(chunk):
|
||||
# (List[any]) -> (List[any])
|
||||
'''Same as 'f' but for a chunck'''
|
||||
return map(f,chunk)
|
||||
|
||||
|
||||
q_in = multiprocessing.JoinableQueue()
|
||||
q_out = multiprocessing.Queue()
|
||||
# All the worker will sepuku after reseaving this message
|
||||
# Remove that we need to always put in `q_in` a not None value.
|
||||
stop_condition = None
|
||||
|
||||
def worker():
|
||||
# () -> None
|
||||
'''Read a task from q_in, excute it, and store it in q_out
|
||||
|
||||
Note:
|
||||
- We use 'F' and not 'f'.
|
||||
- The for loop will break when stop_contition occur
|
||||
- We get, and put an idx to allow the possibility of ordering afterward
|
||||
- We store any exeception, to raise her afterward
|
||||
'''
|
||||
for i, x in iter(q_in.get, stop_condition):
|
||||
|
||||
try:
|
||||
result = F(x)
|
||||
except BaseException as e:
|
||||
t = e
|
||||
else:
|
||||
t = (i, result)
|
||||
|
||||
q_out.put(t)
|
||||
q_in.task_done()
|
||||
|
||||
q_in.task_done()
|
||||
|
||||
# Process' creation
|
||||
l_proc = [multiprocessing.Process(target=worker) for _ in range(nproc)]
|
||||
for p in l_proc:
|
||||
p.daemon = True
|
||||
p.start()
|
||||
|
||||
# Add the job to the queue (Note we add an idx, this will all)
|
||||
for i, x in enumerate(it_chunk):
|
||||
q_in.put((i, x))
|
||||
|
||||
# Now add the stop contidion and join
|
||||
# (Because q_in.get is blocking we don't need to join the queue before)
|
||||
for _ in l_proc:
|
||||
q_in.put(stop_condition)
|
||||
q_in.join()
|
||||
|
||||
# Get all the chunk and join the process
|
||||
l_res = [q_out.get() for _ in range(len(it_chunk))]
|
||||
|
||||
for p in l_proc:
|
||||
p.join()
|
||||
|
||||
# Check if error have occured
|
||||
try:
|
||||
from itertools import ifilter
|
||||
e = next(ifilter(lambda t: isinstance(t,BaseException), l_res))
|
||||
except StopIteration:
|
||||
# Now we need first to order the result, and secondly to flatte it
|
||||
return [item for _, chunk in sorted(l_res) for item in chunk]
|
||||
else:
|
||||
raise e
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# I O _ R E L A T E D
|
||||
# ~#~#~#~#~#
|
||||
import hashlib
|
||||
import os
|
||||
NTHREADS=1 #int(os.getenv('OMP_NUM_THREADS',1))
|
||||
def cached_file(filename, text):
|
||||
# (str,str) -> bool
|
||||
'''Check if file locatte at filename containt the same data as text
|
||||
|
||||
def strip(x):
|
||||
return x.strip()
|
||||
Return:
|
||||
True if data is the same, false otherwise
|
||||
'''
|
||||
|
||||
def lower(x):
|
||||
return x.lower()
|
||||
def digest(data):
|
||||
# (str) -> str
|
||||
'''compute an uniq data id'''
|
||||
return hashlib.md5(data).hexdigest()
|
||||
|
||||
def same_file(filename,txt):
|
||||
assert isinstance(filename,str)
|
||||
if (type(txt) == list):
|
||||
buffer = ''.join(txt)
|
||||
else:
|
||||
buffer = txt
|
||||
|
||||
try:
|
||||
file = open(filename,"r")
|
||||
except IOError:
|
||||
return False
|
||||
stream = file.read()
|
||||
file.close()
|
||||
|
||||
if len(stream) != len(buffer):
|
||||
return False
|
||||
if stream != buffer:
|
||||
return False
|
||||
return True
|
||||
|
||||
def build_dim(dim):
|
||||
if len(dim) == 0:
|
||||
return ""
|
||||
else:
|
||||
return "(%s)"%( ",".join(dim) )
|
||||
|
||||
def build_dim_colons(v):
|
||||
d = v.dim
|
||||
if d == []:
|
||||
return ""
|
||||
else:
|
||||
x = map(lambda x: ":", d)
|
||||
return "(%s)"%(','.join(x))
|
||||
|
||||
|
||||
import error
|
||||
def find_subname(line):
|
||||
buffer = line.lower
|
||||
if not buffer.endswith(')'):
|
||||
buffer += "()"
|
||||
buffer = buffer.split('(')
|
||||
buffer = buffer[0].split()
|
||||
if len(buffer) < 2:
|
||||
error.fail(line,"Syntax Error")
|
||||
return buffer[-1]
|
||||
|
||||
def make_single(l):
|
||||
d = {}
|
||||
for x in l:
|
||||
d[x] = True
|
||||
return d.keys()
|
||||
|
||||
def flatten(l):
|
||||
if type(l) == list:
|
||||
result = []
|
||||
for i in range(len(l)):
|
||||
elem = l[i]
|
||||
result += flatten(elem)
|
||||
return result
|
||||
else:
|
||||
return [l]
|
||||
|
||||
def dimsize(x):
|
||||
assert isinstance(x,str)
|
||||
buffer = x.split(':')
|
||||
if len(buffer) == 1:
|
||||
return x
|
||||
else:
|
||||
assert len(buffer) == 2
|
||||
size = ""
|
||||
b0, b1 = buffer
|
||||
if b0.replace('-','').isdigit() and b1.replace('-','').isdigit():
|
||||
size = str( int(b1) - int(b0) + 1 )
|
||||
try:
|
||||
text_ref = open(filename, 'rb').read()
|
||||
except IOError:
|
||||
return False
|
||||
else:
|
||||
if b0.replace('-','').isdigit():
|
||||
size = "(%s) - (%d)"%(b1,int(b0)-1)
|
||||
elif b1.replace('-','').isdigit():
|
||||
size = "(%d) - (%s)"%(int(b1)+1,b0)
|
||||
else:
|
||||
size = "(%s) - (%s) + 1"%(b1,b0)
|
||||
return size
|
||||
return digest(text_ref) == digest(text)
|
||||
|
||||
def put_info(text,filename):
|
||||
assert type(text) == list
|
||||
if len(text) > 0:
|
||||
assert type(text[0]) == tuple
|
||||
from irpf90_t import Line
|
||||
assert type(text[0][0]) == list
|
||||
assert isinstance(text[0][1], Line)
|
||||
lenmax = 80 - len(filename)
|
||||
format = "%"+str(lenmax)+"s ! %s:%4s"
|
||||
for vars,line in text:
|
||||
line.text = format%(line.text.ljust(lenmax),line.filename,str(line.i))
|
||||
return text
|
||||
|
||||
import cPickle as pickle
|
||||
import os, sys
|
||||
def parallel_loop(f,source):
|
||||
pidlist = range(NTHREADS)
|
||||
def lazy_write_file(filename, text, conservative=False,touch=False):
|
||||
# (str, str, bool) -> None
|
||||
'''Write data lazily in filename location.
|
||||
|
||||
src = [ [] for i in xrange(NTHREADS) ]
|
||||
index = 0
|
||||
try:
|
||||
source = map( lambda x: (len(x[1]),(x[0], x[1])), source )
|
||||
source.sort()
|
||||
source = map( lambda x: x[1], source )
|
||||
except:
|
||||
pass
|
||||
for i in source:
|
||||
index += 1
|
||||
if index == NTHREADS:
|
||||
index = 0
|
||||
src[index].append(i)
|
||||
Note:
|
||||
If convervative is set, we don't overwrite.
|
||||
'''
|
||||
|
||||
thread_id = 0
|
||||
fork = 1
|
||||
r = range(0,NTHREADS)
|
||||
for thread_id in xrange(1,NTHREADS):
|
||||
r[thread_id], w = os.pipe()
|
||||
fork = os.fork()
|
||||
if fork == 0:
|
||||
os.close(r[thread_id])
|
||||
w = os.fdopen(w,'w')
|
||||
break
|
||||
if not os.path.exists(filename) or not cached_file(filename, text) and not conservative:
|
||||
with open(filename, 'w') as f:
|
||||
f.write(text)
|
||||
elif touch:
|
||||
os.utime(filename,None)
|
||||
|
||||
def listdir(directory, abspath=False):
|
||||
#(str, bool) -> List[str]
|
||||
'''Replacement of the std:listdir but with the possibility to get the abosulte path'''
|
||||
|
||||
l_filename = os.listdir(directory)
|
||||
if not abspath:
|
||||
return l_filename
|
||||
else:
|
||||
os.close(w)
|
||||
r[thread_id] = os.fdopen(r[thread_id],'r')
|
||||
pidlist[thread_id] = fork
|
||||
thread_id = 0
|
||||
return [os.path.abspath(os.path.join(directory, f)) for f in l_filename]
|
||||
|
||||
result = []
|
||||
for filename, text in src[thread_id]:
|
||||
result.append( (filename, f(filename,text)) )
|
||||
result.sort()
|
||||
def check_output(*popenargs, **kwargs):
|
||||
"""Run command with arguments and return its output as a byte string.
|
||||
Backported from Python 2.7 as it's implemented as pure python on stdlib.
|
||||
>>> check_output(['/usr/bin/python', '--version'])
|
||||
Python 2.6.2
|
||||
"""
|
||||
import subprocess
|
||||
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
|
||||
output, unused_err = process.communicate()
|
||||
retcode = process.poll()
|
||||
if retcode:
|
||||
cmd = kwargs.get("args")
|
||||
if cmd is None:
|
||||
cmd = popenargs[0]
|
||||
error = subprocess.CalledProcessError(retcode, cmd)
|
||||
error.output = output
|
||||
raise error
|
||||
return output
|
||||
|
||||
if fork == 0:
|
||||
pickle.dump(result,w,-1)
|
||||
w.close()
|
||||
os._exit(0)
|
||||
|
||||
for i in xrange(1,NTHREADS):
|
||||
result += pickle.load(r[i])
|
||||
r[i].close()
|
||||
os.waitpid(pidlist[i],0)[1]
|
||||
|
||||
return result
|
||||
# ~#~#~#~#~#
|
||||
# L i s t
|
||||
# ~#~#~#~#~#
|
||||
|
||||
|
||||
def uniquify(l,sort=False):
|
||||
# (Iter, bool) -> List[Any]
|
||||
'''Uniquify a immutable iterable. Don't preserve the order'''
|
||||
r = list(set(l))
|
||||
if not sort:
|
||||
return r
|
||||
else:
|
||||
return sorted(r)
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "10",dimsize("10") #-> "10"
|
||||
print "0:10",dimsize("0:10") # -> "11"
|
||||
print "0:x",dimsize("0:x") # -> "x+1"
|
||||
print "-3:x",dimsize("-3:x") # -> "x+1"
|
||||
print "x:y",dimsize("x:y") # -> "y-x+1"
|
||||
print "x:5",dimsize("x:5") # -> "y-x+1"
|
||||
def OrderedUniqueList(l):
|
||||
# (Iter, bool) -> List[Any]
|
||||
'''Uniquify a immutable iterable. Don't preserve the order'''
|
||||
return sorted(set(l))
|
||||
|
||||
def flatten(l_2d):
|
||||
# (List [ List[Any] ]) -> List
|
||||
'''Construct a copy of the 2d list collapsed into one dimension.
|
||||
|
||||
Note:
|
||||
- We collapse in a C-style fashion (row_major).
|
||||
'''
|
||||
|
||||
return [item for l_1d in l_2d for item in l_1d]
|
||||
|
||||
|
||||
# ~#~#~#~#~#
|
||||
# I R P _ R E L A T E D
|
||||
# ~#~#~#~#~#
|
||||
def build_dim(l_dim, colons=False):
|
||||
# (List[str],bool) -> str
|
||||
'''Contruct a valid fortran90 array dimension code from a list dimension
|
||||
|
||||
Exemple:
|
||||
[4,8] -> (4,8) if not colons
|
||||
[4,8] -> (:,:) if colons
|
||||
|
||||
'''
|
||||
if not l_dim:
|
||||
return ""
|
||||
|
||||
l_dim_colons = [':'] * len(l_dim) if colons else l_dim
|
||||
|
||||
return "(%s)" % (",".join(l_dim_colons))
|
||||
|
||||
|
||||
def build_use(l_ent, d_ent):
|
||||
# (List, Dict[str,Entity]) -> list
|
||||
'''Contruct the fortran90 'use' statement for the list of entity'''
|
||||
return OrderedUniqueList(" use %s" % d_ent[x].fmodule for x in l_ent)
|
||||
|
||||
def build_call_provide(l_ent, d_ent):
|
||||
# (List, Dict[str,Entity]) -> list
|
||||
'''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)
|
||||
l_same_as = OrderedUniqueList(d_ent[x].same_as for x in l_ent)
|
||||
return flatten(map(fun, l_same_as))
|
||||
|
||||
|
697
src/variable.py
697
src/variable.py
@ -1,697 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
|
||||
# the Implicit Reference to Parameters (IRP) method.
|
||||
# Copyright (C) 2009 Anthony SCEMAMA
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Anthony Scemama
|
||||
# LCPQ - IRSAMC - CNRS
|
||||
# Universite Paul Sabatier
|
||||
# 118, route de Narbonne
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from irpf90_t import *
|
||||
from util import *
|
||||
import error
|
||||
from command_line import command_line
|
||||
|
||||
class Variable(object):
|
||||
|
||||
############################################################
|
||||
def __init__(self,text,label,name = None):
|
||||
assert type(text) == list
|
||||
assert len(text) > 0
|
||||
assert type(text[0]) == Begin_provider
|
||||
self.label = label
|
||||
self.text = text
|
||||
if name is not None:
|
||||
self._name = name
|
||||
|
||||
############################################################
|
||||
def is_touched(self):
|
||||
if '_is_touched' not in self.__dict__:
|
||||
from variables import variables
|
||||
result = self.is_read
|
||||
for i in self.children:
|
||||
if variables[i].is_touched:
|
||||
result = True
|
||||
break
|
||||
self._is_touched = result
|
||||
return self._is_touched
|
||||
is_touched = property(is_touched)
|
||||
|
||||
############################################################
|
||||
def has_openmp(self):
|
||||
if '_has_openmp' not in self.__dict__:
|
||||
self._has_openmp = False
|
||||
self.builder()
|
||||
return self._has_openmp
|
||||
has_openmp = property(has_openmp)
|
||||
|
||||
############################################################
|
||||
def is_written(self):
|
||||
if '_is_written' not in self.__dict__:
|
||||
from variables import variables
|
||||
result = False
|
||||
for i in self.parents:
|
||||
if variables[i].is_written:
|
||||
result = True
|
||||
break
|
||||
self._is_written = result
|
||||
return self._is_written
|
||||
is_written = property(is_written)
|
||||
|
||||
############################################################
|
||||
def is_read(self):
|
||||
if '_is_read' not in self.__dict__:
|
||||
from variables import variables
|
||||
result = False
|
||||
for i in self.parents:
|
||||
if variables[i].is_read:
|
||||
result = True
|
||||
break
|
||||
self._is_read = result
|
||||
return self._is_read
|
||||
is_read = property(is_read)
|
||||
|
||||
############################################################
|
||||
def is_main(self):
|
||||
if '_is_main' not in self.__dict__:
|
||||
self._is_main = (self.name == self.same_as)
|
||||
return self._is_main
|
||||
is_main = property(is_main)
|
||||
|
||||
############################################################
|
||||
def name(self):
|
||||
'''Name is lowercase'''
|
||||
if '_name' not in self.__dict__:
|
||||
buffer = None
|
||||
text = self.text
|
||||
for line in text:
|
||||
if type(line) == Begin_provider:
|
||||
self._name = line.filename[1]
|
||||
break
|
||||
return self._name
|
||||
name = property(name)
|
||||
|
||||
############################################################
|
||||
def doc(self):
|
||||
if '_doc' not in self.__dict__:
|
||||
text = self.text
|
||||
buffer = filter(lambda l:type(l) == Doc, text)
|
||||
self._doc = map(lambda l: l.text.lstrip()[1:], buffer)
|
||||
if buffer == []:
|
||||
error.warn(None,"Variable %s is not documented"%(self.name))
|
||||
return self._doc
|
||||
doc = property(doc)
|
||||
|
||||
############################################################
|
||||
def documented(self):
|
||||
if '_documented' not in self.__dict__:
|
||||
self._documented = (self.doc != [])
|
||||
return self._documented
|
||||
documented = property(documented)
|
||||
|
||||
############################################################
|
||||
def includes(self):
|
||||
if '_includes' not in self.__dict__:
|
||||
self._includes = []
|
||||
text = self.text
|
||||
for line in filter(lambda x: type(x) == Include,text):
|
||||
self._includes.append(line.filename)
|
||||
make_single(self._includes)
|
||||
return self._includes
|
||||
includes = property(includes)
|
||||
|
||||
############################################################
|
||||
def calls(self):
|
||||
if '_calls' not in self.__dict__:
|
||||
self._calls = []
|
||||
text = self.text
|
||||
for line in filter(lambda x: type(x) == Call,text):
|
||||
sub = line.text.split('(',1)[0].split()[1].lower()
|
||||
self._calls.append(sub)
|
||||
make_single(self._calls)
|
||||
return self._calls
|
||||
calls=property(fget=calls)
|
||||
|
||||
############################################################
|
||||
def others(self):
|
||||
if '_others' not in self.__dict__:
|
||||
result = []
|
||||
append = result.append
|
||||
f = lambda l: type(l) in [Begin_provider, Cont_provider]
|
||||
text = self.text
|
||||
lines = filter(f, text)
|
||||
for line in lines:
|
||||
append(line.filename[1])
|
||||
result.remove(self.name)
|
||||
self._others = result
|
||||
return self._others
|
||||
others = property(others)
|
||||
|
||||
############################################################
|
||||
def same_as(self):
|
||||
if '_same_as' not in self.__dict__:
|
||||
if type(self.line) == Begin_provider:
|
||||
result = self.name
|
||||
else:
|
||||
result = self.text[0].filename[1]
|
||||
self._same_as = result
|
||||
return self._same_as
|
||||
same_as = property(same_as)
|
||||
|
||||
############################################################
|
||||
def allocate(self):
|
||||
if '_allocate' not in self.__dict__:
|
||||
if not self.is_main:
|
||||
self._allocate = []
|
||||
else:
|
||||
from variables import variables
|
||||
def f(var):
|
||||
return variables[var].dim != []
|
||||
self._allocate = filter ( f, self.others + [self.name] )
|
||||
return self._allocate
|
||||
allocate = property(allocate)
|
||||
|
||||
############################################################
|
||||
def dim(self):
|
||||
if '_dim' not in self.__dict__:
|
||||
line = self.line.text.split('!')[0]
|
||||
buffer = line.replace(']','').split(',',2)
|
||||
if len(buffer) == 2:
|
||||
self._dim = []
|
||||
else:
|
||||
buffer = buffer[2].strip()[1:-1].split(',')
|
||||
self._dim = map(strip,buffer)
|
||||
return self._dim
|
||||
dim = property(dim)
|
||||
|
||||
############################################################
|
||||
def type(self):
|
||||
if '_type' not in self.__dict__:
|
||||
line = self.line.text
|
||||
buffer = line.split(',')[0]
|
||||
try:
|
||||
buffer = buffer.split('[')[1].strip()
|
||||
except IndexError:
|
||||
error.fail(None,"Error in definition of %s."%(self.name))
|
||||
if self.dim != []:
|
||||
buffer = "%s, allocatable"%(buffer)
|
||||
self._type = buffer
|
||||
return self._type
|
||||
type = property(type)
|
||||
|
||||
############################################################
|
||||
def fmodule(self):
|
||||
if '_fmodule' not in self.__dict__:
|
||||
self._fmodule = self.line.filename[0].replace('/','__').split('.irp.f')[0]+'_mod'
|
||||
return self._fmodule
|
||||
fmodule = property(fmodule)
|
||||
|
||||
############################################################
|
||||
def regexp(self):
|
||||
if '_regexp' not in self.__dict__:
|
||||
import re
|
||||
self._regexp = re.compile( \
|
||||
r"([^a-z0-9'\"_]|^)%s([^a-z0-9_]|$)"%(self.name),re.I)
|
||||
return self._regexp
|
||||
regexp = property(regexp)
|
||||
|
||||
############################################################
|
||||
def line(self):
|
||||
if '_line' not in self.__dict__:
|
||||
f = lambda l: type(l) in [Begin_provider, Cont_provider]
|
||||
text = self.text
|
||||
lines = filter(f, text)
|
||||
for line in lines:
|
||||
buffer = line.filename[1]
|
||||
if self._name == buffer:
|
||||
self._line = line
|
||||
break
|
||||
assert '_line' in self.__dict__
|
||||
return self._line
|
||||
line = property(line)
|
||||
|
||||
############################################################
|
||||
def header(self):
|
||||
if '_header' not in self.__dict__:
|
||||
name = self.name
|
||||
self._header = [ " %s :: %s %s"%(self.type, name, build_dim_colons(self) ) ]
|
||||
if command_line.coarray:
|
||||
if self.dim == []:
|
||||
self._header[0] += " [*]"
|
||||
else:
|
||||
self._header[0] += " [:]"
|
||||
if self.dim != [] and command_line.align != '1':
|
||||
self._header += [" !DIR$ ATTRIBUTES ALIGN: %s :: %s"%(command_line.align,name)]
|
||||
if self.is_main:
|
||||
self._header += [ " logical :: %s_is_built = .False."%(name) ]
|
||||
return self._header
|
||||
header = property(header)
|
||||
|
||||
############################################################
|
||||
def toucher(self):
|
||||
if '_toucher' not in self.__dict__:
|
||||
if not self.is_main:
|
||||
self._toucher = []
|
||||
else:
|
||||
from modules import modules
|
||||
from variables import variables
|
||||
if '_needed_by' not in self.__dict__:
|
||||
import parsed_text
|
||||
parents = self.parents
|
||||
parents.sort()
|
||||
mods = map(lambda x: variables[x].fmodule, parents)
|
||||
mods = make_single(mods)+[self.fmodule]
|
||||
name = self.name
|
||||
result = [ "subroutine touch_%s"%(name) ]
|
||||
result += map(lambda x: " Use %s"%(x),mods)
|
||||
result.append(" implicit none")
|
||||
if command_line.do_debug:
|
||||
length = str(len("touch_%s"%(name)))
|
||||
result += [ " character*(%s) :: irp_here = 'touch_%s'"%(length,name) ]
|
||||
if command_line.do_debug:
|
||||
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("")
|
||||
self._toucher = result
|
||||
return self._toucher
|
||||
toucher = property(toucher)
|
||||
|
||||
##########################################################
|
||||
def locker(self):
|
||||
if '_locker' not in self.__dict__:
|
||||
if not command_line.do_openmp:
|
||||
self._locker = []
|
||||
else:
|
||||
from modules import modules
|
||||
from variables import variables
|
||||
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("")
|
||||
self._locker = result
|
||||
return self._locker
|
||||
locker = property(locker)
|
||||
|
||||
##########################################################
|
||||
def reader(self):
|
||||
if '_reader' not in self.__dict__:
|
||||
if not self.is_main:
|
||||
self._reader = []
|
||||
else:
|
||||
if '_needs' not in self.__dict__:
|
||||
import parsed_text
|
||||
from variables import variables
|
||||
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)",
|
||||
" irp_iunit = irp_iunit+1",
|
||||
" 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_colons(variables[n])),
|
||||
" 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("")
|
||||
self._reader = result
|
||||
return self._reader
|
||||
reader = property(reader)
|
||||
|
||||
##########################################################
|
||||
def writer(self):
|
||||
if '_writer' not in self.__dict__:
|
||||
if not self.is_main:
|
||||
self._writer = []
|
||||
else:
|
||||
from variables import variables
|
||||
if '_needs' not in self.__dict__:
|
||||
import parsed_text
|
||||
name = self.name
|
||||
result = [ \
|
||||
"subroutine writer_%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("writer_%s"%(self.name))
|
||||
result += [\
|
||||
" character*(%d) :: irp_here = 'writer_%s'"%(length,name),
|
||||
" call irp_enter(irp_here)" ]
|
||||
result += [ \
|
||||
" if (.not.%s_is_built) then"%(self.same_as),
|
||||
" call provide_%s"%(self.same_as),
|
||||
" endif" ]
|
||||
result += map(lambda x: " call writer_%s(irp_num)"%(x),self.needs)
|
||||
result += [ \
|
||||
" irp_is_open = .True.",
|
||||
" irp_iunit = 9",
|
||||
" do while (irp_is_open)",
|
||||
" irp_iunit = irp_iunit+1",
|
||||
" 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='UNKNOWN',action='WRITE')"%(n),
|
||||
" write(irp_iunit,*) %s%s"%(n,build_dim_colons(variables[n])),
|
||||
" close(irp_iunit)" ]
|
||||
if command_line.do_debug:
|
||||
result.append(" call irp_leave(irp_here)")
|
||||
result.append("end subroutine writer_%s"%(name))
|
||||
result.append("")
|
||||
self._writer = result
|
||||
return self._writer
|
||||
writer = property(writer)
|
||||
|
||||
##########################################################
|
||||
def free(self):
|
||||
if '_free' not in self.__dict__:
|
||||
name = self.name
|
||||
result = [ "!","! >>> FREE %s"%(name),
|
||||
" %s_is_built = .False."%(self.same_as) ]
|
||||
if self.dim != []:
|
||||
if command_line.do_memory:
|
||||
result += [ \
|
||||
" if (allocated(%s)) then"%(name),
|
||||
" deallocate (%s)"%(name),
|
||||
" print *, 'Deallocating %s'"%(name),
|
||||
" endif" ]
|
||||
else:
|
||||
result += [ \
|
||||
" if (allocated(%s)) then"%(name),
|
||||
" deallocate (%s)"%(name),
|
||||
" endif" ]
|
||||
result.append("! <<< END FREE")
|
||||
self._free = result
|
||||
return self._free
|
||||
free = property(free)
|
||||
|
||||
##########################################################
|
||||
def provider(self):
|
||||
if '_provider' not in self.__dict__:
|
||||
if not self.is_main:
|
||||
self._provider = []
|
||||
else:
|
||||
if '_to_provide' not in self.__dict__:
|
||||
import parsed_text
|
||||
from variables import variables, build_use, call_provides
|
||||
name = self.name
|
||||
same_as = self.same_as
|
||||
|
||||
def build_alloc(name):
|
||||
self = variables[name]
|
||||
if self.dim == []:
|
||||
return []
|
||||
|
||||
def do_size():
|
||||
result = " print *, ' size: ("
|
||||
result += ','.join(self.dim)
|
||||
return result+")'"
|
||||
|
||||
def check_dimensions():
|
||||
result = map(lambda x: "(%s>0)"%(dimsize(x)), self.dim)
|
||||
result = ".and.".join(result)
|
||||
result = " if (%s) then"%(result)
|
||||
return result
|
||||
|
||||
def dimensions_OK():
|
||||
result = [ " irp_dimensions_OK = .True." ]
|
||||
for i,k in enumerate(self.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(self.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),
|
||||
do_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),
|
||||
do_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),
|
||||
do_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 )
|
||||
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 += call_provides(self.to_provide)
|
||||
result += flatten( map(build_alloc,[self.same_as]+self.others) )
|
||||
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("")
|
||||
self._provider = result
|
||||
return self._provider
|
||||
provider = property(provider)
|
||||
|
||||
##########################################################
|
||||
def builder(self):
|
||||
if '_builder' not in self.__dict__:
|
||||
if not self.is_main:
|
||||
self._builder = []
|
||||
else:
|
||||
import parsed_text
|
||||
from variables import build_use, call_provides
|
||||
for filename,buffer in parsed_text.parsed_text:
|
||||
if self.line.filename[0].startswith(filename):
|
||||
break
|
||||
text = []
|
||||
same_as = self.same_as
|
||||
inside = False
|
||||
for vars,line in buffer:
|
||||
if type(line) == Begin_provider:
|
||||
if line.filename[1] == same_as:
|
||||
inside = True
|
||||
vars = []
|
||||
if inside:
|
||||
text.append( (vars,line) )
|
||||
text += map( lambda x: ([],Simple_line(line.i,x,line.filename)), call_provides(vars) )
|
||||
if command_line.do_profile and type(line) == Begin_provider:
|
||||
text.append( ( [], Declaration(line.i," double precision :: irp_rdtsc, irp_rdtsc1, irp_rdtsc2",line.filename) ) )
|
||||
text.append( ( [], Simple_line(line.i," irp_rdtsc1 = irp_rdtsc()",line.filename) ) )
|
||||
if type(line) == End_provider:
|
||||
if inside:
|
||||
break
|
||||
name = self.name
|
||||
text = parsed_text.move_to_top(text,Declaration)
|
||||
text = parsed_text.move_to_top(text,Implicit)
|
||||
text = parsed_text.move_to_top(text,Use)
|
||||
text = map(lambda x: x[1], text)
|
||||
# inside_omp = False
|
||||
for line in filter(lambda x: type(x) not in [ Begin_doc, End_doc, Doc], text):
|
||||
if type(line) == Begin_provider:
|
||||
result = []
|
||||
if command_line.directives and command_line.inline in ["all","builders"]:
|
||||
result += [ "!DEC$ ATTRIBUTES INLINE :: bld_%s"%(same_as) ]
|
||||
result += [ "subroutine bld_%s"%(name) ]
|
||||
result += build_use([name]+self.needs)
|
||||
elif type(line) == Cont_provider:
|
||||
pass
|
||||
elif type(line) == End_provider:
|
||||
if command_line.do_profile:
|
||||
result += [ " irp_rdtsc2 = irp_rdtsc()" ,
|
||||
" call irp_set_timer(%d,(irp_rdtsc2-irp_rdtsc1))"%self.label ]
|
||||
result.append( "end subroutine bld_%s"%(name) )
|
||||
break
|
||||
elif type(line) == Openmp:
|
||||
# Detect OpenMP blocks
|
||||
buffer = line.text.lower().split()
|
||||
if buffer[1] == "parallel":
|
||||
# inside_omp = True
|
||||
self._has_openmp = True
|
||||
# if buffer[1] == "end" and buffer[2] == "parallel":
|
||||
# inside_omp = False
|
||||
result.append(line.text)
|
||||
else:
|
||||
# if inside_omp:
|
||||
# if type(line) in [ Provide_all, Provide, Touch, SoftTouch ]:
|
||||
# error.fail(line,str(type(line))+"is not allowed in an OpenMP block.")
|
||||
result.append(line.text)
|
||||
self._builder = result
|
||||
return self._builder
|
||||
builder = property(builder)
|
||||
|
||||
##########################################################
|
||||
def children(self):
|
||||
if '_children' not in self.__dict__:
|
||||
if not self.is_main:
|
||||
self._children = []
|
||||
from variables import variables
|
||||
if '_needs' not in self.__dict__:
|
||||
import parsed_text
|
||||
result = []
|
||||
for x in self.needs:
|
||||
result.append(x)
|
||||
try:
|
||||
result += variables[x].children
|
||||
except RuntimeError:
|
||||
pass # Exception will be checked after
|
||||
self._children = make_single(result)
|
||||
if self.name in result:
|
||||
error.fail(self.line,"Cyclic dependencies:\n%s"%(str(self._children)))
|
||||
return self._children
|
||||
children = property(children)
|
||||
|
||||
##########################################################
|
||||
def parents(self):
|
||||
if '_parents' not in self.__dict__:
|
||||
if not self.is_main:
|
||||
self._parents = []
|
||||
else:
|
||||
from variables import variables
|
||||
if '_needed_by' not in self.__dict__:
|
||||
import parsed_text
|
||||
result = []
|
||||
for x in self.needed_by:
|
||||
result.append(x)
|
||||
try:
|
||||
result += variables[x].parents
|
||||
except RuntimeError:
|
||||
pass # Exception will be checked after
|
||||
self._parents = make_single(result)
|
||||
if self.name in result:
|
||||
error.fail(self.line,"Cyclic dependencies:\n%s"%(str(self._parents)))
|
||||
return self._parents
|
||||
parents = property(parents)
|
||||
|
||||
######################################################################
|
||||
if __name__ == '__main__':
|
||||
from preprocessed_text import preprocessed_text
|
||||
from variables import variables
|
||||
#for v in variables.keys():
|
||||
# print v
|
||||
def print_dot(x,done):
|
||||
if x.children == []:
|
||||
return
|
||||
for i in x.needs:
|
||||
pair = (x.name, i)
|
||||
if pair not in done:
|
||||
print "%s -> %s"%( x.name, i )
|
||||
done[pair] = None
|
||||
print_dot(variables[i],done)
|
||||
|
||||
print "digraph G { "
|
||||
# print_dot(variables['e_loc'], {})
|
||||
print_dot(variables['psi_value'], {})
|
||||
print "}"
|
@ -1,96 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
|
||||
# the Implicit Reference to Parameters (IRP) method.
|
||||
# Copyright (C) 2009 Anthony SCEMAMA
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Anthony Scemama
|
||||
# LCPQ - IRSAMC - CNRS
|
||||
# Universite Paul Sabatier
|
||||
# 118, route de Narbonne
|
||||
# 31062 Toulouse Cedex 4
|
||||
# scemama@irsamc.ups-tlse.fr
|
||||
|
||||
|
||||
from variable import *
|
||||
from irpf90_t import *
|
||||
from command_line import command_line
|
||||
from util import *
|
||||
|
||||
######################################################################
|
||||
def create_variables():
|
||||
from preprocessed_text import preprocessed_text
|
||||
result = {}
|
||||
icount = 0
|
||||
for filename, text in preprocessed_text:
|
||||
buffer = []
|
||||
inside = False
|
||||
for line in text:
|
||||
if type(line) == Begin_provider:
|
||||
inside = True
|
||||
if inside:
|
||||
buffer.append(line)
|
||||
if type(line) == End_provider:
|
||||
inside = False
|
||||
icount += 1
|
||||
v = Variable(buffer,icount)
|
||||
if v.name in result:
|
||||
print "Warning: Duplicate provider for %s in"%(v.name)
|
||||
print "- ", v.line.filename[0], " line ", v.line.i
|
||||
print "- ", result[v.name].line.filename[0], " line ", result[v.name].line.i
|
||||
print "Choosing first version"
|
||||
result[v.name] = v
|
||||
for other in v.others:
|
||||
if other in result:
|
||||
print "Warning: Duplicate provider for %s in"%(other)
|
||||
print "- ", v.line.filename[0], " line ", v.line.i
|
||||
print "- ", result[other].line.filename[0], " line ", result[other].line.i
|
||||
print "Choosing first version"
|
||||
result[other] = Variable(buffer,icount,other)
|
||||
buffer = []
|
||||
return result
|
||||
|
||||
variables = create_variables()
|
||||
|
||||
######################################################################
|
||||
def build_use(vars):
|
||||
result = map(lambda x: " use %s"%(variables[x].fmodule), vars)
|
||||
result = make_single(result)
|
||||
return result
|
||||
|
||||
######################################################################
|
||||
def call_provides(vars,opt=False):
|
||||
vars = make_single( map(lambda x: variables[x].same_as, vars) )
|
||||
if opt:
|
||||
all_children = flatten( map(lambda x: variables[x].children, vars ))
|
||||
vars = filter(lambda x: x not in all_children,vars)
|
||||
def fun(x):
|
||||
result = []
|
||||
result += [ \
|
||||
" if (.not.%s_is_built) then"%(x) ]
|
||||
result += [ \
|
||||
" call provide_%s"%(x) ]
|
||||
result += [ \
|
||||
" endif" ]
|
||||
return result
|
||||
|
||||
result = flatten ( map (fun, vars) )
|
||||
return result
|
||||
|
||||
######################################################################
|
||||
if __name__ == '__main__':
|
||||
for v in variables.keys():
|
||||
print v
|
@ -1 +1 @@
|
||||
version = "1.6.9"
|
||||
version = "2.0.0"
|
||||
|
Loading…
Reference in New Issue
Block a user