10
0
mirror of https://gitlab.com/scemama/irpf90.git synced 2024-12-22 12:23:32 +01:00

Revert "IRPF90 v2"

This commit is contained in:
Anthony Scemama 2017-02-01 21:28:10 +01:00 committed by GitHub
parent 4674d7e0ab
commit e6b6a35585
46 changed files with 4277 additions and 4553 deletions

View File

@ -14,10 +14,6 @@ Dependencies
Installing IRPF90
-----------------
``pip install irpf90``
or
``${IRPF90_HOME}`` is the location of your irpf90 directory::
``` bash

View File

@ -1,69 +1,13 @@
IRPF90= irpf90
IRPF90FLAGS= -I ./ -I input/
BUILD_SYSTEM= make
IRPF90 = python ../src/irpf90.py -I input -a -d -j
FC = ifort
FCFLAGS= -O2
NINJA = ninja -j 1 -v
.EXPORT_ALL_VARIABLES:
SRC=
OBJ=
LIB=
AR = ar
CC = gcc
CFLAGS = -O2
CXX = g++
CXXFLAGS = -O2
FC = gfortran
FCFLAGS = -O2
LIB =
RANLIB = ranlib
include irpf90.make
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
irpf90.make: $(wildcard *.irp.f)
$(IRPF90)

View File

@ -1,8 +1,12 @@
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

View File

@ -1,4 +1,4 @@
BEGIN_PROVIDER [integer, t ]
BEGIN_PROVIDER [ integer, t ]
t = u1+v+4
END_PROVIDER
@ -7,7 +7,6 @@ BEGIN_PROVIDER [integer,w]
END_PROVIDER
BEGIN_PROVIDER [ integer, v ]
implicit none
v = u2+w+2
END_PROVIDER
@ -19,7 +18,6 @@ END_PROVIDER
BEGIN_PROVIDER [ integer, u2 ]
integer :: fu
u2 = fu(d3,d4)
!df
END_PROVIDER
integer function fu(x,y)

View File

@ -1,280 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

View File

@ -1,2 +0,0 @@
include irpf90 README.md irpman irp_indent

View File

@ -1 +0,0 @@
../src

View File

@ -1,2 +0,0 @@
[metadata]
description-file = README.md

View File

@ -1,16 +0,0 @@
from distutils.core import setup
setup(
name = 'irpf90',
packages = ['irpf90_libs'], # this must be the same as the name above
version = '1.6.9',
description = 'IRPF90 is a Fortran90 preprocessor written in Python for programming using the Implicit Reference to Parameters (IRP) method. It simplifies the development of large fortran codes in the field of scientific high performance computing.',
author = 'Anthony Scemama',
author_email = 'scemama@irsamc.ups-tlse.fr',
url = 'http://irpf90.ups-tlse.fr', # use the URL to the github repo
download_url = 'https://github.com/scemama/irpf90/archive/v1.6.9.tar.gz', # I'll explain this in a second
keywords = ['programming', 'fortran', 'IRP'], # arbitrary keywords
classifiers = [],
scripts = ["irpf90", "irpman", "irpf90_indent"],
)

View File

@ -1,3 +0,0 @@
[style]
based_on_style = pep8
COLUMN_LIMIT = 100

View File

@ -1,7 +1,21 @@
PYTHON=python
PYVERSION=$(shell $(PYTHON) -c "import sys; print(sys.version[:3])")
HAS_CYTHON=$(shell bash -c "which cython &> /dev/null && echo 1 || echo 0")
ifneq ($(HAS_CYTHON),0)
../bin/irpf90: irpf90.so
rm ../bin/irpf90 ; cd ../bin ; ln -s ../src/irpf90_python.exe irpf90
irpf90.so : $(wildcard *.py) irpf90.c
./cython_setup.py build_ext --inplace
irpf90.c: irpf90.py
cython --embed irpf90.py
else
../bin/irpf90: irpf90_python.exe
rm ../bin/irpf90 ; cd ../bin ; ln -s ../src/irpf90_python.exe irpf90
endif
clean:
rm -f *.c *.so *.pyc *.pyo 2>/dev/null

View File

View File

@ -1,537 +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 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

73
src/checkpoint.py Normal file
View File

@ -0,0 +1,73 @@
#!/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()

View File

@ -63,7 +63,8 @@ end
precondition = ""
else:
precondition = "PROVIDE "+precondition
from util import lazy_write_file
lazy_write_file(filename,template%locals())
file = open(filename,'w')
file.write(template%locals())
file.close()

View File

@ -24,11 +24,6 @@
# 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
@ -57,7 +52,6 @@ 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):
@ -67,16 +61,17 @@ class CommandLine(object):
self.argv = list(sys.argv)
self.executable_name = self.argv[0]
@irpy.lazy_property
def defined(self):
return [ a for o,a in self.opts if o in [ "-D", '--'+options['D'][0] ] ]
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)
@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] ]:
@ -85,32 +80,41 @@ class CommandLine(object):
if a[-1] != '/':
a = a+'/'
self._include_dir.append(a)
return self._include_dir
@irpy.lazy_property
def inline(self):
return next( (a for o,a in self.opts if o in [ "-n", '--'+options['n'][0] ]),'')
return self._include_dir
include_dir = property(fget=include_dir)
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)
@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
return self._substituted
substituted = property(fget=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:
return [buffer[0], int(buffer[1]), None, filename]
self._codelet = [buffer[0], int(buffer[1]), None, filename]
elif len(buffer) == 3:
return [buffer[0], int(buffer[2]), buffer[1], filename]
self._codelet = [buffer[0], int(buffer[2]), buffer[1], filename]
else:
print """
Error in codelet definition. Use:
@ -119,38 +123,80 @@ or
--codelet=provider:precondition:NMAX
"""
sys.exit(1)
return self._codelet
codelet = property(fget=codelet)
@irpy.lazy_property
def preprocessed(self):
return [a for o,a in self.ops if o in [ "-p", '--'+options['p'][0] ] ]
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 touched(self):
return [a for o,a in self.ops if o in [ "-t", '--'+options['t'][0] ] ]
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)
@irpy.lazy_property
def align(self):
return next( (a for o,a in self.opts if o in [ "-l", '--'+options['l'][0] ]),'1')
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)
@irpy.lazy_property
def coarray(self):
return any(o for o,a in self.opts if o in [ "-C", '--'+options['C'][0] ])
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)
@irpy.lazy_property
def warnings(self):
return any(o for o,a in self.opts if o in [ "-W", '--'+options['W'][0] ])
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)
@irpy.lazy_property
def openmp(self):
return any(o for o,a in self.opts if o in [ "-z", '--'+options['z'][0] ])
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)
@irpy.lazy_property
def ninja(self):
return any(o for o,a in self.opts if o in [ "-j", '--'+options['j'][0] ])
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)
@irpy.lazy_property
def directives(self):
return not(any(o for o,a in self.opts if o in [ "-r", '--'+options['r'][0] ]))
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)
def usage(self):
t = """
@ -205,10 +251,17 @@ 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):
return not(any( (self.do_version, self.do_help, self.do_preprocess, self.do_touch, self.do_init)))
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)
command_line = CommandLine()

View File

@ -24,171 +24,166 @@
# 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
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_]
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(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(line):
assert type(line) == str
line = line.strip()
return [line if line else ".br"]
def process_doc(file,line):
assert type(line) == str
line = line.strip()
if line == "":
line = ".br"
print >>file, line
######################################################################
def process_deps(l):
assert isinstance(l, (list, set))
return ['%s\n.br' % v for v in sorted(l)]
def process_deps(file,l):
assert type(l) == list
for v in l:
print >>file, "%s\n.br"%(v,)
######################################################################
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 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 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 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 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) == 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_)
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()
######################################################################
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)
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)
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)
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_)
os.waitpid(pid1,0)
os.waitpid(pid2,0)
######################################################################
if __name__ == '__main__':
run()
run()

View File

@ -24,9 +24,29 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
def main():
import irpf90_libs.irpf90
irpf90_libs.irpf90.main()
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import os
to_remove = """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
)
main()

View File

@ -1,726 +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 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

68
pip/irpman → src/error.py Executable file → Normal file
View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/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
@ -24,41 +24,43 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
# Define auto-completion for bash
function run ()
{
cat << EOF | exec python - $@
import sys, os
import sys
from irpf90_t import *
from command_line import command_line
do_warnings = command_line.do_warnings
from irpf90_libs.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)
######################################################################
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)
os.system("man ./"+mandir+sys.argv[1].lower()+".l")
EOF
}
case "$0" in
*irpman)
if [[ -z $1 ]] ; then
echo "To activate auto-completion in bash:"
echo "source " $0
else
run $@
fi
;;
######################################################################
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)
*)
_irpman_complete()
{
local cur
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -W "`[[ -f tags ]] && cat tags | cut -d' ' -f 1`" -- "$cur" ) )
} && complete -F _irpman_complete irpman
;;
esac
######################################################################
if __name__ == '__main__':
line = Empty_line(3,"empty", "testfile")
fail(line, "Message")

89
src/init.py Normal file
View File

@ -0,0 +1,89 @@
#!/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

View File

@ -85,9 +85,9 @@ subroutine irp_enter(irp_where)
nthread = 1
"""
txt += """
print *, 'Allocating irp_stack(',STACKMAX,',',0:nthread,')'
print *, 'Allocating irp_cpu(',STACKMAX,',',0:nthread,')'
print *, 'Allocating stack_index(',0:nthread,')'
print *, 'Allocating irp_stack(',STACKMAX,',',nthread,')'
print *, 'Allocating irp_cpu(',STACKMAX,',',nthread,')'
print *, 'Allocating stack_index(',nthread,')'
endif"""
txt +="""
$2
@ -128,9 +128,9 @@ $1
nthread = 1
"""
txt +="""
print *, 'Allocating irp_stack(',STACKMAX,',',0:nthread,')'
print *, 'Allocating irp_cpu(',STACKMAX,',',0:nthread,')'
print *, 'Allocating stack_index(',0:nthread,')'
print *, 'Allocating irp_stack(',STACKMAX,',',nthread,')'
print *, 'Allocating irp_cpu(',STACKMAX,',',nthread,')'
print *, 'Allocating stack_index(',nthread,')'
endif
"""
txt += """
@ -172,16 +172,16 @@ end subroutine
!$OMP END PARALLEL
!$OMP CRITICAL
if (.not.alloc) then
allocate(irp_stack(0:STACKMAX,0:nthread))
allocate(irp_cpu(0:STACKMAX,0:nthread))
allocate(stack_index(0:nthread))
allocate(irp_stack(0:STACKMAX,nthread))
allocate(irp_cpu(0:STACKMAX,nthread))
allocate(stack_index(nthread))
stack_index = 0
alloc = .True.
endif
!$OMP END CRITICAL
endif
stack_index(ithread) = min(stack_index(ithread)+1,STACKMAX)
irp_stack(stack_index(ithread),ithread) = irp_where"""
stack_index(ithread+1) = mod(stack_index(ithread+1)+1,STACKMAX)
irp_stack(stack_index(ithread+1),ithread+1) = irp_where"""
else:
s += """
nthread = 1
@ -193,13 +193,13 @@ end subroutine
alloc = .True.
endif
endif
stack_index(1) = min(stack_index(1)+1,STACKMAX)
stack_index(1) = mod(stack_index(1)+1,STACKMAX)
irp_stack(stack_index(1),1) = irp_where"""
if do_memory:
txt+="""
print *, 'Allocating irp_stack(',STACKMAX,','0:nthread,')'
print *, 'Allocating irp_cpu(',STACKMAX,','0:nthread,')'
print *, 'Allocating stack_index(',0:nthread,')'"""
print *, 'Allocating irp_stack(',STACKMAX,','nthread,')'
print *, 'Allocating irp_cpu(',STACKMAX,','nthread,')'
print *, 'Allocating stack_index(',nthread,')'"""
else:
s = ""
txt = txt.replace("$1",s)
@ -207,8 +207,8 @@ end subroutine
# $2
if do_debug:
txt = txt.replace("$2","""
print *, ithread, ':', white(1:stack_index(ithread))//'-> ', trim(irp_where)
call cpu_time(irp_cpu(stack_index(ithread),ithread))""")
print *, ithread, ':', white(1:stack_index(ithread+1))//'-> ', trim(irp_where)
call cpu_time(irp_cpu(stack_index(ithread+1),ithread+1))""")
else:
txt = txt.replace("$2","")
@ -216,16 +216,16 @@ end subroutine
if do_debug:
txt = txt.replace("$3","""
call cpu_time(cpu)
print *, ithread, ':', white(1:stack_index(ithread))//'<- ', &
trim(irp_stack(stack_index(ithread),ithread)), &
cpu-irp_cpu(stack_index(ithread),ithread)""")
print *, ithread, ':', white(1:stack_index(ithread+1))//'<- ', &
trim(irp_stack(stack_index(ithread+1),ithread+1)), &
cpu-irp_cpu(stack_index(ithread+1),ithread+1)""")
else:
txt = txt.replace("$3","")
# $4
if do_debug or do_assert:
txt = txt.replace("$4","""
stack_index(ithread) = max(0,stack_index(ithread)-1)""")
stack_index(ithread+1) = stack_index(ithread+1)-1""")
else:
txt = txt.replace("$4","")
@ -248,13 +248,18 @@ subroutine irp_trace
if (.not.alloc) return
print *, 'Stack trace: ', ithread
print *, '-------------------------'
do i=1,stack_index(ithread)
print *, trim(irp_stack(i,ithread))
do i=1,stack_index(ithread+1)
print *, trim(irp_stack(i,ithread+1))
enddo
print *, '-------------------------'
end subroutine
"""
util.lazy_write_file(FILENAME,txt)
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()

View File

@ -1,4 +1,5 @@
#!/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
@ -24,85 +25,95 @@
# 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
pass
sys.setcheckinterval(1000)
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()
return
if command_line.do_version:
from version import version
print version
return
if command_line.do_help:
command_line.usage()
if command_line.do_init:
from build_file import create_generalmakefile
create_generalmakefile(command_line.do_ninja)
return
if command_line.do_version:
from version import version
print version
comm_world = Irpy_comm_world()
from init import init
if command_line.do_init:
init()
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_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_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_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_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 command_line.do_codelet:
import profile
profile.build_rdtsc()
import codelet
codelet.run()
if command_line.do_codelet:
import profile
profile.build_rdtsc()
import codelet
codelet.run()
if not command_line.do_run:
return
if not command_line.do_run:
return
init()
comm_world.create_buildfile(command_line.do_ninja)
comm_world.write_modules()
comm_world.create_touches()
comm_world.create_man()
import irp_stack
irp_stack.create()
if command_line.do_profile:
import profile
profile.run(comm_world.d_entity)
import makefile
makefile.create()
if command_line.do_openmp:
comm_world.create_lock()
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 __name__ == '__main__':
main()
main()

View File

@ -24,63 +24,385 @@
# 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 = text
self.filename = filename
def __init__(self,i,text,filename):
self.i = i
self._text = None
self.filename = filename
self._lower = None
self.set_text(text)
@irpy.lazy_property
def lower(self):
return self.text.lower()
def get_text(self):
return self._text
def set_text(self,value):
self._text = value
self._lower = value.lower()
def __repr__(self):
return "%20s:%5d : %s (%s)" % (type(self).__name__, self.i, self.text, self.filename)
def get_lower(self):
return self._lower
class LineWithName(Line):
text = property(fget=get_text, fset=set_text)
lower = property(fget=get_lower)
@irpy.lazy_property
def subname(self):
buf = self.lower
if not buf.endswith(')'):
buf += "()"
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)
l_buf = buf.split('(')
l_name = l_buf[0].split()
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)
if len(l_name) < 2:
import loger
logger.error("Syntax Error: %s" % line)
sys.exit(1)
return l_name.pop()
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()
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, ), {})

View File

@ -28,13 +28,12 @@
import os
import sys
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)
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")
os.system("man %s" % os.path.join(mandir,filename))

View File

@ -1,322 +0,0 @@
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))

View File

@ -1,160 +0,0 @@
#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

34
pip/irpf90_indent → src/locks.py Executable file → Normal file
View File

@ -24,9 +24,35 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
def main():
import irpf90_libs.irpf90_indent
irpf90_libs.irpf90_indent.main()
main()
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 Normal file
View File

@ -0,0 +1,204 @@
#!/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()

View File

@ -1,4 +1,4 @@
#!/unr/bin/env python
#!/usr/bin/env python
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
# the Implicit Reference to Parameters (IRP) method.
# Copyright (C) 2009 Anthony SCEMAMA
@ -24,246 +24,204 @@
# 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, 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 __init__(self,text,filename):
self.text = put_info(text,filename)
self.filename = filename[:-6]
self.name = "%s_mod"%(self.filename).replace('/','__').replace('.','Dot')
@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 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 is_main(self):
return self.prog_name is not 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 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 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)
if body:
result = ["module %s" % (self.name)]
result += body
result += ["end module %s" % (self.name)]
else:
result = []
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)
return 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)
@irpy.lazy_property
def has_irp_module(self):
return bool(self.head)
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 needed_vars(self):
return set(n for var in self.l_entity for n in var.needs)
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 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, ...'
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):
result = []
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
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
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.)'''
def modify_functions(text):
result = []
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))
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)
from parsed_text import move_to_top_list, move_interface
move_to_top_list(result, [Declaration, Implicit, Use])
move_interface(result)
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)
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

68
src/modules.py Normal file
View File

@ -0,0 +1,68 @@
#!/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 Normal file
View File

@ -0,0 +1,408 @@
#!/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", "rdtsc.o" ]
l_common_s += [ "irp_profile.irp.F90", "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

View File

@ -24,529 +24,526 @@
# 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_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_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_subroutine_in_line(line):
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'])
assert type(line) == Call
buffer = line.text.split('(')[0]
buffer = buffer.split()[1].lower()
return buffer
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 get_parsed_text(filename, text, variables, subroutines, vtuple):
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):
varlist = []
result = []
append = result.append
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
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)) )
else:
l = find_variables_in_line(line, vtuple)
l = filter(lambda x: x not in varlist, l)
append(Parsed_text(l, line))
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()
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.
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`
def move_to_top(text,t):
assert type(text) == list
assert t in [ NoDep, Declaration, Implicit, Use, Cont_provider ]
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))
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...
'''
return text
assert set(it).issubset([NoDep, Declaration, Implicit, Use, Cont_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
# ~ # ~ # ~
# 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(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
'''
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
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))
build_sub_needs()
#####################################################################
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
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
parsed_text = add_subroutine_needs()
######################################################################
def move_variables(parsed_text):
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]]
'''Move variables into the top of the declaraiton'''
def move_variables():
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
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")
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)
result.reverse()
result.reverse()
# 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
# 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
main_result = []
for filename,text in parsed_text:
main_result.append( (filename, func(filename,text)) )
return main_result
#return parallel_loop(func,parsed_text)
parsed_text = move_variables()
######################################################################
def build_needs(parsed_text, subroutines, stuple, variables):
'out: variable'
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
# ~#~#~#~#~#
# Needs and to_provide
# ~#~#~#~#~#
# 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)
for filename, text in parsed_text:
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)]
build_needs()
for start, end in zip(l_begin, l_end):
l_vars_start, line_start = text[start]
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
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
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
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 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
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
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

