跳转到内容

ROSE 编译器框架/OpenMP 支持

来自维基教科书,自由的教科书,为自由的世界

官方文档

  • ROSE 手册有一章(第 12 章 OpenMP 支持)解释了详细信息。 pdf
  • 一篇论文发表了 ROSE OpenMP 实现的独特性 pdf
  • 一篇关于加速器 (GPU) 支持的论文:“使用 OpenMP 加速器模型的早期经验。”

OpenMP 功能

[编辑 | 编辑源代码]

ROSE 支持 C/C++ 的 OpenMP 3.0(以及有限的 Fortran 支持),并且有一个来自 OpenMP 4.0 的实验性 OpenMP 加速器模型实现

与前端() 的连接点位于 sage_support.cpp 中,通过 SgFile::secondaryPassOverSourceFile() 调用的 OmpSupport::processOpenMP()

void processOpenMP(SgSourceFile *sageFilePtr) of ompAstConstruction.cpp // ROSE 中 OpenMP 处理的顶级驱动程序

  • 前端解析源文件 (ompparser.yy 和 ompFortranParser.C) 位于 https://github.com/rose-compiler/rose/tree/master/src/frontend/SageIII
    • void build_OpenMP_AST(SgSourceFile *sageFilePtr) of ompAstConstruction.cpp // 处理编译指示并为 OpenMP 构建 AST
      • void attachOmpAttributeInfo(SgSourceFile *sageFilePtr) of ompAstConstruction.cpp // 查找并解析 OpenMP 编译指示为 OmpAttribute 信息。
      • convert_OpenMP_pragma_to_AST() // 将属性转换为专用 OpenMP AST 节点
  • 将 OpenMP 转换为线程代码的转换位于 omp_lowering.cpp 中,位于 https://github.com/rose-compiler/rose/blob/master/src/midend/programTransformation/ompLowering
    • lower_omp()
  • OpenMP 运行时接口在上述同一 ompLowering 目录下的 libxomp.h 和 xomp.c 中定义
    • GCC 的 OpenMP 运行时库 libgomp 与此实现一起使用。
    • 可以选择使用其他运行时库,例如 Omni 运行时库,与 ROSE 连接。但这种支持没有得到积极维护。

OpenMP 处理发生在 rose/src/frontend/SageIII/sage_support/sage_support.cpp 中的 void SgFile::secondaryPassOverSourceFile() 中。此阶段收集有关源文件的额外信息,例如注释、预处理指令等。

配置:在配置 ROSE 时,请始终尝试使用 --with-gomp_omp_runtime_library=/usr/apps/gcc/4.4.1/lib64/。因此,生成的 ROSE 翻译器可以自动链接到 libgomp.a 来为您生成可执行文件。这也将允许执行 omp Lowering 的执行测试以捕获错误。没有此选项,只有编译级别测试会运行。

命令行选项

[编辑 | 编辑源代码]

与所有其他支持 OpenMP 的编译器一样,您必须使用 -rose:openmp:lowering 显式启用此支持,例如

 identityTranslator -rose:openmp:lowering your_openmp_code.c

此选项告诉 ROSE 翻译器识别 OpenMP 编译指示并将输入转换为使用 libgomp 运行时库。通过使用详细标志,可以查看编译、后端编译器和链接的详细命令行。

 identityTranslator -rose:openmp:lowering  -rose:verbose 3 your_openmp_code.c

此详细模式下将显示三个内部步骤

  • ROSE 翻译器的翻译:identityTranslator -rose:openmp:lowering -rose:verbose 3 ...-DUSE_ROSE --c -D_OPENMP your_openmp_code.c
  • 后端编译器编译:gcc -DUSE_ROSE -D_OPENMP -I/export/tmp.liao6/workspace/masterClean/build64/install/include rose_your_openmp_code.c -c -o mg_your_openmp_code.o
  • 链接:gcc your_openmp_code.o -lm /export/tmp.liao6/workspace/masterClean/build64/install/lib/libxomp.a /usr/apps/gcc/4.4.1/lib64//libgomp.a -lpthread

