diff --git a/software/utils/cruiser/README.md b/software/utils/cruiser/README.md
index 0ccab0ed154e525adbaac2c692226c2e7683b65d..68cdf8c1b14fdca48c9b10d2616bddbddf4dd799 100644
--- a/software/utils/cruiser/README.md
+++ b/software/utils/cruiser/README.md
@@ -1,53 +1,379 @@
-# cruiser
-### 项目介绍
-Cruiser是一款自动化精度分析工具。能够针对所提供的源码进行半自动化差异源分析,定位到函数级差异源码。大幅降低精度分析难度。
+# 精度分析库libcruiser.so
-### 现行版本
+### 工具简介
-1.2.0
+本项目的核心能力库,提供了底层对变量的hash和NaN/Inf值检测的能力。该库具备多进程场景下分RANK判断的能力,能够准确地识别和处理精度差异问题。此外,输出的日志可以与待优化程序的日志耦合在一起输出,也可以单独输出到单独的日志文件中。
-### 二进制地址
+### 工具版本
-[cruiser.exe](https://gitee.com/kirky_x/kuneng-hpc-bin/tree/master/cruiser)
+2.2.0
-### 使用说明
+- **增加对线程的感知:**增加用于非MPI,多线程场景下的使用能力,适配EDA等场景的软件特性
+- **增加对老版本编译器的适应能力:**针对一些接口适配了低版本编译器,增加场景适配能力
+- **增强版本管理能力:**通过软链接增加用户对分析库的版本感知能力
-Cruiser仅支持命令行方式进行使用,支持选项参数和配置文件两种配置输出方式进行使用。工具默认运行方式:参数选项方式。
+### 适用变量
-#### 参数选项方式
+- **√ 支持**
+
+ 基本变量,基本变量数组,结构体当中的基本变量,结构体当中的数组
+
+- **× 不支持**
+
+ 链表,整个结构体变量,结构体变量数组
+
+### 适用场景
+
+1. **双平台精度差异定位:**将变量hash成md5值,对比程序在双平台运行后输出日志中的md5值,递归定位,最终定位导致精度差异的源码。
+
+ ```text
+ [FLAG]:Custom Flag [PARAM]:Name of Parameter [MODE]:Mpi Mode [RESULT]: Md5 Value of Parameter
+ ```
+
+
+
+2. **变量异常值(NaN/Inf)定位:**检测传入的变量是否为NaN/Inf值,是否含有或全部为NaN/Inf值。
+
+ ```shell
+ # [变量/数组] 全部为NaN值或Inf值
+ [FLAG]:Custom Flag [PARAM]:Name of Parameter [MODE]:Mpi Mode [RESULT]:ALL NAN
+
+ # [数组] 存在NaN值或Inf值
+ [FLAG]:Custom Flag [PARAM]:Name of Parameter [MODE]:Mpi Mode [RESULT]:ALL NAN
+ ```
+
+### 结果说明
+
+| 结果项 | 说明 |
+| -------- | --------------------------------------------------- |
+| [FLAG] | 用户自定义标志位 |
+| [PARAM] | 变量名称 |
+| [MODE] | MPI模式 |
+| [RESULT] | 输出结果,结果为32位hash值或者ALL NAN 或者EXIST NAN |
+
+### 目录结构
```shell
-./cruiser.exe [options]
+/path/to/libcruiser
+├── include
+│ ├── cruiser.h #适用MPI版本头文件
+│ └── cruiser_thr.h #适用多线程版本头文件
+└── lib
+ ├── libcruiser_mpi.so -> libcruiser_mpi.so.2
+ ├── libcruiser_mpi.so.2 -> libcruiser_mpi.so.2.2.0
+ ├── libcruiser_mpi.so.2.2.0 #适用仅MPI场景,mode输出:RANK-1
+ ├── libcruiser.so -> libcruiser.so.2
+ ├── libcruiser.so.2 -> libcruiser.so.2.2.0
+ ├── libcruiser.so.2.2.0 #适用MPI-多线程混合场景,mode输出:RANK-1-TID-10001
+ ├── libcruiser_thr.so -> libcruiser_thr.so.2
+ ├── libcruiser_thr.so.2 -> libcruiser_thr.so.2.2.0
+ └── libcruiser_thr.so.2.2.0 #使用仅多线程场景,mode输出:TID-10001
```
-#### 配置文件方式
+### 快速上手
-```shell
-./cruiser.exe --config config.ini
+1. 将工具压缩包`libcruiser.tar.gz`上传至服务器并解压。上传路径一般为项目源码的根目录。此处假设上传路径为:`/path/to/cruiser`。
+
+ ```shell
+ cd /path/to/cruiser
+ tar -xvf libcruiser.tar.gz
+ mv ./cruiser/* .
+ ```
+
+ 需要注意:若服务器为集群环境,则需要上传至共享目录中。
+
+2. ,在待精度调优的软件源码中插入输出语句,即调用对应API。若源码为C/C++语言,则源码中需要引入头文件cruiser.h。
+
+3. 修改项目源码编译脚本,在程序链接选项中追加以下语句:
+
+ ```shell
+ -L/path/to/cruiser/lib -lcruiser -lcrypto
+ ```
+
+ 若编译器版本为GNU且版本低于4.5:
+
+ ```shell
+ -L/path/to/cruiser/lib -lcruiser -lcrypto -lm
+ ```
+
+ 若源码为C/C++语言,则需额外追加头文件地址:
+
+ ```shell
+ -L/path/to/cruiser/lib -lcruiser -lcrypto -I/path/to/cruiser/include
+ ```
+
+4. 修改运行脚本,加入以下语句。
+
+ ```shell
+ export LD_LIBRARY_PATH=/path/to/cruiser/lib:$LD_LIBRARY_PATH
+ ```
+
+ (可选)工具默认将结果输出至标准输出,如需将精度日志重定向到指定文件,则需在运行脚本中指定重定向的路径,工具会将日志重定向到该路径下的`cruiser.log`文件当中。若指定的文件夹没有可写权限时,将自动将日志重定向至`$HOME`目录下。
+
+ ```shell
+ # 假定日志需重定向输出至/path/to/,日志将会被重定向至/path/to/cruiser.log
+ export CRUISER_LOG=/path/to/
+ ```
+
+5. 编译并运行程序。
+
+6. 手动或使用自动化定位工具`cruiser.exe`对比输出的日志,找到差异情况。
+
+7. 递归使用,找到导致精度差异的源码。
+
+### 接口预览
+
+##### 仅多线程场景
+
+- 值差异场景
+
+ ```c
+ // C/C++接口
+ void Hash(void *data, const char *name_data, int type, int len_data, const char *flag);
+
+ // Fortran接口
+ void hash(void *data, const char *name_data, const int *type, const int *len_data, const char *flag);
+ ```
+
+- NaN/Inf值场景
+
+ ```c
+ // C/C++接口
+ void Nan(void *data, const char *name_data, int type, int len_data, const char *flag);
+
+ // Fortran接口
+ void nan(void *data, const char *name_data, const int *type, const int *len_data, const char *flag);
+ ```
+
+- 综合场景(即打印hash值,也检测Na/Inf值)
+
+ ```c
+ // C/C++接口
+ void Cruiser(void *data, const char *name_data, int type, int len_data, const char *flag);
+
+ // Fortran接口
+ void cruiser(void *data, const char *name_data, const int *type, const int *len_data, const char *flag);
+ ```
+
+##### MPI场景
+
+- 值差异场景
+
+ ```c
+ // C/C++接口
+ void Hash(void *data, const char *name_data, int type, int len_data, const char *flag, int rank);
+
+ // Fortran接口
+ void hash(void *data, const char *name_data, const int *type, const int *len_data, const char *flag, const int *rank);
+ ```
+
+- NaN/Inf值场景
+
+ ```c
+ // C/C++接口
+ void Nan(void *data, const char *name_data, int type, int len_data, const char *flag, int rank);
+
+ // Fortran接口
+ void nan(void *data, const char *name_data, const int *type, const int *len_data, const char *flag, const int *rank);
+ ```
+
+- 综合场景(即打印hash值,也检测Na/Inf值)
+
+ ```c
+ // C/C++接口
+ void Cruiser(void *data, const char *name_data, int type, int len_data, const char *flag, int rank);
+
+ // Fortran接口
+ void cruiser(void *data, const char *name_data, const int *type, const int *len_data, const char *flag, const int *rank);
+ ```
+
+##### 额外接口
+
+ 为了解决Fortran与C/C++语言间,字符串结构不同带来的字符串变量乱码现象,提供一个字符串修正的Fortran接口进行使用。本接口最大支持256个字符。
+
+ ```fortran
+ character correct(string)
+ ```
+
+##### 参数含义
+
+ | 变量名 | 类型 | 含义 | 备注 |
+ | --------- | ------------------------------------- | ------------------ | ------------------------------------------------------------ |
+ | data | void* | 变量地址 | - |
+ | name_data | const char * | 变量名称 | - |
+ | type | C/C++: int,
Fortran: const int * | 变量类型 | 建议接口:
C/C++: sizeof(x) or sizeof(x[0]),
Fortran: kind(x) |
+ | len_data | C/C++: int,
Fortran: const int * | 变量长度 | 建议接口:
C/C++: 1 or sizeof(x)/sizeof(x[0]),
Fortran: size(x) |
+ | flag | const char * | 用户自定义字符串, | 建议此处传入充分的信息
filename(文件路径,建议使用绝对路径)
\|function(方法名称,包含类信息和方法信息)
\|mode(模式位,call function or assign parameter)
\|status(状态位,START或者END)\|row(行号) |
+ | rank | C/C++: int,
Fortran: const int * | 指定rank号 | 在rank=-1时,使能全rank打印模式;
在rank=0时,使能主进程模式;
在rank为正整数时,使能指定rank输出模式;
在单进程场景下,指定任何数都无影响。 |
+
+
+
+### 使用样例
+
+样例以值差异场景为基础进行介绍,NaN/Inf值场景和综合场景可以通过替换API进行达成。所有接口在不同场景下的参数类型相同,可进行替换进行使用。
+
+##### C/C++
+
+假定初始源码文件:/path/to/source.c。
+
+```c
+int function(int param1, float param2){
+ double param3[] = {...};
+ ...
+ function1(param1, param3);
+ ...
+ param2 = function2();
+ ...
+ return 0;
+}
+```
+
+一般情况
+
+```c
+#incldue
+
+int function(int param1, float param2){
+ double param3[] = {...};
+ ...
+ int type = sizeof(param3[0]);
+ int length = sizeof(param3)/type;
+ Hash(¶m1, "param1", sizeof(param1), 1, "/path/to/source.c|function|call function1|START|8", -1);
+ Hash(¶m3, "param3", type, length, "/path/to/source.c|function|call function1|START|9", -1);
+ function1(param1, param3);
+ Hash(¶m1, "param1", sizeof(param1), 1, "/path/to/source.c|function|call function1|END|11", -1);
+ Hash(¶m3, "param3", type, length, "/path/to/source.c|function|call function1|END|12", -1);
+ ...
+ Hash(¶m2, "param2", sizeof(param2), 1, "/path/to/source.c|function|assign param2|START|14", -1);
+ param2 = function2();
+ Hash(¶m2, "param2", sizeof(param2), 1, "/path/to/source.c|function|assign param2|START|16", -1);
+ ...
+ return 0;
+}
+
+// 输出
+[FLAG]:/path/to/source.c|function|call function1|START|8 [PARAM]:param1 [MODE]:SINGLE [RESULT]: e58ew9w6w58d4s2s3w8errh135hsey30
+[FLAG]:/path/to/source.c|function|call function1|START|9 [PARAM]:param3 [MODE]:SINGLE [RESULT]: 34f6hn1ryt54i3a1v3s8t4i73avdgsh6
+[FLAG]:/path/to/source.c|function|call function1|END|11 [PARAM]:param1 [MODE]:SINGLE [RESULT]: df5j4dh1d54hd43215d35fdjh8d2f1hf
+[FLAG]:/path/to/source.c|function|call function1|END|12 [PARAM]:param3 [MODE]:SINGLE [RESULT]: fd54h6gasr4h6gs5dh48a4r651dvb8br
+[FLAG]:/path/to/source.c|function|assign param2|START|14 [PARAM]:param2 [MODE]:SINGLE [RESULT]: r45ha16fh5b4fhs1gd4fh4rhb4r8h45s
+[FLAG]:/path/to/source.c|function|assign param2|END|16 [PARAM]:param2 [MODE]:SINGLE [RESULT]: sr65h46h46d4n6h4r84eh5rh151brh84
+```
+
+指定进程号
+
+```c
+#incldue
+
+int function(int param1, float param2){
+ double param3[] = {...};
+ ...
+ int rank = 66;
+ ...
+ int type = sizeof(param3[0]);
+ int length = sizeof(param3)/type;
+ Hash_Rank(¶m1, "param1", sizeof(param1), 1, "/path/to/source.c|function|call function1|START|12", rank);
+ Hash_Rank(¶m3, "param3", type, length, "/path/to/source.c|function|call function1|START|13", rank);
+ function1(param1, param3);
+ Hash_Rank(¶m1, "param1", sizeof(param1), 1, "/path/to/source.c|function|call function1|END|15", rank);
+ Hash_Rank(¶m3, "param3", type, length, "/path/to/source.c|function|call function1|END|16", rank);
+ ...
+ Hash_Rank(¶m2, "param2", sizeof(param2), 1, "/path/to/source.c|function|assign param2|START|18", rank);
+ param2 = function2();
+ Hash_Rank(¶m2, "param2", sizeof(param2), 1, "/path/to/source.c|function|assign param2|START|20", rank);
+ ...
+ return 0;
+}
+// 输出
+[FLAG]:/path/to/source.c|function|call function1|START|8 [PARAM]:param1 [MODE]:RANK-66 [RESULT]: e58ew9w6w58d4s2s3w8errh135hsey30
+[FLAG]:/path/to/source.c|function|call function1|START|9 [PARAM]:param3 [MODE]:RANK-66 [RESULT]: 34f6hn1ryt54i3a1v3s8t4i73avdgsh6
+[FLAG]:/path/to/source.c|function|call function1|END|11 [PARAM]:param1 [MODE]:RANK-66 [RESULT]: df5j4dh1d54hd43215d35fdjh8d2f1hf
+[FLAG]:/path/to/source.c|function|call function1|END|12 [PARAM]:param3 [MODE]:RANK-66 [RESULT]: fd54h6gasr4h6gs5dh48a4r651dvb8br
+[FLAG]:/path/to/source.c|function|assign param2|START|14 [PARAM]:param2 [MODE]:RANK-66 [RESULT]: r45ha16fh5b4fhs1gd4fh4rhb4r8h45s
+[FLAG]:/path/to/source.c|function|assign param2|END|16 [PARAM]:param2 [MODE]:RANK-66 [RESULT]: sr65h46h46d4n6h4r84eh5rh151brh84
+```
+
+##### Fortran
+
+假定初始源码文件:/path/to/source.F90。
+
+```fortran
+subroutine function
+ ...
+ implicit none
+ integer param1
+ real :: param2
+ double :: param3(:)
+ ...
+ call function(param1, param3)
+ ...
+ param2 = call function2()
+ ...
+end subroutine function
```
-### 选项支持
-
-| 选项 | 说明 | 默认值 |
-| ------------------ | ------------------------------------------------------------ | ------------------------------------- |
-| --config | 指定使用配置文件对工具进行配置初始化。此选项具有排他性,使用后其他选项均失效。 | - |
-| --root | 指定源码目录 | 默认程序运行路径 |
-| --log-arm | 指定arm平台运行所生成日志的路径 | 默认程序运行路径下名为‘arm.log’的文件 |
-| --log-x86 | 指定x86平台运行所生成日志的路径 | 默认程序运行路径下名为‘x86.log’的文件 |
-| --log | 指定cruiser日志输出的路径 | 默认程序运行路径下名为‘log’的文件夹 |
-| --log-mode | 指定日志输出的模式。支持:
**ALL(全量模式)**:将使用所有支持的模式。
**STANDARD(标准输出模式)**:指定将工具的日志输出到标准输出上。
**FILE(文本文件模式)**:指定将工具的日志以文本文件的形式输出到log指定的目录当中。 | ALL(不区分大小写) |
-| --hook-granularity | 指定插桩的粒度。支持:
**ALL(全量模式)**:使用在MPI使能场景,将带进程号打印所有进程中插桩标记的变量的md5值。
**MASTER(主进程模式)**:使用在MPI使能场景,将只打印主进程中插桩标记的变量的md5值。
**SINGLE(单进程模式)**:使用在非MPI使能场景,将打印该执行进程中插桩标记的变量的md5值。注意:在MPI使能场景下,将不带ramk号打印所有标记的变量的md5值。 | MASTER(不区分大小写) |
-| --hook-style | 指定接口的风格。目前支持:INC,NATIVE。
**INC**:头文件样式,需要与dump_hook_xxx.inc匹配才能使用。
**NATIVE**:原生风格,c接口形式。 | NATIVE |
-| --hook-level | 指定向下递归插桩函数的层级数,在HOOK.mode为主时生效。 | 5 |
-| --hook-split | 指定插桩过程中参数过长时的切割长度。 | 2 |
-| --hook-main | 指定主函数模式下,主函数位置,以(文件路径,[类名.]函数名)的格式,支持多个指定。 | - |
-| --filter-path | 索引时要跳过的路径。 | - |
-| --filter-file | 索引时要跳过的文件。 | |
-| --help | 获取选项信息。 | - |
-
-### 注意事项
-
-目前插装时会自动将结构体一同插入输出桩,需手动进行删除。
+一般情况
+```fortran
+subroutine function
+ ...
+ implicit none
+ character :: correct
+ integer param1
+ real :: param2
+ double :: param3(:)
+ ...
+ call hash(¶m1, correct("param1", kind(param1), 1, correct("/path/to/source.F90|function|call function1|START|8"), -1)
+ call hash(¶m3, correct("param3", kind(param3), size(param3), "/path/to/source.F90|function|call function1|START|9"), -1)
+ call function(param1, param3)
+ call hash(¶m1, correct("param1", kind(param1), 1, correct("/path/to/source.F90|function|call function1|END|11"), -1)
+ call hash(¶m3, correct("param3", kind(param3), size(param3), correct("/path/to/source.F90|function|call function1|END|12"), -1)
+ ...
+ call hash(¶m1, correct("param1", kind(param1), 1, correct("/path/to/source.F90|function|assign param2|START|14"), -1)
+ param2 = call function2()
+ call hash(¶m1, correct("param1", kind(param1), 1, correct("/path/to/source.F90|function|assign param2|START|16"), -1)
+ ...
+end subroutine function
+
+! 输出
+[FLAG]:/path/to/source.F90|function|call function1|START|8 [PARAM]:param1 [MODE]:SINGLE [RESULT]: e58ew9w6w58d4s2s3w8errh135hsey30
+[FLAG]:/path/to/source.F90|function|call function1|START|9 [PARAM]:param3 [MODE]:SINGLE [RESULT]: 34f6hn1ryt54i3a1v3s8t4i73avdgsh6
+[FLAG]:/path/to/source.F90|function|call function1|END|11 [PARAM]:param1 [MODE]:SINGLE [RESULT]: df5j4dh1d54hd43215d35fdjh8d2f1hf
+[FLAG]:/path/to/source.F90|function|call function1|END|12 [PARAM]:param3 [MODE]:SINGLE [RESULT]: fd54h6gasr4h6gs5dh48a4r651dvb8br
+[FLAG]:/path/to/source.F90|function|assign param2|START|14 [PARAM]:param2 [MODE]:SINGLE [RESULT]: r45ha16fh5b4fhs1gd4fh4rhb4r8h45s
+[FLAG]:/path/to/source.F90|function|assign param2|END|16 [PARAM]:param2 [MODE]:SINGLE [RESULT]: sr65h46h46d4n6h4r84eh5rh151brh84
+```
+
+指定进程号
+
+```fortran
+subroutine function
+ ...
+ implicit none
+ character :: correct
+ integer param1
+ real :: param2
+ double :: param3(:)
+ ...
+ call hash_rank(¶m1, correct("param1"), kind(param1), 1, correct("/path/to/source.F90|function|call function1|START|8"), 66)
+ call hash_rank(¶m3, correct("param3"), kind(param3), size(param3), correct("/path/to/source.F90|function|call function1|START|9"), 66)
+ call function(param1, param3)
+ call hash_rank(¶m1, correct("param1"), kind(param1), 1, correct("/path/to/source.F90|function|call function1|END|11", 66)
+ call hash_rank(¶m3, correct("param3"), kind(param3), size(param3), correct("/path/to/source.F90|function|call function1|END|12"), 66)
+ ...
+ call hash_rank(¶m1, correct("param1"), kind(param1), 1, correct("/path/to/source.F90|function|assign param2|START|14"), 66)
+ param2 = call function2()
+ call hash_rank(¶m1, correct("param1"), kind(param1), 1, correct("/path/to/source.F90|function|assign param2|START|16"), 66)
+ ...
+end subroutine function
+
+! 输出
+[FLAG]:/path/to/source.F90|function|call function1|START|8 [PARAM]:param1 [MODE]:RANK-66 [RESULT]: e58ew9w6w58d4s2s3w8errh135hsey30
+[FLAG]:/path/to/source.F90|function|call function1|START|9 [PARAM]:param3 [MODE]:RANK-66 [RESULT]: 34f6hn1ryt54i3a1v3s8t4i73avdgsh6
+[FLAG]:/path/to/source.F90|function|call function1|END|11 [PARAM]:param1 [MODE]:RANK-66 [RESULT]: df5j4dh1d54hd43215d35fdjh8d2f1hf
+[FLAG]:/path/to/source.F90|function|call function1|END|12 [PARAM]:param3 [MODE]:RANK-66 [RESULT]: fd54h6gasr4h6gs5dh48a4r651dvb8br
+[FLAG]:/path/to/source.F90|function|assign param2|START|14 [PARAM]:param2 [MODE]:RANK-66 [RESULT]: r45ha16fh5b4fhs1gd4fh4rhb4r8h45s
+[FLAG]:/path/to/source.F90|function|assign param2|END|16 [PARAM]:param2 [MODE]:RANK-66 [RESULT]: sr65h46h46d4n6h4r84eh5rh151brh84
+```
diff --git a/software/utils/cruiser/kp_libprintmd5.so b/software/utils/cruiser/kp_libprintmd5.so
deleted file mode 100644
index 7a5472dca75f61c1eca209eba3fa6ac43e51bf53..0000000000000000000000000000000000000000
Binary files a/software/utils/cruiser/kp_libprintmd5.so and /dev/null differ
diff --git a/software/utils/cruiser/kunpeng/config_template.ini b/software/utils/cruiser/kunpeng/config_template.ini
new file mode 100644
index 0000000000000000000000000000000000000000..0944cd43a957d57da2b592fe863ecc6651b87d0d
--- /dev/null
+++ b/software/utils/cruiser/kunpeng/config_template.ini
@@ -0,0 +1,57 @@
+[INITIAL]
+; The root directory of the source code. By default, the program running directory is selected as the source code root directory
+dir_root =
+; The log file name output by the platform 1
+log_1 =
+; The log file name output by the platform 2
+log_2 =
+; Specify the main function entry of the program, which only takes effect when 'mode' is set to MAIN
+; format: (directory1, class.function), (directory2, function), ...
+; NOTE: No space characters in the path!!!
+main =
+
+[LOGGER]
+; The log directory
+log_path =
+; The log mode currently supports: ALL, STANDARD, FILE, CSV.
+; standard: Redirect log data to standard output
+; FILE: Redirect the log data to the log file
+; CSV: Redirect the log data to the csv file
+; Using all will apply all output modes
+mode = ALL
+
+[HOOK]
+; Hook mode. The hook mode currently supports: MAIN, LOG, and log mode is used by default
+; MAIN: Hook from the main function to all variables in the sub-function called by the lower level
+; LOG: Hook different variables according to the logs generated by different platforms
+mode = log
+; The process granularity of program log printing. Now supports: ALL, MASTER, SINGLE
+; ALL: For multi-process programs, print the output of all processes
+; MASTER: For multi-process programs, only the output of the main process (process 0) is printed
+; SINGLE: For single-process programs
+granularity = MASTER
+; Stake in statement style. Currently supported: INC, NATIVE
+; INC: Header file style, which needs to be matched with dump_hook_xxx.inc for use
+; NATIVE: Native style, c interface form
+style = INC
+; Configure cruiser's current capabilities, currently supporting HASH and NAN capabilities
+capacity = HASH
+; Setting whether the code is compiled using the GNU compiler will affect the compilation of program instrumentation.
+; This option takes effect when style is 'NATIVE'
+;is_gnu = FALSE
+; The number of levels of downward recursive hooking sub-functions takes effect when HOOK.mode is main
+depth = 3
+; The number of cutting for too long parameters during hook.
+split = 2
+; The regular expression of analyzing flag data in the log
+separator = |
+
+[FILTER]
+; Path to skip when indexing. Please use a relative path relative to the root directory
+path =
+; File to skip when indexing. Please use a relative path relative to the root directory
+file = *.F
+; Class to skip when indexing
+class =
+; Function to skip when indexing
+function =
diff --git a/software/utils/cruiser/kunpeng/cruiser.exe b/software/utils/cruiser/kunpeng/cruiser.exe
new file mode 100644
index 0000000000000000000000000000000000000000..5b9654204ef2e378eca949c480862bd6e27c5f37
Binary files /dev/null and b/software/utils/cruiser/kunpeng/cruiser.exe differ
diff --git a/software/utils/cruiser/kunpeng/libcruiser-2.2.0-arm.tar.gz b/software/utils/cruiser/kunpeng/libcruiser-2.2.0-arm.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..32245a85933dee8bfea616c4482e33f0419defa0
Binary files /dev/null and b/software/utils/cruiser/kunpeng/libcruiser-2.2.0-arm.tar.gz differ
diff --git a/software/utils/cruiser/usage.md b/software/utils/cruiser/usage.md
new file mode 100644
index 0000000000000000000000000000000000000000..640930a571dfa3411a3e5b20687eb9c19522ce2b
--- /dev/null
+++ b/software/utils/cruiser/usage.md
@@ -0,0 +1,59 @@
+# cruiser
+# 悟合(Cuiser)——自动化精度定位工具
+
+### 项目介绍
+
+悟合(项目英文名:Cruiser)是一款先进的自动化精度差异定位工具,致力于帮助用户准确识别和解决同一套程序代码在不同芯片架构下的精度差异问题。
+
+在当前市场上,x86架构和arm架构是主流的芯片架构。然而,由于这两种架构底层的浮点计算位数、存储比特位数以及指令集的差异,使得同一套程序代码在运行后可能会产生不一致的结果,即发生了精度差异。这种差异不仅会影响程序的准确性和可靠性,还可能会造成不可预计的负面影响。
+
+为了应对这一挑战,悟合应运而生。它提供了一套全面而高效的精度定位解决方案,旨在帮助用户快速准确地定位导致精度差异的原因。无论是编译器、数学库、通信库等软件,还是交换机、网口等硬件导致的精度差异,悟合都能深入分析并找出潜在的,不易发现的精度差异源。
+
+悟合具备严谨、正式和专业的特点,以确保文案的准确性和专业性。它不仅能够帮助开发人员提高程序的精度和稳定性,还能够节省宝贵的时间和资源。通过使用悟合工具,用户可以更加自信地交付高质量的精度解决方案,满足用户的需求和期望。
+
+无论您是一名开发人员、测试人员还是项目经理,悟合都是您的得力助手。它将帮助您更好地理解和解决精度差异问题,提升软件开发的效率和质量。选择悟合,选择卓越的精度定位解决方案!
+
+### 项目功能
+
+按照差异类型可以将精度差异分为值差异类型的精度差异和NaN/Inf值类型的精度差异。本项目提供的能力为一种精度优化的解决方能,此方案能够定位并解决上述的这两种类型的精度差异问题。通过使用我们的工具,您可以轻松地定位出发生精度问题的具体代码行数,即定位到具体诱发精度差异的语句。
+
+| 精度差异类型 | 能力情况 |
+| ------------- | -------- |
+| 值差异类型 | 支持 √ |
+| NaN/Inf值类型 | 支持 √ |
+
+本项目分为自动化定位工具cruiser.exe和精度分析库libcruiser.so组成。
+
+- **自动化定位工具cruiser.exe:**具备强大的源码分析能力,能够快速分析源代码,并自动将插桩语句插入源码中。这一功能大大减少了人工对源码的分析成本,提升了精度差异定位的速度和调优效率。通过使用cruiser.exe,您可以在较短的时间内找到导致精度问题的代码行,从而节省宝贵的定位时间。
+- **精度分析库libcruiser.so:**本项目的核心能力库,提供了底层对变量的hash和NaN/Inf值检测的能力。该库具备多进程场景下分RANK判断的能力,能够准确地识别和处理精度差异问题。此外,输出的日志可以与待优化程序的日志耦合在一起输出,也可以单独输出到单独的日志文件中。这种灵活性使得您可以根据需要选择最合适的输出方式。
+
+本项目的目标是提供一个全面而高效的解决方案,帮助开发人员快速定位和解决精度差异问题。通过使用我们的工具和库,您可以提高代码质量和性能,减少调试和维护的时间成本。无论是在软件开发过程中还是在优化阶段,本项目都能为您提供有力的支持。
+
+### 现行版本
+
+2.2.0
+
+### 使用说明
+
+Cruiser仅支持配置文件方式进行使用。
+
+主函数模式:需在ini配置文件中指定dir_root、main、log_path
+
+日志模式:需在ini配置文件中指定dir_root、log_1、log_2、log_path
+
+#### 配置文件方式
+
+```shell
+./cruiser.exe --config config.ini
+```
+
+### 选项支持
+
+| 选项 | 说明 | 默认值 |
+| ------------------ | ------------------------------------------------------------ | ------------------------------------- |
+| --config/-f | 指定使用配置文件对工具进行配置初始化。此选项具有排他性,使用后其他选项均失效。 | - |
+| --help | 获取选项信息。 | - |
+
+### 注意事项
+
+目前自动化情况不支持复杂结构体,全局变量,且语言仅支持fortran。
\ No newline at end of file
diff --git a/software/utils/cruiser/x86/config_template.ini b/software/utils/cruiser/x86/config_template.ini
new file mode 100644
index 0000000000000000000000000000000000000000..0944cd43a957d57da2b592fe863ecc6651b87d0d
--- /dev/null
+++ b/software/utils/cruiser/x86/config_template.ini
@@ -0,0 +1,57 @@
+[INITIAL]
+; The root directory of the source code. By default, the program running directory is selected as the source code root directory
+dir_root =
+; The log file name output by the platform 1
+log_1 =
+; The log file name output by the platform 2
+log_2 =
+; Specify the main function entry of the program, which only takes effect when 'mode' is set to MAIN
+; format: (directory1, class.function), (directory2, function), ...
+; NOTE: No space characters in the path!!!
+main =
+
+[LOGGER]
+; The log directory
+log_path =
+; The log mode currently supports: ALL, STANDARD, FILE, CSV.
+; standard: Redirect log data to standard output
+; FILE: Redirect the log data to the log file
+; CSV: Redirect the log data to the csv file
+; Using all will apply all output modes
+mode = ALL
+
+[HOOK]
+; Hook mode. The hook mode currently supports: MAIN, LOG, and log mode is used by default
+; MAIN: Hook from the main function to all variables in the sub-function called by the lower level
+; LOG: Hook different variables according to the logs generated by different platforms
+mode = log
+; The process granularity of program log printing. Now supports: ALL, MASTER, SINGLE
+; ALL: For multi-process programs, print the output of all processes
+; MASTER: For multi-process programs, only the output of the main process (process 0) is printed
+; SINGLE: For single-process programs
+granularity = MASTER
+; Stake in statement style. Currently supported: INC, NATIVE
+; INC: Header file style, which needs to be matched with dump_hook_xxx.inc for use
+; NATIVE: Native style, c interface form
+style = INC
+; Configure cruiser's current capabilities, currently supporting HASH and NAN capabilities
+capacity = HASH
+; Setting whether the code is compiled using the GNU compiler will affect the compilation of program instrumentation.
+; This option takes effect when style is 'NATIVE'
+;is_gnu = FALSE
+; The number of levels of downward recursive hooking sub-functions takes effect when HOOK.mode is main
+depth = 3
+; The number of cutting for too long parameters during hook.
+split = 2
+; The regular expression of analyzing flag data in the log
+separator = |
+
+[FILTER]
+; Path to skip when indexing. Please use a relative path relative to the root directory
+path =
+; File to skip when indexing. Please use a relative path relative to the root directory
+file = *.F
+; Class to skip when indexing
+class =
+; Function to skip when indexing
+function =
diff --git a/software/utils/cruiser/x86/cruiser.exe b/software/utils/cruiser/x86/cruiser.exe
new file mode 100644
index 0000000000000000000000000000000000000000..5680a3e45879032444abaf926d797081d63baa54
Binary files /dev/null and b/software/utils/cruiser/x86/cruiser.exe differ
diff --git a/software/utils/cruiser/x86/libcruiser-2.2.0-x86.tar.gz b/software/utils/cruiser/x86/libcruiser-2.2.0-x86.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..8e2dcabacca6aad7a90b9d618cb60f302a71f847
Binary files /dev/null and b/software/utils/cruiser/x86/libcruiser-2.2.0-x86.tar.gz differ
diff --git a/software/utils/cruiser/x86_libprintmd5.so b/software/utils/cruiser/x86_libprintmd5.so
deleted file mode 100644
index cbad088542c967588e2eb3c2ddff2e9b32a6efb4..0000000000000000000000000000000000000000
Binary files a/software/utils/cruiser/x86_libprintmd5.so and /dev/null differ