已合并
Add BoxMullerFloat #3071
梅国晗954517创建于 6月1日
Add BoxMullerFloat #3071
已合并
共 11 个文件变更+23-12
| @@ -311,8 +311,8 @@ __aicore__ inline void BoxMullerMulSIMD( | |||
| 311 | } | 311 | } |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | -// Box-Muller transform | 314 | +// Box-Muller transform(Use BoxMullerFloatSafe for eps-protected version) |
| 315 | -__simt_callee__ __aicore__ inline void BoxMullerFloat(float u1, const float u2, float* z0, float* z1) | 315 | +__simt_callee__ __aicore__ inline void BoxMullerFloatSafe(float u1, const float u2, float* z0, float* z1) |
| 316 | { | 316 | { |
| 317 | const float eps = 1.0e-7f; | 317 | const float eps = 1.0e-7f; |
| 318 | if (u1 < eps) { | 318 | if (u1 < eps) { |
| @@ -325,6 +325,16 @@ __simt_callee__ __aicore__ inline void BoxMullerFloat(float u1, const float u2, | |||
| 325 | *z1 *= r; | 325 | *z1 *= r; |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | +// Box-Muller transform (Use BoxMullerFloat for torch-aligned, no eps clamping. ) | ||
| 329 | +__simt_callee__ __aicore__ inline void BoxMullerFloat(float u1, const float u2, float* z0, float* z1) | ||
| 330 | +{ | ||
| 331 | + float v = static_cast<float>(DOUBLE_MULTIPLE * PI * u2); | ||
| 332 | + float r = sqrtf(-DOUBLE_MULTIPLE * logf(u1)); | ||
| 333 | + sincosf(v, z0, z1); | ||
| 334 | + *z0 *= r; | ||
| 335 | + *z1 *= r; | ||
| 336 | +} | ||
| 337 | + | ||
| 328 | template <uint16_t COPY_SIZE> | 338 | template <uint16_t COPY_SIZE> |
| 329 | __simt_callee__ __aicore__ inline void CopyArray(uint32_t* dst, const uint32_t* src) | 339 | __simt_callee__ __aicore__ inline void CopyArray(uint32_t* dst, const uint32_t* src) |
| 330 | { | 340 | { |
| @@ -49,6 +49,7 @@ struct NormalTransform { | |||
| 49 | float u1 = results[pairBase] * RAND_2POW32_INV + RAND_2POW32_INV_HALF; | 49 | float u1 = results[pairBase] * RAND_2POW32_INV + RAND_2POW32_INV_HALF; |
| 50 | float u2 = results[pairBase + 1] * RAND_2POW32_INV + RAND_2POW32_INV_HALF; | 50 | float u2 = results[pairBase + 1] * RAND_2POW32_INV + RAND_2POW32_INV_HALF; |
| 51 | float z0, z1; | 51 | float z0, z1; |
| 52 | + // 使用对齐torch版本的BoxMullerFloat,无需eps保护 | ||
| 52 | BoxMullerFloat(u1, u2, &z0, &z1); | 53 | BoxMullerFloat(u1, u2, &z0, &z1); |
| 53 | float z = (iStep % 2 == 0) ? z0 : z1; | 54 | float z = (iStep % 2 == 0) ? z0 : z1; |
| 54 | if constexpr (IsSameType<T, float>::value) { | 55 | if constexpr (IsSameType<T, float>::value) { |
| @@ -302,7 +302,7 @@ int main() { | |||
| 302 | float meanValue = 1.2f; | 302 | float meanValue = 1.2f; |
| 303 | float stdValue = 2.5f; | 303 | float stdValue = 2.5f; |
| 304 | int64_t seed = 1; | 304 | int64_t seed = 1; |
| 305 | - int64_t offset = 2; | 305 | + int64_t offset = 4; |
| 306 | 306 | ||
| 307 | // 创建out aclTensor | 307 | // 创建out aclTensor |
| 308 | ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | 308 | ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); |
| @@ -308,7 +308,7 @@ int main() { | |||
| 308 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; | 308 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; |
| 309 | float meanValue = 1.2f; | 309 | float meanValue = 1.2f; |
| 310 | int64_t seed = 1; | 310 | int64_t seed = 1; |
| 311 | - int64_t offset = 1; | 311 | + int64_t offset = 4; |
| 312 | // 创建self aclTensor | 312 | // 创建self aclTensor |
| 313 | ret = CreateAclTensor(stdHostData, stdShape, &stdDeviceAddr, aclDataType::ACL_FLOAT, &std); | 313 | ret = CreateAclTensor(stdHostData, stdShape, &stdDeviceAddr, aclDataType::ACL_FLOAT, &std); |
| 314 | CHECK_RET(ret == ACL_SUCCESS, return ret); | 314 | CHECK_RET(ret == ACL_SUCCESS, return ret); |
| @@ -311,7 +311,7 @@ int main() { | |||
| 311 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; | 311 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; |
| 312 | float stdValue = 1.2f; | 312 | float stdValue = 1.2f; |
| 313 | int64_t seed = 1; | 313 | int64_t seed = 1; |
| 314 | - int64_t offset = 1; | 314 | + int64_t offset = 4; |
| 315 | // 创建self aclTensor | 315 | // 创建self aclTensor |
| 316 | ret = CreateAclTensor(meanHostData, meanShape, &meanDeviceAddr, aclDataType::ACL_FLOAT, &mean); | 316 | ret = CreateAclTensor(meanHostData, meanShape, &meanDeviceAddr, aclDataType::ACL_FLOAT, &mean); |
| 317 | CHECK_RET(ret == ACL_SUCCESS, return ret); | 317 | CHECK_RET(ret == ACL_SUCCESS, return ret); |
| @@ -320,7 +320,7 @@ int main() { | |||
| 320 | std::vector<float> stdHostData = {0.5, 0.6, 0.4, 0.5}; | 320 | std::vector<float> stdHostData = {0.5, 0.6, 0.4, 0.5}; |
| 321 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; | 321 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; |
| 322 | int64_t seed = 1; | 322 | int64_t seed = 1; |
| 323 | - int64_t offset = 1; | 323 | + int64_t offset = 4; |
| 324 | 324 | ||
| 325 | // 创建mean aclTensor | 325 | // 创建mean aclTensor |
| 326 | ret = CreateAclTensor(meanHostData, meanShape, &meanDeviceAddr, aclDataType::ACL_FLOAT, &mean); | 326 | ret = CreateAclTensor(meanHostData, meanShape, &meanDeviceAddr, aclDataType::ACL_FLOAT, &mean); |
| @@ -94,7 +94,7 @@ int main() | |||
| 94 | float meanValue = 1.2f; | 94 | float meanValue = 1.2f; |
| 95 | float stdValue = 2.5f; | 95 | float stdValue = 2.5f; |
| 96 | int64_t seed = 1; | 96 | int64_t seed = 1; |
| 97 | - int64_t offset = 2; | 97 | + int64_t offset = 4; |
| 98 | 98 | ||
| 99 | // 创建out aclTensor | 99 | // 创建out aclTensor |
| 100 | ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | 100 | ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); |
| @@ -97,7 +97,7 @@ int main() | |||
| 97 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; | 97 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; |
| 98 | float meanValue = 1.2f; | 98 | float meanValue = 1.2f; |
| 99 | int64_t seed = 1; | 99 | int64_t seed = 1; |
| 100 | - int64_t offset = 1; | 100 | + int64_t offset = 4; |
| 101 | // 创建self aclTensor | 101 | // 创建self aclTensor |
| 102 | ret = CreateAclTensor(stdHostData, stdShape, &stdDeviceAddr, aclDataType::ACL_FLOAT, &std); | 102 | ret = CreateAclTensor(stdHostData, stdShape, &stdDeviceAddr, aclDataType::ACL_FLOAT, &std); |
| 103 | CHECK_RET(ret == ACL_SUCCESS, return ret); | 103 | CHECK_RET(ret == ACL_SUCCESS, return ret); |
| @@ -97,7 +97,7 @@ int main() | |||
| 97 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; | 97 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; |
| 98 | float stdValue = 1.2f; | 98 | float stdValue = 1.2f; |
| 99 | int64_t seed = 1; | 99 | int64_t seed = 1; |
| 100 | - int64_t offset = 1; | 100 | + int64_t offset = 4; |
| 101 | // 创建self aclTensor | 101 | // 创建self aclTensor |
| 102 | ret = CreateAclTensor(meanHostData, meanShape, &meanDeviceAddr, aclDataType::ACL_FLOAT, &mean); | 102 | ret = CreateAclTensor(meanHostData, meanShape, &meanDeviceAddr, aclDataType::ACL_FLOAT, &mean); |
| 103 | CHECK_RET(ret == ACL_SUCCESS, return ret); | 103 | CHECK_RET(ret == ACL_SUCCESS, return ret); |
| @@ -100,7 +100,7 @@ int main() | |||
| 100 | std::vector<float> stdHostData = {0.5, 0.6, 0.4, 0.5}; | 100 | std::vector<float> stdHostData = {0.5, 0.6, 0.4, 0.5}; |
| 101 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; | 101 | std::vector<float> outHostData = {0.0, 0.0, 0.0, 0.0}; |
| 102 | int64_t seed = 1; | 102 | int64_t seed = 1; |
| 103 | - int64_t offset = 1; | 103 | + int64_t offset = 4; |
| 104 | 104 | ||
| 105 | // 创建mean aclTensor | 105 | // 创建mean aclTensor |
| 106 | ret = CreateAclTensor(meanHostData, meanShape, &meanDeviceAddr, aclDataType::ACL_FLOAT, &mean); | 106 | ret = CreateAclTensor(meanHostData, meanShape, &meanDeviceAddr, aclDataType::ACL_FLOAT, &mean); |
| @@ -73,7 +73,7 @@ __simt_callee__ __aicore__ inline void GenSamples(float* results, const uint32_t | |||
| 73 | // the desired number of elements that fall within the pre-defined cutoff | 73 | // the desired number of elements that fall within the pre-defined cutoff |
| 74 | // threshold. | 74 | // threshold. |
| 75 | float f[2]; | 75 | float f[2]; |
| 76 | - RandomKernelBase::BoxMullerFloat(Uint32ToFloat(counterRst[0]), Uint32ToFloat(counterRst[1]), &f[0], &f[1]); | 76 | + RandomKernelBase::BoxMullerFloatSafe(Uint32ToFloat(counterRst[0]), Uint32ToFloat(counterRst[1]), &f[0], &f[1]); |
| 77 | FilterSample(results, index, f[0]); | 77 | FilterSample(results, index, f[0]); |
| 78 | if (index >= static_cast<int>(GROUP_SIZE)) { | 78 | if (index >= static_cast<int>(GROUP_SIZE)) { |
| 79 | return; | 79 | return; |
| @@ -83,7 +83,7 @@ __simt_callee__ __aicore__ inline void GenSamples(float* results, const uint32_t | |||
| 83 | return; | 83 | return; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | - RandomKernelBase::BoxMullerFloat(Uint32ToFloat(counterRst[2]), Uint32ToFloat(counterRst[3]), &f[0], &f[1]); | 86 | + RandomKernelBase::BoxMullerFloatSafe(Uint32ToFloat(counterRst[2]), Uint32ToFloat(counterRst[3]), &f[0], &f[1]); |
| 87 | FilterSample(results, index, f[0]); | 87 | FilterSample(results, index, f[0]); |
| 88 | if (index >= static_cast<int>(GROUP_SIZE)) { | 88 | if (index >= static_cast<int>(GROUP_SIZE)) { |
| 89 | return; | 89 | return; |


将原
BoxMullerFloat重命名为BoxMullerFloatSafe后,新增了同名但无 eps 保护的新BoxMullerFloat。stateless_normal.h(不在本 PR 变更范围内)通过using namespace RandomKernelBase调用BoxMullerFloat(u1, u2, &z0, &z1),此前调用的是带 eps 保护的版本,此 PR 后隐式切换为无 eps 保护的对齐 torch 版本,行为发生变化。需要确认:1)
stateless_normal是否有意使用对齐 torch 的无 eps 版本(即当前隐式切换后的行为),若是请在该文件中显式标注或加注释说明;2) 若需保持原有安全行为,则应将该调用改为BoxMullerFloatSafe。truncated_normal_v2已显式改为BoxMullerFloatSafe(截断采样场景需要 eps 保护避免极端值浪费迭代),逻辑正确。但stateless_normal未做对应处理,存在遗漏风险。