有关 OpenMP 支持的更多命令行选项选择

  • -rose:OpenMP, -rose:openmp 遵循 OpenMP 3.0 针对 C/C++ 和 Fortran 的规范,执行以下操作之一
  • -rose:OpenMP:parse_only, -rose:openmp:parse_only 将 OpenMP 指令解析为 OmpAttributes,不执行其他操作(现在的默认行为)
  • -rose:OpenMP:ast_only, -rose:openmp:ast_only 在 -rose:openmp:parse_only 之上,从 OmpAttributes 构建 OpenMP AST 节点,不执行其他操作
  • -rose:OpenMP:lowering, -rose:openmp:lowering 在 -rose:openmp:ast_only 之上,将具有 OpenMP 节点的 AST 转换为针对 GCC GOMP 运行时库的多线程代码

内部步骤

[编辑 | 编辑源代码]

编译

  • ./identityTranslator -I../../../../../../rose-develop/src/frontend/SageIII -I../../../../../../rose-develop/src/midend/programTransformation/ompLowering -I../../../../.. -rose:openmp:lowering -g --edg:no_warnings -c ../../../../../../rose-develop/tests/nonsmoke/functional/CompileTests/OpenMP_tests/pi.c

链接

gcc pi.o -o pi.out -L../../../../../src/midend -lxomp /usr/lib/gcc/x86_64-linux-gnu/4.9//libgomp.a -lpthread -lm

测试

  • ROSE 中大约有 70 个内置执行测试(许多测试具有自我验证)。
    • OpenMP 解析测试:tests/CompileTests/OpenMP_tests
    • OpenMP 翻译和执行测试:rose/tests/roseTests/ompLoweringTests,需要 --with-gomp_omp_runtime_library=/usr/apps/gcc/4.4.x(或更高版本)/lib64/ 来链接并运行测试。

一些基准测试用于在 Jenkins(我们的回归测试服务器)中测试 ROSE 中的 OpenMP 支持

  • a22b-NPB-2.3-C-parallel:所有 8 个基准测试通过
  • a21-SPEC-OMP-64bit-parallel:3 个基准测试通过。
  • LULESH OpenMP 版本:下载

对于内置测试

如果要让它们在键入“make check”时自动执行,您必须配置 GOMP 的路径。例如,../sourcetree ... --with-gomp_omp_runtime_library=/usr/apps/gcc/4.4.1/lib64/

解析 OpenMP 指令

[编辑 | 编辑源代码]

前端解析源文件 (ompparser.yy 和 ompFortranParser.C) 位于 https://github.com/rose-compiler/rose/tree/master/src/frontend/SageIII

要识别一个新关键字,例如一个子句:target ()

  • 在 ompparser.yy 中添加一个令牌名称:%token TARGET
  • 在 omplexer.ll 中解析令牌:target {return cond_return ( TARGET ); }
  • 在 ompparser.yy 中添加语法规则
openmp_directive : parallel_directive 
...
          | target_directive
....

target_directive: /* #pragma */ OMP TARGET {
                       ompattribute = buildOmpAttribute(e_target,gNode,true);
                       omptype = e_target;
                     }
                     target_clause_optseq 
                   ;

OmpAttribute

[编辑 | 编辑源代码]

解析结果存储到持久 AST 属性中。使用名为 OmpAttribute 的派生类型。

./src/frontend/SageIII/OmpAttribute.h /.C

AST 对 OpenMP 的支持

[edit | edit source]

我们定义了一组专门的 AST 节点来表示源代码中的 OpenMP 指令。例如,您可以使用 dotGeneratorWholeASTGraph 查看示例输入代码的 AST

/* A kernel for two level parallelizable loop with reduction */
float u[100][100];
float foo ()
{
  int i,j;
  float temp, error;
#pragma omp parallel for private (temp,i,j) reduction (+:error)
  for (i = 0; i < 100; i++)
    for (j = 0; j < 100; j++)
      {
        temp = u[i][j];
        error = error + temp * temp;
      }
  return error;
}

./dotGeneratorWholeASTGraph -c -rose:OpenMP:ast_only reduction_1.c

