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:
parent
4674d7e0ab
commit
e6b6a35585
@ -14,10 +14,6 @@ Dependencies
|
||||
Installing IRPF90
|
||||
-----------------
|
||||
|
||||
``pip install irpf90``
|
||||
|
||||
or
|
||||
|
||||
``${IRPF90_HOME}`` is the location of your irpf90 directory::
|
||||
|
||||
``` bash
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
280
pip/LICENSE.txt
280
pip/LICENSE.txt
@ -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
|
@ -1,2 +0,0 @@
|
||||
include irpf90 README.md irpman irp_indent
|
||||
|
@ -1 +0,0 @@
|
||||
../src
|
@ -1,2 +0,0 @@
|
||||
[metadata]
|
||||
description-file = README.md
|
16
pip/setup.py
16
pip/setup.py
@ -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"],
|
||||
)
|
||||
|
@ -1,3 +0,0 @@
|
||||
[style]
|
||||
based_on_style = pep8
|
||||
COLUMN_LIMIT = 100
|
14
src/Makefile
14
src/Makefile
@ -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
|
||||
|
@ -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
73
src/checkpoint.py
Normal 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()
|
||||
|
@ -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()
|
||||
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
726
src/entity.py
726
src/entity.py
@ -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
68
pip/irpman → src/error.py
Executable file → Normal 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
89
src/init.py
Normal 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
|
||||
|
@ -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()
|
||||
|
||||
|
||||
|
131
src/irpf90.py
131
src/irpf90.py
@ -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()
|
||||
|
||||
|
408
src/irpf90_t.py
408
src/irpf90_t.py
@ -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, ), {})
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
160
src/lib_irpy.py
160
src/lib_irpy.py
@ -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
34
pip/irpf90_indent → src/locks.py
Executable file → Normal 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
204
src/makefile.py
Normal 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()
|
||||
|
394
src/module.py
394
src/module.py
@ -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
68
src/modules.py
Normal 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
408
src/ninja.py
Normal 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
|
||||
|
||||
|
@ -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
@ -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()
|
||||
|
@ -47,7 +47,7 @@ re_decl = re.compile( "".join( [ r"^\ *",
|
||||
r"|external *(::)?",
|
||||
r"|equivalence *(::)?",
|
||||
r"|type",
|
||||
r"|endtype",
|
||||
r"|end ?type",
|
||||
r")[^=(]"
|
||||
] ) )
|
||||
|
||||
|
104
src/routine.py
104
src/routine.py
@ -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
131
src/subroutine.py
Normal 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
72
src/subroutines.py
Normal 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
|
@ -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()
|
||||
|
||||
|
413
src/util.py
413
src/util.py
@ -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
685
src/variable.py
Normal 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
86
src/variables.py
Normal 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
|
@ -1 +1 @@
|
||||
version = "2.0.0"
|
||||
version = "1.6.7"
|
||||
|
@ -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
|
||||
|
@ -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=∇
|
||||
iab ∇ nabla
|
||||
syntax match irpf90NiceOperator "\C\<grad_" conceal cchar=∇
|
||||
iab ∇ grad_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
|
||||
|
Loading…
Reference in New Issue
Block a user