mirror of
https://gitlab.com/scemama/irpf90.git
synced 2025-01-03 01:55:42 +01:00
Add ashe and // support
This commit is contained in:
parent
f1ce16195f
commit
598587bcf3
2602
src/ashes.py
Normal file
2602
src/ashes.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -54,6 +54,7 @@ options['p'] = [ 'preprocess' , 'Prints a preprocessed file to standard output
|
||||
options['r'] = [ 'no_directives', 'Ignore all compiler directives !DEC$ and !DIR$', 0 ]
|
||||
options['s'] = [ 'substitute' , 'Substitute values in do loops for generating specific optimized code.', 1 ]
|
||||
options['t'] = [ 'touch' , 'Display which entities are touched when touching the variable given as an argument.', 1 ]
|
||||
options['T'] = [ 'Task' , 'Auto-parallelism ', 0 ]
|
||||
options['v'] = [ 'version' , 'Prints version of irpf90', 0 ]
|
||||
options['w'] = [ 'warnings' , 'Activate Warnings', 0 ]
|
||||
options['z'] = [ 'openmp' , 'Activate for OpenMP code', 0 ]
|
||||
|
246
src/entity.py
246
src/entity.py
@ -501,8 +501,146 @@ class Entity(object):
|
||||
if not self.is_main:
|
||||
return []
|
||||
|
||||
from ashes import AshesEnv
|
||||
template = '''
|
||||
{#l_allocate}
|
||||
{subroutine|s}
|
||||
{/l_allocate}
|
||||
|
||||
{?inline}
|
||||
!DEC$ ATTRIBUTES FORCEINLINE :: provide_{name}
|
||||
{/inline}
|
||||
subroutine provide_{name}
|
||||
|
||||
{?do_openmp}
|
||||
use omp_lib
|
||||
{/do_openmp}
|
||||
|
||||
{#l_module}
|
||||
{name}
|
||||
{/l_module}
|
||||
|
||||
implicit none
|
||||
character*(8+{@size key=name/}),parameter :: irp_here = 'provide_{name}'
|
||||
|
||||
{?do_openmp}
|
||||
call irp_lock_{name}(.True.)
|
||||
{/do_openmp}
|
||||
|
||||
{?do_debug}
|
||||
call irp_enter(irp_here)
|
||||
{/do_debug}
|
||||
|
||||
{#l_children}
|
||||
if (.NOT.{name}_is_built) then
|
||||
call provide_{name}
|
||||
endif
|
||||
{/l_children}
|
||||
|
||||
{#do_task}
|
||||
!$omp task default(shared) {depend}
|
||||
{/do_task}
|
||||
|
||||
{#l_allocate}
|
||||
call allocate_{name}
|
||||
{/l_allocate}
|
||||
call bld_{name}
|
||||
|
||||
{#do_task}
|
||||
!$omp end task
|
||||
{/do_task}
|
||||
|
||||
{name}_is_built = .TRUE.
|
||||
|
||||
{?do_openmp}
|
||||
call irp_lock_{name}(.False.)
|
||||
{/do_openmp}
|
||||
|
||||
{?do_debug}
|
||||
call irp_leave(irp_here)
|
||||
{/do_debug}
|
||||
|
||||
end subroutine provide_{name}
|
||||
'''
|
||||
from util import mangled
|
||||
|
||||
name = self.name
|
||||
same_as = self.same_as
|
||||
var = self.d_entity[name]
|
||||
l_module = [ {'name':x} for x in build_use([self.name] + self.to_provide, self.d_entity)]
|
||||
l_allocate = [ {'name':n, 'subroutine':self.build_alloc(n)} for n in self.l_name if self.d_entity[n].dim]
|
||||
l_children = [ {'name':x} for x in mangled(self.to_provide, self.d_entity) ]
|
||||
|
||||
in_ = ['depend(in: %s)' % n for n in self.to_provide]
|
||||
out_ = ['depend(out: %s)' % n for n in self.l_name]
|
||||
do_task = [ {'depend':' '.join(in_ + out_) } ] if command_line.do_Task else []
|
||||
|
||||
ashes_env = AshesEnv()
|
||||
ashes_env.register_source('provide',template)
|
||||
|
||||
l = ashes_env.render('provide', {'name': name,
|
||||
'l_module':l_module,
|
||||
'l_allocate':l_allocate,
|
||||
'l_children':l_children,
|
||||
'do_debug':command_line.do_debug,
|
||||
'do_openmp':command_line.do_openmp,
|
||||
'do_task':do_task})
|
||||
|
||||
return l.split('\n')
|
||||
|
||||
def build_alloc(self,name):
|
||||
var = self.d_entity[name]
|
||||
from ashes import AshesEnv
|
||||
template = ("""
|
||||
|
||||
subroutine allocate_{name}
|
||||
|
||||
{#l_module}
|
||||
{name}
|
||||
{/l_module}
|
||||
|
||||
character*(9+{@size key=name/}),parameter :: irp_here = 'allocate_{name}'
|
||||
integer :: irp_err
|
||||
|
||||
if ( allocated({name}) .AND.( &
|
||||
{#l_dim}
|
||||
( SIZE({name},{rank}) /= {value} ) {@sep}.OR.{/sep} &
|
||||
{/l_dim}
|
||||
)) then
|
||||
|
||||
{?do_memory}
|
||||
print *, irp_here//': Deallocated {name}'
|
||||
{/do_memory}
|
||||
|
||||
deallocate( {name}, stat=irp_err )
|
||||
|
||||
if (irp_err /= 0) then
|
||||
print *, irp_here//': Deallocation failed: {name}'
|
||||
print *,' size: {dim}'
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
if ( .NOT. allocated({name}) ) then
|
||||
|
||||
{?do_memory}
|
||||
print *, irp_here//': Allocate {name} ({dim})'
|
||||
{/do_memory}
|
||||
|
||||
{^corray}
|
||||
allocate({name} ({dim}), stat=irp_err)
|
||||
{:else}
|
||||
allocate({name} ({dim}[*]), stat=irp_err)
|
||||
{/corray}
|
||||
if (irp_err /= 0) then
|
||||
print *, irp_here//': Allocation failed: {name}'
|
||||
print *,' size: {dim}'
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
end subroutine
|
||||
|
||||
""")
|
||||
|
||||
def dimsize(x):
|
||||
# (str) -> str
|
||||
@ -515,7 +653,6 @@ class Entity(object):
|
||||
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:
|
||||
@ -524,105 +661,20 @@ class Entity(object):
|
||||
size = "(%d) - (%s)" % (int(b1) + 1, b0)
|
||||
else:
|
||||
size = "(%s) - (%s) + 1" % (b1, b0)
|
||||
|
||||
return size
|
||||
|
||||
def build_alloc(name):
|
||||
l_dim = [{'name':name, 'rank':i+1, 'value':dimsize(k)} for i, k in enumerate(var.dim)]
|
||||
l_module = [ {'name':x} for x in build_use([var.name] + var.needs, self.d_entity) ]
|
||||
|
||||
var = self.d_entity[name]
|
||||
if var.dim == []:
|
||||
return []
|
||||
ashes_env = AshesEnv()
|
||||
ashes_env.register_source('hello',template)
|
||||
|
||||
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.l_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
|
||||
return ashes_env.render('hello', {'name': name,
|
||||
'dim':','.join(var.dim),
|
||||
'corray': command_line.coarray,
|
||||
'l_dim': l_dim,
|
||||
'l_module':l_module,
|
||||
'do_memory':command_line.do_memory})
|
||||
|
||||
##########################################################
|
||||
@irpy.lazy_property
|
||||
|
@ -667,6 +667,11 @@ def irp_simple_statements(text):
|
||||
assert type(line) == Program
|
||||
program_name = line.lower.split()[1]
|
||||
temp = [Program(0, "program irp_program", program_name)]
|
||||
|
||||
if command_line.do_Task:
|
||||
for i in [" call omp_set_nested(.TRUE.)", "!$omp parallel", "!$omp single"]:
|
||||
temp += [Simple_line(0, i, line.filename)]
|
||||
|
||||
if command_line.do_profile:
|
||||
temp += [Simple_line(0, "call irp_init_timer()", line.filename)]
|
||||
if command_line.do_openmp:
|
||||
@ -676,10 +681,16 @@ def irp_simple_statements(text):
|
||||
temp += [Simple_line(0, "call irp_print_timer()", line.filename)]
|
||||
|
||||
temp += [Simple_line(0, " call irp_finalize_%s()" % (irp_id), line.filename)]
|
||||
|
||||
if command_line.do_Task:
|
||||
for i in ["!$omp taskwait","!$omp end single", "!$omp end parallel"]:
|
||||
temp += [Simple_line(0, i, line.filename)]
|
||||
|
||||
temp += [End(0, "end program", line.filename)]
|
||||
|
||||
result = temp + process_subroutine(
|
||||
Subroutine(line.i, "subroutine %s" % (program_name, ), line.filename))
|
||||
|
||||
return result
|
||||
|
||||
d = {
|
||||
|
Loading…
Reference in New Issue
Block a user