op2.py源码阅读和注释以及工具拆分


#!/usr/bin/env python

"""
OP2 source code transformation tool

This tool parses the user's original source code to produce
target-specific code to execute the user's kernel functions.

This prototype is written in Python and is directly based on the
parsing and code generation of the matlab source code transformation code

usage: ./op2.py 'file1','file2', ..., [kernel_dir]

This takes as input

file1.cpp, file2.cpp, ...

and produces as output modified versions

file1_op.cpp, file2_op.cpp, ...

then calls a number of target-specific code generators
to produce individual kernel files of the form

xxx_kernel.cpp  -- for OpenMP x86 execution
xxx_kernel.cu   -- for CUDA execution

plus a master kernel file of the form

file1_kernels.cpp  -- for OpenMP x86 execution`
file1_kernels.cu   -- for CUDA execution

If user kernel files are located in a sub-directory (e.g. 'kernel_dir'), then
this directory can be provided as argument as well.
"""

import sys
import re
import datetime
import os

# Import MPI+SEQ and MPI+autovectorised SEQ
from op2_gen_seq import op2_gen_seq
from op2_gen_mpi_vec import op2_gen_mpi_vec

# import OpenMP and CUDA code generation functions
from op2_gen_openmp_simple import op2_gen_openmp_simple
from op2_gen_openmp import op2_gen_openmp

from op2_gen_openacc import op2_gen_openacc

from op2_gen_cuda import op2_gen_cuda
from op2_gen_cuda_simple import op2_gen_cuda_simple
from op2_gen_cuda_simple_hyb import op2_gen_cuda_simple_hyb
from op2_gen_openmp4 import op2_gen_openmp4

from op2_gen_common import *

# from http://stackoverflow.com/a/241506/396967
# 这一部分去除掉源码里的注释

def comment_remover(text):
  """Remove comments from text"""

  def replacer(match):
    s = match.group(0)
    if s.startswith('/'):
      return ""
    else:
      return s
  pattern = re.compile(
    r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
    re.DOTALL | re.MULTILINE
  )
  return re.sub(pattern, replacer, text)


def op_parse_calls(text):
  """Parsing for op_init/op_exit/op_partition/op_hdf5 calls"""

  # remove comments just for this call
  text = comment_remover(text)

  inits = len(re.findall('op_init', text))
  exits = len(re.findall('op_exit', text))
  parts = len(re.findall('op_partition', text))
  hdf5s = len(re.findall('hdf5', text))

  return (inits, exits, parts, hdf5s)

def op_decl_set_parse(text):
  """Parsing for op_decl_set calls"""

  sets = []
  for m in re.finditer('op_decl_set\((.*)\)', text):
    args = m.group(1).split(',')

    # check for syntax errors
    if len(args) != 2:
      print 'Error in op_decl_set : must have three arguments'
      return

    sets.append({
   
      'name': args[1].strip()
      })
  for m in re.finditer('op_decl_set_hdf5\((.*)\)', text):
    args = m.group(1).split(',')

    # check for syntax errors
    if len(args) != 2:
      print 'Error in op_decl_set : must have three arguments'
      return

    sets.append({
   
      'name': args[1].strip()[1:-1]
      })

  return sets


def op_decl_const_parse(text):
  """Parsing for op_decl_const calls"""

  consts = []
  for m in re.finditer('op_decl_const\((.*)\)', text):
    args = m.group(1).split(',')

    # check for syntax errors
    if len(args) != 3:
      print 'Error in op_decl_const : must have three arguments'
      return

    consts.append({
   
      'loc': m.start(),
      'dim': args[0].strip(),
      'type': args[1].strip(),
      'name': args[2].strip(),
      'name2': args[2].strip()
      })

  return consts


def extract_declared_globals(text):
  """ Parsing for variables that have been declared 'extern' by user """

  globals_found = []
  global_pattern = r'[\s]*extern[\s]+[\w]+[\s]+([\w]+)'
  for match in re.findall(global_pattern, text):
    globals_found.append(match)
  return globals_found


def arg_parse(text, j):
  """Parsing arguments in op_par_loop to find the correct closing brace"""

  depth = 0
  loc2 = j
  while 1:
    if text[loc2] == '(':
      depth = depth + 1

    elif text[loc2] == ')':
      depth = depth - 1
      if depth == 0:
        return loc2
    loc2 = loc2 + 1


def get_arg_dat(arg_string, j):
  loc = arg_parse(arg_string, j + 1)
  dat_args_string = arg_string[arg_string.find('(', j) + 1:loc]

  # remove comments
  dat_args_string = comment_remover(dat_args_string)

  # check for syntax errors
  if len(dat_args_string.split(',')) != 6:
    print 'Error parsing op_arg_dat(%s): must have six arguments' \
        % dat_args_string
    return

  # split the dat_args_string into  6 and create a struct with the elements
  # and type as op_arg_dat
  temp_dat = {
   'type': 'op_arg_dat',
        'dat': dat_args_string.split(',')[0].strip(),
        'idx': dat_args_string.split(',')[1].strip(),
        'map': dat_args_string.split(',')[2].strip(),
        'dim': dat_args_string.split(',')[3].strip(),
        'typ': dat_args_string.split(',')[4].strip(),
        'acc': dat_args_string.split(',')[5].strip(),
        'opt':''}

  return temp_dat

def get_opt_arg_dat(arg_string, j):
  loc = arg_parse(arg_string, j + 1)
  dat_args_string = arg_string[arg_string.find('(', j) + 1:loc]

  # remove comments
  dat_args_string = comment_remover(dat_args_string)
  # check for syntax errors
  if len(dat_args_string.split(',')) != 7:
    print 'Error parsing op_opt_arg_dat(%s): must have 7 arguments' \
        % dat_args_string
    return

  # split the dat_args_string into  6 and create a struct with the elements
  # and type as op_arg_dat
  temp_dat = {
   'type': 'op_opt_arg_dat',
        'opt': dat_args_string.split(',')[0].strip(),
        'dat': dat_args_string.split(',')[1].strip(),
        'idx': dat_args_string.split(',')[2].strip(),
        'map': dat_args_string.split(',')[3].strip(),
        'dim': dat_args_string.split(',')[4].strip(),
        'typ': dat_args_string.split(',')[5].strip(),
        'acc': dat_args_string.split(',')[6].strip()}

  return temp_dat


def get_arg_gbl(arg_string, k):
  loc = arg_parse(arg_string, k + 1)
  gbl_args_string = arg_string[arg_string.find('(', k) + 1:loc]

  # remove comments
  gbl_args_string = comment_remover(gbl_args_string)

  # check for syntax errors
  if len(gbl_args_string.split(',')) != 4:
    print 'Error parsing op_arg_gbl(%s): must have four arguments' \
        % gbl_args_string
    return

  # split the gbl_args_string into  4 and create a struct with the elements
  # and type as op_arg_gbl
  temp_gbl = {
   'type': 'op_arg_gbl',
        'data': gbl_args_string.split(',')[0].strip(),
        'dim': gbl_args_string.split(',')[1].strip(),
        'typ': gbl_args_string.split(',')[2].strip(),
        'acc': gbl_args_string.split(',')[3].strip(),
        'opt':''}

  return temp_gbl

def append_init_soa(text):
  text = re.sub('\\bop_init\\b\\s*\((.*)\)','op_init_soa(\\1,1)', text)
  text = re.sub('\\bop_mpi_init\\b\\s*\((.*)\)','op_mpi_init_soa(\\1,1)', text)
  return text

def op_par_loop_parse(text):
  """Parsing for op_par_loop calls"""

  loop_args 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值