生成的 dot 图将包含以下节点

  • SgBasicBlock // 函数定义的基本块
    • SgOmpParallelStatement // AST 中专门的 OpenMP 并行语句
      • SgOmpForStatement // 专门的 Omp for 语句。它有 SgOmpReductionClause 和 SgOmpPrivateClause,通过 ->get_clauses() 获得
        • SgForStatement // 受 "omp parallel for" 影响的实际循环

组合指令(如 "omp parallel for")被拆分为两个指令 "omp parallel" 和 "omp for"。所有子句尽可能地附加到内部指令。这是为了支持以后更简单的处理(例如在 OpenMP 降级中)。

  • 注意:目前还没有针对组合指令的专用 AST 节点。但如果需要,我们可以添加它们。

Omp 节点

[edit | edit source]

OpenMP AST 节点列表如下(来自 http://rosecompiler.org/ROSE_HTML_Reference/annotated.html

  • SgOmpAlignedClause
  • SgOmpAtomicStatement
  • SgOmpBarrierStatement
  • SgOmpBeginClause
  • SgOmpBodyStatement
  • SgOmpClause
  • SgOmpClauseBodyStatement
  • SgOmpCollapseClause
  • SgOmpCopyinClause
  • SgOmpCopyprivateClause
  • SgOmpCriticalStatement
  • SgOmpDefaultClause
  • SgOmpDeviceClause
  • SgOmpDoStatement
  • SgOmpEndClause
  • SgOmpExpressionClause
  • SgOmpFirstprivateClause
  • SgOmpFlushStatement
  • SgOmpForStatement
  • SgOmpIfClause
  • SgOmpLastprivateClause
  • SgOmpLinearClause
  • SgOmpMapClause
  • SgOmpMasterStatement
  • SgOmpNowaitClause
  • SgOmpNumThreadsClause
  • SgOmpOrderedClause
  • SgOmpOrderedStatement
  • SgOmpParallelStatement
  • SgOmpPrivateClause
  • SgOmpReductionClause
  • SgOmpSafelenClause
  • SgOmpScheduleClause
  • SgOmpSectionsStatement
  • SgOmpSectionStatement
  • SgOmpSharedClause
  • SgOmpSimdStatement
  • SgOmpSingleStatement
  • SgOmpTargetDataStatement
  • SgOmpTargetStatement
  • SgOmpTaskStatement
  • SgOmpTaskwaitStatement
  • SgOmpThreadprivateStatement
  • SgOmpUniformClause
  • SgOmpUntiedClause
  • SgOmpVariablesClause
  • SgOmpWorkshareStatement

请参考 Doxygen 文档了解成员访问函数。

AST 图

[edit | edit source]

要查看输入 OpenMP 代码的 AST 图,您应该使用 dotGraphGeneratorWhole 或 pdfGenerator。

一个示例 dot 图可在 parallefor.dot.png 中找到,该文件位于 https://github.com/chunhualiao/rose-ast 中。

访问 OpenMP 子句和变量

[edit | edit source]

请参考 Doxygen 文档了解 SgOmp* 节点的成员访问函数。

许多辅助函数在 OmpSupport 命名空间中定义,如 http://rosecompiler.org/ROSE_HTML_Reference/namespaceOmpSupport.html 所示

如何访问这些节点信息的最佳示例在 ROSE 的 OpenMP 降级步骤中。

例如,要获取 threadprivate 子句中的变量引用列表,代码如下所示

  void transOmpThreadprivate(SgNode * node)
  {
    ROSE_ASSERT(node != NULL );
    SgOmpThreadprivateStatement* target = isSgOmpThreadprivateStatement(node);
    ROSE_ASSERT(target != NULL );

    SgVarRefExpPtrList nameList = target->get_variables ();
    for (size_t i = 0; i<nameList.size(); i++)
    {
      SgInitializedName* init_name = nameList[i]->get_symbol()->get_declaration();
      ROSE_ASSERT(init_name != NULL);
      SgVariableDeclaration*  decl = isSgVariableDeclaration(init_name-> get_declaration());
      ROSE_ASSERT (decl != NULL);
     ....
    }
   .... 
  }


另一个示例检查变量是否在某些 OpenMP 子句的变量列表中

#include "rose.h"
#include "omp_lowering.h"  // many helper functions are declared here

using namespace OmpSupport; 

...
 SgInitializedName* orig_var = ... ;
 SgOmpClauseBodyStatement* clause_stmt = isSgOmpClauseBodyStatement(ompStmt);

// check if orig_var is within the specified clauses of an OpenMP statement (e.g. omp for)
  VariantVector vvt (V_SgOmpPrivateClause);
  vvt.push_back(V_SgOmpReductionClause);
  vvt.push_back(V_SgOmpFirstprivateClause);
  vvt.push_back(V_SgOmpLastprivateClause);

if (isInClauseVariableList(orig_var, clause_stmt, vvt))
{
...
}

// another one: check if a loop index variable is already in private() or not

isPrivateInRegion = isInClauseVariableList(index_var, isSgOmpClauseBodyStatement(omp_stmt), V_SgOmpPrivateClause);


// add loop index variable into the private() clause
  addClauseVariable(index_var,isSgOmpClauseBodyStatement(omp_loop), V_SgOmpPrivateClause);          

查询数据共享属性

[edit | edit source]

有一个接口函数可以查询 OpenMP 程序中引用的变量的数据共享属性,该函数在 https://github.com/rose-compiler/rose/blob/master/src/midend/programTransformation/ompLowering/omp_lowering.h 中声明

namespace OmpSupport {

  //! Return the data sharing attribute type of a variable, specified as a symbol and an anchor node 
  //! (Must be the inner most node associated with the variable reference, e.g. a SgVarRefExp, SgVariableDeclaration, etc)
  //! Possible returned values include: e_shared, e_private,  e_firstprivate,  e_lastprivate,  e_reduction, 
  //! e_threadprivate, e_copyin, and e_copyprivate.
  ROSE_DLL_API omp_construct_enum getDataSharingAttribute (SgSymbol* var, SgNode* anchor_node);

  //! Return the OpenMP data sharing attribute type of a variable reference
  ROSE_DLL_API omp_construct_enum getDataSharingAttribute (SgVarRefExp* varRef);

...
}

测试/示例代码

#include <vector>
#include "OmpSupport.h"  // this file includes several headers declaring OmpSupport namespace
using namespace std;
using namespace OmpSupport;
using namespace SageInterface;

class visitorTraversal : public AstSimpleProcessing
{
  protected:
    virtual void visit(SgNode* n);
};

void visitorTraversal::visit(SgNode* node)
{
  if (SgLocatedNode* lnode = isSgLocatedNode(node))
  {
    //skip system headers
    if (insideSystemHeader (lnode))
      return;

    if (SgForStatement* forloop= isSgForStatement(node))
    {
      cout<<"for loop at line "<< forloop->get_file_info()->get_line() <<endl;
      std::vector< SgVarRefExp * > ref_vec;
      collectVarRefs (forloop, ref_vec);
      for (std::vector< SgVarRefExp * >::iterator iter = ref_vec.begin(); iter!= ref_vec.end(); iter ++)
      {
        SgSymbol* s = (*iter)->get_symbol();
        omp_construct_enum atr = getDataSharingAttribute (*iter);
        // will redirect to a .output file to enable diff-based correctness checking
        cout<<s->get_name()<<"\t"<<toString(atr) <<endl;
      }
    }
  }
}

int main(int argc, char * argv[])
{
  SgProject *project = frontend (argc, argv);

  visitorTraversal myvisitor;
  myvisitor.traverseInputFiles(project,preorder);

  return backend(project);
}

测试命令行

./getDataSharingAttribute -c -rose:openmp:ast_only openmpcode.c

AST 节点的反解析

[edit | edit source]

它们定义在

src/backend/unparser/languageIndependenceSupport/unparseLanguageIndependentConstructs.h

src/backend/unparser/languageIndependenceSupport/unparseLanguageIndependentConstructs.C

从您的翻译器启用 OpenMP 处理

[edit | edit source]

启用 OpenMP 解析和 AST 创建

[edit | edit source]

最简单且推荐的方法是在您的翻译器中传递命令行选项 "-rose:OpenMP:ast_only"。

  • 这将打开解析 OpenMP 指令和创建专用 OpenMP AST 节点的功能。用户可以选择开启/关闭 OpenMP 解析功能。

第二个选项(推荐)是您可以在翻译器中内部推送选项

// Option 2: recommended 
#include "rose.h"

int main(int argc, char* argv[])
 {
   vector<string> argvList(argv,argv+argc);
  if (your-condition-meet)
   argvList.push_back("-rose:OpenMP:ast_only");

   // the frontend will correctly handle OpenMP.
   // All internal flags will be automatically set correctly.
   // Several internal actions will be turned on in parsing, translation and the connection to the backend compiler
   SgProject* project = frontend (argvList);
   //...
}

第三个选项(不推荐),您可以复制翻译器中的所有内部处理,如 https://github.com/rose-compiler/rose/blob/master/src/frontend/SageIII/sage_support/cmdline.cpphttps://github.com/rose-compiler/rose/blob/master/src/frontend/SageIII/sage_support/sage_support.cpp 所示

  • 这有点复杂,因为您现在接触到了项目和文件级别的内部标志。
  • 您必须了解几个标志如何协同工作以控制解析、AST 创建和降级。
  • 并明确调用 OpenMP 处理函数
  • 如果需要后端编译器,则将 "-DOPENMP" 传递给后端编译器。
// Option 3: not really recommended due to the complexity involved.
#include "rose.h"
#include "ompAstConstruction.h"

int main(int argc, char* argv[])
 {

   vector<string> argvList(argv, argv+argc);

   // the default frontend does not handle OpenMP at all. 
   SgProject* project = frontend (argvList);
  ..
    // optional
    // OmpSupport::enable_debugging = true;

    // We assuming one single input file at a time
    // You need to do this for all file if your translator accepts multiple files
     SgFile * cur_file = project->get_fileList()[0];

   // set three flags related to OpenMP processing
     cur_file->set_openmp(true);  // the top level flag
     cur_file->set_openmp_parse_only(false); 
     cur_file->set_openmp_ast_only(true); 
     cur_file->set_openmp_lowering(false);

    // process OpenMP directives within this file, based on the flag setting
    // At least two phases are involved: one is to do the parsing and AST creation
    // the other is to handle -DOPENMP when connecting to the backend compiler
     OmpSupport::processOpenMP(isSgSourceFile(cur_file));

   AstTests::runAllTests(project);
   return backend(project);
}

启用 OpenMP 降级

[edit | edit source]

有时需要从您自己的翻译器中调用 OpenMP 降级,而不是从 ROSE 的内置 frontend() 中调用。以下是一个示例

#include "rose.h"
#include "ompAstConstruction.h"

int main()
 {
  SgProject* project = frontend(argvList,frontendConstantFolding);
  ..
    OmpSupport::enable_accelerator = true;
    OmpSupport::enable_debugging = true;


    // We only process one single input file at a time
     ROSE_ASSERT (project->get_fileList().size() ==1);
     SgFile * cur_file = project->get_fileList()[0];

  // set three flags related to OpenMP processing
     cur_file->set_openmp(true);
     cur_file->set_openmp_lowering(true);
     cur_file->set_openmp_parse_only(false);

     // process OpenMP directives, including omp target
     OmpSupport::processOpenMP(isSgSourceFile(cur_file));

   AstTests::runAllTests(project);
   return backend(project);

}

检测支持

[edit | edit source]

XOMP(ROSE 的 OpenMP 运行时层)支持简单的事件检测来收集关键 OpenMP 事件的时间戳。收集的数据有助于进一步分析,例如调查执行期间的串行与并行区域。


环境变量以打开此支持

  • XOMP_REGION_INSTR =0|1: 仅公开此环境变量将打开此支持。默认情况下此选项处于关闭状态,以避免不必要的开销。
    • 在 BASH 中:键入 "export XOMP_REGION_INSTR=1"

打开此功能后,使用 rose 编译您的 OpenMP 代码。可执行文件将生成一个数据文件,其文件名前缀为时间戳,例如 "2013_03_05_10_05_45.jacobi"。此文件将包含时间戳、值 1 或 2 以及串行和并行执行之间每次更改的文件位置。

从 XOMP 生成的 data 文件生成图形的示例 GNU plot 脚本

# cat timeline-plot.sc
set xlabel 'time stamps'
set yrange [0:3]
#set output "lulesh.eps" 
#set terminal postscript eps
plot "sp.A.8threads" using ($1-1362509569.298380):2 with lines
#plot "timeline1.data" using 1:2 with lines

示例生成的 GNU plot 图形:X 轴是时间轴,Y 轴用于串行(值 1)与并行(值 2)执行

Rose-xomp-timeline-npb-mg-A-8threads

,

Rose-xomp-lulesh-timeline-8threads


此支持的相关提交

实现规模有多大?

[编辑 | 编辑源代码]

2015 年 7 月 7 日收集的数据

直接源代码行

[liao6@tux322:~/workspace/masterDevClean/sourcetree/src/frontend/SageIII]wc omp*
  1900   6723  75176 ompAstConstruction.cpp
    20     39    504 ompAstConstruction.h
  1504   4821  45545 ompFortranParser.C
   128    365   3361 omp.h
   241   1171   9011 omplexer.ll
   284    779   9714 omp_lib.f90
    57    119   1784 omp_lib.h
    17     76    647 omp_lib_kinds.h
  1056   3010  40607 ompparser.yy
  5207  17103 186349 total

[liao6@tux322:~/workspace/masterDevClean/sourcetree/src/midend/programTransformation/ompLowering]wc *.h *.inc *.cu *.cpp *.sh *.c 
    152     702    7533 libgomp_g.h
     51     208    1814 libompc.h
     57     130    1885 libxompf.h
    387    2424   17562 libxomp.h
    212    1232   10559 omp_lowering.h
    771    2841   38153 run_me_callers2.inc
    771    2841   35845 run_me_callers.inc
  67843  103833 1891978 run_me_defs.inc
  76291  143257 1761968 run_me_task_defs.inc
    973    4246   35237 xomp_cuda_lib.cu
    334    1921   13137 xomp_cuda_lib_inlined.cu
   5939   26563  267555 omp_lowering.cpp
     24     139    1021 run_me_caller_generator2.sh
     21     101     736 run_me_caller_generator.sh
     45     163    1138 run_me_generator.sh
     86     405    2709 run_me_task_generator.sh
    156     584    4418 xomp_accelerator_sched_test.c
    194     821    5919 xomp_accelerator_sched_test_v2.c
   1823    6642   54788 xomp.c
 156130  299053 4153955 total

间接支持源文件

[liao6@tux322:~/workspace/masterDevClean/sourcetree/src/midend/programTransformation/astOutlining]wc *.cc *.cc
   576   1390  15514 ASTtools.cc
   175    539   4869 Block.cc
   307    668   6188 Case.cc
   371   1254  10678 Check.cc
    97    537   3803 CollectVars.cc
    33     79    682 Copy.cc
   101    263   2611 ExtractIfs.cc
   219   1009   9306 GenerateCall.cc
  1422   6803  61202 GenerateFunc.cc
   185    482   3563 If.cc
    63    131   1524 IfDirectiveContextFinder.cc
   163    481   4711 IfDirectiveExtractor.cc
   785   3165  33825 Insert.cc
   149    484   4329 Jumps.cc
    59    120    945 NameGenerator.cc
   292    910   9030 NonLocalControlFlow.cc
    64    176   1895 NonLocalDecls.cc
   373   1299  12924 Outliner.cc
   405   1416  12345 PragmaInterface.cc
    41     94   1191 PrePostTraversal.cc
   102    357   3178 Preprocess.cc
   445   1373  14757 PreprocessingInfo.cc
   436   1352  12210 PreprocIfs.cc
   209    763   7185 StmtRewrite.cc
    33     85    893 This.cc
   293   1045  10043 ThisExprs.cc
   712   3499  33690 Transform.cc
   424   1405  13887 VarSym.cc
   576   1390  15514 ASTtools.cc
   175    539   4869 Block.cc
   307    668   6188 Case.cc
   371   1254  10678 Check.cc
    97    537   3803 CollectVars.cc
    33     79    682 Copy.cc
   101    263   2611 ExtractIfs.cc
   219   1009   9306 GenerateCall.cc
  1422   6803  61202 GenerateFunc.cc
   185    482   3563 If.cc
    63    131   1524 IfDirectiveContextFinder.cc
   163    481   4711 IfDirectiveExtractor.cc
   785   3165  33825 Insert.cc
   149    484   4329 Jumps.cc
    59    120    945 NameGenerator.cc
   292    910   9030 NonLocalControlFlow.cc
    64    176   1895 NonLocalDecls.cc
   373   1299  12924 Outliner.cc
   405   1416  12345 PragmaInterface.cc
    41     94   1191 PrePostTraversal.cc
   102    357   3178 Preprocess.cc
   445   1373  14757 PreprocessingInfo.cc
   436   1352  12210 PreprocIfs.cc
   209    763   7185 StmtRewrite.cc
    33     85    893 This.cc
   293   1045  10043 ThisExprs.cc
   712   3499  33690 Transform.cc
   424   1405  13887 VarSym.cc
 17068  62358 593956 total

[liao6@tux322:~/workspace/masterDevClean/sourcetree/src/frontend/SageIII/sageInterface]wc sageBuilder.C sageBuilder.h sageBuilder_fortran.C sageInterface.C sageInterface.h sageInterface_type.C
  16842   64856  784120 sageBuilder.C
   1489    8428   90956 sageBuilder.h
    104     212    3408 sageBuilder_fortran.C
  19213   71263  847054 sageInterface.C
   2406   14864  128891 sageInterface.h
   2208    7633   87896 sageInterface_type.C
  42262  167256 1942325 total

ROSE 中的 OpenMP 实现支持 OpenMP 3.0 和 OpenMP 4.0 中的加速器(GPU)支持。它有三个组成部分:前端、中间端和运行时层,分别有 4849、6151 和 6203 行代码。总共有 17203 行代码专门用于实现 OpenMP。

此外,ROSE 中还有另外两个支持组件用于帮助 OpenMP 实现:1) AST 概述器(将代码部分提取到函数中)和 2) AST 接口函数(构建和操作 AST)。AST 概述器有 17068 行代码。AST 接口函数有 42262 行代码。因此,间接源文件的行数为 42262 行。