View File

@ -45,15 +45,22 @@ import subprocess
import tempfile
import os
import threading
from irpf90_t import irpdir
def build_rdtsc():
filename = irpdir+"irp_rdtsc.c"
file,filename = tempfile.mkstemp()
filename += ".c"
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)
def build_module(variables):
threading.Thread(target=t).start()
def build_module():
from variables import variables
data = """
module irp_timer
double precision :: irp_profile(3,%(n)d)
@ -97,10 +104,11 @@ subroutine irp_init_timer
double precision :: irp_rdtsc, t0
irp_profile = 0.d0
irp_rdtsc_shift = 0.d0
do i=1,1000000
do i=1,1000
t0 = irp_rdtsc()
irp_rdtsc_shift = irp_rdtsc_shift + (irp_rdtsc()-t0)
enddo
irp_rdtsc_shift = 1.d-6*(irp_rdtsc()-t0)
irp_rdtsc_shift = 1.d-3*irp_rdtsc_shift
%(text)s
end
@ -169,7 +177,9 @@ end
file.write(data)
file.close()
def run(d_entity):
build_module(d_entity)
def run():
build_module()
build_rdtsc()
if __name__ == "__main__":
build_rdtsc()

View File

@ -47,7 +47,7 @@ re_decl = re.compile( "".join( [ r"^\ *",
r"|external *(::)?",
r"|equivalence *(::)?",
r"|type",
r"|endtype",
r"|end ?type",
r")[^=(]"
] ) )

View File

@ -1,104 +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 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))

131
src/subroutine.py Normal file
View File

@ -0,0 +1,131 @@
#!/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

72
src/subroutines.py Normal file
View File

@ -0,0 +1,72 @@
#!/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

View File

@ -24,42 +24,50 @@
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
from irpf90_t import irp_id,irpdir
import os
from util import lazy_write_file
def create(modules,variables):
# (Dict[str,Module]. Dict[str, Variable]) -> None
'''Create the fortran90 finalize subroutine and the touched one'''
from irpf90_t import *
from util import *
from variables import variables
from modules import modules
finalize = "subroutine irp_finalize_%s\n"%(irp_id)
for m in filter(lambda x: not modules[x].is_main and modules[x].has_irp_module, modules):
finalize += " use %s\n"%(modules[m].name)
FILENAME=irpdir+'irp_touches.irp.F90'
main_modules_name =[ m.name for m in modules.values() if m.is_main]
def create():
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:
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 != []:
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
filename=os.path.join(irpdir,'irp_touches.irp.F90')
lazy_write_file(filename,''.join(out))
if not same_file(FILENAME,out):
file = open(FILENAME,'w')
file.writelines(out)
file.close()
if __name__ == '__main__':
create()

View File

@ -24,282 +24,169 @@
# 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
def cached_file(filename, text):
# (str,str) -> bool
'''Check if file locatte at filename containt the same data as text
NTHREADS=1 #int(os.getenv('OMP_NUM_THREADS',1))
Return:
True if data is the same, false otherwise
'''
def strip(x):
return x.strip()
def digest(data):
# (str) -> str
'''compute an uniq data id'''
return hashlib.md5(data).hexdigest()
def lower(x):
return x.lower()
try:
text_ref = open(filename, 'rb').read()
except IOError:
return False
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 )
else:
return digest(text_ref) == digest(text)
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
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
def lazy_write_file(filename, text, conservative=False,touch=False):
# (str, str, bool) -> None
'''Write data lazily in filename location.
import cPickle as pickle
import os, sys
def parallel_loop(f,source):
pidlist = range(NTHREADS)
Note:
If convervative is set, we don't overwrite.
'''
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)
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
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
else:
return [os.path.abspath(os.path.join(directory, f)) for f in l_filename]
os.close(w)
r[thread_id] = os.fdopen(r[thread_id],'r')
pidlist[thread_id] = fork
thread_id = 0
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
result = []
for filename, text in src[thread_id]:
result.append( (filename, f(filename,text)) )
result.sort()
# ~#~#~#~#~#
# L i s t
# ~#~#~#~#~#
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
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)
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))
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"

685
src/variable.py Normal file
View File

@ -0,0 +1,685 @@
#!/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
for line in variables['e_loc'].parents:
print line

86
src/variables.py Normal file
View File

@ -0,0 +1,86 @@
#!/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)
result[v.name] = v
for other in v.others:
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

View File

@ -1 +1 @@
version = "2.0.0"
version = "1.6.7"

View File

@ -39,7 +39,7 @@ def install():
file.close()
if not os.access(VIM+"/syntax",os.F_OK):
os.mkdir(VIM+"/syntax")
wd = os.path.abspath(os.path.dirname(__file__))
wd = os.path.abspath(os.path.dirname(__file__))+"/../vim"
os.symlink(wd+"/irpf90.vim",VIM+"/syntax/irpf90.vim")
except:
pass

View File

@ -373,120 +373,4 @@ map K :call ReadMan()<CR>
set equalprg=irpf90_indent
if exists('g:no_irpf90_conceal') || !has('conceal') || &enc != 'utf-8'
finish
endif
syntax match irpf90NiceOperator "<-" conceal cchar=
iab<-
syntax match irpf90NiceOperator "->" conceal cchar=
iab->
syntax match irpf90NiceOperator "==" conceal cchar=
iab==
syntax match irpf90NiceOperator "\.eq\." conceal cchar=
syntax match irpf90NiceOperator "/=" conceal cchar=
iab ≠ /=
syntax match irpf90NiceOperator "\.ne\." conceal cchar=
syntax match irpf90NiceOperator "\.or\." conceal cchar=
iab .or.
syntax match irpf90NiceOperator "\.and\." conceal cchar=
iab ∧ .and.
syntax match irpf90NiceOperator "*" conceal cchar=×
iab × *
let s:extraConceal = 1
" Some windows font don't support some of the characters,
" so if they are the main font, we don't load them :)
if has("win32")
let s:incompleteFont = [ 'Consolas'
\ , 'Lucida Console'
\ , 'Courier New'
\ ]
let s:mainfont = substitute( &guifont, '^\([^:,]\+\).*', '\1', '')
for s:fontName in s:incompleteFont
if s:mainfont ==? s:fontName
let s:extraConceal = 0
break
endif
endfor
endif
if s:extraConceal
syntax match irpf90NiceOperator "<=" conceal cchar=
syntax match irpf90NiceOperator "\.le\." conceal cchar=
iab<=
syntax match irpf90NiceOperator ">=" conceal cchar=
syntax match irpf90NiceOperator "\.ge\." conceal cchar=
iab>=
syntax match irpf90NiceOperator "\.lt\." conceal cchar=<
syntax match irpf90NiceOperator "\.gt\." conceal cchar=>
syntax match irpf90NiceOperator "=>" conceal cchar=
iab=>
syntax match irpf90NiceOperator "\:\:" conceal cchar=
iab ∷ ::
syntax match irpf90NiceOperator "++" conceal cchar=
iab++
syntax match irpf90NiceOperator "\<lapl_" conceal cchar=Δ
syntax match irpf90NiceOperator "\C\<Delta\>" conceal cchar=Δ
iab Δ Delta
syntax match irpf90NiceOperator "\C\<Lambda\>" conceal cchar=Λ
iab Λ Lambda
syntax match irpf90NiceOperator "\C\<Pi\>" conceal cchar=Π
iab Π Pi
syntax match irpf90NiceOperator "\C\<Sigma\>" conceal cchar=Σ
iab Σ Sigma
syntax match irpf90NiceOperator "\C\<Psi\>" conceal cchar=Ψ
iab Ψ Psi
syntax match irpf90NiceOperator "\C\<Omega\>" conceal cchar=Ω
iab Ω Omega
syntax match irpf90NiceOperator "\C\<alpha\>" conceal cchar=α
iab α alpha
syntax match irpf90NiceOperator "\C\<beta\>" conceal cchar=β
iab β beta
syntax match irpf90NiceOperator "\C\<gamma\>" conceal cchar=γ
iab γ gamma
syntax match irpf90NiceOperator "\C\<delta\>" conceal cchar=δ
iab δ delta
syntax match irpf90NiceOperator "\C\<epsilon\>" conceal cchar=ε
iab ε epsilon
syntax match irpf90NiceOperator "\C\<zeta\>" conceal cchar=ζ
iab ζ zeta
syntax match irpf90NiceOperator "\C\<theta\>" conceal cchar=θ
iab θ theta
syntax match irpf90NiceOperator "\C\<eta\>" conceal cchar=η
iab η eta
syntax match irpf90NiceOperator "\C\<lambda\>" conceal cchar=λ
iab λ lambda
syntax match irpf90NiceOperator "\C\<mu\>" conceal cchar=μ
iab μ mu
syntax match irpf90NiceOperator "\C\<nu\>" conceal cchar=ν
iab ν nu
syntax match irpf90NiceOperator "\C\<pi\>" conceal cchar=π
iab π pi
syntax match irpf90NiceOperator "\C\<rho\>" conceal cchar=ρ
iab ρ rho
syntax match irpf90NiceOperator "\C\<sigma\>" conceal cchar=σ
iab σ sigma
syntax match irpf90NiceOperator "\C\<tau\>" conceal cchar=τ
iab τ tau
syntax match irpf90NiceOperator "\C\<phi\>" conceal cchar=φ
iab φ phi
syntax match irpf90NiceOperator "\C\<nabla\>" conceal cchar=
iabnabla
syntax match irpf90NiceOperator "\C\<grad_" conceal cchar=
iabgrad_o
syntax match irpf90NiceOperator "\C\<chi\>" conceal cchar=χ
iab χ chi
syntax match irpf90NiceOperator "\C\<psi\>" conceal cchar=ψ
iab ψ psi
syntax match irpf90NiceOperator "\C\<omega\>" conceal cchar=ω
iab ω omega
endif
hi link irpf90NiceOperator Operator
hi! link Conceal Operator
setlocal conceallevel=2
" vim: set fenc=utf-8:
" vim: ts=8 tw=132