已合并
use torch_npu._C instead of option #43708
huangyunlong创建于 8月4日
use torch_npu._C instead of option #43708
已合并
huangyunlong创建于 8月4日
7 个文件变更+59-10
@@ -122,7 +122,7 @@ class TorchFillUninitializedMemoryTestCase(TestCase):
122 self.assertTrue(res.eq(max_val).all())122 self.assertTrue(res.eq(max_val).all())
123 123 
124 124 
125-instantiate_device_type_tests(TorchFillUninitializedMemoryTestCase, globals(), only_for='privateuse1')125+instantiate_device_type_tests(TorchFillUninitializedMemoryTestCase, globals(), only_for=('privateuse1',))
126 126 
127 127 
128if __name__ == '__main__':128if __name__ == '__main__':
@@ -3,6 +3,7 @@
3#include <ATen/native/ResizeCommon.h>3#include <ATen/native/ResizeCommon.h>
4 4 
5#include "torch_npu/csrc/framework/FormatHelper.h"5#include "torch_npu/csrc/framework/FormatHelper.h"
6+#include "torch_npu/csrc/framework/interface/EnvVariables.h"
6#include "torch_npu/csrc/aten/NPUNativeFunctions.h"7#include "torch_npu/csrc/aten/NPUNativeFunctions.h"
7#include "torch_npu/csrc/aten/common/ResizeNpu.h"8#include "torch_npu/csrc/aten/common/ResizeNpu.h"
8 9 
@@ -62,7 +63,7 @@ const at::Tensor& NPUNativeFunctions::resize_(
62 // fill newly added storage section with NaN/MAX_INT when requested.63 // fill newly added storage section with NaN/MAX_INT when requested.
63 if (C10_UNLIKELY(at::globalContext().deterministicAlgorithms() &&64 if (C10_UNLIKELY(at::globalContext().deterministicAlgorithms() &&
64 at::globalContext().deterministicFillUninitializedMemory() &&65 at::globalContext().deterministicFillUninitializedMemory() &&
65- at_npu::native::env::CheckFillUninitializedMemory())) {66+ at_npu::native::env::globalNpuContext().npuFillUninitializedMemory())) {
66 at::native::fill_resize_deterministic_(self, static_cast<int64_t>(old_storage_nbytes));67 at::native::fill_resize_deterministic_(self, static_cast<int64_t>(old_storage_nbytes));
67 }68 }
68 return self;69 return self;
@@ -120,7 +120,7 @@ inline bool should_fill_empty_deterministic()
120{120{
121 return at::globalContext().deterministicAlgorithms() &&121 return at::globalContext().deterministicAlgorithms() &&
122 at::globalContext().deterministicFillUninitializedMemory() &&122 at::globalContext().deterministicFillUninitializedMemory() &&
123- at_npu::native::env::CheckFillUninitializedMemory();123+ at_npu::native::env::globalNpuContext().npuFillUninitializedMemory();
124}124}
125 125 
126void window_function_checks(126void window_function_checks(
@@ -320,9 +320,6 @@ bool CheckCompatibleImplFor(CompatibleKey compatible_key)
320 return CheckCompatibleImpl();320 return CheckCompatibleImpl();
321}321}
322 322 
323-TORCH_NPU_REGISTER_OPTION(TORCH_NPU_FILL_UNINITIALIZED_MEMORY)
324-REGISTER_OPTION_BOOL_FUNCTION(CheckFillUninitializedMemory, TORCH_NPU_FILL_UNINITIALIZED_MEMORY, "0", "1")
325- 
326REGISTER_OPTION_HOOK(ALLOW_CONV_HF32, [](const std::string &val) {323REGISTER_OPTION_HOOK(ALLOW_CONV_HF32, [](const std::string &val) {
327 static const std::string mm_hf32_option_name = "ALLOW_MATMUL_HF32";324 static const std::string mm_hf32_option_name = "ALLOW_MATMUL_HF32";
328 auto mm_hf32_val = c10_npu::option::GetOption(mm_hf32_option_name);325 auto mm_hf32_val = c10_npu::option::GetOption(mm_hf32_option_name);
@@ -363,6 +360,19 @@ REGISTER_OPTION_HOOK(ACL_OP_DEBUG_OPTION, [](const std::string &val) {
363 360 
364TORCH_NPU_REGISTER_OPTION(CUBE_MATH_TYPE)361TORCH_NPU_REGISTER_OPTION(CUBE_MATH_TYPE)
365 362 
363+NpuContext& globalNpuContext() {
364+ static NpuContext globalNpuContext_;
365+ return globalNpuContext_;
366+}
367+ 
368+bool NpuContext::npuFillUninitializedMemory() const {
369+ return _npu_fill_uninitialized_memory;
370+}
371+ 
372+void NpuContext::setNpuFillUninitializedMemory(bool b) {
373+ _npu_fill_uninitialized_memory = b;
374+}
375+ 
366} // namespace env376} // namespace env
367} // namespace native377} // namespace native
368} // namespace at_npu378} // namespace at_npu
@@ -32,12 +32,22 @@ enum class CompatibleKey {
32bool CheckCompatibleImpl();32bool CheckCompatibleImpl();
33bool CheckCompatibleImplFor(CompatibleKey compatible_key);33bool CheckCompatibleImplFor(CompatibleKey compatible_key);
34bool CheckCompatibleImplBlackListFor(CompatibleKey compatible_key);34bool CheckCompatibleImplBlackListFor(CompatibleKey compatible_key);
35-bool CheckFillUninitializedMemory();
36 35 
37bool IsAllowFP32ToFP16();36bool IsAllowFP32ToFP16();
38bool IsAllowConvHF32();37bool IsAllowConvHF32();
39bool IsAllowMatmulHF32();38bool IsAllowMatmulHF32();
40 39 
40+class NpuContext {
41+ public:
42+ bool npuFillUninitializedMemory() const;
43+ void setNpuFillUninitializedMemory(bool /*b*/);
44+ 
45+ private:
46+ bool _npu_fill_uninitialized_memory = false;
47+};
48+ 
49+NpuContext& globalNpuContext();
50+ 
41} // namespace env51} // namespace env
42} // namespace native52} // namespace native
43} // namespace at_npu53} // namespace at_npu
@@ -2525,6 +2525,27 @@ PyObject* THNPModule_get_deterministic_level(PyObject* self, PyObject* noargs) {
2525 END_HANDLE_TH_ERRORS2525 END_HANDLE_TH_ERRORS
2526}2526}
2527 2527 
2528+static PyObject* THNPModule_setNpuFillUninitializedMemory(
2529+ PyObject* _unused,
2530+ PyObject* arg) {
2531+ HANDLE_TH_ERRORS
2532+ TORCH_CHECK(
2533+ PyBool_Check(arg), "expected a bool, but got ", THPUtils_typename(arg));
2534+ at_npu::native::env::globalNpuContext().setNpuFillUninitializedMemory(
2535+ arg == Py_True);
2536+ Py_RETURN_NONE;
2537+ END_HANDLE_TH_ERRORS
2538+}
2539+ 
2540+static PyObject* THNPModule_npuFillUninitializedMemory(
2541+ PyObject* _unused,
2542+ PyObject* noargs) {
2543+ if (at_npu::native::env::globalNpuContext().npuFillUninitializedMemory())
2544+ Py_RETURN_TRUE;
2545+ else
2546+ Py_RETURN_FALSE;
2547+}
atomgit-bot
atomgit-botatomgit-bot8月4日

🟡 Medium Priority

变更行:Module.cpp 第 2540–2547 行新增的 THNPModule_npuFillUninitializedMemory 函数( _npu_get_fill_uninitialized_memory 的 C 实现)没有 HANDLE_TH_ERRORS / END_HANDLE_TH_ERRORS 宏包裹。

受影响的调用链:Python 调用 torch_npu._C._npu_get_fill_uninitialized_memory()THNPModule_npuFillUninitializedMemoryglobalNpuContext().npuFillUninitializedMemory()

失败模式:该文件内所有其他 Python 可调用函数(包括其兄弟 setter THNPModule_setNpuFillUninitializedMemoryTHNPModule_get_deterministic_level 等)均使用 HANDLE_TH_ERRORS / END_HANDLE_TH_ERRORS 将 C++ 异常转换为 Python 异常。缺少该保护时,若内部代码(如 globalNpuContext() 的初始化、或未来对 NpuContext 的扩展)抛出 C++ 异常,异常将直接穿透 Python 解释器边界导致进程崩溃(UB)。

虽然当前 NpuContext::npuFillUninitializedMemory() 仅返回一个 bool、几乎不可能抛出异常,但这是一个一致性/维护性缺陷:后续任何对 NpuContext 的修改都可能无意中引入异常风险,而此处缺乏保护不会被编译器或审查人注意到。

建议:为 THNPModule_npuFillUninitializedMemory 添加 HANDLE_TH_ERRORS / END_HANDLE_TH_ERRORS 宏包裹,与文件中所有其他 Python C API 函数保持一致。

改动建议
2547
+ static PyObject* THNPModule_npuFillUninitializedMemory(
2548
+ PyObject* _unused,
2549
+ PyObject* noargs) {
2550
+ HANDLE_TH_ERRORS
2551
+ if (at_npu::native::env::globalNpuContext().npuFillUninitializedMemory())
2552
+ Py_RETURN_TRUE;
2553
+ else
2554
+ Py_RETURN_FALSE;
2555
+ END_HANDLE_TH_ERRORS
2547
2556
  }
应用建议
likedislike
huangyunlong
8月4日 评论:
2548+ 
2528PyObject* THNPModule_hasPrimaryContext_wrap(PyObject* self, PyObject* arg) {2549PyObject* THNPModule_hasPrimaryContext_wrap(PyObject* self, PyObject* arg) {
2529 HANDLE_TH_ERRORS2550 HANDLE_TH_ERRORS
2530 TORCH_CHECK(2551 TORCH_CHECK(
@@ -2855,6 +2876,14 @@ static struct PyMethodDef THNPModule_methods[] = {
2855 (PyCFunction)THNPModule_get_deterministic_level,2876 (PyCFunction)THNPModule_get_deterministic_level,
2856 METH_NOARGS,2877 METH_NOARGS,
2857 nullptr},2878 nullptr},
2879+ {"_npu_set_fill_uninitialized_memory",
2880+ (PyCFunction)THNPModule_setNpuFillUninitializedMemory,
2881+ METH_O,
2882+ nullptr},
2883+ {"_npu_get_fill_uninitialized_memory",
2884+ (PyCFunction)THNPModule_npuFillUninitializedMemory,
2885+ METH_NOARGS,
2886+ nullptr},
2858 {"_npu_sleep",2887 {"_npu_sleep",
2859 (PyCFunction)THNPModule_npuSleep,2888 (PyCFunction)THNPModule_npuSleep,
2860 METH_O,2889 METH_O,
@@ -2,7 +2,7 @@ def _add_deterministic_patch():
2 """2 """
3 Patch torch.utils.deterministic.fill_uninitialized_memory setter so that3 Patch torch.utils.deterministic.fill_uninitialized_memory setter so that
4 setting it also synchronizes the NPU-side option4 setting it also synchronizes the NPU-side option
5- TORCH_NPU_FILL_UNINITIALIZED_MEMORY via torch_npu._C._npu_setOption.5+ _npu_fill_uninitialized_memory via torch_npu._C._npu_set_fill_uninitialized_memory.
6 """6 """
7 import torch_npu7 import torch_npu
8 import torch.utils.deterministic as det_mod8 import torch.utils.deterministic as det_mod
@@ -19,7 +19,6 @@ def _add_deterministic_patch():
19 # 1. call original setter: torch._C._set_deterministic_fill_uninitialized_memory(mode)19 # 1. call original setter: torch._C._set_deterministic_fill_uninitialized_memory(mode)
20 _orig_fset(self, mode)20 _orig_fset(self, mode)
21 # 2. sync NPU-side option21 # 2. sync NPU-side option
22- option = {"TORCH_NPU_FILL_UNINITIALIZED_MEMORY": "1" if mode else "0"}22+ torch_npu._C._npu_set_fill_uninitialized_memory(mode)
23- torch_npu._C._npu_setOption(option)
24 23 
25 _Deterministic.fill_uninitialized_memory = property(_orig_fget, _new_fset)24 _Deterministic.fill_uninitialized_memory = property(_orig_fget, _new_fset)