计算直接和间接源文件,ROSE 中与 OpenMP 实现相关的代码行数为 76533 行。

使用在线软件构建成本计算器 (http://www.csgnetwork.com/costconstrmodelcalc.html),假设开发人员每月可以编写和维护 500 行代码。我们估计开发 17.2K 行专门的 OpenMP 源文件需要 48 个工作月(或使用 10K 每人每月成本率为 480K)。直接和间接源文件的总成本估计为 228 个工作月或 228 万。

我们还没有尝试将 ROSE 中的解析和反解析组件添加到此估计中。粗略估计解析输入代码和之后反解析源代码为输出需要大约 100 万行代码。

出版物

[编辑 | 编辑源代码]
  • Chunhua Liao、Yonghong Yan、Bronis R. de Supinski、Daniel J. Quinlan 和 Barbara Chapman,“OpenMP 加速器模型的早期经验”。在低功耗设备和加速器时代的 OpenMP 中,第 84-98 页。施普林格柏林海德堡,2013 年。
  • Chunhua Liao、Daniel J. Quinlan、Thomas Panas 和 Bronis de Supinski,基于 ROSE 的 OpenMP 3.0 研究编译器,支持多个运行时库,第六届 OpenMP 国际研讨会 (IWOMP),2010 年 6 月 14-16 日,日本筑波。LLNL-CONF-422873
华夏公益教科书