性能仪器精化自动化框架PIRA解决了使用 Score-P 时为未知代码库生成合理性能测量的耗时任务。欲了解更多信息,请参阅我们的论文:
[PI18] | 扬-帕特里克·莱尔、亚历山大·哈克、克里斯蒂安·比绍夫。 PIRA:性能仪表精化自动化。第五届 ACM SIGPLAN 软件工程和并行计算系统人工智能和经验方法 (AI-SEPS) 国际研讨会,第 1-10 页,ACM,2018 年。 |
[PI19] | 扬-帕特里克·莱尔、亚历山德鲁·卡洛托尤、克里斯蒂安·比肖夫、菲利克斯·沃尔夫。用于经验性能建模的自动仪器细化。在国际编程和性能可视化工具研讨会 (ProTools)中,第 40-47 页,IEEE,2019。 |
[PI21] | 彼得·阿兹特、雅尼克·菲施勒、扬-帕特里克·莱尔、克里斯蒂安·比肖夫。 MPI 应用中的自动低开销负载不平衡检测。 Euro-Par 2021:并行处理。计算机科学讲义,第 12820 卷,第 19-34 页,Springer,2021 年。 |
PIRA 运行以下四个阶段(迭代 2-4 个阶段):
PIRA 支持函数的编译时和运行时过滤,包括通过自动生成的包装器对 MPI 函数进行运行时过滤。在编译时过滤中,仅在编译时检测所需的函数,从而显着降低总体测量影响。相反,在运行时过滤中,编译器将检测挂钩插入到目标应用程序的每个函数中,并且过滤在运行时发生。
PIRA 需要 CMake (>=3.16)、Clang/LLVM 10、Python 3、Qt5 和 OpenMPI 4。它(或 MetaCG)将进一步下载(和构建)
如果您想在无法访问互联网的环境中构建 PIRA,请参阅resources/build_submodules.sh
脚本,并根据您的需要进行调整。
克隆 PIRA 存储库。
$> git clone https://github.com/tudasc/pira
$> cd pira
其次,使用提供的脚本构建依赖的子模块,或传递不同选项的值(通过-h
查看可用选项的使用信息)。所有下载和构建的文件将放置在external/src/
中,而所有安装将放置在external/install/
中。指定为编译 PIRA 外部而生成的编译进程数。该脚本将下载 PIRA 的默认版本的依赖项。这些版本也在我们的 CI 中进行了测试,预计可以正常工作。
$> cd resources
$> ./build_submodules.sh -p <ncores>
最后一步,构建脚本会将子模块的安装路径写入文件resources/setup_paths.sh
中。如果您希望重建 PIRA,请记住git restore
此文件。
我们还提供了一个(实验性) Dockerfile
来构建 PIRA 并进行尝试。
$> podman build -t pira:master -f docker/Dockerfile .
当在容器内运行时,例如集成测试,请按如下方式调用脚本。
$> cd resources
$> . setup_paths.sh
$> cd ../test/integration/GameOfLife # Example test case
# By default PIRA will look into $HOME/.local, which is not currently existent in the docker
# XDG_DATA_HOME signals where to put the profiling data PIRA generates
$> XDG_DATA_HOME=/tmp ./run.sh
有关如何使用 PIRA 的完整示例,请查看/test/integration/*
文件夹中的run.sh
脚本。 GameOfLife
文件夹及其测试用例是一个潜在的良好起点。
首先,通过在resources
文件夹中获取脚本来设置所需的路径。
$> cd resources/
$> . setup_paths.sh
然后,您可以使用./test/integration/GameOfLife
文件夹中提供的run.sh
脚本在 Conway 的 Game of Life 的非常简单的实现上运行 PIRA 示例应用程序。
$> cd ./test/integration/GameOfLife
$> ./run.sh
该脚本从一开始就执行所需的所有步骤,即为新的目标代码准备所有组件,以最终调用 PIRA。在后续部分中,将更详细地解释这些步骤。步骤是:
config
配置文件的路径(必需参数)--config-version [1,2]
PIRA 配置的版本,2 是默认值,鼓励使用; 1 已弃用。--runtime-filter
使用运行时过滤,默认为 false。在编译时过滤中,函数不在编译时进行检测,显着降低了总体测量影响,但需要在每次迭代中重建目标。相反,通过运行时过滤,编译器会在目标应用程序的每个函数中插入检测挂钩。--iterations [number]
Pira 迭代次数,默认值为 3。--repetitions [number]
测量重复次数,默认值为 3。--tape
应写入(有点广泛)日志磁带的位置。--extrap-dir
放置 Extra-p 文件夹结构的基本目录。--extrap-prefix
Extra-P 前缀,应该是字符序列。--version
打印 PIRA 安装的版本号--analysis-parameters
包含 PGIS 分析参数的配置文件路径。 Extra-P 和 LIDe 模式均需要。--slurm-config [path to slurm cfg file]
允许在 slurm 集群上运行目标代码。需要 slurm 配置文件。请参阅本节了解更多信息。 --hybrid-filter-iters [number]
在 [number] 次迭代后重新编译,在其间使用运行时过滤。--export
将生成的 Extra-P 模型和数据集大小附加到目标的 IPCG 文件中。--export-runtime-only
需要--export
;仅将所有重复的运行时间中值附加到函数。仅在不使用 Extra-P 时可用。--load-imbalance-detection [path to cfg file]
启用并配置负载不平衡检测模式。请阅读本节以获取更多信息。 PIRA 使用源代码信息来构建初始工具并决定在迭代细化期间将哪些功能添加到工具中。它提供了一个基于 Clang 的调用图工具,可以收集所有必需的信息并将信息输出到.json
文件中。您可以在子目录./extern/src/metacg/cgcollector
中找到cgcollector
工具。 PIRA 要求调用图文件采用版本 2 (MetaCG v2) 中的 MetaCG 文件格式。
有关 CGCollector 及其组件的更多信息可以在 MetaCG 文档中找到。
应用 CGCollector 通常分两步进行。
首先,对项目中的每个源文件调用cgc
。例如:
for f in $(find ./src -type f ( -iname "*.c" -o -iname "*.cpp" ) ); do
cgc --metacg-format-version=2 $f
done
然后使用cgmerge
将步骤 1 中创建的.ipcg
文件合并为通用文件。
"null"
2. 如果您的项目包含多个main
函数,请仅合并具有正确main
函数的文件。 echo "null" > $IPCG_FILENAME
find ./src -name "*.ipcg" -exec cgmerge $IPCG_FILENAME $IPCG_FILENAME {} +
最终的图需要放入callgraph-analyzer的目录中。由于当前使用PGIS进行CG分析,因此将生成的整个程序文件复制到PGIS目录中。目前,PGIS 目录中的文件按照item_flavor.mcg
模式命名非常重要。一个项目代表一个目标应用程序。下一节将详细介绍术语风味和物品。
# Assuming $PIRA holds the top-level PIRA directory
$> cp my-app.mcg $PIRA/extern/install/pgis/bin/item_flavor.mcg
PIRA 配置包含 PIRA 运行自动过程所需的所有信息。需要在配置文件中指定的各种目录可以是绝对路径,也可以是相对于 pira 执行路径的路径。路径可能包含环境变量,例如$HOME
。这些示例取自./test/integration/GameOfLife
中的 GameOfLife 示例。
用户指定:在其中查找后续定义的项目的目录,在示例中,该目录是./gol/serial_non_template
。这些目录被赋予别名,使用“%”符号取消引用。 PIRA 中的项目是一个目标应用程序,以特定方式构建,这就是它被分组在builds下的配置中的原因。
{
"builds": {
"%gol": {
"items": {
"gol": {
...
}
}
}
}
"directories": {
"gol": "./gol/serial_non_template"
}
}
每个项目都指定应使用哪个分析仪。默认分析器随 PIRA 一起提供,源代码可以分别在./extern/src/metacg/pgis
或安装在./extern/install/pgis/bin
中找到。分析器负责指导仪器的改进,因此是 PIRA 框架的重要组成部分。
argmap字段指定运行性能实验时传递给目标应用程序的不同参数。如何将参数传递到目标应用程序由不同的映射器定义。在示例中,使用了线性映射器,它只是按照列表中给定的顺序迭代名为size的参数的值。
"argmap": {
"mapper": "Linear",
"size": [50, 80, 110, 150, 300, 500]
}
立方体字段是 PIRA 应存储获得的 Score-P 配置文件的位置。它将在该位置构建一个目录树,因此用户可以在 PIRA 完成后,通过简单地向 Extra-P 建模工具传递相应的位置(即示例中的/tmp/pira)来轻松调用 Extra-P 建模工具。
"cubes": "/tmp/pira"
风味字段增加了另一个可能的区别级别,因为目标应用程序可以以不同的风味构建。一个示例是指定目标应用程序应链接的不同数学库。
最后, functors目录将 PIRA 指向查找用户提供的 Python 函数的位置,这些函数最终告诉 PIRA 如何构建、运行和分析目标应用程序。在示例中,PIRA 指向相对于配置位置的名为functors的目录。
"flavors": [
"ct"
],
"functors": "./functors",
"mode": "CT"
在此版本的 PIRA 中,模式字段被忽略。
到目前为止,用户需要实现五个不同的函子:
analyze_<ITEM>_<FLAVOR>.py
:调用分析器。clean_<ITEM>_<FLAVOR>.py
:清理构建目录。<ITEM>_<FLAVOR>.py
:构建检测版本。no_instr_<ITEM>_<FLAVOR>.py
:构建普通版本。runner_<ITEM>_<FLAVOR>.py
:运行目标应用程序。函子通常支持两种调用模式:主动和被动。函子通过将函数get_method()
返回的字典中的相应值设置为True
来告诉 PIRA 它使用哪种模式。
在主动模式下,仿函数本身会调用所需的命令,例如构建软件。调用时,函子会传递一个**kwargs
参数,其中包含当前目录和子进程 shell 的实例等。
被动模式仅返回要执行的命令,例如字符串make
来调用项目顶级目录中的简单 Makefile。它还传递一个kwargs
参数,该参数保存特定信息,例如添加到 CXXFLAGS 或其他链接器标志所需的预定义值。被动函子的示例可以在examples
和test
目录中找到。目前,所有实现的函子都使用被动模式。
PIRA 将以下关键字参数传递给所有函子。此外,不同的 PIRA 组件可能会传递额外的参数。
重要提示:我们现在推出自己的 Score-P 版本。因此,不再需要调整 PIRA 中的编译命令。查看test/integration/AMG2013
中的函子,了解不同信息的用法示例。
目前,没有信息传递给所有函子
[0]
访问第一个参数, [1]
访问第二个参数,依此类推。.so
文件的路径(对于 MPI 过滤至关重要)。 某些分析模式需要附加参数。具体来说,PIRA LIDe(见下文)和 Extra-P 建模分析需要用户提供参数。创建一个 JSON 文件并使用--analysis-parameters
-switch 提供其到 PIRA 的路径。以下示例包含 Extra-P 建模模式的参数。聚合多个 Extra-P 模型(当在不同上下文中调用函数时)的可用策略有: FirstModel
、 Sum
、 Average
、 Maximum
。
{
"Modeling": {
"extrapolationThreshold": 2.1,
"statementThreshold": 200,
"modelAggregationStrategy": "Sum"
}
}
有关负载不平衡检测功能的更多详细信息,请参阅[PI21]。使用--load-imbalance-detection
参数为 PIRA 调用提供配置文件的路径。该 JSON 文件需要具有以下结构:
{
"metricType": "ImbalancePercentage",
"imbalanceThreshold": 0.05,
"relevanceThreshold": 0.05,
"contextStrategy": "None",
"contextStepCount": 5,
"childRelevanceStrategy": "RelativeToMain",
"childConstantThreshold": 1,
"childFraction": 0.001
}
要使用 SLURM 工作负载管理器在集群上运行 PIRA,请使用--slurm-config
标志调用它。给出批处理系统配置文件的路径。请参阅以_Slurm
为后缀的集成测试 ( test/integration/*_Slurm/
)。 PIRA 目前支持带有 SLURM 工作负载管理器的批处理系统。 PIRA 支持使用module
系统,该系统可以在 slurm 集群上找到。
批处理系统配置文件是一个JSON文件,其结构如下:
{
"general": {
"backend": "slurm",
"interface": "pyslurm",
"timings": "subprocess"
},
"module-loads": [
{
"name": "gcc",
"version": "8.5"
},
{
"name": "llvm",
"version": "10.0.0",
"depends-on": [
{
"name": "gcc",
"version": "8.5"
}
]
}
],
"batch-settings": {
"time_str": "00:10:00",
"mem_per_cpu": 3800,
"number_of_tasks": 1,
"partition": null,
"reservation": null,
"account": "your_account_here",
"cpus_per_task": 96
}
}
分解:
general
部分:允许您选择 PIRA 在批处理系统上执行代码的方式。由于本节中的每个选项都是可选的,因此如果您愿意使用默认值,则可以省略整个部分:backend
:使用什么工作负载管理器。选择: slurm
,用于 slurm 工作负载管理器。默认值: slurm
,因此可选。interface
:PIRA 应以何种方式与批处理系统管理器进行交互。对于 SLURM 后端,这些是: pyslurm
,使用 PySlurm (这需要安装 PySlurm,请参阅本节; sbatch-wait
,使用带--wait
标志的标准sbatch
; os
,用于标准sbatch
和squeue
交互调用。默认值: pyslurm
,因此可选。timings
:目标代码的计时应该如何完成。选择: subprocess
,用于在子进程中使用 python 包装器和os.times
进行计时(如果在本地运行,则与 PIRA 的做法完全相同); os
,使用/usr/bin/time
。默认值: subprocess
,因此可选。force-sequential
:默认false
。设置为true
以强制 PIRA/批处理系统按顺序执行所有运行(一次仅执行一次目标代码)。这意味着 PIRA 将注意您的批处理系统运行重复,以及按顺序扩展实验中的不同作业。如果设置为false
保留为 false,PIRA 将尝试指示批处理系统在每次迭代中并行执行尽可能多的执行。module-loads
部分:目前未在 PIRA 中使用,正在进行中!目前,您需要在启动 PIRA 之前手动加载所有模块!意味着哪些模块应该与module
系统一起加载。这需要一个到位(PIRA 可能使用命令module load
和module purge
)。如果您没有适当的module
系统,或者不想使用它,请完全忽略此部分,或设置"module-loads": null
。要指定 PIRA 应加载的模块,请指定模块列表,如上例所示。name
。version
是可选的,如果没有给出,它将取决于module
系统加载的默认模块版本。建议始终明确给出版本。depends-on
也是可选的。给出该模块所依赖的模块列表。这些模块必须有一个name
,并且可以选择指定version
。 PIRA 使用此处定义的依赖项来确定模块的加载顺序null
,则假定该模块没有依赖项。depends-on
PIRA 将(尝试)完全按照配置文件中给出的顺序加载模块。batch-setting
部分:批处理系统的实际硬件和作业选项。该部分中的某些选项是强制性的,您不能省略该部分。time
: sbatch --time
选项,强制。mem-per-cpu
: sbatch --mem-per-cpu
选项,强制。ntasks
: sbatch --ntasks
选项,强制。partition
、 reservation
、 account
(全部默认为null
=未给定)、 cpus-per-task
(默认为4
)、 exclusive
(默认为true
; pyslurm
不支持)和cpu-freq
(默认为null
)。sbatch
选项。这是由于 PIRA 内部使用了一些选项(例如--array
选项)来将重复映射到作业数组。 如何在集群上安装 PySlurm 以及安装哪个版本,很大程度上取决于您的 SLURM 版本和 SLURM 安装。 pyslurm 与 PIRA 的安装和打包解决方案正在进行中。请参阅他们的自述文件。您可以尝试以下一些方法:
include
和lib
目录。python3 setup.py build --slurm-lib=/opt/slurm/21.08.6/lib --slurm-inc=/opt/slurm/21.08.6/include
python3 setup.py install --slurm-lib=/opt/slurm/21.08.6/lib --slurm-inc=/opt/slurm/21.08.6/include
。