# coding: utf-8
from sympy.core import Tuple
from sympy.utilities.iterables import iterable
from pyccel.ast.core import Module, Program
from pyccel.ast.core import Nil
from pyccel.ast.core import get_initial_value
from pyccel.ast.core import DottedName
from pyccel.ast.core import Variable, IndexedVariable, IndexedElement
from pyccel.ast.core import Assign, Declare, AugAssign
from pyccel.ast.core import Block, ParallelBlock
from pyccel.ast.core import Range, Tile, Tensor
from pyccel.ast.core import Comment
from pyccel.ast.core import AnnotatedComment
from pyccel.ast.core import EmptyLine
from pyccel.ast.core import Print
from pyccel.ast.core import Len
from pyccel.ast.core import Import
from pyccel.ast.core import For, ForIterator, While, With, If, Del
from pyccel.ast.core import FunctionDef, ClassDef
from pyccel.ast.core import ConstructorCall
from pyccel.ast.parallel.basic import Basic
##########################################################
# Base class for OpenACC
##########################################################
[docs]class ACC(Basic):
"""Base class for OpenACC."""
pass
##########################################################
##########################################################
# Basic Statements
##########################################################
[docs]class ACC_Parallel(ParallelBlock, ACC):
"""
ACC Parallel construct statement.
Examples
>>> from pyccel.parallel.openacc import ACC_Parallel
>>> from pyccel.parallel.openacc import ACC_NumThread
>>> from pyccel.parallel.openacc import ACC_Default
>>> from pyccel.ast.core import Variable, Assign, Block
>>> n = Variable('int', 'n')
>>> x = Variable('int', 'x')
>>> body = [Assign(x,2.*n + 1.), Assign(n, n + 1)]
>>> variables = [x,n]
>>> clauses = [ACC_NumThread(4), ACC_Default('shared')]
>>> ACC_Parallel(clauses, variables, body)
#pragma parallel num_threads(4) default(shared)
x := 1.0 + 2.0*n
n := 1 + n
"""
_prefix = '#pragma'
name = 'parallel'
def __new__(cls, clauses, variables, body):
if not iterable(clauses):
raise TypeError('Expecting an iterable for clauses')
_valid_clauses = (ACC_Async,
ACC_Wait,
ACC_NumGangs,
ACC_NumWorkers,
ACC_VectorLength,
ACC_DeviceType,
ACC_If,
ACC_Reduction,
ACC_Copy,
ACC_Copyin,
ACC_Copyout,
ACC_Create,
ACC_Present,
ACC_DevicePtr,
ACC_Private,
ACC_FirstPrivate,
ACC_Default)
for clause in clauses:
if not isinstance(clause, _valid_clauses):
raise TypeError('Wrong clause for ACC_Parallel')
return ParallelBlock.__new__(cls, clauses, variables, body)
[docs]class ACC_For(ForIterator, ACC):
"""
ACC Loop construct statement.
Examples
"""
_prefix = '#pragma'
name = 'do'
def __new__(cls, loop, clauses):
if not iterable(clauses):
raise TypeError('Expecting an iterable for clauses')
_valid_clauses = (ACC_Collapse,
ACC_Gang,
ACC_Worker,
ACC_Vector,
ACC_Seq,
ACC_Auto,
ACC_Tile,
ACC_DeviceType,
ACC_Independent,
ACC_Private,
ACC_Reduction)
for clause in clauses:
if not isinstance(clause, _valid_clauses):
raise TypeError('Wrong clause for ACC_For, '
'given {0}'.format(type(clause)))
return Basic.__new__(cls, loop, clauses)
@property
def loop(self):
return self._args[0]
@property
def clauses(self):
return self._args[1]
@property
def target(self):
return self.loop.target
@property
def iterable(self):
return self.loop.iterable
@property
def body(self):
return self.loop.body
#################################################
#################################################
# Clauses
#################################################
[docs]class ACC_Async(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Async
>>> ACC_Async('x', 'y')
async(x, y)
"""
name = 'async'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'async({})'.format(args)
[docs]class ACC_Auto(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Auto
>>> ACC_Auto()
auto
"""
name = 'auto'
def _sympystr(self, printer):
return 'auto'
[docs]class ACC_Bind(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Bind
>>> ACC_Bind('n')
bind(n)
"""
name = 'bind'
def __new__(cls, *args, **options):
if not(len(args) == 1):
raise ValueError('Expecting 1 entry, '
'given {0}'.format(len(args)))
variable = args[0]
return Basic.__new__(cls, variable)
@property
def variable(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
variable = '{0}'.format(sstr(self.variable))
return 'bind({0})'.format(variable)
[docs]class ACC_Collapse(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Collapse
>>> ACC_Collapse(2)
collapse(2)
"""
name = 'collapse'
def __new__(cls, *args, **options):
if not(len(args) == 1):
raise ValueError('Expecting 1 entry, '
'given {0}'.format(len(args)))
n = args[0]
return Basic.__new__(cls, n)
@property
def n_loops(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
n_loops = '{0}'.format(sstr(self.n_loops))
return 'collapse({0})'.format(n_loops)
[docs]class ACC_Copy(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Copy
>>> ACC_Copy('x', 'y')
copy(x, y)
"""
name = 'copy'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'copy({})'.format(args)
[docs]class ACC_Copyin(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Copyin
>>> ACC_Copyin('x', 'y')
copyin(x, y)
"""
name = 'copyin'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'copyin({})'.format(args)
[docs]class ACC_Copyout(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Copyout
>>> ACC_Copyout('x', 'y')
copyout(x, y)
"""
name = 'copyout'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'copyout({})'.format(args)
[docs]class ACC_Create(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Create
>>> ACC_Create('x', 'y')
create(x, y)
"""
name = 'create'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'create({})'.format(args)
[docs]class ACC_Default(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Default
>>> ACC_Default('present')
default(present)
"""
name = None
def __new__(cls, *args, **options):
status = args[0]
return Basic.__new__(cls, status)
@property
def status(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
status = self.status
if status:
status = sstr(self.status)
else:
status = ''
return 'default({})'.format(status)
[docs]class ACC_DefaultAsync(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_DefaultAsync
>>> ACC_DefaultAsync('x', 'y')
default_async(x, y)
"""
name = 'default_async'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'default_async({})'.format(args)
[docs]class ACC_Delete(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Delete
>>> ACC_Delete('x', 'y')
delete(x, y)
"""
name = 'delete'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'delete({})'.format(args)
[docs]class ACC_Device(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Device
>>> ACC_Device('x', 'y')
device(x, y)
"""
name = 'device'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'device({})'.format(args)
[docs]class ACC_DeviceNum(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_DeviceNum
>>> ACC_DeviceNum(2)
device_num(2)
"""
name = 'device_num'
def __new__(cls, *args, **options):
if not(len(args) == 1):
raise ValueError('Expecting 1 entry, '
'given {0}'.format(len(args)))
n = args[0]
return Basic.__new__(cls, n)
@property
def n_device(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
n_device = '{0}'.format(sstr(self.n_device))
return 'device_num({0})'.format(n_device)
[docs]class ACC_DevicePtr(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_DevicePtr
>>> ACC_DevicePtr('x', 'y')
deviceptr(x, y)
"""
name = 'deviceptr'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'deviceptr({})'.format(args)
[docs]class ACC_DeviceResident(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_DeviceResident
>>> ACC_DeviceResident('x', 'y')
device_resident(x, y)
"""
name = 'device_resident'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'device_resident({})'.format(args)
[docs]class ACC_DeviceType(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_DeviceType
>>> ACC_DeviceType('x', 'y')
device_type(x, y)
"""
name = 'device_type'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'device_type({})'.format(args)
[docs]class ACC_Finalize(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Finalize
>>> ACC_Finalize()
finalize
"""
name = 'finalize'
def _sympystr(self, printer):
return 'finalize'
[docs]class ACC_FirstPrivate(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_FirstPrivate
>>> ACC_FirstPrivate('x', 'y')
firstprivate(x, y)
"""
name = 'firstprivate'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'firstprivate({})'.format(args)
[docs]class ACC_Gang(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Gang
>>> ACC_Gang('x', 'y')
gang(x, y)
"""
name = 'gang'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'gang({})'.format(args)
[docs]class ACC_Host(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Host
>>> ACC_Host('x', 'y')
host(x, y)
"""
name = 'host'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'host({})'.format(args)
[docs]class ACC_If(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_If
>>> ACC_If(True)
if (True)
"""
name = 'if'
def __new__(cls, *args, **options):
test = args[0]
return Basic.__new__(cls, test)
@property
def test(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
return 'if({})'.format(sstr(self.test))
[docs]class ACC_IfPresent(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_IfPresent
>>> ACC_IfPresent()
if_present
"""
name = 'if_present'
def _sympystr(self, printer):
return 'if_present'
[docs]class ACC_Independent(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Independent
>>> ACC_Independent()
independent
"""
name = 'independent'
def _sympystr(self, printer):
return 'independent'
[docs]class ACC_Link(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Link
>>> ACC_Link('x', 'y')
link(x, y)
"""
name = 'link'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'link({})'.format(args)
[docs]class ACC_NoHost(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_NoHost
>>> ACC_NoHost()
nohost
"""
name = 'nohost'
def _sympystr(self, printer):
return 'nohost'
[docs]class ACC_NumGangs(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_NumGangs
>>> ACC_NumGangs(2)
num_gangs(2)
"""
name = 'num_gangs'
def __new__(cls, *args, **options):
if not(len(args) == 1):
raise ValueError('Expecting 1 entry, '
'given {0}'.format(len(args)))
n = args[0]
return Basic.__new__(cls, n)
@property
def n_gang(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
n_gang = '{0}'.format(sstr(self.n_gang))
return 'num_gangs({0})'.format(n_gang)
[docs]class ACC_NumWorkers(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_NumWorkers
>>> ACC_NumWorkers(2)
num_workers(2)
"""
name = 'num_workers'
def __new__(cls, *args, **options):
if not(len(args) == 1):
raise ValueError('Expecting 1 entry, '
'given {0}'.format(len(args)))
n = args[0]
return Basic.__new__(cls, n)
@property
def n_worker(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
n_worker = '{0}'.format(sstr(self.n_worker))
return 'num_workers({0})'.format(n_worker)
[docs]class ACC_Present(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Present
>>> ACC_Present('x', 'y')
present(x, y)
"""
name = 'present'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'present({})'.format(args)
[docs]class ACC_Private(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Private
>>> ACC_Private('x', 'y')
private(x, y)
"""
name = 'private'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'private({})'.format(args)
[docs]class ACC_Reduction(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Reduction
>>> ACC_Reduction('+', 'x', 'y')
reduction('+': (x, y))
"""
name = 'reduction'
def __new__(cls, *args, **options):
op = args[0]
arguments = args[1:]
return Basic.__new__(cls, op, arguments)
@property
def operation(self):
return self._args[0]
@property
def variables(self):
return self._args[1]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
op = sstr(self.operation)
return "reduction({0}: {1})".format(op, args)
[docs]class ACC_Self(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Self
>>> ACC_Self('x', 'y')
self(x, y)
"""
name = 'self'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'self({})'.format(args)
[docs]class ACC_Seq(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Seq
>>> ACC_Seq()
seq
"""
name = 'seq'
def _sympystr(self, printer):
return 'seq'
[docs]class ACC_Tile(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Tile
>>> ACC_Tile('x', 'y')
tile(x, y)
"""
name = 'tile'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'tile({})'.format(args)
[docs]class ACC_UseDevice(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_UseDevice
>>> ACC_UseDevice('x', 'y')
use_device(x, y)
"""
name = 'use_device'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'use_device({})'.format(args)
[docs]class ACC_Vector(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Vector
>>> ACC_Vector('x', 'y')
vector(x, y)
"""
name = 'vector'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'vector({})'.format(args)
[docs]class ACC_VectorLength(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_VectorLength
>>> ACC_VectorLength(2)
vector_length(2)
"""
name = 'vector_length'
def __new__(cls, *args, **options):
if not(len(args) == 1):
raise ValueError('Expecting 1 entry, '
'given {0}'.format(len(args)))
n = args[0]
return Basic.__new__(cls, n)
@property
def n(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
return 'vector_length({0})'.format(sstr(self.n))
[docs]class ACC_Wait(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Wait
>>> ACC_Wait('x', 'y')
wait(x, y)
"""
name = 'wait'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'wait({})'.format(args)
[docs]class ACC_Worker(ACC):
"""
Examples
>>> from pyccel.parallel.openacc import ACC_Worker
>>> ACC_Worker('x', 'y')
worker(x, y)
"""
name = 'worker'
def __new__(cls, *args, **options):
return Basic.__new__(cls, args)
@property
def variables(self):
return self._args[0]
def _sympystr(self, printer):
sstr = printer.doprint
args = ', '.join('{0}'.format(sstr(i)) for i in self.variables)
return 'worker({})'.format(args)
##########################################################
##########################################################
#Â useful functions
##########################################################
[docs]def accfy(stmt, **options):
"""
Converts some statements to OpenACC statments.
stmt: stmt, list
statement or a list of statements
"""
if isinstance(stmt, (list, tuple, Tuple)):
return [accfy(i, **options) for i in stmt]
if isinstance(stmt, Tensor):
# TODO to implement
return stmt
if isinstance(stmt, ForIterator):
iterable = accfy(stmt.iterable, **options)
target = stmt.target
body = accfy(stmt.body, **options)
clauses = get_for_clauses(iterable)
if (clauses is None):
return ForIterator(target, iterable, body, strict=False)
else:
loop = ForIterator(target, iterable, body, strict=False)
return ACC_For(loop, clauses)
if isinstance(stmt, For):
iterable = accfy(stmt.iterable, **options)
target = stmt.target
body = accfy(stmt.body, **options)
return For(target, iterable, body, strict=False)
if isinstance(stmt, list):
return [accfy(a, **options) for a in stmt]
if isinstance(stmt, While):
test = accfy(stmt.test, **options)
body = accfy(stmt.body, **options)
return While(test, body)
if isinstance(stmt, With):
test = accfy(stmt.test, **options)
body = accfy(stmt.body, **options)
settings = accfy(stmt.settings, **options)
clauses = get_with_clauses(test)
if (clauses is None):
return With(test, body, settings)
else:
# TODO to be defined
variables = []
return ACC_Parallel(clauses, variables, body)
if isinstance(stmt, If):
args = []
for block in stmt.args:
test = block[0]
stmts = block[1]
t = accfy(test, **options)
s = accfy(stmts, **options)
args.append((t,s))
return If(*args)
if isinstance(stmt, FunctionDef):
name = accfy(stmt.name, **options)
arguments = accfy(stmt.arguments, **options)
results = accfy(stmt.results, **options)
body = accfy(stmt.body, **options)
local_vars = accfy(stmt.local_vars, **options)
global_vars = accfy(stmt.global_vars, **options)
return FunctionDef(name, arguments, results, \
body, local_vars, global_vars)
if isinstance(stmt, ClassDef):
name = accfy(stmt.name, **options)
attributs = accfy(stmt.attributs, **options)
methods = accfy(stmt.methods, **options)
options = accfy(stmt.options, **options)
return ClassDef(name, attributs, methods, options)
if isinstance(stmt, Module):
name = accfy(stmt.name, **options)
variables = accfy(stmt.variables, **options)
funcs = accfy(stmt.funcs , **options)
classes = accfy(stmt.classes , **options)
imports = accfy(stmt.imports , **options)
imports += [Import('openacc')]
return Module(name, variables, funcs, classes,
imports=imports)
if isinstance(stmt, Program):
name = accfy(stmt.name, **options)
variables = accfy(stmt.variables, **options)
funcs = accfy(stmt.funcs , **options)
classes = accfy(stmt.classes , **options)
imports = accfy(stmt.imports , **options)
body = accfy(stmt.body , **options)
modules = accfy(stmt.modules , **options)
imports += [Import('openacc')]
return Program(name, variables, funcs, classes, body,
imports=imports, modules=modules)
if isinstance(stmt, ParallelBlock):
variables = stmt.variables
body = stmt.body
clauses = stmt.clauses
return ACC_Parallel(clauses, variables, body)
return stmt
##########################################################
# ...
[docs]def get_with_clauses(expr):
# ...
def _format_str(a):
if isinstance(a, str):
return a.strip('\'')
else:
return a
# ...
# ...
d_attributs = {}
d_args = {}
# ...
# ... we first create a dictionary of attributs
if isinstance(expr, Variable):
if expr.cls_base:
d_attributs = expr.cls_base.attributs_as_dict
elif isinstance(expr, ConstructorCall):
attrs = expr.attributs
for i in attrs:
d_attributs[str(i).replace('self.', '')] = i
# ...
# ...
if not d_attributs:
raise ValueError('Can not find attributs')
# ...
# ...
if isinstance(expr, Variable):
cls_base = expr.cls_base
if not cls_base:
return None
if not(('openacc' in cls_base.options) and ('with' in cls_base.options)):
return None
elif isinstance(expr, ConstructorCall):
# arguments[0] is 'self'
# TODO must be improved in syntax, so that a['value'] is a sympy object
for a in expr.arguments[1:]:
if isinstance(a, dict):
# we add '_' tp be conform with the private variables convention
d_args['_{0}'.format(a['key'])] = a['value']
else:
return None
# ...
# ... get initial values for all attributs
# TODO do we keep 'self' hard coded?
d = {}
for k,v in d_attributs.items():
i = DottedName('self', k)
d[k] = get_initial_value(expr, i)
# ...
# ... update the dictionary with the class parameters
for k,v in d_args.items():
d[k] = d_args[k]
# ...
# ... initial values for clauses
_async = None
_wait = None
_num_gangs = None
_num_workers = None
_vector_length = None
_device_type = None
_if = None
_reduction = None
_copy = None
_copyin = None
_copyout = None
_create = None
_present = None
_deviceptr = None
_private = None
_firstprivate = None
_default = None
# ...
# ... async
if not(d['_async'] is None):
if not isinstance(d['_async'], Nil):
ls = d['_async']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_async = ACC_Async(*ls)
# ...
# ... copy
if not(d['_copy'] is None):
if not isinstance(d['_copy'], Nil):
ls = d['_copy']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_copy = ACC_Copy(*ls)
# ...
# ... copyin
if not(d['_copyin'] is None):
if not isinstance(d['_copyin'], Nil):
ls = d['_copyin']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_copyin = ACC_Copyin(*ls)
# ...
# ... copyout
if not(d['_copyout'] is None):
if not isinstance(d['_copyout'], Nil):
ls = d['_copyout']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_copyout = ACC_Copyout(*ls)
# ...
# ... create
if not(d['_create'] is None):
if not isinstance(d['_create'], Nil):
ls = d['_create']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_create = ACC_Copyin(*ls)
# ...
# ... default
if not(d['_default'] is None):
if not isinstance(d['_default'], Nil):
ls = d['_default']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls[0] = _format_str(ls[0])
_default = ACC_Default(*ls)
# ...
# ... deviceptr
if not(d['_deviceptr'] is None):
if not isinstance(d['_deviceptr'], Nil):
ls = d['_deviceptr']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_deviceptr = ACC_DevicePtr(*ls)
# ...
# ... devicetype
if not(d['_device_type'] is None):
if not isinstance(d['_device_type'], Nil):
ls = d['_device_type']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_device_type = ACC_DeviceType(*ls)
# ...
# ... firstprivate
if not(d['_firstprivate'] is None):
if not isinstance(d['_firstprivate'], Nil):
ls = d['_firstprivate']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_firstprivate = ACC_FirstPrivate(*ls)
# ...
# ... if
# TODO improve this to take any boolean expression for arg.
# see OpenACC specifications
if not(d['_if'] is None):
if not isinstance(d['_if'], Nil):
arg = d['_if']
ls = [arg]
_if = ACC_If(*ls)
# ...
# ... num_gangs
# TODO improve this to take any int expression for arg.
# see OpenACC specifications
if not(d['_num_gangs'] is None):
if not isinstance(d['_num_gangs'], Nil):
arg = d['_num_gangs']
ls = [arg]
_num_gangs = ACC_NumGangs(*ls)
# ...
# ... num_workers
# TODO improve this to take any int expression for arg.
# see OpenACC specifications
if not(d['_num_workers'] is None):
if not isinstance(d['_num_workers'], Nil):
arg = d['_num_workers']
ls = [arg]
_num_workers = ACC_NumWorkers(*ls)
# ...
# ... present
if not(d['_present'] is None):
if not isinstance(d['_present'], Nil):
ls = d['_present']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_present = ACC_Present(*ls)
# ...
# ... private
if not(d['_private'] is None):
if not isinstance(d['_private'], Nil):
ls = d['_private']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_private = ACC_Private(*ls)
# ...
# ... reduction
if not(d['_reduction'] is None):
if not isinstance(d['_reduction'], Nil):
ls = d['_reduction']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_reduction = ACC_Reduction(*ls)
# ...
# ... vector_length
if not(d['_vector_length'] is None):
if not isinstance(d['_vector_length'], Nil):
arg = d['_vector_length']
ls = [arg]
_vector_length = ACC_VectorLength(*ls)
# ...
# ... wait
if not(d['_wait'] is None):
if not isinstance(d['_wait'], Nil):
ls = d['_wait']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_wait = ACC_Wait(*ls)
# ...
# ...
clauses = (_async,
_wait,
_num_gangs,
_num_workers,
_vector_length,
_device_type,
_if,
_reduction,
_copy,
_copyin,
_copyout,
_create,
_present,
_deviceptr,
_private,
_firstprivate,
_default)
clauses = [i for i in clauses if not(i is None)]
clauses = Tuple(*clauses)
# ...
return clauses
# ...
# ...
[docs]def get_for_clauses(expr):
# ...
def _format_str(a):
if isinstance(a, str):
return a.strip('\'')
else:
return a
# ...
# ...
d_attributs = {}
d_args = {}
# ...
# ... we first create a dictionary of attributs
if isinstance(expr, Variable):
if expr.cls_base:
d_attributs = expr.cls_base.attributs_as_dict
elif isinstance(expr, ConstructorCall):
attrs = expr.attributs
for i in attrs:
d_attributs[str(i).replace('self.', '')] = i
# ...
# ...
if not d_attributs:
raise ValueError('Can not find attributs')
# ...
# ...
if isinstance(expr, Variable):
cls_base = expr.cls_base
if not cls_base:
return None, None
if not(('openacc' in cls_base.options) and ('iterable' in cls_base.options)):
return None, None
elif isinstance(expr, ConstructorCall):
# arguments[0] is 'self'
# TODO must be improved in syntax, so that a['value'] is a sympy object
for a in expr.arguments[1:]:
if isinstance(a, dict):
# we add '_' tp be conform with the private variables convention
d_args['_{0}'.format(a['key'])] = a['value']
else:
return None, None
# ...
# ... get initial values for all attributs
# TODO do we keep 'self' hard coded?
d = {}
for k,v in d_attributs.items():
i = DottedName('self', k)
d[k] = get_initial_value(expr, i)
# ...
# ... update the dictionary with the class parameters
for k,v in d_args.items():
d[k] = d_args[k]
# ...
# ... initial values for clauses
_collapse = None
_gang = None
_worker = None
_vector = None
_seq = None
_auto = None
_tile = None
_device_type = None
_independent = None
_private = None
_reduction = None
# ...
# ... auto
if not(d['_auto'] is None):
if not isinstance(d['_auto'], Nil):
_auto = ACC_Auto()
# ...
# ... collapse
if not(d['_collapse'] is None):
if not isinstance(d['_collapse'], Nil):
ls = [d['_collapse']]
_collapse = ACC_Collapse(*ls)
# ...
# ... device_type
if not(d['_device_type'] is None):
if not isinstance(d['_device_type'], Nil):
ls = d['_device_type']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_device_type = ACC_DeviceType(*ls)
# ...
# ... gang
if not(d['_gang'] is None):
if not isinstance(d['_gang'], Nil):
ls = d['_gang']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_gang = ACC_Gang(*ls)
# ...
# ... independent
if not(d['_independent'] is None):
if not isinstance(d['_independent'], Nil):
_independent = ACC_Independent()
# ...
# ... private
if not(d['_private'] is None):
if not isinstance(d['_private'], Nil):
ls = d['_private']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_private = ACC_Private(*ls)
# ...
# ... reduction
if not(d['_reduction'] is None):
if not isinstance(d['_reduction'], Nil):
ls = d['_reduction']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_reduction = ACC_Reduction(*ls)
# ...
# ... seq
if not(d['_seq'] is None):
if not isinstance(d['_seq'], Nil):
_seq = ACC_Seq()
# ...
# ... tile
if not(d['_tile'] is None):
if not isinstance(d['_tile'], Nil):
ls = d['_tile']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_tile = ACC_Tile(*ls)
# ...
# ... vector
if not(d['_vector'] is None):
if not isinstance(d['_vector'], Nil):
ls = d['_vector']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_vector = ACC_Vector(*ls)
# ...
# ... worker
if not(d['_worker'] is None):
if not isinstance(d['_worker'], Nil):
ls = d['_worker']
if not isinstance(ls, (list, tuple, Tuple)):
ls = [ls]
ls = [_format_str(a) for a in ls]
_worker = ACC_Worker(*ls)
# ...
# ...
clauses = (_collapse,
_gang,
_worker,
_vector,
_seq,
_auto,
_tile,
_device_type,
_independent,
_private,
_reduction)
clauses = [i for i in clauses if not(i is None)]
clauses = Tuple(*clauses)
# ...
return clauses
# ...