Source code for pyccel.parser.syntax.openmp

# coding: utf-8

"""
"""

from os.path import join, dirname

from pyccel.parser.syntax.basic import BasicStmt
from pyccel.ast.core import AnnotatedComment

DEBUG = False

[docs]class Openmp(object): """Class for Openmp syntax.""" def __init__(self, **kwargs): """ Constructor for Openmp. """ self.statements = kwargs.pop('statements', [])
[docs]class OpenmpStmt(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.stmt = kwargs.pop('stmt') super(OpenmpStmt, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OpenmpStmt: expr") stmt = self.stmt if isinstance(stmt, OmpEndClause): return stmt.expr elif isinstance(stmt, OmpParallelConstruct): return stmt.expr elif isinstance(stmt, OmpLoopConstruct): return stmt.expr elif isinstance(stmt, OmpSingleConstruct): return stmt.expr else: raise TypeError('Wrong stmt for OpenmpStmt')
[docs]class OmpParallelConstruct(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.clauses = kwargs.pop('clauses') super(OmpParallelConstruct, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpParallelConstruct: expr") _valid_clauses = (OmpNumThread, \ OmpDefault, \ OmpPrivate, \ OmpShared, \ OmpFirstPrivate, \ OmpCopyin, \ OmpReduction, \ OmpProcBind) txt = 'parallel' for clause in self.clauses: if isinstance(clause, _valid_clauses): txt = '{0} {1}'.format(txt, clause.expr) else: raise TypeError('Wrong clause for OmpParallelConstruct') return AnnotatedComment('omp', txt)
[docs]class OmpLoopConstruct(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.clauses = kwargs.pop('clauses') super(OmpLoopConstruct, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpLoopConstruct: expr") _valid_clauses = (OmpPrivate, \ OmpFirstPrivate, \ OmpLastPrivate, \ OmpReduction, \ OmpSchedule, \ OmpCollapse, \ OmpLinear, \ OmpOrdered) txt = 'do' for clause in self.clauses: if isinstance(clause, _valid_clauses): txt = '{0} {1}'.format(txt, clause.expr) else: raise TypeError('Wrong clause for OmpLoopConstruct. Given : ', \ type(clause)) return AnnotatedComment('omp', txt)
[docs]class OmpSingleConstruct(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.clauses = kwargs.pop('clauses') super(OmpSingleConstruct, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpSingleConstruct: expr") _valid_clauses = (OmpPrivate, \ OmpFirstPrivate) txt = 'single' for clause in self.clauses: if isinstance(clause, _valid_clauses): txt = '{0} {1}'.format(txt, clause.expr) else: raise TypeError('Wrong clause for OmpSingleConstruct') return AnnotatedComment('omp', txt)
[docs]class OmpEndClause(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.construct = kwargs.pop('construct') self.simd = kwargs.pop('simd', '') self.nowait = kwargs.pop('nowait', '') super(OmpEndClause, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpEndClause: expr") txt = 'end {0} {1} {2}'.format(self.construct, self.simd, self.nowait) return AnnotatedComment('omp', txt)
[docs]class OmpNumThread(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.thread = kwargs.pop('thread') super(OmpNumThread, self).__init__(**kwargs) @property def expr(self): # TODO check if variable exist in namespace if DEBUG: print("> OmpNumThread: expr") thread = self.thread return 'num_threads({})'.format(thread)
[docs]class OmpDefault(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.status = kwargs.pop('status') super(OmpDefault, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpDefault: expr") return 'default({})'.format(self.status)
[docs]class OmpProcBind(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.status = kwargs.pop('status') super(OmpProcBind, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpProcBind: expr") return 'proc_bind({})'.format(self.status)
[docs]class OmpPrivate(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.args = kwargs.pop('args') super(OmpPrivate, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpPrivate: expr") # TODO check if variable exist in namespace args = ', '.join(str(arg) for arg in self.args) return 'private({})'.format(args)
[docs]class OmpShared(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.args = kwargs.pop('args') super(OmpShared, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpShared: expr") # TODO check if variable exist in namespace args = ', '.join(str(arg) for arg in self.args) return 'shared({})'.format(args)
[docs]class OmpFirstPrivate(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.args = kwargs.pop('args') super(OmpFirstPrivate, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpFirstPrivate: expr") # TODO check if variable exist in namespace args = ', '.join(str(arg) for arg in self.args) return 'firstprivate({})'.format(args)
[docs]class OmpLastPrivate(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.args = kwargs.pop('args') super(OmpLastPrivate, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpLastPrivate: expr") # TODO check if variable exist in namespace args = ', '.join(str(arg) for arg in self.args) return 'lastprivate({})'.format(args)
[docs]class OmpCopyin(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.args = kwargs.pop('args') super(OmpCopyin, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpCopyin: expr") # TODO check if variable exist in namespace args = ', '.join(str(arg) for arg in self.args) return 'copyin({})'.format(args)
[docs]class OmpReduction(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.op = kwargs.pop('op') self.args = kwargs.pop('args') super(OmpReduction, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpReduction: expr") # TODO check if variable exist in namespace op = self.op args = ', '.join(str(arg) for arg in self.args) return 'reduction({0}: {1})'.format(op, args)
[docs]class OmpCollapse(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.n = kwargs.pop('n') super(OmpCollapse, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpCollapse: expr") return 'collapse({})'.format(self.n)
[docs]class OmpOrdered(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.n = kwargs.pop('n', None) super(OmpOrdered, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpOrdered: expr") if self.n: return 'ordered({})'.format(self.n) else: return 'ordered'
[docs]class OmpLinear(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.val = kwargs.pop('val') self.step = kwargs.pop('step') super(OmpLinear, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpLinear: expr") return 'linear({0}:{1})'.format(self.val, self.step)
[docs]class OmpSchedule(BasicStmt): """Class representing a .""" def __init__(self, **kwargs): """ """ self.kind = kwargs.pop('kind') self.chunk_size = kwargs.pop('chunk_size', None) super(OmpSchedule, self).__init__(**kwargs) @property def expr(self): if DEBUG: print("> OmpSchedule: expr") if self.chunk_size: return 'schedule({0}, {1})'.format(self.kind, self.chunk_size) else: return 'schedule({0})'.format(self.kind)
################################################# ################################################# # whenever a new rule is added in the grammar, we must update the following # lists. omp_directives = [OmpParallelConstruct, OmpLoopConstruct, OmpSingleConstruct, OmpEndClause] omp_clauses = [OmpCollapse, OmpCopyin, OmpFirstPrivate, OmpLastPrivate, OmpLinear, OmpOrdered, OmpNumThread, OmpDefault, OmpPrivate, OmpProcBind, OmpPrivate, OmpReduction, OmpSchedule, OmpShared] omp_classes = [Openmp, OpenmpStmt] + omp_directives + omp_clauses
[docs]def parse(filename=None, stmts=None, debug=False): this_folder = dirname(__file__) # Get meta-model from language description grammar = join(this_folder, '../grammar/openmp.tx') from textx.metamodel import metamodel_from_file meta = metamodel_from_file(grammar, debug=debug, classes=omp_classes) # Instantiate model if filename: model = meta.model_from_file(filename) elif stmts: model = meta.model_from_str(stmts) else: raise ValueError('Expecting a filename or a string') stmts = [] for stmt in model.statements: if isinstance(stmt, OpenmpStmt): e = stmt.stmt.expr stmts.append(e) if len(stmts) == 1: return stmts[0] else: return stmts