chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:40:42 +08:00
commit e25996e7db
15472 changed files with 3536181 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
file(
GLOB TEST_OPS
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"test_*.py")
string(REPLACE ".py" "" TEST_OPS "${TEST_OPS}")
foreach(TEST_OP ${TEST_OPS})
py_test_modules(${TEST_OP} MODULES ${TEST_OP})
endforeach()
@@ -0,0 +1,35 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def try_import_torch():
try:
import torch
return torch
except ModuleNotFoundError:
return None
def use_torch_specific_fn():
torch = try_import_torch()
if torch is None:
return
# torch._dynamo.allow_in_graph is a torch specific function, it shouldn't be accessed via proxy
torch._dynamo.allow_in_graph(lambda x: x)
# Use torch specific function at execute module stage
use_torch_specific_fn()
@@ -0,0 +1,22 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def use_torch_compat_api():
import torch
torch.randn([2, 3])
use_torch_compat_api()
@@ -0,0 +1,22 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from torch_module_side_effects import _ensure_init_once
from . import (
_dynamo as _dynamo,
nn as nn,
)
_ensure_init_once()
@@ -0,0 +1,17 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def allow_in_graph(fn):
return fn
@@ -0,0 +1,15 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from . import functional as functional
@@ -0,0 +1,17 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def relu(x):
return max(x, 0)
@@ -0,0 +1,43 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
PyTorch module side effects simulation.
The PyTorch module can only be initialized once. If imported multiple times,
it raises a RuntimeError to simulate side effects during imports.
For example:
>>> import sys
>>> import torch # Works fine the first time
>>> del sys.modules['torch']
>>> import torch # Raises an error due to re-initialization
We simulate this behavior to test how Paddle's torch proxy handles such side effects.
Since the torch module will be cleared when removed from sys.modules, we need to create
a new module to record the initialization state.
"""
initialized = False
def _ensure_init_once():
global initialized
if not initialized:
initialized = True
return
raise RuntimeError(
"torch core module is already initialized, this can happen due to side effects of imports."
)
+34
View File
@@ -0,0 +1,34 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import paddle
class TestCAPI(unittest.TestCase):
def test_glibcxx_use_cxx11_abi(self):
val = paddle._C._GLIBCXX_USE_CXX11_ABI
self.assertIsInstance(
val, bool, "_GLIBCXX_USE_CXX11_ABI should return a bool"
)
def test_get_custom_class_python_wrapper_not_found(self):
with self.assertRaises(Exception) as cm:
paddle._C._get_custom_class_python_wrapper("fake_ns", "FakeClass")
self.assertIn("not found", str(cm.exception).lower())
if __name__ == "__main__":
unittest.main()
+32
View File
@@ -0,0 +1,32 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import paddle
class TestForbidKeywordsDecorator(unittest.TestCase):
def test(self):
with self.assertRaises(TypeError) as cm:
self.assertWarnsRegex(
UserWarning,
"may behave differently from its PyTorch counterpart",
paddle.sort,
)
paddle.sort(input=paddle.to_tensor([2, 1, 3]), axis=0)
if __name__ == '__main__':
unittest.main()
+361
View File
@@ -0,0 +1,361 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import tempfile
import unittest
from unittest import mock
import paddle.base as core
from paddle.utils.cpp_extension import (
CUDA_HOME,
_get_cuda_arch_flags,
_get_num_workers,
_get_pybind11_abi_build_flags,
extension_utils,
)
class TestGetCudaArchFlags(unittest.TestCase):
def setUp(self):
if not core.is_compiled_with_cuda() or core.is_compiled_with_rocm():
self.skipTest('should compile with cuda (not rocm).')
self._old_env = dict(os.environ)
def tearDown(self):
os.environ.clear()
os.environ.update(self._old_env)
def test_with_user_cflags(self):
flags = _get_cuda_arch_flags(cflags=["-arch=sm_90"])
self.assertEqual(flags, [])
def test_with_env_hopper(self):
os.environ["PADDLE_CUDA_ARCH_LIST"] = "Hopper"
flags = _get_cuda_arch_flags()
# Hopper -> 9.0+PTX -> sm_90 + compute_90
self.assertIn("-gencode=arch=compute_90,code=sm_90", flags)
self.assertIn("-gencode=arch=compute_90,code=compute_90", flags)
def test_with_env_hopper_and_flags(self):
os.environ["PADDLE_CUDA_ARCH_LIST"] = "Hopper"
flags = _get_cuda_arch_flags("Hopper")
# Hopper -> 9.0+PTX -> sm_90 + compute_90
self.assertIn("-gencode=arch=compute_90,code=sm_90", flags)
self.assertIn("-gencode=arch=compute_90,code=compute_90", flags)
def test_with_env_multiple(self):
os.environ["PADDLE_CUDA_ARCH_LIST"] = "8.6;9.0+PTX"
flags = _get_cuda_arch_flags()
self.assertIn("-gencode=arch=compute_86,code=sm_86", flags)
self.assertIn("-gencode=arch=compute_90,code=sm_90", flags)
self.assertIn("-gencode=arch=compute_90,code=compute_90", flags)
os.environ["PADDLE_CUDA_ARCH_LIST"] = "8.6,9.0+PTX"
flags = _get_cuda_arch_flags()
self.assertIn("-gencode=arch=compute_86,code=sm_86", flags)
self.assertIn("-gencode=arch=compute_90,code=sm_90", flags)
self.assertIn("-gencode=arch=compute_90,code=compute_90", flags)
os.environ["PADDLE_CUDA_ARCH_LIST"] = "8.6 9.0+PTX"
flags = _get_cuda_arch_flags()
self.assertIn("-gencode=arch=compute_86,code=sm_86", flags)
self.assertIn("-gencode=arch=compute_90,code=sm_90", flags)
self.assertIn("-gencode=arch=compute_90,code=compute_90", flags)
def test_auto_detect(self):
if "PADDLE_CUDA_ARCH_LIST" in os.environ:
del os.environ["PADDLE_CUDA_ARCH_LIST"]
flags = _get_cuda_arch_flags()
self.assertTrue(len(flags) > 0)
def test_get_cuda_arch_flags_with_invalid_arch(self):
os.environ["PADDLE_CUDA_ARCH_LIST"] = "invalid_arch"
with self.assertRaises(ValueError) as context:
_get_cuda_arch_flags()
self.assertIn(
"Unknown CUDA arch (invalid_arch) or GPU not supported",
str(context.exception),
)
def test_skip_paddle_extension_name_flag(self):
flags = _get_cuda_arch_flags(cflags=["-DPADDLE_EXTENSION_NAME=my_ext"])
self.assertNotEqual(flags, [])
def test_rocm_returns_empty_flags(self):
with mock.patch.object(
extension_utils.core, "is_compiled_with_rocm", return_value=True
):
self.assertEqual(_get_cuda_arch_flags(), [])
class TestGetRocmArchFlags(unittest.TestCase):
def setUp(self):
self._old_env = dict(os.environ)
def tearDown(self):
os.environ.clear()
os.environ.update(self._old_env)
def test_default_arch_list(self):
if "PADDLE_ROCM_ARCH_LIST" in os.environ:
del os.environ["PADDLE_ROCM_ARCH_LIST"]
os.environ["ROCM_PATH"] = "/tmp/paddle-missing-rocm-for-test"
os.environ["ROCM_HOME"] = "/tmp/paddle-missing-rocm-for-test"
flags = extension_utils.get_rocm_arch_flags([])
self.assertIn("-fno-gpu-rdc", flags)
self.assertIn("--offload-arch=gfx906", flags)
self.assertIn("--offload-arch=gfx936", flags)
self.assertNotIn("--offload-arch=gfx950", flags)
def test_rocm70_default_arch_list(self):
if "PADDLE_ROCM_ARCH_LIST" in os.environ:
del os.environ["PADDLE_ROCM_ARCH_LIST"]
with tempfile.TemporaryDirectory() as rocm_home:
hip_include = os.path.join(rocm_home, "include", "hip")
os.makedirs(hip_include)
with open(
os.path.join(hip_include, "hip_version.h"),
"w",
encoding="utf-8",
) as f:
f.write(
"#define HIP_VERSION_MAJOR 7\n"
"#define HIP_VERSION_MINOR 0\n"
"#define HIP_VERSION_PATCH 0\n"
)
os.environ["ROCM_PATH"] = rocm_home
os.environ["ROCM_HOME"] = rocm_home
flags = extension_utils.get_rocm_arch_flags([])
self.assertIn("--offload-arch=gfx90a", flags)
self.assertIn("--offload-arch=gfx950", flags)
def test_env_arch_list_override(self):
os.environ["PADDLE_ROCM_ARCH_LIST"] = "gfx950;gfx942 gfx942,gfx908"
flags = extension_utils.get_rocm_arch_flags([])
arch_flags = [
flag for flag in flags if flag.startswith("--offload-arch=")
]
self.assertEqual(
sorted(arch_flags),
[
"--offload-arch=gfx908",
"--offload-arch=gfx942",
"--offload-arch=gfx950",
],
)
def test_user_arch_flags_keep_no_gpu_rdc(self):
flags = extension_utils.get_rocm_arch_flags(["--offload-arch=gfx950"])
self.assertEqual(flags, ["-fno-gpu-rdc"])
def test_user_split_arch_flags_keep_no_gpu_rdc(self):
flags = extension_utils.get_rocm_arch_flags(
["--offload-arch", "gfx950"]
)
self.assertEqual(flags, ["-fno-gpu-rdc"])
def test_user_arch_flags_without_duplicate_no_gpu_rdc(self):
flags = extension_utils.get_rocm_arch_flags(
["-fno-gpu-rdc", "--offload-arch=gfx950"]
)
self.assertEqual(flags, [])
def test_rocm_version_header_empty_home(self):
self.assertIsNone(extension_utils._get_rocm_version_from_header(""))
def test_rocm_version_header_oserror(self):
with tempfile.TemporaryDirectory() as rocm_home:
hip_include = os.path.join(rocm_home, "include", "hip")
os.makedirs(hip_include)
hip_version_file = os.path.join(hip_include, "hip_version.h")
with open(hip_version_file, "w", encoding="utf-8") as f:
f.write("")
with mock.patch(
"paddle.utils.cpp_extension.extension_utils.open",
side_effect=OSError("forced"),
create=True,
):
self.assertIsNone(
extension_utils._get_rocm_version_from_header(rocm_home)
)
def test_default_arch_list_falls_back_to_opt_rocm(self):
for var in ("ROCM_HOME", "ROCM_PATH"):
os.environ.pop(var, None)
with mock.patch.object(
extension_utils,
"_get_rocm_version_from_header",
return_value=None,
) as mocked:
result = extension_utils._get_default_rocm_arch_list()
mocked.assert_called_once_with("/opt/rocm")
self.assertEqual(result, extension_utils._ROCM_LEGACY_AMDGPU_TARGETS)
def test_get_rocm_arch_flags_accepts_none_cflags(self):
if "PADDLE_ROCM_ARCH_LIST" in os.environ:
del os.environ["PADDLE_ROCM_ARCH_LIST"]
os.environ["ROCM_PATH"] = "/tmp/paddle-missing-rocm-for-test"
os.environ["ROCM_HOME"] = "/tmp/paddle-missing-rocm-for-test"
flags = extension_utils.get_rocm_arch_flags(None)
self.assertIn("-fno-gpu-rdc", flags)
self.assertIn("--offload-arch=gfx906", flags)
class TestCppExtensionUtils(unittest.TestCase):
def test_cuda_home(self):
if core.is_compiled_with_cuda():
value = CUDA_HOME
self.assertTrue(value is None or isinstance(value, str))
def test_get_pybind11_abi_build_flags(self):
flags = _get_pybind11_abi_build_flags()
self.assertIsInstance(flags, list)
for f in flags:
self.assertIsInstance(f, str)
def test_get_num_workers_with_env_verbose_false(self):
os.environ["MAX_JOBS"] = "8"
num = _get_num_workers(verbose=False)
self.assertEqual(num, 8)
def test_get_num_workers_with_env_verbose_true(self):
os.environ["MAX_JOBS"] = "8"
num = _get_num_workers(verbose=True)
self.assertEqual(num, 8)
def test_get_num_workers_without_env_verbose_true(self):
if "MAX_JOBS" in os.environ:
del os.environ["MAX_JOBS"]
num = _get_num_workers(verbose=True)
self.assertEqual(num, None)
def test_normalize_extension_kwargs_add_phi_lib_on_windows(self):
with (
mock.patch.object(extension_utils, 'IS_WINDOWS', True),
mock.patch.object(
extension_utils,
'create_sym_link_if_not_exist',
return_value='libpaddle.lib',
),
mock.patch.object(
extension_utils, 'find_paddle_libraries', return_value=[]
),
mock.patch.object(
extension_utils,
'find_paddle_custom_device_includes',
return_value=[],
),
mock.patch.object(
extension_utils, 'find_paddle_includes', return_value=[]
),
mock.patch.object(
extension_utils, 'find_python_includes', return_value=[]
),
):
kwargs = extension_utils.normalize_extension_kwargs(
{'extra_link_args': ['/DEBUG']}, use_cuda=False
)
self.assertEqual(
kwargs['extra_link_args'],
[
'/DEBUG',
*extension_utils.MSVC_LINK_FLAGS,
'libpaddle.lib',
'phi.lib',
],
)
def test_normalize_extension_kwargs_keep_user_phi_lib_on_windows(self):
with (
mock.patch.object(extension_utils, 'IS_WINDOWS', True),
mock.patch.object(
extension_utils,
'create_sym_link_if_not_exist',
return_value='libpaddle.lib',
),
mock.patch.object(
extension_utils, 'find_paddle_libraries', return_value=[]
),
mock.patch.object(
extension_utils,
'find_paddle_custom_device_includes',
return_value=[],
),
mock.patch.object(
extension_utils, 'find_paddle_includes', return_value=[]
),
mock.patch.object(
extension_utils, 'find_python_includes', return_value=[]
),
):
kwargs = extension_utils.normalize_extension_kwargs(
{
'extra_link_args': [
'/DEBUG',
'phi.lib',
'libpaddle.lib',
]
},
use_cuda=False,
)
self.assertEqual(kwargs['extra_link_args'].count('phi.lib'), 1)
self.assertEqual(kwargs['extra_link_args'].count('libpaddle.lib'), 1)
def test_normalize_extension_kwargs_add_cuda_libs_on_windows(self):
with (
mock.patch.object(extension_utils, 'IS_WINDOWS', True),
mock.patch.object(
extension_utils,
'create_sym_link_if_not_exist',
return_value='libpaddle.lib',
),
mock.patch.object(
extension_utils, 'find_paddle_libraries', return_value=[]
),
mock.patch.object(
extension_utils,
'find_paddle_custom_device_includes',
return_value=[],
),
mock.patch.object(
extension_utils, 'find_paddle_includes', return_value=[]
),
mock.patch.object(
extension_utils, 'find_python_includes', return_value=[]
),
):
kwargs = extension_utils.normalize_extension_kwargs(
{
'extra_link_args': [
'/DEBUG',
'phi.lib',
'cudadevrt.lib',
]
},
use_cuda=True,
)
self.assertEqual(kwargs['extra_link_args'].count('phi.lib'), 1)
self.assertEqual(kwargs['extra_link_args'].count('libpaddle.lib'), 1)
self.assertEqual(kwargs['extra_link_args'].count('cudadevrt.lib'), 1)
self.assertEqual(
kwargs['extra_link_args'].count('cudart_static.lib'), 1
)
if __name__ == "__main__":
unittest.main()
+817
View File
@@ -0,0 +1,817 @@
# Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import paddle
from paddle.base import core
def is_custom_device():
custom_dev_types = paddle.device.get_all_custom_device_type()
if custom_dev_types and paddle.device.is_compiled_with_custom_device(
custom_dev_types[0]
):
return True
return False
def only_has_cpu():
return (
not core.is_compiled_with_cuda()
and not core.is_compiled_with_xpu()
and not is_custom_device()
)
class TestErrorCPU(unittest.TestCase):
def test_max_memory_allocated_raises_on_cpu(self):
if only_has_cpu():
with self.assertRaisesRegex(
ValueError, "not supported in CPU PaddlePaddle"
):
paddle.cuda.max_memory_allocated()
with self.assertRaisesRegex(
ValueError, "not supported in CPU PaddlePaddle"
):
paddle.device.max_memory_allocated()
with self.assertRaisesRegex(
ValueError, "not supported in CPU PaddlePaddle"
):
paddle.cuda.max_memory_reserved()
with self.assertRaisesRegex(
ValueError, "not supported in CPU PaddlePaddle"
):
paddle.device.max_memory_reserved()
with self.assertRaisesRegex(
ValueError, "not supported in CPU PaddlePaddle"
):
paddle.cuda.reset_max_memory_allocated()
with self.assertRaisesRegex(
ValueError, "not supported in CPU PaddlePaddle"
):
paddle.device.reset_max_memory_allocated()
with self.assertRaisesRegex(
ValueError, "not supported in CPU PaddlePaddle"
):
paddle.cuda.reset_max_memory_reserved()
with self.assertRaisesRegex(
ValueError, "not supported in CPU PaddlePaddle"
):
paddle.device.reset_max_memory_reserved()
class TestDeviceAPIs(unittest.TestCase):
"""Test paddle.device APIs across different hardware types."""
def setUp(self):
"""Set up test environment."""
self.cuda_available = core.is_compiled_with_cuda()
self.xpu_available = core.is_compiled_with_xpu()
self.custom_device_available = is_custom_device()
# Get available custom device types
if self.custom_device_available:
self.custom_device_types = core.get_all_custom_device_type()
self.default_custom_device = self.custom_device_types[0]
else:
self.custom_device_types = []
self.default_custom_device = None
def test_device_count_cuda(self):
"""Test device_count with CUDA."""
if not core.is_compiled_with_cuda():
self.skipTest("CUDA not available")
count = paddle.device.device_count()
self.assertIsInstance(count, int)
self.assertGreaterEqual(count, 0)
def test_device_count_xpu(self):
"""Test device_count with XPU."""
if not core.is_compiled_with_xpu():
self.skipTest("XPU not available")
count = paddle.device.device_count()
self.assertIsInstance(count, int)
self.assertGreaterEqual(count, 0)
def test_device_count_customdevice(self):
"""Test device_count with custom device."""
if not is_custom_device():
self.skipTest("Custom device not available")
count = paddle.device.device_count()
self.assertIsInstance(count, int)
self.assertGreaterEqual(count, 0)
# Test with specific device type
count_custom = paddle.device.device_count(self.default_custom_device)
self.assertIsInstance(count_custom, int)
self.assertGreaterEqual(count_custom, 0)
def test_get_device_properties_cuda(self):
"""Test get_device_properties with CUDA."""
if not core.is_compiled_with_cuda():
self.skipTest("CUDA not available")
# Test with default device
props = paddle.device.get_device_properties()
self.assertIsNotNone(props)
# Test with string input
props_str = paddle.device.get_device_properties('gpu:0')
self.assertIsNotNone(props_str)
props_str = paddle.device.get_device_properties('cuda:0')
self.assertIsNotNone(props_str)
# Test with integer input
props_int = paddle.device.get_device_properties(0)
self.assertIsNotNone(props_int)
# Test with CUDAPlace input
props_int = paddle.device.get_device_properties(paddle.CUDAPlace(0))
self.assertIsNotNone(props_int)
def test_get_device_properties_customdevice(self):
"""Test get_device_properties with custom device."""
if not is_custom_device():
self.skipTest("Custom device not available")
# Test with default device
props = paddle.device.get_device_properties()
self.assertIsNotNone(props)
# Test with string input (device only)
props_device = paddle.device.get_device_properties(
self.default_custom_device
)
self.assertIsNotNone(props_device)
# Test with string input (device:id)
props_str = paddle.device.get_device_properties(
f'{self.default_custom_device}:0'
)
self.assertIsNotNone(props_str)
# Test with integer input
props_int = paddle.device.get_device_properties(0)
self.assertIsNotNone(props_int)
# Test with CustomPlace input
props_custom = paddle.device.get_device_properties(
paddle.CustomPlace(self.default_custom_device, 0)
)
self.assertIsNotNone(props_custom)
def test_empty_cache_cuda(self):
"""Test empty_cache with CUDA."""
if not core.is_compiled_with_cuda():
self.skipTest("CUDA not available")
# Should not raise any exception
paddle.device.empty_cache()
def test_empty_cache_customdevice(self):
"""Test empty_cache with custom device."""
if not is_custom_device():
self.skipTest("Custom device not available")
# Should not raise any exception
paddle.device.empty_cache()
def test_memory_apis_cuda(self):
"""Test memory management APIs with CUDA with actual tensor allocation."""
if not core.is_compiled_with_cuda():
self.skipTest("CUDA not available")
# Set device to GPU
paddle.device.set_device('gpu')
# Test max_memory_allocated with different input types
mem1 = paddle.device.max_memory_allocated()
self.assertIsInstance(mem1, int)
self.assertGreaterEqual(mem1, 0)
mem2 = paddle.device.max_memory_allocated('gpu:0')
self.assertIsInstance(mem2, int)
self.assertGreaterEqual(mem2, 0)
mem3 = paddle.device.max_memory_allocated(0)
self.assertIsInstance(mem3, int)
self.assertGreaterEqual(mem3, 0)
mem7 = paddle.device.max_memory_allocated(paddle.CUDAPlace(0))
self.assertIsInstance(mem7, int)
self.assertGreaterEqual(mem7, 0)
# Test max_memory_allocated with different input types
mem1 = paddle.cuda.max_memory_allocated()
self.assertIsInstance(mem1, int)
self.assertGreaterEqual(mem1, 0)
mem2 = paddle.cuda.max_memory_allocated('gpu:0')
self.assertIsInstance(mem2, int)
self.assertGreaterEqual(mem2, 0)
mem3 = paddle.cuda.max_memory_allocated(0)
self.assertIsInstance(mem3, int)
self.assertGreaterEqual(mem3, 0)
mem7 = paddle.cuda.max_memory_allocated(paddle.CUDAPlace(0))
self.assertIsInstance(mem7, int)
self.assertGreaterEqual(mem7, 0)
# Test max_memory_reserved with different input types
mem4 = paddle.device.max_memory_reserved()
self.assertIsInstance(mem4, int)
self.assertGreaterEqual(mem4, 0)
mem8 = paddle.device.max_memory_reserved('gpu:0')
self.assertIsInstance(mem8, int)
self.assertGreaterEqual(mem8, 0)
mem4 = paddle.cuda.max_memory_reserved()
self.assertIsInstance(mem4, int)
self.assertGreaterEqual(mem4, 0)
mem8 = paddle.cuda.max_memory_reserved('gpu:0')
self.assertIsInstance(mem8, int)
self.assertGreaterEqual(mem8, 0)
mem9 = paddle.device.max_memory_reserved(0)
self.assertIsInstance(mem9, int)
self.assertGreaterEqual(mem9, 0)
mem10 = paddle.device.max_memory_reserved(paddle.CUDAPlace(0))
self.assertIsInstance(mem10, int)
self.assertGreaterEqual(mem10, 0)
# Test memory_allocated with different input types
mem5 = paddle.device.memory_allocated()
self.assertIsInstance(mem5, int)
self.assertGreaterEqual(mem5, 0)
mem11 = paddle.device.memory_allocated('gpu:0')
self.assertIsInstance(mem11, int)
self.assertGreaterEqual(mem11, 0)
mem12 = paddle.device.memory_allocated(0)
self.assertIsInstance(mem12, int)
self.assertGreaterEqual(mem12, 0)
mem13 = paddle.device.memory_allocated(paddle.CUDAPlace(0))
self.assertIsInstance(mem13, int)
self.assertGreaterEqual(mem13, 0)
# Test memory_reserved with different input types
mem6 = paddle.device.memory_reserved()
self.assertIsInstance(mem6, int)
self.assertGreaterEqual(mem6, 0)
mem14 = paddle.device.memory_reserved('gpu:0')
self.assertIsInstance(mem14, int)
self.assertGreaterEqual(mem14, 0)
mem15 = paddle.device.memory_reserved(0)
self.assertIsInstance(mem15, int)
self.assertGreaterEqual(mem15, 0)
mem16 = paddle.device.memory_reserved(paddle.CUDAPlace(0))
self.assertIsInstance(mem16, int)
self.assertGreaterEqual(mem16, 0)
# Now test actual memory allocation and tracking
initial_allocated = paddle.device.memory_allocated()
initial_max_allocated = paddle.device.max_memory_allocated()
initial_reserved = paddle.device.memory_reserved()
initial_max_reserved = paddle.device.max_memory_reserved()
# Allocate first tensor (10MB)
tensor1 = paddle.randn([256, 256, 256], dtype='float32') # ~67MB
# Check memory after first allocation
allocated_after_first = paddle.device.memory_allocated()
max_allocated_after_first = paddle.device.max_memory_allocated()
reserved_after_first = paddle.device.memory_reserved()
max_reserved_after_first = paddle.device.max_memory_reserved()
self.assertGreater(allocated_after_first, initial_allocated)
self.assertGreater(max_allocated_after_first, initial_max_allocated)
self.assertGreaterEqual(reserved_after_first, initial_reserved)
self.assertGreaterEqual(max_reserved_after_first, initial_max_reserved)
# Allocate second tensor (5MB)
tensor2 = paddle.randn([128, 128, 128], dtype='float32') # ~8MB
# Check memory after second allocation
allocated_after_second = paddle.device.memory_allocated()
max_allocated_after_second = paddle.device.max_memory_allocated()
reserved_after_second = paddle.device.memory_reserved()
max_reserved_after_second = paddle.device.max_memory_reserved()
# Memory should have increased further
self.assertGreater(allocated_after_second, allocated_after_first)
self.assertGreater(
max_allocated_after_second, max_allocated_after_first
)
self.assertGreaterEqual(reserved_after_second, reserved_after_first)
self.assertGreaterEqual(
max_reserved_after_second, max_reserved_after_first
)
# Release first tensor
del tensor1
# Check memory after releasing first tensor
allocated_after_release = paddle.device.memory_allocated()
max_allocated_after_release = paddle.device.max_memory_allocated()
reserved_after_release = paddle.device.memory_reserved()
max_reserved_after_release = paddle.device.max_memory_reserved()
# Current allocated should decrease, but max should stay the same
self.assertLess(allocated_after_release, allocated_after_second)
self.assertEqual(
max_allocated_after_release, max_allocated_after_second
)
self.assertLessEqual(reserved_after_release, reserved_after_second)
self.assertEqual(max_reserved_after_release, max_reserved_after_second)
# Test reset functions
paddle.device.reset_max_memory_allocated()
paddle.device.reset_max_memory_reserved()
paddle.device.synchronize()
# Check memory after reset
allocated_after_reset = paddle.device.memory_allocated()
max_allocated_after_reset = paddle.device.max_memory_allocated()
reserved_after_reset = paddle.device.memory_reserved()
max_reserved_after_reset = paddle.device.max_memory_reserved()
# Current allocated should remain the same, but max should be reset to current level
self.assertEqual(allocated_after_reset, allocated_after_release)
self.assertLessEqual(
max_allocated_after_reset, max_allocated_after_release
)
self.assertEqual(reserved_after_reset, reserved_after_release)
self.assertLessEqual(
max_reserved_after_reset, max_reserved_after_release
)
# Clean up
del tensor2
paddle.device.empty_cache()
def test_memory_apis_customdevice(self):
"""Test memory management APIs with custom device with actual tensor allocation."""
if not is_custom_device():
self.skipTest("Custom device not available")
# Set device to custom device
paddle.device.set_device(self.default_custom_device)
# Test max_memory_allocated with different input types
mem1 = paddle.device.max_memory_allocated()
self.assertIsInstance(mem1, int)
self.assertGreaterEqual(mem1, 0)
mem2 = paddle.device.max_memory_allocated(self.default_custom_device)
self.assertIsInstance(mem2, int)
self.assertGreaterEqual(mem2, 0)
mem3 = paddle.device.max_memory_allocated(
f'{self.default_custom_device}:0'
)
self.assertIsInstance(mem3, int)
self.assertGreaterEqual(mem3, 0)
mem4 = paddle.device.max_memory_allocated(0)
self.assertIsInstance(mem4, int)
self.assertGreaterEqual(mem4, 0)
# Test with CustomPlace
custom_place = core.CustomPlace(self.default_custom_device, 0)
mem5 = paddle.device.max_memory_allocated(custom_place)
self.assertIsInstance(mem5, int)
self.assertGreaterEqual(mem5, 0)
# Test max_memory_reserved with different input types
mem6 = paddle.device.max_memory_reserved()
self.assertIsInstance(mem6, int)
self.assertGreaterEqual(mem6, 0)
mem7 = paddle.device.max_memory_reserved(self.default_custom_device)
self.assertIsInstance(mem7, int)
self.assertGreaterEqual(mem7, 0)
mem8 = paddle.device.max_memory_reserved(
f'{self.default_custom_device}:0'
)
self.assertIsInstance(mem8, int)
self.assertGreaterEqual(mem8, 0)
mem9 = paddle.device.max_memory_reserved(0)
self.assertIsInstance(mem9, int)
self.assertGreaterEqual(mem9, 0)
# Test with CustomPlace
custom_place = core.CustomPlace(self.default_custom_device, 0)
mem10 = paddle.device.max_memory_reserved(custom_place)
self.assertIsInstance(mem10, int)
self.assertGreaterEqual(mem10, 0)
# Test memory_allocated with different input types
mem11 = paddle.device.memory_allocated()
self.assertIsInstance(mem11, int)
self.assertGreaterEqual(mem11, 0)
mem12 = paddle.device.memory_allocated(self.default_custom_device)
self.assertIsInstance(mem12, int)
self.assertGreaterEqual(mem12, 0)
mem13 = paddle.device.memory_allocated(
f'{self.default_custom_device}:0'
)
self.assertIsInstance(mem13, int)
self.assertGreaterEqual(mem13, 0)
mem14 = paddle.device.memory_allocated(0)
self.assertIsInstance(mem14, int)
self.assertGreaterEqual(mem14, 0)
# Test with CustomPlace
custom_place = core.CustomPlace(self.default_custom_device, 0)
mem15 = paddle.device.memory_allocated(custom_place)
self.assertIsInstance(mem15, int)
self.assertGreaterEqual(mem15, 0)
# Test memory_reserved with different input types
mem16 = paddle.device.memory_reserved()
self.assertIsInstance(mem16, int)
self.assertGreaterEqual(mem16, 0)
mem17 = paddle.device.memory_reserved(self.default_custom_device)
self.assertIsInstance(mem17, int)
self.assertGreaterEqual(mem17, 0)
mem18 = paddle.device.memory_reserved(f'{self.default_custom_device}:0')
self.assertIsInstance(mem18, int)
self.assertGreaterEqual(mem18, 0)
mem19 = paddle.device.memory_reserved(0)
self.assertIsInstance(mem19, int)
self.assertGreaterEqual(mem19, 0)
# Test with CustomPlace
custom_place = core.CustomPlace(self.default_custom_device, 0)
mem20 = paddle.device.memory_reserved(custom_place)
self.assertIsInstance(mem20, int)
self.assertGreaterEqual(mem20, 0)
# Now test actual memory allocation and tracking
initial_allocated = paddle.device.memory_allocated()
initial_max_allocated = paddle.device.max_memory_allocated()
initial_reserved = paddle.device.memory_reserved()
initial_max_reserved = paddle.device.max_memory_reserved()
# Allocate first tensor
tensor1 = paddle.randn([128, 128, 128], dtype='float32') # ~8MB
# Check memory after first allocation
allocated_after_first = paddle.device.memory_allocated()
max_allocated_after_first = paddle.device.max_memory_allocated()
reserved_after_first = paddle.device.memory_reserved()
max_reserved_after_first = paddle.device.max_memory_reserved()
# Memory should have increased
self.assertGreater(allocated_after_first, initial_allocated)
self.assertGreater(max_allocated_after_first, initial_max_allocated)
self.assertGreaterEqual(reserved_after_first, initial_reserved)
self.assertGreaterEqual(max_reserved_after_first, initial_max_reserved)
# Allocate second tensor
tensor2 = paddle.randn([64, 64, 64], dtype='float32') # ~2MB
# Check memory after second allocation
allocated_after_second = paddle.device.memory_allocated()
max_allocated_after_second = paddle.device.max_memory_allocated()
reserved_after_second = paddle.device.memory_reserved()
max_reserved_after_second = paddle.device.max_memory_reserved()
# Memory should have increased further
self.assertGreater(allocated_after_second, allocated_after_first)
self.assertGreater(
max_allocated_after_second, max_allocated_after_first
)
self.assertGreaterEqual(reserved_after_second, reserved_after_first)
self.assertGreaterEqual(
max_reserved_after_second, max_reserved_after_first
)
# Release first tensor
del tensor1
# Check memory after releasing first tensor
allocated_after_release = paddle.device.memory_allocated()
max_allocated_after_release = paddle.device.max_memory_allocated()
reserved_after_release = paddle.device.memory_reserved()
max_reserved_after_release = paddle.device.max_memory_reserved()
# Current allocated should decrease, but max should stay the same
self.assertLess(allocated_after_release, allocated_after_second)
self.assertEqual(
max_allocated_after_release, max_allocated_after_second
)
self.assertLessEqual(reserved_after_release, reserved_after_second)
self.assertEqual(max_reserved_after_release, max_reserved_after_second)
# Test reset functions
paddle.device.reset_max_memory_allocated()
paddle.device.reset_max_memory_reserved()
# Check memory after reset
allocated_after_reset = paddle.device.memory_allocated()
max_allocated_after_reset = paddle.device.max_memory_allocated()
reserved_after_reset = paddle.device.memory_reserved()
max_reserved_after_reset = paddle.device.max_memory_reserved()
# Current allocated should remain the same, but max should be reset to current level
self.assertEqual(allocated_after_reset, allocated_after_release)
self.assertLessEqual(
max_allocated_after_reset, max_allocated_after_release
)
self.assertEqual(reserved_after_reset, reserved_after_release)
self.assertLessEqual(
max_reserved_after_reset, max_reserved_after_release
)
# Clean up
del tensor2
paddle.device.empty_cache()
def test_reset_memory_apis_cuda(self):
"""Test reset memory APIs with CUDA with actual tensor allocation."""
if not core.is_compiled_with_cuda():
self.skipTest("CUDA not available")
# Set device to GPU
paddle.device.set_device('gpu')
# Get initial memory values
initial_max_allocated = paddle.device.max_memory_allocated()
initial_max_reserved = paddle.device.max_memory_reserved()
# Allocate tensor to increase memory usage
tensor = paddle.randn([256, 256, 256], dtype='float32') # ~67MB
# Check that max memory has increased
max_allocated_after_alloc = paddle.device.max_memory_allocated()
max_reserved_after_alloc = paddle.device.max_memory_reserved()
self.assertGreater(max_allocated_after_alloc, initial_max_allocated)
self.assertGreaterEqual(max_reserved_after_alloc, initial_max_reserved)
# Test reset functions with different input types
paddle.device.reset_max_memory_allocated()
paddle.device.reset_max_memory_allocated('gpu:0')
paddle.device.reset_max_memory_allocated(0)
paddle.device.reset_max_memory_allocated(paddle.CUDAPlace(0))
# Test reset functions with different input types
paddle.device.reset_peak_memory_stats()
paddle.device.reset_peak_memory_stats('gpu:0')
paddle.device.reset_peak_memory_stats('cuda:0')
paddle.device.reset_peak_memory_stats(0)
paddle.device.reset_peak_memory_stats(paddle.CUDAPlace(0))
# Test reset functions with different input types
paddle.cuda.reset_peak_memory_stats()
paddle.cuda.reset_peak_memory_stats('gpu:0')
paddle.cuda.reset_peak_memory_stats(0)
paddle.cuda.reset_peak_memory_stats(paddle.CUDAPlace(0))
paddle.device.reset_max_memory_reserved()
paddle.device.reset_max_memory_reserved('gpu:0')
paddle.device.reset_max_memory_reserved('cuda:0')
paddle.device.reset_max_memory_reserved(0)
paddle.device.reset_max_memory_reserved(paddle.CUDAPlace(0))
# Test reset functions with different input types
paddle.cuda.reset_max_memory_allocated()
paddle.cuda.reset_max_memory_allocated('gpu:0')
paddle.cuda.reset_max_memory_allocated('cuda:0')
paddle.cuda.reset_max_memory_allocated(0)
paddle.cuda.reset_max_memory_allocated(paddle.CUDAPlace(0))
paddle.cuda.reset_max_memory_reserved()
paddle.cuda.reset_max_memory_reserved('gpu:0')
paddle.cuda.reset_max_memory_reserved('cuda:0')
paddle.cuda.reset_max_memory_reserved(0)
paddle.cuda.reset_max_memory_reserved(paddle.CUDAPlace(0))
# Check that max memory has been reset
max_allocated_after_reset = paddle.device.max_memory_allocated()
max_reserved_after_reset = paddle.device.max_memory_reserved()
# Max memory should be reset to current level (which should be lower than after allocation)
self.assertLessEqual(
max_allocated_after_reset, max_allocated_after_alloc
)
self.assertLessEqual(max_reserved_after_reset, max_reserved_after_alloc)
# Clean up
del tensor
paddle.device.empty_cache()
def test_reset_memory_apis_customdevice(self):
"""Test reset memory APIs with custom device with actual tensor allocation."""
if not is_custom_device():
self.skipTest("Custom device not available")
# Set device to custom device
paddle.device.set_device(self.default_custom_device)
# Get initial memory values
initial_max_allocated = paddle.device.max_memory_allocated()
initial_max_reserved = paddle.device.max_memory_reserved()
# Allocate tensor to increase memory usage
tensor = paddle.randn([128, 128, 128], dtype='float32') # ~8MB
# Check that max memory has increased
max_allocated_after_alloc = paddle.device.max_memory_allocated()
max_reserved_after_alloc = paddle.device.max_memory_reserved()
self.assertGreater(max_allocated_after_alloc, initial_max_allocated)
self.assertGreaterEqual(max_reserved_after_alloc, initial_max_reserved)
# Test reset functions with different input types
paddle.device.reset_max_memory_allocated()
paddle.device.reset_max_memory_allocated(self.default_custom_device)
paddle.device.reset_max_memory_allocated(
f'{self.default_custom_device}:0'
)
paddle.device.reset_max_memory_allocated(0)
custom_place = core.CustomPlace(self.default_custom_device, 0)
paddle.device.reset_max_memory_allocated(custom_place)
paddle.device.reset_max_memory_reserved()
paddle.device.reset_max_memory_reserved(self.default_custom_device)
paddle.device.reset_max_memory_reserved(
f'{self.default_custom_device}:0'
)
paddle.device.reset_max_memory_reserved(0)
custom_place = core.CustomPlace(self.default_custom_device, 0)
paddle.device.reset_max_memory_reserved(custom_place)
# Check that max memory has been reset
max_allocated_after_reset = paddle.device.max_memory_allocated()
max_reserved_after_reset = paddle.device.max_memory_reserved()
# Max memory should be reset to current level (which should be lower than after allocation)
self.assertLessEqual(
max_allocated_after_reset, max_allocated_after_alloc
)
self.assertLessEqual(max_reserved_after_reset, max_reserved_after_alloc)
# Clean up
del tensor
paddle.device.empty_cache()
def test_stream_apis_cuda(self):
"""Test stream APIs with CUDA."""
if not core.is_compiled_with_cuda():
self.skipTest("CUDA not available")
# Test current_stream with different input types
stream1 = paddle.device.current_stream()
self.assertIsNotNone(stream1)
stream2 = paddle.device.current_stream(paddle.CUDAPlace(0))
self.assertIsNotNone(stream2)
# stream3 = paddle.device.current_stream(0)
# self.assertIsNotNone(stream3)
# Test synchronize
paddle.device.synchronize()
paddle.device.synchronize(paddle.CUDAPlace(0))
# paddle.device.synchronize(0)
def test_stream_apis_customdevice(self):
"""Test stream APIs with custom device."""
if not is_custom_device():
self.skipTest("Custom device not available")
# Test current_stream with different input types
stream1 = paddle.device.current_stream()
self.assertIsNotNone(stream1)
stream2 = paddle.device.current_stream(self.default_custom_device)
self.assertIsNotNone(stream2)
stream3 = paddle.device.current_stream(
f'{self.default_custom_device}:0'
)
self.assertIsNotNone(stream3)
# stream4 = paddle.device.current_stream(0)
# self.assertIsNotNone(stream4)
# Test synchronize
paddle.device.synchronize()
paddle.device.synchronize(self.default_custom_device)
paddle.device.synchronize(f'{self.default_custom_device}:0')
# paddle.device.synchronize(0)
def test_stream_apis_xpu(self):
"""Test stream APIs with XPU."""
if not core.is_compiled_with_xpu():
self.skipTest("XPU not available")
# Test current_stream with different input types
stream1 = paddle.device.current_stream()
self.assertIsNotNone(stream1)
stream2 = paddle.device.current_stream(core.XPUPlace(0))
self.assertIsNotNone(stream2)
# stream3 = paddle.device.current_stream(0)
# self.assertIsNotNone(stream3)
# Test synchronize
paddle.device.synchronize()
paddle.device.synchronize('xpu:0')
# paddle.device.synchronize(0)
def test_error_handling(self):
"""Test error handling for invalid inputs."""
if not (
core.is_compiled_with_xpu()
or core.is_compiled_with_cuda()
or is_custom_device()
):
self.skipTest("CUDA, XPU and Custom device not available")
# Test invalid device ID format
with self.assertRaises(ValueError):
paddle.device.max_memory_allocated('gpu:invalid')
# Test invalid input type
with self.assertRaises(ValueError):
paddle.device.max_memory_allocated([1, 2, 3])
def test_get_default_device_cuda(self):
"""Test get_default_device with CUDA."""
if not core.is_compiled_with_cuda():
self.skipTest("CUDA not available")
paddle.device.set_device('gpu')
dev = paddle.get_default_device()
self.assertIsInstance(dev, paddle.device.Device)
self.assertEqual(dev.type, 'cuda')
def test_get_default_device_customdevice(self):
"""Test get_default_device with custom device."""
if not is_custom_device():
self.skipTest("Custom device not available")
paddle.device.set_device(self.default_custom_device)
dev = paddle.get_default_device()
self.assertIsInstance(dev, paddle.device.Device)
self.assertEqual(dev.type, self.default_custom_device)
def test_tensor_device_cuda(self):
"""Test Tensor.device property with CUDA."""
if not core.is_compiled_with_cuda():
self.skipTest("CUDA not available")
paddle.device.set_device('gpu')
t = paddle.randn([2, 2])
dev = t.device
self.assertIsInstance(dev, paddle.device.Device)
self.assertEqual(dev.type, 'cuda')
self.assertIsNotNone(dev.index)
del t
def test_tensor_device_customdevice(self):
"""Test Tensor.device property with custom device."""
if not is_custom_device():
self.skipTest("Custom device not available")
paddle.device.set_device(self.default_custom_device)
t = paddle.randn([2, 2])
dev = t.device
self.assertIsInstance(dev, paddle.device.Device)
self.assertEqual(dev.type, self.default_custom_device)
self.assertIsNotNone(dev.index)
del t
def test_device_class_customdevice(self):
"""Test Device class with custom device type string and Place conversion."""
if not is_custom_device():
self.skipTest("Custom device not available")
# String construction
dev = paddle.device.Device(f'{self.default_custom_device}:0')
self.assertEqual(dev.type, self.default_custom_device)
self.assertEqual(dev.index, 0)
# _to_place round-trip
place = dev._to_place()
self.assertTrue(place.is_custom_place())
if __name__ == '__main__':
unittest.main()
+400
View File
@@ -0,0 +1,400 @@
# Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import paddle
from paddle.base import core
def is_custom_device():
custom_dev_types = paddle.device.get_all_custom_device_type()
if custom_dev_types and paddle.device.is_compiled_with_custom_device(
custom_dev_types[0]
):
return True
return False
class TestEventStreamAPIs(unittest.TestCase):
"""Test paddle.device Event and Stream APIs across different hardware types."""
def setUp(self):
"""Set up test environment."""
if not (
core.is_compiled_with_cuda()
or core.is_compiled_with_xpu()
or is_custom_device()
):
self.skipTest("CUDA, XPU or Custom Device not available")
self.cuda_available = core.is_compiled_with_cuda()
self.xpu_available = core.is_compiled_with_xpu()
self.custom_device_available = is_custom_device()
# Get available custom device types
if self.custom_device_available:
self.custom_device_types = core.get_all_custom_device_type()
self.default_custom_device = self.custom_device_types[0]
else:
self.custom_device_types = []
self.default_custom_device = None
self._original_device = paddle.device.get_device()
self._original_stream = paddle.device.current_stream()
def tearDown(self):
"""Clean up after timing functionality test."""
paddle.device.synchronize()
paddle.device.set_device(self._original_device)
try:
paddle.device.set_stream(self._original_stream)
except Exception:
pass
def test_event_stream_apis_cuda(self):
"""Test Event and Stream APIs with CUDA."""
if not core.is_compiled_with_cuda():
self.skipTest("CUDA not available")
self._test_event_stream_apis_impl('gpu:0')
def test_event_stream_apis_customdevice(self):
"""Test Event and Stream APIs with custom device."""
if not is_custom_device():
self.skipTest("Custom device not available")
self._test_event_stream_apis_impl(f'{self.default_custom_device}:0')
def test_event_stream_apis_xpu(self):
"""Test Event and Stream APIs with XPU."""
if not core.is_compiled_with_xpu():
self.skipTest("XPU not available")
self._test_event_stream_apis_impl('xpu:0')
def _test_event_stream_apis_impl(self, device_str):
"""Test Event and Stream APIs implementation."""
# Set device
paddle.device.set_device(device_str)
# Test Event creation with different parameters
event1 = paddle.device.Event()
self.assertIsInstance(event1, paddle.device.Event)
event2 = paddle.device.Event(enable_timing=True)
self.assertIsInstance(event2, paddle.device.Event)
event3 = paddle.device.Event(enable_timing=True, blocking=True)
self.assertIsInstance(event3, paddle.device.Event)
# Test Stream creation with different parameters
stream1 = paddle.device.Stream()
self.assertIsInstance(stream1, paddle.device.Stream)
stream2 = paddle.device.Stream(device=device_str)
self.assertIsInstance(stream2, paddle.device.Stream)
stream3 = paddle.device.Stream(device=device_str, priority=1)
self.assertIsInstance(stream3, paddle.device.Stream)
# Test current_stream
current_stream = paddle.device.current_stream()
self.assertIsInstance(current_stream, paddle.device.Stream)
# Test set_stream
prev_stream = paddle.device.set_stream(stream1)
self.assertIsInstance(prev_stream, paddle.device.Stream)
prev_stream = paddle.cuda.set_stream(stream1)
self.assertIsInstance(prev_stream, paddle.cuda.Stream)
# Test Event.record() with default stream
event1.record()
# Query result may be True immediately for some devices
try:
self.assertFalse(event1.query())
except AssertionError:
pass # Some devices may complete immediately
# Test Event.record() with specific stream
self.assertTrue(event2.query())
# Test Event.synchronize()
event1.synchronize() # Wait for event to complete
self.assertTrue(event1.query()) # Should be completed now
# Test Stream.query()
if not core.is_compiled_with_xpu():
self.assertTrue(
stream1.query()
) # Should be completed (no work submitted)
# Test Stream.synchronize()
stream1.synchronize() # Should not raise exception
# Test Stream.wait_event()
stream2.wait_event(event1)
# Test Stream.wait_stream()
stream2.wait_stream(stream1)
# Test Stream.record_event()
event4 = stream1.record_event()
self.assertIsInstance(event4, paddle.device.Event)
# Test record_event with existing event
stream1.record_event(event3)
# Test Event.elapsed_time()
if hasattr(event1, 'event_base') and hasattr(event2, 'event_base'):
# Create events with timing enabled
start_event = paddle.device.Event(enable_timing=True)
end_event = paddle.device.Event(enable_timing=True)
# Record start event
start_event.record()
# Submit some work to the stream
with paddle.device.stream_guard(stream1):
# Create a tensor to ensure some work is done
tensor = paddle.randn([100, 100], dtype='float32')
result = tensor * 2
# Record end event
end_event.record()
# Synchronize to ensure events are recorded
end_event.synchronize()
# Measure elapsed time
if not core.is_compiled_with_xpu():
elapsed_time = start_event.elapsed_time(end_event)
self.assertIsInstance(elapsed_time, (int, float))
self.assertGreaterEqual(elapsed_time, 0)
# Test stream_guard context manager
with paddle.device.stream_guard(stream1):
# Inside the context, current stream should be stream1
guarded_stream = paddle.device.current_stream()
self.assertEqual(guarded_stream.device, stream1.device)
# Test operations within stream guard
tensor1 = paddle.ones([10, 10])
tensor2 = paddle.ones([10, 10])
result = tensor1 + tensor2
# After exiting context, stream should be restored
restored_stream = paddle.device.current_stream()
self.assertEqual(restored_stream.device, prev_stream.device)
# Test Stream properties and methods
self.assertTrue(hasattr(stream1, 'stream_base'))
self.assertTrue(hasattr(stream1, 'device'))
if not core.is_compiled_with_xpu():
self.assertTrue(callable(stream1.query))
self.assertTrue(callable(stream1.synchronize))
self.assertTrue(callable(stream1.wait_event))
self.assertTrue(callable(stream1.wait_stream))
self.assertTrue(callable(stream1.record_event))
# Test Event properties and methods
self.assertTrue(hasattr(event1, 'event_base'))
self.assertTrue(hasattr(event1, 'device'))
self.assertTrue(callable(event1.record))
self.assertTrue(callable(event1.query))
if not core.is_compiled_with_xpu():
self.assertTrue(callable(event1.elapsed_time))
self.assertTrue(callable(event1.synchronize))
# Test Stream equality and hash
stream_copy = paddle.device.Stream(device=device_str)
self.assertNotEqual(stream1, stream_copy) # Different stream objects
self.assertEqual(
hash(stream1), hash(stream1)
) # Same hash for same object
# Test Stream representation
stream_repr = repr(stream1)
self.assertIn('paddle.device.Stream', stream_repr)
self.assertIn(str(stream1.device), stream_repr)
# Test Event representation
event_repr = repr(event1)
self.assertIsNotNone(event_repr)
# Clean up
paddle.device.synchronize()
def test_event_stream_error_handling(self):
"""Test Event and Stream error handling."""
# Test with invalid device types
with self.assertRaises(TypeError):
paddle.device.Event(device='invalid_device:0')
with self.assertRaises(ValueError):
paddle.device.Stream(device='invalid_device:0')
# Test Event.elapsed_time with incompatible events
if core.is_compiled_with_cuda() or is_custom_device():
device_str = (
'gpu:0'
if core.is_compiled_with_cuda()
else f'{self.default_custom_device}:0'
)
paddle.device.set_device(device_str)
event1 = paddle.device.Event()
event2 = paddle.device.Event()
# Should not raise exception even if events are not recorded
try:
elapsed = event1.elapsed_time(event2)
self.assertIsInstance(elapsed, (int, float))
except Exception:
# Some implementations might raise exception, which is also acceptable
pass
class TestEventStreamTimingFunctionality(unittest.TestCase):
"""Test Event timing functionality with actual work in isolated environment."""
def setUp(self):
"""Set up test environment for timing functionality."""
if not (
core.is_compiled_with_cuda()
or core.is_compiled_with_xpu()
or is_custom_device()
):
self.skipTest("CUDA, XPU or Custom Device not available")
self.cuda_available = core.is_compiled_with_cuda()
self.custom_device_available = is_custom_device()
# Get available custom device types
if self.custom_device_available:
self.custom_device_types = core.get_all_custom_device_type()
self.default_custom_device = self.custom_device_types[0]
else:
self.custom_device_types = []
self.default_custom_device = None
self._original_device = paddle.device.get_device()
self._original_stream = paddle.device.current_stream()
def tearDown(self):
"""Clean up after timing functionality test."""
paddle.device.synchronize()
paddle.device.set_device(self._original_device)
try:
paddle.device.set_stream(self._original_stream)
except Exception:
pass
def test_event_stream_timing_functionality(self):
"""Test Event timing functionality with actual work."""
if not (self.cuda_available or self.custom_device_available):
self.skipTest(
"Timing functionality test requires CUDA or custom device"
)
device_str = (
'gpu:0'
if self.cuda_available
else f'{self.default_custom_device}:0'
)
paddle.device.set_device(device_str)
# Create events with timing enabled
start_event = paddle.device.Event(enable_timing=True)
end_event = paddle.device.Event(enable_timing=True)
# Create a stream for work execution
stream = paddle.device.Stream(device=device_str)
# Record start event
start_event.record(stream)
# Perform some work on the stream
with paddle.device.stream_guard(stream):
# Create and perform operations on tensors
x = paddle.randn([1000, 1000], dtype='float32')
y = paddle.randn([1000, 1000], dtype='float32')
# Matrix multiplication - computationally intensive
z = paddle.matmul(x, y)
# Ensure the operation is executed
z_mean = z.mean()
# Record end event
end_event.record(stream)
# Wait for the end event to complete
end_event.synchronize()
if not core.is_compiled_with_xpu():
# Calculate elapsed time
elapsed_time = start_event.elapsed_time(end_event)
# Verify the timing result
self.assertIsInstance(elapsed_time, (int, float))
self.assertGreater(elapsed_time, 0) # Should take some time
class TestEventAPIs(unittest.TestCase):
"""Unified test for paddle.Event, paddle.device.Event, and paddle.cuda.Event."""
def setUp(self):
if not paddle.device.is_compiled_with_cuda():
self.skipTest("This test requires CUDA.")
self.device = "gpu:0"
paddle.device.set_device(self.device)
self.event_classes = [
("paddle.Event", paddle.Event),
("paddle.cuda.Event", paddle.cuda.Event),
]
def test_event_timing_consistency(self):
"""Check timing consistency across different Event APIs."""
for name, EventCls in self.event_classes:
with self.subTest(api=name):
start = EventCls(enable_timing=True)
end = EventCls(enable_timing=True)
start.record()
x = paddle.randn([2048, 2048], dtype="float32")
y = paddle.randn([2048, 2048], dtype="float32")
z = paddle.matmul(x, y)
_ = z.mean()
end.record()
end.synchronize()
elapsed = start.elapsed_time(end)
self.assertIsInstance(elapsed, (int, float))
self.assertGreater(
elapsed,
0.0,
f"{name} should measure positive elapsed time.",
)
def test_event_methods_available(self):
"""Ensure all Event variants expose expected methods."""
for name, EventCls in self.event_classes:
with self.subTest(api=name):
e = EventCls(enable_timing=True)
self.assertTrue(hasattr(e, "record"))
self.assertTrue(hasattr(e, "synchronize"))
self.assertTrue(hasattr(e, "elapsed_time"))
if __name__ == '__main__':
unittest.main()
+79
View File
@@ -0,0 +1,79 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import paddle
from paddle import get_device_module
class TestGetDeviceModule(unittest.TestCase):
def test_str_devices(self):
self.assertIs(get_device_module("gpu:0"), paddle.cuda)
self.assertIs(get_device_module("cuda:0"), paddle.cuda)
self.assertIs(get_device_module("xpu:0"), paddle.device.xpu)
custom_devices = [
"metax_gpu",
"biren_gpu",
"custom_cpu",
"gcu",
"iluvatar_gpu",
"intel_gpu",
"intel_hpu",
"mlu",
"mps",
"npu",
"sdaa",
]
for dev in custom_devices:
self.assertIs(get_device_module(dev), paddle.device.custom_device)
self.assertIs(get_device_module('cpu'), paddle.device.cpu)
with self.assertRaises(RuntimeError):
get_device_module("unknown_device")
def test_place_devices(self):
if paddle.cuda.is_available() and paddle.device.is_compiled_with_cuda():
self.assertIs(get_device_module(paddle.CUDAPlace(0)), paddle.cuda)
def test_none_device(self):
current_device_module = get_device_module(None)
current_device_type = paddle.device.get_device().split(":")[0].lower()
if current_device_type in ("cuda", "gpu"):
self.assertIs(current_device_module, paddle.cuda)
elif current_device_type == "xpu":
self.assertIs(current_device_module, paddle.device.xpu)
elif current_device_type in [
"metax_gpu",
"biren_gpu",
"custom_cpu",
"gcu",
"iluvatar_gpu",
"intel_gpu",
"intel_hpu",
"mlu",
"mps",
"npu",
"sdaa",
]:
self.assertIs(current_device_module, paddle.device.custom_device)
elif current_device_type == "cpu":
self.assertIs(current_device_module, paddle.device.cpu)
if __name__ == "__main__":
unittest.main()
+60
View File
@@ -0,0 +1,60 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import paddle
@paddle.library.custom_op(
"test_namespace::add_one",
mutates_args=(),
)
def add_one(x):
return x + 1
@add_one.register_fake
def add_one_fake_fn(x):
return x
@paddle.library.custom_op(
"test_namespace::add_two",
mutates_args=(),
)
def add_two(x):
return x + 2
class TestCallCustomOp(unittest.TestCase):
def test_call_custom_op(self):
self.assertEqual(paddle.ops.test_namespace.add_one(1), 2)
class TestRegisterFake(unittest.TestCase):
def test_register_fake_without_call(self):
paddle.library.register_fake(
"test_namespace::add_two",
lambda x: x + 2,
)
def test_register_fake_with_call(self):
paddle.library.register_fake("test_namespace::add_three")(
lambda x: x + 3,
)
if __name__ == "__main__":
unittest.main()
+496
View File
@@ -0,0 +1,496 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import unittest
from unittest import TestCase
import paddle
def should_skip_tests():
"""
Check if tests should be skipped based on device availability.
Skip if neither CUDA, XPU, nor any custom device is available.
"""
# Check CUDA availability
cuda_available = paddle.is_compiled_with_cuda()
# Check XPU availability
xpu_available = paddle.is_compiled_with_xpu()
# Check custom device availability
custom_available = False
try:
custom_devices = paddle.device.get_all_custom_device_type()
if custom_devices:
for device_type in custom_devices:
if paddle.device.is_compiled_with_custom_device(device_type):
custom_available = True
break
except Exception:
custom_available = False
# Skip tests if no supported devices are available
return not (cuda_available or xpu_available or custom_available)
# Check if we should skip all tests
if should_skip_tests():
print(
"Skipping paddle.cuda API tests: No CUDA, XPU, or custom devices available"
)
sys.exit(0)
class TestCurrentDevice(TestCase):
def test_current_device_return_type(self):
"""Test that current_device returns an integer."""
device_id = paddle.cuda.current_device()
self.assertIsInstance(
device_id, int, "current_device should return an integer"
)
def test_current_device_non_negative(self):
"""Test that current_device returns a non-negative integer."""
device_id = paddle.cuda.current_device()
self.assertGreaterEqual(
device_id, 0, "current_device should return a non-negative integer"
)
def test_current_device_with_device_set(self):
"""Test current_device after setting device."""
if paddle.device.cuda.device_count() > 0:
# Test with CUDA device
original_device = paddle.device.get_device()
# Set to device 0 if available
paddle.device.set_device('gpu:0')
device_id = paddle.cuda.current_device()
self.assertEqual(
device_id, 0, "current_device should return 0 when gpu:0 is set"
)
# Restore original device
paddle.device.set_device(original_device)
class TestDeviceCount(TestCase):
def test_device_count_return_type(self):
"""Test that device_count returns an integer."""
count = paddle.cuda.device_count()
self.assertIsInstance(
count, int, "device_count should return an integer"
)
def test_device_count_non_negative(self):
"""Test that device_count returns a non-negative integer."""
count = paddle.cuda.device_count()
self.assertGreaterEqual(
count, 0, "device_count should return a non-negative integer"
)
class TestEmptyCache(TestCase):
def test_empty_cache_return_type(self):
"""Test that empty_cache returns None."""
result = paddle.cuda.empty_cache()
self.assertIsNone(result, "empty_cache should return None")
def test_empty_cache_no_exception(self):
"""Test that empty_cache does not raise any exceptions."""
try:
paddle.cuda.empty_cache()
except Exception as e:
self.fail(f"empty_cache raised an exception: {e}")
def test_empty_cache_with_memory_allocation(self):
"""Test that empty_cache works after memory allocation."""
if paddle.cuda.device_count() > 0:
# Get initial memory state
initial_memory = paddle.cuda.memory_allocated()
# Allocate some memory
tensor = paddle.randn([1000, 1000])
allocated_memory = paddle.cuda.memory_allocated()
# Verify that memory was actually allocated
self.assertGreater(
allocated_memory,
initial_memory,
"Memory should increase after tensor allocation",
)
# Delete tensor and empty cache
del tensor
paddle.cuda.empty_cache()
# Check memory after empty_cache
final_memory = paddle.cuda.memory_allocated()
# Memory should be reduced after empty_cache
# Note: We allow some tolerance as memory management may not free everything immediately
self.assertLessEqual(
final_memory,
allocated_memory,
"Memory should be reduced after empty_cache",
)
class TestIsInitialized(TestCase):
def test_is_initialized_return_type(self):
"""Test that is_initialized returns a boolean."""
result = paddle.cuda.is_initialized()
self.assertIsInstance(
result, bool, "is_initialized should return a boolean"
)
def test_is_initialized_no_exception(self):
"""Test that is_initialized does not raise any exceptions."""
try:
paddle.cuda.is_initialized()
except Exception as e:
self.fail(f"is_initialized raised an exception: {e}")
def test_is_initialized_with_device_availability(self):
"""Test that is_initialized returns True when devices are available."""
# This test checks if is_initialized correctly detects device compilation
# The result should be consistent with device availability checks
initialized = paddle.cuda.is_initialized()
# If any device is available, is_initialized should return True
cuda_available = paddle.is_compiled_with_cuda()
xpu_available = paddle.is_compiled_with_xpu()
# Check custom devices
custom_available = False
try:
custom_devices = paddle.device.get_all_custom_device_type()
if custom_devices:
for device_type in custom_devices:
if paddle.device.is_compiled_with_custom_device(
device_type
):
custom_available = True
break
except Exception:
custom_available = False
# is_initialized should return True if any device type is compiled
expected = cuda_available or xpu_available or custom_available
self.assertEqual(
initialized,
expected,
f"is_initialized should return {expected} when cuda={cuda_available}, xpu={xpu_available}, custom={custom_available}",
)
class TestMemoryAllocated(TestCase):
def test_memory_allocated_return_type(self):
"""Test that memory_allocated returns an integer."""
result = paddle.cuda.memory_allocated()
self.assertIsInstance(
result, int, "memory_allocated should return an integer"
)
def test_memory_allocated_non_negative(self):
"""Test that memory_allocated returns a non-negative integer."""
result = paddle.cuda.memory_allocated()
self.assertGreaterEqual(
result, 0, "memory_allocated should return a non-negative integer"
)
def test_memory_allocated_consistency(self):
"""Test that memory_allocated returns consistent results when called multiple times."""
result1 = paddle.cuda.memory_allocated()
result2 = paddle.cuda.memory_allocated()
# Memory should be the same or increase (but not decrease without explicit free)
self.assertGreaterEqual(
result2, result1 - 1024, "memory_allocated should be consistent"
)
def test_memory_allocated_with_device_param(self):
"""Test that memory_allocated works with device parameter."""
if paddle.cuda.device_count() > 0:
# Test with device index
result_index = paddle.cuda.memory_allocated(0)
self.assertIsInstance(
result_index,
int,
"memory_allocated should return an integer with device index",
)
self.assertGreaterEqual(
result_index,
0,
"memory_allocated should return non-negative with device index",
)
def test_memory_allocated_no_exception(self):
"""Test that memory_allocated does not raise any exceptions."""
try:
paddle.cuda.memory_allocated()
except Exception as e:
self.fail(f"memory_allocated raised an exception: {e}")
class TestMemoryReserved(TestCase):
def test_memory_reserved_return_type(self):
"""Test that memory_reserved returns an integer."""
result = paddle.cuda.memory_reserved()
self.assertIsInstance(
result, int, "memory_reserved should return an integer"
)
def test_memory_reserved_non_negative(self):
"""Test that memory_reserved returns a non-negative integer."""
result = paddle.cuda.memory_reserved()
self.assertGreaterEqual(
result, 0, "memory_reserved should return a non-negative integer"
)
def test_memory_reserved_consistency(self):
"""Test that memory_reserved returns consistent results when called multiple times."""
result1 = paddle.cuda.memory_reserved()
result2 = paddle.cuda.memory_reserved()
# Reserved memory should be the same or increase (but not decrease without explicit free)
self.assertGreaterEqual(
result2, result1 - 1024, "memory_reserved should be consistent"
)
def test_memory_reserved_with_device_param(self):
"""Test that memory_reserved works with device parameter."""
if paddle.cuda.device_count() > 0:
# Test with device index
result_index = paddle.cuda.memory_reserved(0)
self.assertIsInstance(
result_index,
int,
"memory_reserved should return an integer with device index",
)
self.assertGreaterEqual(
result_index,
0,
"memory_reserved should return non-negative with device index",
)
def test_memory_reserved_no_exception(self):
"""Test that memory_reserved does not raise any exceptions."""
try:
paddle.cuda.memory_reserved()
except Exception as e:
self.fail(f"memory_reserved raised an exception: {e}")
def test_memory_reserved_vs_allocated(self):
"""Test that memory_reserved is greater than or equal to memory_allocated."""
if paddle.cuda.is_initialized():
reserved = paddle.cuda.memory_reserved()
allocated = paddle.cuda.memory_allocated()
self.assertGreaterEqual(
reserved,
allocated,
"memory_reserved should be >= memory_allocated",
)
class TestSetDevice(TestCase):
def test_set_device_return_type(self):
"""Test that set_device returns None."""
if paddle.is_compiled_with_cuda() and paddle.cuda.device_count() > 0:
result = paddle.cuda.set_device(0)
self.assertIsNone(result, "set_device should return None")
def test_set_device_no_exception(self):
"""Test that set_device does not raise any exceptions."""
if paddle.is_compiled_with_cuda() and paddle.cuda.device_count() > 0:
try:
paddle.cuda.set_device(0)
except Exception as e:
self.fail(f"set_device raised an exception: {e}")
def test_set_device_with_int_param(self):
"""Test that set_device works with integer parameter."""
if paddle.is_compiled_with_cuda() and paddle.cuda.device_count() > 0:
try:
# Test with device index 0
paddle.cuda.set_device(0)
# Verify device was set correctly
current_device = paddle.cuda.current_device()
self.assertEqual(
current_device, 0, "set_device should set device to 0"
)
except Exception as e:
self.fail(
f"set_device with int parameter raised an exception: {e}"
)
def test_set_device_int_after_cpu_place(self):
"""Test int parameter after switching the expected place to CPU."""
if not (
paddle.is_compiled_with_cuda() and paddle.cuda.device_count() > 0
):
return
original_device = paddle.device.get_device()
try:
paddle.device.set_device('cpu')
paddle.cuda.set_device(0)
self.assertEqual(
paddle.cuda.current_device(),
0,
'cuda.set_device(0) should select GPU 0 even when the '
'current place is CPU',
)
except Exception as e:
self.fail(
f'cuda.set_device(int) after a CPU place raised an '
f'exception: {e}'
)
finally:
paddle.device.set_device(original_device)
def test_set_device_with_str_param(self):
"""Test that set_device works with string parameter."""
if paddle.is_compiled_with_cuda() and paddle.cuda.device_count() > 0:
try:
# Test with device string
paddle.cuda.set_device('gpu:0')
# Verify device was set correctly
current_device = paddle.cuda.current_device()
self.assertEqual(
current_device,
0,
"set_device should set device to 0 with 'gpu:0'",
)
paddle.cuda.set_device('cuda:0')
current_device = paddle.cuda.current_device()
self.assertEqual(
current_device,
0,
"set_device should set device to 0 with 'cuda:0'",
)
# bare 'gpu' / 'cuda' select the default GPU without raising
paddle.cuda.set_device('gpu')
paddle.cuda.set_device('cuda')
except Exception as e:
self.fail(
f"set_device with string parameter raised an exception: {e}"
)
def test_set_device_with_cuda_place_param(self):
"""Test that set_device works with CUDAPlace parameter."""
if paddle.is_compiled_with_cuda() and paddle.cuda.device_count() > 0:
try:
# Test with CUDAPlace
place = paddle.CUDAPlace(0)
paddle.cuda.set_device(place)
# Verify device was set correctly
current_device = paddle.cuda.current_device()
self.assertEqual(
current_device,
0,
"set_device should set device to 0 with CUDAPlace",
)
except Exception as e:
self.fail(
f"set_device with CUDAPlace parameter raised an exception: {e}"
)
def test_set_device_with_xpu_place_param(self):
"""paddle.cuda.set_device rejects an XPUPlace; use paddle.device.set_device."""
if paddle.is_compiled_with_xpu():
with self.assertRaises(ValueError):
paddle.cuda.set_device(paddle.XPUPlace(0))
def test_set_device_with_xpu_str_param(self):
"""paddle.cuda.set_device rejects an 'xpu:*' string; use paddle.device.set_device."""
with self.assertRaises(ValueError):
paddle.cuda.set_device('xpu:0')
def test_set_device_with_custom_place_param(self):
"""paddle.cuda.set_device rejects a CustomPlace; use paddle.device.set_device."""
custom_devices = paddle.device.get_all_custom_device_type()
if custom_devices:
with self.assertRaises(ValueError):
paddle.cuda.set_device(paddle.CustomPlace(custom_devices[0], 0))
def test_set_device_with_custom_str_param(self):
"""paddle.cuda.set_device rejects a custom-device string; use paddle.device.set_device."""
with self.assertRaises(ValueError):
paddle.cuda.set_device('npu:0')
def test_set_device_invalid_param(self):
"""Test that set_device raises ValueError for invalid parameter types."""
with self.assertRaises(ValueError) as context:
paddle.cuda.set_device(3.14) # Invalid float parameter
self.assertIn("Unsupported device type", str(context.exception))
with self.assertRaises(ValueError) as context:
paddle.cuda.set_device([0]) # Invalid list parameter
self.assertIn("Unsupported device type", str(context.exception))
class TestBf16Supported(unittest.TestCase):
def test_is_bf16_supported(self):
self.assertIsInstance(paddle.cuda.is_bf16_supported(), bool)
self.assertIsInstance(paddle.device.is_bf16_supported(), bool)
self.assertIsInstance(paddle.device.is_bf16_supported(True), bool)
self.assertIsInstance(paddle.cuda.is_bf16_supported(False), bool)
if should_skip_tests():
self.assertFalse(paddle.cuda.is_bf16_supported())
self.assertFalse(paddle.device.is_bf16_supported())
class TestManualSeed(unittest.TestCase):
def test_device_manual_seed(self):
paddle.device.manual_seed(102)
x1 = paddle.randn([2, 3])
paddle.device.manual_seed(999)
x2 = paddle.randn([2, 3])
paddle.device.manual_seed(102)
x3 = paddle.randn([2, 3])
self.assertTrue(
paddle.equal_all(x1, x3),
"Random outputs should be identical with the same seed",
)
self.assertFalse(
paddle.equal_all(x1, x2),
"Random outputs should differ with different seeds",
)
def test_cuda_manual_seed(self):
paddle.cuda.manual_seed(102)
x1 = paddle.randn([2, 3], dtype='float32')
paddle.cuda.manual_seed(999)
x2 = paddle.randn([2, 3], dtype='float32')
paddle.cuda.manual_seed(102)
x3 = paddle.randn([2, 3], dtype='float32')
self.assertTrue(
paddle.equal_all(x1, x3),
"Random outputs should be identical with the same seed",
)
self.assertFalse(
paddle.equal_all(x1, x2),
"Random outputs should differ with different seeds",
)
if __name__ == '__main__':
unittest.main()
+88
View File
@@ -0,0 +1,88 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import numpy as np
import paddle
class TestRngState(unittest.TestCase):
def test_get_and_set_rng_state_cuda(self):
original_state = paddle.cuda.get_rng_state()
try:
r = paddle.cuda.get_rng_state()
self.assertIsInstance(r, paddle.core.GeneratorState)
s = paddle.randn([10, 10])
paddle.cuda.set_rng_state(r)
s1 = paddle.randn([10, 10])
np.testing.assert_allclose(s.numpy(), s1.numpy(), rtol=0, atol=0)
finally:
paddle.cuda.set_rng_state(original_state)
def test_get_and_set_rng_state_cpu(self):
original_state = paddle.cuda.get_rng_state('cpu')
cur_dev = paddle.device.get_device()
paddle.set_device('cpu')
r = paddle.cuda.get_rng_state('cpu')
self.assertIsInstance(r, paddle.core.GeneratorState)
s = paddle.randn([10, 10])
paddle.cuda.set_rng_state(r, device='cpu')
s1 = paddle.randn([10, 10])
np.testing.assert_allclose(s.numpy(), s1.numpy(), rtol=0, atol=0)
paddle.cuda.set_rng_state(original_state, device='cpu')
paddle.set_device(cur_dev)
def test_invalid_device_raises(self):
with self.assertRaises(ValueError):
paddle.set_rng_state(paddle.get_rng_state(), device="unknown:0")
original_state = paddle.get_rng_state()
try:
r = paddle.get_rng_state()
if len(r) > 0:
self.assertIsInstance(r[0], paddle.core.GeneratorState)
s = paddle.randn([10, 10])
paddle.set_rng_state(r)
s1 = paddle.randn([10, 10])
np.testing.assert_allclose(s.numpy(), s1.numpy(), rtol=0, atol=0)
finally:
paddle.set_rng_state(original_state)
def test_api_compatibility(self):
paddle_get_obj = paddle.device.cpu.get_rng_state
alias_get_obj = paddle.random.get_rng_state
self.assertTrue(paddle_get_obj is alias_get_obj)
paddle_set_obj = paddle.device.cpu.set_rng_state
alias_set_obj = paddle.random.set_rng_state
self.assertTrue(paddle_set_obj is alias_set_obj)
def test_alias(self):
state = paddle.random.get_rng_state()
paddle.random.set_rng_state(state)
if __name__ == "__main__":
unittest.main()
+209
View File
@@ -0,0 +1,209 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pathlib
import sys
import unittest
from typing import Optional
from unittest.mock import MagicMock
import numpy as np
import paddle
from paddle.compat.proxy import create_fake_class, create_fake_function
sys.path.append(str(pathlib.Path(__file__).parent / "fake_modules"))
def use_torch_inside_inner_function():
import torch
return torch.sin(torch.tensor([0.0, 1.0, 2.0])).numpy()
class TestTorchProxy(unittest.TestCase):
def test_enable_compat(self):
with self.assertRaises(ModuleNotFoundError):
import torch
paddle.enable_compat()
import torch
self.assertIs(torch.sin, paddle.sin)
import torch.nn
self.assertIs(torch.nn.Conv2d, paddle.nn.Conv2d)
import torch.nn.functional
self.assertIs(torch.nn.functional.sigmoid, paddle.nn.functional.sigmoid)
with self.assertRaises(ModuleNotFoundError):
import torch.nonexistent_module
paddle.disable_compat()
with self.assertRaises(ModuleNotFoundError):
import torch
with self.assertRaises(ModuleNotFoundError):
import torch.nn
with self.assertRaises(ModuleNotFoundError):
import torch.nn.functional
def test_use_compat_guard(self):
with self.assertRaises(ModuleNotFoundError):
import torch
with paddle.use_compat_guard():
import torch
self.assertIs(torch.sin, paddle.sin)
with self.assertRaises(ModuleNotFoundError):
import torch
with paddle.use_compat_guard():
import torch
self.assertIs(torch.cos, paddle.cos)
with paddle.use_compat_guard(enable=False):
with self.assertRaises(ModuleNotFoundError):
import torch
with paddle.use_compat_guard(enable=True):
import torch
with self.assertRaises(ModuleNotFoundError):
import torch
@paddle.use_compat_guard()
def test_use_torch_inside_inner_function(self):
result = use_torch_inside_inner_function()
np.testing.assert_allclose(
result, np.sin([0.0, 1.0, 2.0]), atol=1e-6, rtol=1e-6
)
class TestTorchProxyBlockedModule(unittest.TestCase):
def test_blocked_module(self):
with paddle.use_compat_guard():
with self.assertRaises(ModuleNotFoundError):
import torch._dynamo.allow_in_graph # noqa: F401
with self.assertRaises(AttributeError):
import torch_proxy_blocked_module
paddle.compat.extend_torch_proxy_blocked_modules(
{"torch_proxy_blocked_module"}
)
import torch_proxy_blocked_module
# Use torch specific function out of execute module stage
torch_proxy_blocked_module.use_torch_specific_fn()
class TestTorchProxyLocalEnabledModule(unittest.TestCase):
def test_local_enabled_module(self):
with self.assertRaises(ModuleNotFoundError):
import torch_proxy_local_enabled_module
paddle.enable_compat(scope="torch_proxy_local_enabled_module")
with self.assertRaises(ModuleNotFoundError):
import torch # noqa: F401
import torch_proxy_local_enabled_module
torch_proxy_local_enabled_module.use_torch_compat_api()
paddle.compat.proxy.TORCH_PROXY_FINDER._globally_enabled = False
paddle.compat.proxy.TORCH_PROXY_FINDER._local_enabled_scope = set()
paddle.disable_compat()
class TestTorchProxyUseMockedModule(unittest.TestCase):
def test_use_mocked_module(self):
# Define mocked torch before use torch proxy
mocked_torch = MagicMock()
sys.modules["torch"] = mocked_torch
with paddle.use_compat_guard(scope=set()):
import torch
# torch proxy should not affect mocked torch,
# because the `import torch` not under the enabled scope
self.assertIs(torch, mocked_torch)
self.assertIs(torch, mocked_torch)
class TestOverrideTorchModule(unittest.TestCase):
@paddle.use_compat_guard()
def test_relu(self):
import torch
self.assertIs(torch.relu, paddle.nn.functional.relu)
@paddle.use_compat_guard()
def test_torch_version_class(self):
import torch
self.assertIs(torch.TorchVersion, paddle.PaddleVersion)
self.assertIsInstance(torch.__version__, paddle.PaddleVersion)
@paddle.use_compat_guard()
def test_access_compat_functions_by_getattr(self):
import torch
self.assertIs(torch.nn.Unfold, paddle.compat.nn.Unfold)
self.assertIs(torch.nn.Linear, paddle.compat.nn.Linear)
@paddle.use_compat_guard()
def test_access_compat_functions_by_import(self):
from torch.nn.functional import linear, softmax
self.assertIs(softmax, paddle.compat.nn.functional.softmax)
self.assertIs(linear, paddle.compat.nn.functional.linear)
class TestFakeInterface(unittest.TestCase):
def test_fake_interface(self):
FakeGenerator = create_fake_class(
"torch.Generator",
{"manual_seed": create_fake_function("manual_seed")},
)
fake_gen = FakeGenerator()
self.assertTrue(hasattr(fake_gen, "manual_seed"))
class TestDeviceAsTypeHints(unittest.TestCase):
@paddle.use_compat_guard()
def test_device_as_type_hints(self):
import torch
# TODO: Remove Optional[...] coverage once Python 3.10 support is dropped.
def fn(x: Optional[torch.device]): # noqa: UP045
return x
self.assertTrue(callable(torch.device))
self.assertEqual(
fn.__annotations__["x"],
Optional[torch.device], # noqa: UP045
)
cpu_device = torch.device("cpu")
self.assertEqual(str(cpu_device), "cpu")
self.assertEqual(
torch.device.is_compiled_with_xpu(),
paddle.device.is_compiled_with_xpu(),
)
if __name__ == "__main__":
unittest.main()
+98
View File
@@ -0,0 +1,98 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pathlib
import sys
import unittest
import paddle
from paddle.compat.proxy import (
ProxyModule,
)
sys.path.append(str(pathlib.Path(__file__).parent / "fake_modules"))
sys.path.append(str(pathlib.Path(__file__).parent / "fake_torch_modules"))
class TestTorchProxyMixRealTorch(unittest.TestCase):
def check_is_not_proxy(self):
import torch
from torch.nn.functional import relu
self.assertNotIsInstance(torch, ProxyModule)
self.assertIsNot(paddle.nn.functional.relu, relu)
def check_is_proxy(self):
import torch
from torch.nn.functional import relu
self.assertIsInstance(torch, ProxyModule)
self.assertIs(paddle.nn.functional.relu, relu)
def test_nested_torch_proxy(self):
self.check_is_not_proxy()
with paddle.use_compat_guard(enable=True):
self.check_is_proxy()
with paddle.use_compat_guard(enable=False):
self.check_is_not_proxy()
with paddle.use_compat_guard(enable=True):
self.check_is_proxy()
with paddle.use_compat_guard(enable=True):
self.check_is_proxy()
with paddle.use_compat_guard(enable=False):
self.check_is_not_proxy()
self.check_is_not_proxy()
self.check_is_proxy()
self.check_is_not_proxy()
def test_local_enabled_module_import(self):
self.check_is_not_proxy()
with paddle.use_compat_guard(
enable=True, scope={"torch_proxy_local_enabled_module"}
):
self.check_is_not_proxy()
self.check_is_not_proxy()
def test_blocked_module_import(self):
self.check_is_not_proxy()
paddle.compat.extend_torch_proxy_blocked_modules(
{"torch_proxy_blocked_module"}
)
with paddle.use_compat_guard(enable=True):
import torch_proxy_blocked_module # noqa: F401
self.check_is_proxy()
self.check_is_not_proxy()
def test_blocked_module_inside_local_enabled_proxy_import(self):
self.check_is_not_proxy()
paddle.compat.extend_torch_proxy_blocked_modules(
{"torch_proxy_blocked_module"}
)
with paddle.use_compat_guard(
enable=True, scope={"torch_proxy_local_enabled_module"}
):
import torch_proxy_blocked_module # noqa: F401
self.check_is_not_proxy()
self.check_is_not_proxy()
if __name__ == "__main__":
unittest.main()
+55
View File
@@ -0,0 +1,55 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import inspect
import unittest
from paddle.version import cuda
class TestCudaVariable(unittest.TestCase):
def test_has_signature(self):
self.assertTrue(hasattr(cuda, '__signature__'))
self.assertIsInstance(cuda.__signature__, inspect.Signature)
self.assertEqual(len(cuda.__signature__.parameters), 0)
def test_has_doc(self):
self.assertTrue(hasattr(cuda, '__doc__'))
self.assertIsInstance(cuda.__doc__, str)
self.assertTrue(len(cuda.__doc__.strip()) > 0)
def test_inspect_recognizes(self):
self.assertTrue(inspect.getdoc(cuda))
self.assertIsInstance(inspect.signature(cuda), inspect.Signature)
def test_cuda_functionality(self):
self.assertIsInstance(cuda, str)
self.assertTrue(len(cuda) > 0)
self.assertEqual(str(cuda), cuda)
self.assertTrue(callable(cuda))
self.assertTrue(
hasattr(cuda, 'startswith'),
"Return value of cuda does not have 'startswith' attribute",
)
result = cuda()
self.assertIsInstance(result, str)
self.assertEqual(result, cuda)
self.assertTrue(
hasattr(result, 'startswith'),
"Return value of cuda() does not have 'startswith' attribute",
)
if __name__ == "__main__":
unittest.main()