DEV.md 7.79 KB
Newer Older
PanZezhong's avatar
PanZezhong committed
1
2
3
4
5
6
7
8
# InfiniCore 开发者手册

Dear 开发者,感谢你参与 InfiniCore 开源项目的开发!本文档将帮助你了解如何向 InfiniCore 项目贡献代码。

## 项目介绍

### 项目模块体系

9
10
11
12
- infinicore:统一计算框架。提供 Python 和 C++ 接口,支持多种硬件平台。
- infinirt:统一底层运行时库,提供 C 语言接口,依赖 infini-utils。
- infiniop:统一底层算子库,提供 C 语言接口,依赖 infinirt。除了 C++ 算子实现之外,也包括使用九齿(triton)的算子实现,这部分算子需要在编译之前使用脚本生成源文件。安装后可以运行位于 `test/infiniop` 中的单测脚本进行测试。
- infiniccl:统一通信库,提供 C 语言接口,依赖 infinirt。
PanZezhong's avatar
PanZezhong committed
13
14
15
16
17
18
19
20
21
22
23
- infini-utils:全模块通用工具代码。
- utils-test:工具库测试代码,依赖 infini-utils。
- infiniccl-test:通信库测试代码,使用前需要安装好 infiniccl。

### 文件目录结构

```bash
├── xmake.lua  # 总体 xmake 编译配置,包含所有平台的编译选项和宏定义
├── xmake/*.lua  # 各平台 xmake 编译配置, 包含各平台特有的编译方式

├── include/  # 对外暴露的头文件目录,安装时会被复制到安装目录
24
25
26
│   ├── infinicore/*.hpp  # InfiniCore计算库头文件(C++)
│   ├── infiniop/*.h  # InfiniOP算子库子头文件(C)
│   ├── *.h/.hpp  # 模块核心头文件
PanZezhong's avatar
PanZezhong committed
27
28

├── src/  # 各模块源代码目录,包含源代码文件以及不对外暴露的头文件
29
30
31
32
33
34
35
│   ├── infinicore/ # InfiniCore源代码目录
│   │   ├── context/  # 张量运行时/硬件上下文管理源代码目录
│   │   ├── nn/  # 机器学习模块源代码目录
│   │   ├── ops/  # 张量算子源代码目录
│   │   ├── pybind/  # pybind 接口源代码目录
│   │   ├── tensor/  # 张量库源代码目录
│   │ 
PanZezhong's avatar
PanZezhong committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
│   ├── infiniop/ # InfiniOP算子库源代码目录
│   │   ├── devices/  # 每个设备平台各自的通用代码目录
│   │   ├── ops/ # 算子实现代码目录
│   │   │   ├── [op]/
│   │   │   │   ├── [device]/ # 各硬件平台算子实现代码目录
│   │   │   │   ├── operator.cc # 算子C语言接口实现
│   │   ├── reduce/ # 规约类算子通用代码目录
│   │   ├── elementwise/  # 逐元素类算子通用代码目录
│   │   ├── *.h  # 核心结构体定义
│   │
│   ├── infinirt/ # InfiniRT运行时库源代码目录
│   ├── infiniccl/ # InfiniCCL集合通信库源代码目录

├── test/ # 测试源代码目录
50
51
│   ├── infinicore/ # InfiniCore测试目录
│   │       ├── ops/*.py     # 算子单测脚本(依赖各平台PyTorch)
PanZezhong's avatar
PanZezhong committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
│   ├── infiniop/ # InfiniOP算子库单元测试目录
│   │       ├── *.py     # 单测脚本(依赖各平台PyTorch)

├── scripts/ # 脚本目录
│   ├── install.py # 安装编译脚本
│   ├── python_test.py # 运行所有单测脚本
```

## 开发引导

### 代码提交流程

