diff --git a/Makefile b/Makefile index 97732c1..9456ea8 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ src: $(MAKE) -C $@ man: - - $(MAKE) -C $@ + - $(MAKE) -C $@ &> /dev/null all: src man diff --git a/src/checkpoint.py b/src/checkpoint.py new file mode 100644 index 0000000..9a8358a --- /dev/null +++ b/src/checkpoint.py @@ -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() + diff --git a/src/command_line.py b/src/command_line.py index d55515d..59e3185 100644 --- a/src/command_line.py +++ b/src/command_line.py @@ -256,6 +256,7 @@ def print_options(): description = p1.communicate(description)[0] description = description.replace('\n','\n'.ljust(27)) print ("-%s, --%s"%(k,options[k][0])).ljust(25), description+'\n' + print "\n" if __name__ == '__main__': print_options() diff --git a/src/cython_setup.py b/src/cython_setup.py index ae6b6a3..6bb2e85 100755 --- a/src/cython_setup.py +++ b/src/cython_setup.py @@ -29,7 +29,7 @@ from distutils.extension import Extension from Cython.Distutils import build_ext import os -to_remove = """cython_setup.py command_line.py""".split() +to_remove = """cython_setup.py version.py command_line.py""".split() ext_modules = [] files = os.listdir('.') diff --git a/src/irp_stack.py b/src/irp_stack.py index ce238d8..295bfe7 100644 --- a/src/irp_stack.py +++ b/src/irp_stack.py @@ -31,6 +31,7 @@ from command_line import command_line do_assert = command_line.do_assert do_debug = command_line.do_debug do_openmp = command_line.do_openmp +do_memory = command_line.do_memory import irpf90_t @@ -53,34 +54,45 @@ subroutine irp_enter(irp_where) use irp_stack_mod integer :: ithread character*(*) :: irp_where -!$ integer, external :: omp_get_thread_num -!$ integer, external :: omp_get_num_threads - ithread = 0 -!$ ithread = omp_get_thread_num() -$1 """ - - if not command_line.do_openmp: + if do_openmp: txt += """ + integer, external :: omp_get_thread_num + integer, external :: omp_get_num_threads + ithread = omp_get_thread_num() if (ithread /= 0) then print *, 'Error: Provider is called by thread', ithread call irp_trace stop 1 endif +""" + else: + txt += """ + ithread = 0 """ - if command_line.do_memory: - txt+=""" + txt += "$1" + + if do_memory: + txt+=""" if (.not.alloc) then - nthread = 1 +""" + if do_openmp: + txt += """ !$OMP PARALLEL !$OMP SINGLE - !$ nthread = omp_get_num_threads() + nthread = omp_get_num_threads() !$OMP END SINGLE !$OMP END PARALLEL - print *, 'Allocating irp_stack(',STACKMAX,',',nthread,')' - print *, 'Allocating irp_cpu(',STACKMAX,',',nthread,')' - print *, 'Allocating stack_index(',nthread,')' +""" + else: + txt += """ + nthread = 1 + """ + txt += """ + print *, 'Allocating irp_stack(',STACKMAX,',',nthread,')' + print *, 'Allocating irp_cpu(',STACKMAX,',',nthread,')' + print *, 'Allocating stack_index(',nthread,')' endif""" txt +=""" $2 @@ -90,25 +102,41 @@ subroutine irp_enter_f(irp_where) use irp_stack_mod integer :: ithread character*(*) :: irp_where -!$ integer, external :: omp_get_thread_num -!$ integer, external :: omp_get_num_threads - ithread = 0 -!$ ithread = omp_get_thread_num() + """ + if do_openmp: + txt += """ + integer, external :: omp_get_thread_num + integer, external :: omp_get_num_threads + ithread = omp_get_thread_num() +""" + else: + txt += """ + ithread = 0 +""" + txt += """ $1 """ - if command_line.do_memory: - txt+=""" + if do_memory: + txt+=""" if (.not.alloc) then +""" + if do_openmp: + txt += """ !$OMP PARALLEL !$OMP SINGLE - !$ nthread = omp_get_num_threads() + nthread = omp_get_num_threads() + !$OMP END SINGLE + !$OMP END PARALLEL +""" + else: + txt += """ + nthread = 1 +""" + txt +=""" print *, 'Allocating irp_stack(',STACKMAX,',',nthread,')' print *, 'Allocating irp_cpu(',STACKMAX,',',nthread,')' print *, 'Allocating stack_index(',nthread,')' - !$OMP END SINGLE - !$OMP END PARALLEL - endif""" - txt +=""" + endif $2 end subroutine @@ -117,9 +145,17 @@ subroutine irp_leave (irp_where) character*(*) :: irp_where integer :: ithread double precision :: cpu -!$ integer, external :: omp_get_thread_num +""" + if do_openmp: + txt += """ + integer, external :: omp_get_thread_num + ithread = omp_get_thread_num() + """ + else: + txt += """ ithread = 0 -!$ ithread = omp_get_thread_num() + """ + txt += """ $3 $4 end subroutine @@ -127,32 +163,49 @@ end subroutine # $1 if do_assert or do_debug: - txt = txt.replace("$1",""" + s = """ if (.not.alloc) then + """ + if do_openmp: + s += """ !$OMP PARALLEL !$OMP SINGLE - !$ nthread = omp_get_num_threads() + nthread = omp_get_num_threads() !$OMP END SINGLE !$OMP END PARALLEL !$OMP CRITICAL if (.not.alloc) then - allocate(irp_stack(0:STACKMAX,nthread+1)) - allocate(irp_cpu(0:STACKMAX,nthread+1)) - allocate(stack_index(nthread+1)) + 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+1) = mod(stack_index(ithread+1)+1,STACKMAX) - irp_stack(stack_index(ithread+1),ithread+1) = irp_where""") - if command_line.do_memory: + irp_stack(stack_index(ithread+1),ithread+1) = irp_where""" + else: + s += """ + nthread = 1 + if (.not.alloc) then + allocate(irp_stack(0:STACKMAX,1)) + allocate(irp_cpu(0:STACKMAX,1)) + allocate(stack_index(2)) + stack_index = 0 + alloc = .True. + endif + endif + stack_index(1) = mod(stack_index(1)+1,STACKMAX) + irp_stack(stack_index(1),1) = irp_where""" + if do_memory: txt+=""" print *, 'Allocating irp_stack(',STACKMAX,','nthread,')' print *, 'Allocating irp_cpu(',STACKMAX,','nthread,')' print *, 'Allocating stack_index(',nthread,')'""" else: - txt = txt.replace("$1","") + s = "" + txt = txt.replace("$1",s) # $2 if do_debug: @@ -184,9 +237,17 @@ subroutine irp_trace use irp_stack_mod integer :: ithread integer :: i +""" + if do_openmp: + txt += """ !$ integer, external :: omp_get_thread_num - ithread = 0 !$ ithread = omp_get_thread_num() +""" + else: + txt += """ + ithread = 0 +""" + txt += """ if (.not.alloc) return print *, 'Stack trace: ', ithread print *, '-------------------------' diff --git a/src/irpf90.py b/src/irpf90.py index 528289c..ada860f 100644 --- a/src/irpf90.py +++ b/src/irpf90.py @@ -100,6 +100,9 @@ def main(): import touches touches.create() + import checkpoint + checkpoint.create() + import create_man create_man.run() diff --git a/src/makefile.py b/src/makefile.py index cfc55e8..d1ce7eb 100644 --- a/src/makefile.py +++ b/src/makefile.py @@ -91,6 +91,7 @@ def run(): 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: @@ -107,7 +108,7 @@ def run(): 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, "OBJ1 = $(OBJ_IRP) $(OBJ) %sirp_touches.irp.o %sirp_checkpoint.irp.o"%(irpdir,irpdir), if command_line.do_profile: print >>file, " %sirp_profile.irp.o"%(irpdir), " irp_rdtsc.o", if command_line.do_codelet: @@ -150,7 +151,7 @@ def run(): 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: $(OBJ) "%(irpdir), + print >>file, "%sirp_touches.irp.o %sirp_checkpoint.irp.o: $(OBJ) "%(irpdir,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) @@ -162,33 +163,6 @@ def run(): print >>file," ".join(mds) -# print >>file, "%sdist_Makefile:"%(irpdir) -# print >>file, "\t- @echo FC=$(FC) > %sdist_Makefile"%(irpdir) -# print >>file, "\t- @echo FCFLAGS=$(FCFLAGS) >> %sdist_Makefile"%(irpdir) -# print >>file, "\t- @echo LIB=$(LIB) >> %sdist_Makefile"%(irpdir) -# print >>file, "\t- @echo .DEFAULT_GOAL: exe >> %sdist_Makefile"%(irpdir) -# print >>file, "\t- @echo 'exe: $$(EXE).irp.F90 $(OBJ_IRP) $(OBJ) irp_touches.irp.o' >> %sdist_Makefile"%(irpdir) -# print >>file, "\t- @echo '\t$$(FC) -o $$(EXE) $$(EXE).irp.F90 $(OBJ_IRP) $(OBJ) irp_touches.irp.o $$(LIB)' >> %sdist_Makefile"%(irpdir) -# print >>file, "\t- @echo '%%.o: %%.F90' >> %sdist_Makefile"%(irpdir) -# print >>file, "\t- @echo '\t$$(FC) $$(FCFLAGS) -c $$*.F90 -o $$*.o' >> %sdist_Makefile"%(irpdir) -# print >>file, "\t- @echo 'clean:' >> %sdist_Makefile"%(irpdir) -# print >>file, "\t- @echo '\trm *.o *.mod $$(EXE) 2>/dev/null' >> %sdist_Makefile"%(irpdir) -# print >>file, buffer -# print >>file, "\t- @echo '\tirp_touches.irp.o: irp_touches.irp.F90 $(OBJ_IRP) $(OBJ) >> %sdist_Makefile"%(irpdir) - -# print >>file, "%%.dist: %sdist_Makefile"%(irpdir) -# print >>file, "\t- @mkdir -p dist/$*| DO_NOTHING=" -# print >>file, "\t- @cp %s* dist/$*/| DO_NOTHING="%(irpdir) -# print >>file, "\t- @for i in $(ALL) $(OBJ) irp_touches.irp.o $(ALL_OBJ); do rm dist/$*/$$i ; done| DO_NOTHING=" -# print >>file, "\t- @for i in $(ALL) ; do rm dist/$*/$$i.irp.F90 ; done| DO_NOTHING=" -# print >>file, "\t- @rm dist/$*/{*.irp.f,*.mod,irpf90_entities}| DO_NOTHING=" -# print >>file, "\t- @rm dist/$*/*.mod 2>/dev/null| DO_NOTHING=" -# print >>file, "\t- @echo 'EXE = $*' > dist/$*/Makefile| DO_NOTHING=" -# print >>file, "\t- @cat dist/$*/dist_Makefile >> dist/$*/Makefile| DO_NOTHING=" -# print >>file, "\t- @rm dist/$*/dist_Makefile| DO_NOTHING=" -# print >>file, "\t- @cp %s$*.irp.F90 dist/$*/| DO_NOTHING="%(irpdir) -# print >>file, "\t- cd dist ; tar -zcvf ../$*.tar.gz $*\n" - 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" diff --git a/src/preprocessed_text.py b/src/preprocessed_text.py index b7a4bf8..ec7575a 100644 --- a/src/preprocessed_text.py +++ b/src/preprocessed_text.py @@ -522,6 +522,8 @@ def irp_simple_statements(text): def process_assert(line): assert type(line) == Assert if command_line.do_assert: + if '(' not in line.text or ')' not in line.text: + error.fail(line,"Syntax error in ASSERT statement (parentheses)") condition = "(%s"%(line.text.split('(',1)[1]) if condition == "": error.fail(line,"Error in Assert statement") diff --git a/src/profile.py b/src/profile.py index 9f66708..7ff7fe4 100644 --- a/src/profile.py +++ b/src/profile.py @@ -136,8 +136,8 @@ subroutine irp_print_timer() call profile_sort() print '(A24,A8,A17,A20,A13,A20)', '', 'N.Calls', 'Tot Cycles', 'Avg Cycles', & 'Tot Secs', 'Avg Secs' - print '(A)', '----------------------------------------------'// & - '----------------------------------------------' + print '(A)', '---------------------------------------------------'// & + '---------------------------------------------------' do ii=1,%(n)d i = irp_order(ii) if (irp_profile(3,i) > 0.) then diff --git a/src/util.py b/src/util.py index 0c81577..b03a50b 100644 --- a/src/util.py +++ b/src/util.py @@ -110,9 +110,9 @@ def dimsize(x): if b0.replace('-','').isdigit(): size = "%s - (%d)"%(b1,int(b0)-1) elif b1.replace('-','').isdigit(): - size = "%d - %s"%(int(b1)+1,b0) + size = "%d - (%s)"%(int(b1)+1,b0) else: - size = "%s - %s + 1"%(b1,b0) + size = "%s - (%s) + 1"%(b1,b0) return size def put_info(text,filename): diff --git a/src/variable.py b/src/variable.py index bf462b2..56a61a8 100644 --- a/src/variable.py +++ b/src/variable.py @@ -464,17 +464,6 @@ class Variable(object): name = self.name same_as = self.same_as - def check_openmp(): - if not command_line.do_openmp: - result = [ "!$ nthreads = omp_get_num_threads()" , - "!$ if (nthreads > 1) then" , - "!$ print *, irp_here//': Error: Provider in an openMP section'" , - "!$ stop 1", - "!$ endif" ] - else: - result = [] - return result - def build_alloc(name): self = variables[name] if self.dim == []: @@ -547,7 +536,8 @@ class Variable(object): result += [ "!DEC$ ATTRIBUTES FORCEINLINE :: provide_%s"%(name) ] result += [ "subroutine provide_%s"%(name) ] result += build_use( [same_as]+self.to_provide ) - result += ["!$ use omp_lib"] + if command_line.do_openmp: + result += [" use omp_lib"] result.append(" implicit none") length = len("provide_%s"%(name)) result += [\ @@ -557,8 +547,6 @@ class Variable(object): "!$ integer :: nthreads"] if command_line.do_openmp: result.append(" call irp_lock_%s(.True.)"%(same_as)) - else: - result += check_openmp() if command_line.do_assert or command_line.do_debug: result.append(" call irp_enter(irp_here)") result += call_provides(self.to_provide) diff --git a/src/version.py b/src/version.py index e3a0f01..38ec8ed 100644 --- a/src/version.py +++ b/src/version.py @@ -1 +1 @@ -version = "1.5.0" +version = "1.6.0"