Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #ifndef __OP_UNFOLD_KEY_H__
12 : #define __OP_UNFOLD_KEY_H__
13 :
14 : #include <cstdint>
15 : #include <functional>
16 : #include <string>
17 :
18 : #include "hccl_types.h"
19 : #include "workflow_pub.h"
20 :
21 : namespace hccl {
22 :
23 : // 作为展开算子的标识符
24 : // 注意: 由于给定通信域下, 相同数据量相同算子的算法选择是固定的, 不需要在标识符中维护algType或algName
25 : // 注意: 图模式或单算子模式是全局固定的, 不需要在标识符中维护
26 : struct OpUnfoldKey {
27 : explicit OpUnfoldKey();
28 : explicit OpUnfoldKey(const OpUnfoldKey& other); // 拷贝构造函数 (make_pair需要)
29 :
30 : HcclResult Init(
31 : const HcclCMDType curOpType, const HcclDataType curDataType, const HcclReduceOp curReduceType,
32 : const bool curIsZeroCopy, const bool curIsSymmetricMemory, const uint64_t curInputSize,
33 : const bool curIsInplacePreSync, const HcclWorkflowMode curWorkflowMode, const bool curIsCapture,
34 : const uint32_t curRoot = 0);
35 :
36 : // 用于debug
37 : std::string GetKeyString() const;
38 :
39 : bool operator==(const OpUnfoldKey& other) const; // 重载operator==用于std::unordered_map中相等比较
40 : const OpUnfoldKey& operator=(const OpUnfoldKey& other); // 拷贝赋值操作符
41 :
42 : HcclCMDType opType;
43 : HcclDataType dataType;
44 : HcclReduceOp reduceType;
45 : bool isZeroCopy;
46 :
47 : // 是否开启对称内存优化
48 : bool isSymmetricMemory;
49 :
50 : // inputSize和outputSize是由totalCount(由rankSize+count决定)+dataType决定的, 给定通信域rankSize是固定的
51 : // 因为已经维护dataType, 所以inputSize/outputSize/totalCount中只需要维护任意一个即可
52 : // 注意: 对于alltoallv算子, cache查询不依赖具体数据量, inputSize用来区分isBigCount (0: false; 1: true)
53 : uint64_t inputSize;
54 :
55 : // ReduceScatter和AllReduce在开启重执行、in-place update、UserInMem > HcclBuffSize的时候,会触发前同步
56 : // (与正常算子展开逻辑不同)
57 : bool isInplacePreSync;
58 :
59 : // 是否为图模式 (可能存在同一个通信域下的同一个算子, 既执行图模式又执行单算子模式下的算法)
60 : HcclWorkflowMode workflowMode; // 0: 图模式; 1: 单算子模式
61 :
62 : // 是否为aclgraph (aclgraph资源在graph销毁时释放)
63 : bool isCapture;
64 :
65 : // 算子的root参数 (仅对 scatter / broadcast / reduce 三类算子生效)
66 : // 注意: 这三类算子在不同root下, SQE模板内的远端rank id / link句柄 / notify id不同, 必须把root纳入key
67 : // 其他算子root字段无意义, 固定为0即可
68 : // 历史兼容性: 默认值0与"root=0"语义重合, 不影响非root算子的cache命中行为
69 : uint32_t root;
70 : };
71 :
72 : }; // namespace hccl
73 :
74 : namespace std {
75 :
76 : // 全特化std::hash<OpUnfoldKey>, 用于std::unordered_map中计算哈希值
77 : template <>
78 : struct hash<hccl::OpUnfoldKey> {
79 4 : size_t operator()(const hccl::OpUnfoldKey& key) const
80 : {
81 : // 使用std::hash计算key中每个字段的哈希值
82 : std::hash<bool> hashBool;
83 : std::hash<uint8_t> hashUint8;
84 : std::hash<uint64_t> hashUint64;
85 :
86 : // 假设opType/dataType/reduceType <= 255
87 4 : const size_t opTypeHashValue = hashUint8(static_cast<uint8_t>(key.opType));
88 4 : const size_t dataTypeHashValue = hashUint8(static_cast<uint8_t>(key.dataType));
89 4 : const size_t reduceTypeHashValue = hashUint8(static_cast<uint8_t>(key.reduceType));
90 :
91 4 : const size_t isZeroCopyHashValue = hashBool(key.isZeroCopy);
92 4 : const size_t isSymmetricMemoryHashValue = hashBool(key.isSymmetricMemory);
93 4 : const size_t inputSizeHashValue = hashUint64(key.inputSize);
94 4 : const size_t isInplacePreSyncHashValue = hashBool(key.isInplacePreSync);
95 :
96 : // 假设workflowMode <= 255
97 4 : const size_t workflowModeHashValue = hashUint8(static_cast<uint8_t>(key.workflowMode));
98 :
99 4 : const size_t isCaptureHashValue = hashBool(key.isCapture);
100 :
101 : // 加入root字段的哈希: 避免不同root (scatter/broadcast/reduce) 在同一桶内冲突
102 4 : const size_t rootHashValue = std::hash<uint32_t>{}(key.root);
103 :
104 : // 简单的哈希混合
105 4 : size_t hashValue = opTypeHashValue;
106 4 : hashValue ^= dataTypeHashValue;
107 4 : hashValue ^= reduceTypeHashValue;
108 4 : hashValue ^= isZeroCopyHashValue;
109 4 : hashValue ^= isSymmetricMemoryHashValue;
110 4 : hashValue ^= inputSizeHashValue;
111 4 : hashValue ^= isInplacePreSyncHashValue;
112 4 : hashValue ^= workflowModeHashValue;
113 4 : hashValue ^= isCaptureHashValue;
114 4 : hashValue ^= rootHashValue;
115 :
116 4 : return hashValue;
117 : }
118 : };
119 :
120 : } // namespace std
121 :
122 : #endif // __OP_UNFOLD_KEY_H__
|