1. 在github仓库issue页面根据任务类型(开发或bug)创建 issue,所有commit必须有对应的 issue 编号。
2. 外部人员需要通过 fork 代码仓库提交 PR。
3. 根据 issue 编号建立分支,分支名字格式为 `issue/#` (# 为issue 编号)。如果出现重复,可在后面添加“-#”序号,或用“/”后增加说明。
4. 所有 commit 信息必须以 `issue/#` 开头,
5. 分支推到远程后,建 Pull Request,标题需要以 `issue/#` 开头。在原issue页面上将该PR关联。
6. PR必须添加至少两位审核员(模块负责人和项目管理员等),PR中需附上最后一次修改后测试通过的截图。
7. PR通过审核,通过自动测试,无代码冲突后方可合并。合并后,关闭原 issue。

### 如何开发一个新算子

74
- 如果你想通过 C++ 以及硬件原生语言开发一个新的算子,请阅读 [infinicore::ops 开发指南](/src/infinicore/ops/README.md)
PanZezhong's avatar
PanZezhong committed
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

### C++ 代码命名书写规范

1. 类型

    内部数据结构类型 `UpperCamelCase`

    ```c++
    // 尽量使用 Infinixx 开头
    struct InfiniopMatmulCudaDescriptor;
    
    template <typename KeyType, typename ValueType>
    class HashMap; 
    
    using ValueMap = std::unordered_map<int, std::string>;
    ```

    对外暴露的指针类型和枚举类型 `infinixx[XxxXxx]_t`

    常量使用 `INFINI_UPPER_SNAKE_CASE`

    ```c++
    typedef struct InfiniopMatmulCudaDescriptor *infiniopMatmulCudaDescriptor_t;
    
    typedef enum {
        // INFINI...
        INFINI_DTYPE_INVALID = 0,
    } infiniDtype_t;
    ```

2. 普通变量、形参、类数据成员,使用 `snake_case`

    成员名前下划线特指private成员,其他情况应避免使用前下划线

    ```c++
    int max_count;
    
    class Example {
    public:
        std::string getUserName(std::string user_id);
    private:
        // private数据成员名字前加下划线
        int _max_count;
        std::string _user_name;
    };
    
    struct UrlTableProperties {  
        string name;
        int num_entries;  
        static Pool<UrlTableProperties>* pool;
    };
    ```

    当形参与函数内部变量或成员变量重名,可选择其中一个名字后加下划线。当函数内部临时变量和成员重名时,临时变量名字后加下划线。后下划线表示“临时”

    ```c++
    void do(int count_){
        int count = count_;
    }
    ```

3. 函数,使用 lowerCamelCase

    ```c++
    int getMaxValue() const;
    ```

142
143
    InfiniCore 中和 torch 对齐的接口,使用 `snake_case`。

PanZezhong's avatar
PanZezhong committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
4. const/volatile修饰符写在类型前面

    ```c++
    const void *ptr;
    const int num;
    ```

### 代码格式化

本项目分别使用 `clang-format-16``black` 对 C/C++ 以及 Python 代码进行格式化。可以使用 [`scripts/format.py`](/scripts/format.py) 脚本实现代码格式化检查和操作。

使用

```shell
python scripts/format.py -h
```

查看脚本帮助信息:

```plaintext
usage: format.py [-h] [--ref REF] [--path [PATH ...]] [--check] [--c C] [--py PY]

options:
  -h, --help         show this help message and exit
  --ref REF          Git reference (commit hash) to compare against.
  --path [PATH ...]  Files to format or check.
  --check            Check files without modifying them.
  --c C              C formatter (default: clang-format-16)
  --py PY            Python formatter (default: black)
```

参数中:

- `ref``path` 控制格式化的文件范围
  -`ref``path` 都为空,格式化当前暂存(git added)的文件;
  - 否则
    -`ref` 非空,将比较指定 commit 和当前代码的差异,只格式化修改过的文件;
    -`path` 非空,可传入多个路径(`--path p0 p1 p2`),只格式化指定路径及其子目录中的文件;
- 若设置 `--check`,将检查代码是否需要修改格式,不修改文件内容;
- 通过 `--c` 指定 c/c++ 格式化器,默认为 `clang-format-16`
- 通过 `--python` 指定 python 格式化器 `black`

### vscode 开发配置

基本配置见 [xmake 官方文档](https://xmake.io/#/zh-cn/plugin/more_plugins?id=%e9%85%8d%e7%bd%ae-intellsence)

- TL;DR
  - clangd

    打开 *xmake.lua*,保存一次以触发编译命令生成,将在工作路径下自动生成 *.vscode/compile_commands.json* 文件。然后在这个文件夹下创建 *settings.json*,填入:

    > .vscode/settings.json

    ```json
    {
        "clangd.arguments": [
            "--compile-commands-dir=.vscode"
        ],
        "xmake.additionalConfigArguments": [
            // 在这里配置 XMAKE_CONFIG_FLAGS
            "--nv-gpu=y"
        ],
    }
    ```