diff --git a/src/command_line.py b/src/command_line.py index 8186cd0..dbabc7d 100644 --- a/src/command_line.py +++ b/src/command_line.py @@ -37,6 +37,8 @@ options['h'] = [ 'help' , 'Print this help', 0 ] options['i'] = [ 'init' , 'Initialize current directory', 0 ] options['D'] = [ 'define' , 'Define variable', 1 ] options['p'] = [ 'preprocess' , 'Preprocess file', 1 ] +options['o'] = [ 'openmp' , 'Auto-parallelization', 0 ] +options['m'] = [ 'memory' , 'Debug memory', 0 ] class CommandLine(object): diff --git a/src/irp_stack.py b/src/irp_stack.py index 0e41af7..b12ca6c 100644 --- a/src/irp_stack.py +++ b/src/irp_stack.py @@ -30,6 +30,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 import irpf90_t @@ -52,8 +53,9 @@ subroutine irp_enter(irp_where) integer :: ithread integer :: nthread character*(*) :: irp_where - ithread = 0 - nthread = 1 +$OMP_DECL + ithread = $OMP_GET_THREAD_NUM + nthread = $OMP_GET_NUM_THREADS $1 $2 end subroutine @@ -63,12 +65,26 @@ subroutine irp_leave (irp_where) character*(*) :: irp_where integer :: ithread double precision :: cpu - ithread = 0 +$OMP_DECL + ithread = $OMP_GET_THREAD_NUM $3 $4 end subroutine """ + # $OMP_DECL + if do_openmp: + txt = txt.replace("$OMP_DECL",""" + integer :: omp_get_num_threads + integer :: omp_get_thread_num +""") + txt = txt.replace("$OMP_GET_NUM_THREADS","omp_get_num_threads()") + txt = txt.replace("$OMP_GET_THREAD_NUM","omp_get_thread_num()") + else: + txt = txt.replace("$OMP_DECL","") + txt = txt.replace("$OMP_GET_NUM_THREADS","1") + txt = txt.replace("$OMP_GET_THREAD_NUM","0") + # $1 if do_assert or do_debug: txt = txt.replace("$1",""" @@ -82,6 +98,11 @@ end subroutine !$OMP END CRITICAL stack_index(ithread+1) = stack_index(ithread+1)+1 irp_stack(stack_index(ithread+1),ithread+1) = irp_where""") + if command_line.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","") diff --git a/src/module.py b/src/module.py index bf7e010..4cfc6da 100644 --- a/src/module.py +++ b/src/module.py @@ -28,6 +28,7 @@ from irpf90_t import * from variable import * from variables import variables +from command_line import command_line import preprocessed_text from util import * @@ -169,11 +170,16 @@ class Fmodule(object): result = map(lambda x: x[1], result) result = map(lambda x: x.text, result) if self.is_main: - result = [ \ - "program irp_program", - " call %s"%(self.prog_name), - "end program", - ] + result + temp = [ "program irp_program" ] + if command_line.do_openmp: + temp += [ "!$OMP PARALLEL" ] + temp += [ "!$OMP MASTER" ] + temp += [ " call %s"%(self.prog_name) ] + if command_line.do_openmp: + temp += [ "!$OMP END MASTER" ] + temp += [ "!$OMP END PARALLEL" ] + temp += [ "end program" ] + result = temp + result self._residual_text = result return self._residual_text residual_text = property(residual_text) diff --git a/src/variable.py b/src/variable.py index 4867444..d799e35 100644 --- a/src/variable.py +++ b/src/variable.py @@ -352,10 +352,17 @@ class Variable(object): result = [ "!","! >>> FREE %s"%(self.name), " %s_is_built = .False."%(self.same_as) ] if self.dim != []: - result += [ \ - " if (allocated(%s)) then"%(name), - " deallocate (%s)"%(name), - " endif" ] + 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 @@ -398,6 +405,9 @@ class Variable(object): def do_allocate(): result = " allocate(%s(%s),stat=irp_err)" result = result%(name,','.join(self.dim)) + if command_line.do_memory: + tmp = "\n print *, 'Allocating %s(%s)'" + result += tmp%(name,','.join(self.dim)) return result result = [ " if (allocated (%s) ) then"%(name) ] @@ -405,6 +415,9 @@ class Variable(object): result += [\ " if (.not.irp_dimensions_OK) then", " deallocate(%s)"%(name) ] + if command_line.do_memory: + result += [\ + " print *, 'Deallocating %s'"%(name) ] result.append(check_dimensions()) result.append(do_allocate()) result += [\ @@ -438,10 +451,14 @@ class Variable(object): result.append(" call irp_enter(irp_here)") result += call_provides(self.to_provide) result += flatten( map(build_alloc,[self.same_as]+self.others) ) - result += [\ - " call bld_%s"%(same_as), - " %s_is_built = .True."%(same_as), - "" ] + if command_line.do_openmp: + result += [ "!$OMP CRITICAL (%s_critical)"%(same_as) ] + result += [ " if (.not.%s_is_built) then"%(same_as) ] + result += [ " call bld_%s"%(same_as) ] + result += [ " %s_is_built = .True."%(same_as), "" ] + if command_line.do_openmp: + result += [ " endif" ] + result += [ "!$OMP END CRITICAL (%s_critical)"%(same_as) ] if command_line.do_assert or command_line.do_debug: result.append(" call irp_leave(irp_here)") result.append("end subroutine provide_%s"%(name) ) diff --git a/src/variables.py b/src/variables.py index 624ce7f..dd48d4d 100644 --- a/src/variables.py +++ b/src/variables.py @@ -27,6 +27,7 @@ from variable import * from irpf90_t import * +from command_line import command_line from util import * ###################################################################### @@ -65,11 +66,27 @@ def call_provides(vars,opt=False): all_children = flatten( map(lambda x: variables[x].children, vars )) vars = filter(lambda x: x not in all_children,vars) def fun(x): - return [ \ + if command_line.do_openmp: + result = [ "!$OMP TASK" ] + else: + result = [] + result += [ \ " if (.not.%s_is_built) then"%(x), " call provide_%s"%(x), " endif" ] - return flatten ( map (fun, vars) ) + if command_line.do_openmp: + result += [ "!$OMP END TASK" ] + return result + + result = flatten ( map (fun, vars) ) + if command_line.do_openmp and result != []: + result.reverse() + result.remove("!$OMP TASK") + result.remove("!$OMP END TASK") + result.reverse() + if "!$OMP TASK" in result: + result += [ "!$OMP TASKWAIT" ] + return result ###################################################################### if __name__ == '__main__':