如何使用 clang 及其 Python 绑定解析具有 OpenACC pragma 指令的 C/C++ 程序的 AST?

问题描述 投票:0回答:1

我想解析具有 OpenACC pragma 指令的 C/C++ 程序的 AST(请参见下面的示例)。

我的最终目标是生成一个 JSON 文件,其中包含给定程序的所有

pragma
-
block of code the pragma operates on
对。因此,例如,参考下面的示例,可能的 JSON 条目对可能如下所示:

代码示例(来自 OpenACC GitHub):

#include <stdio.h>
#include <stdlib.h>

double *init(size_t size)
{
    double *array = (double *)malloc(size * sizeof(double));
#pragma acc enter data create(array[0 : size])
    return array;
}

int main(void)
{
    size_t size = 1000000;
    double *array = init(size);

#pragma acc parallel loop present(array[0 : size])
    for (size_t i = 0; i < size; ++i)
    {
        array[i] = (double)i;
    }

    printf("Value before printing: %f\n", array[42]);

#pragma acc exit data delete (array[0 : size])
    printf("This should be 42: %f\n", array[42]);
    free(array);
}

对于并行化代码块:

pragma: #pragma acc parallel loop present(array[0 : size])
code block: 
for (size_t i = 0; i < size; ++i)
    {
        array[i] = (double)i;
    }

对于(主机)CPU 和(加速器)GPU 之间的数据管理:

pragma: #pragma acc exit data delete (array[0 : size])
code block: 
printf("This should be 42: %f\n", array[42]);
    free(array);

我知道

clang
,特别是它的 Python 绑定,可以让我使用 Python 脚本解析 C/C++ 程序的 AST,我更喜欢使用 Python 脚本而不是编写 C/C++ 程序来完成相同的任务。作为参考,这是我迄今为止编写的 Python 脚本:

import clang.cindex

# Initialize the clang.cindex
clang.cindex.Config.set_library_file('/usr/local/lib/libclang.so') #'/usr/lib/x86_64-linux-gnu/libclang.so')
  
def find_openacc_directives(node):
    """Recursively search the AST for OpenACC compute directives."""
    if node.kind == clang.cindex.CursorKind.OPEN_ACC_COMPUTE_DIRECTIVE:
        print(f"Found OpenACC compute directive at {node.location}")

    # Recurse for children of this node
    for c in node.get_children():
        find_openacc_directives(c)

def parse_file(filename):
    """Parse the file with clang and search for OpenACC compute directives."""
    index = clang.cindex.Index.create()
    tu = index.parse(filename)
    find_openacc_directives(tu.cursor)

# Replace 'your_file.cpp' with your actual file name
parse_file('test2_openacc.cpp')

我希望这个脚本打印出它解析的 AST,这样我就可以看到 AST 的样子,然后最终使脚本生成并存储一个包含像上面示例中那样的对的 JSON 文件。目前,我的这个脚本没有打印任何内容。

什么脚本可以实现我上面提到的意图?我在哪里可以找到更多信息或参考资料以了解有关如何执行此操作的更多信息?

clang abstract-syntax-tree static-analysis openacc libclang
1个回答
0
投票

经过一些研究,不幸的是我只能提供部分 回答。

Clang 对 OpenACC 的支持正在进行中

Clang 当前(截至 2024 年 6 月 12 日)支持不完整。 这是 正在积极开展工作,但可能需要很长时间才能完全 到达。

  • OpenACC Tools页面上,列出了 GCC 但不支持 Clang 作为支持它的编译器。

  • 克拉克 该项目似乎旨在添加它,但尚不清楚这一努力是否 仍在进行中。

  • 基于最近的拉取请求,例如 PR #81188,承诺 正在登陆 Clang 存储库,但这似乎仍然是初步的。

如果你的

libclang.so
理解
OPEN_ACC_COMPUTE_DIRECTIVE
,它必须 是最近的(我的使用 Clang 18.1.4,但不是)。 但基于 PR,我认为 AST 节点还没有制作出来;只有 正在奠定基础、定义常量等

否则,当完全支持落地时,我认为脚本中的代码 应该可以工作(对于其他类型的 AST 节点也是如此)。

您无法使用 Python API 添加编译指示

由于缺乏内置的 OpenACC 支持,可以尝试添加解析 支持所需的

#pragma
,但这需要 C++ API。 看 如何在C中自定义pragma? (这是关于 Clang 的,尽管有问题标题)如果你想尝试 那条路线。

你可以自己解析编译指示

一种可能的方法是自己进行基于文本的解析

#pragma
,然后将它们的位置与源位置相关联 在 Clang AST 中找到。 如果我需要解析,这就是我会做的 现在就打开ACC。

您可以尝试使用 GCC 插件

显然GCC支持OpenACC,并且它有一个 插件接口可能会起作用。 不过我没有任何经验。

© www.soinside.com 2019 - 2024. All rights reserved.