Files
2026-07-13 12:40:42 +08:00

203 lines
7.1 KiB
Python

# Copyright (c) 2020 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 ctypes
import unittest
from op_test import get_device, get_device_class, is_custom_device
import paddle
from paddle import base
from paddle.base import core, framework
class TestSetDeviceEagerSwitch(unittest.TestCase):
"""Test that paddle.set_device immediately switches the underlying
hardware device (e.g. cudaSetDevice) without creating any tensor."""
def _get_cuda_runtime_device_id(self):
"""Use ctypes to call cudaGetDevice directly from CUDA runtime."""
try:
lib_name = 'libcudart.so'
cudart = ctypes.CDLL(lib_name)
except:
return None
device = ctypes.c_int(-1)
cudart.cudaGetDevice(ctypes.byref(device))
return device.value
def test_set_device_switches_cuda_device_immediately(self):
"""After set_device('gpu:1'), cudaGetDevice should return 1
immediately, even before creating any tensor."""
if not core.is_compiled_with_cuda() or core.get_cuda_device_count() < 2:
return
paddle.disable_static()
paddle.device.set_device('gpu:1')
runtime_device = self._get_cuda_runtime_device_id()
if runtime_device is None:
return
self.assertEqual(
runtime_device,
1,
msg=f"Expected cudaGetDevice()=1 after set_device('gpu:1'), "
f"but got {runtime_device}",
)
paddle.device.set_device('gpu:0')
runtime_device = self._get_cuda_runtime_device_id()
self.assertEqual(
runtime_device,
0,
msg=f"Expected cudaGetDevice()=0 after set_device('gpu:0'), "
f"but got {runtime_device}",
)
class TestStaticDeviceManage(unittest.TestCase):
def _test_device(self, device_name, device_class):
paddle.enable_static()
paddle.set_device(device_name)
out1 = paddle.zeros(shape=[1, 3], dtype='float32')
out2 = paddle.ones(shape=[1, 3], dtype='float32')
out3 = paddle.concat(x=[out1, out2], axis=0)
exe = paddle.static.Executor()
exe.run(paddle.base.default_startup_program())
res = exe.run(fetch_list=[out3])
device = paddle.get_device()
self.assertEqual(isinstance(exe.place, device_class), True)
self.assertEqual(device, device_name)
paddle.disable_static()
def test_cpu_device(self):
self._test_device("cpu", core.CPUPlace)
def test_gpu_device(self):
if core.is_compiled_with_cuda():
self._test_device("gpu:0", get_device_class())
def test_xpu_device(self):
if core.is_compiled_with_xpu():
self._test_device("xpu:0", core.XPUPlace)
def test_custom_device(self):
if is_custom_device():
self._test_device(get_device(True), get_device_class())
class TestImperativeDeviceManage(unittest.TestCase):
def test_cpu(self):
with base.dygraph.guard():
paddle.set_device('cpu')
out1 = paddle.zeros(shape=[1, 3], dtype='float32')
out2 = paddle.ones(shape=[1, 3], dtype='float32')
out3 = paddle.concat(x=[out1, out2], axis=0)
device = paddle.get_device()
self.assertEqual(
isinstance(framework._current_expected_place(), core.CPUPlace),
True,
)
self.assertEqual(device, "cpu")
def test_gpu(self):
if core.is_compiled_with_cuda():
with base.dygraph.guard():
paddle.set_device('gpu:0')
out1 = paddle.zeros(shape=[1, 3], dtype='float32')
out2 = paddle.ones(shape=[1, 3], dtype='float32')
out3 = paddle.concat(x=[out1, out2], axis=0)
device = paddle.get_device()
self.assertEqual(
isinstance(
framework._current_expected_place(), get_device_class()
),
True,
)
self.assertEqual(device, "gpu:0")
def test_xpu(self):
if core.is_compiled_with_xpu():
with base.dygraph.guard():
out = paddle.to_tensor([1, 2])
device = paddle.get_device()
self.assertEqual(
isinstance(
framework._current_expected_place(), core.XPUPlace
),
True,
)
self.assertTrue(out.place.is_xpu_place())
self.assertEqual(device, "xpu:0")
def test_custom_device(self):
if is_custom_device():
with base.dygraph.guard():
paddle.set_device(get_device(True))
out1 = paddle.zeros(shape=[1, 3], dtype='float32')
out2 = paddle.ones(shape=[1, 3], dtype='float32')
out3 = paddle.concat(x=[out1, out2], axis=0)
device = paddle.get_device()
self.assertEqual(
isinstance(
framework._current_expected_place(), get_device_class()
),
True,
)
self.assertEqual(device, get_device(True))
class TestGetPaddlePlaceAdaptiveGPU(unittest.TestCase):
"""Test that _get_paddle_place('gpu'/'cuda') respects the globally set device ID."""
def setUp(self):
paddle.disable_static()
def test_empty_device_cuda_follows_set_device(self):
"""paddle.empty(device='cuda') should be placed on the device
selected by paddle.device.set_device('cuda:1'), not always GPU 0."""
if not core.is_compiled_with_cuda():
return
if core.get_cuda_device_count() < 2:
return
paddle.device.set_device('cuda:1')
a = paddle.empty(1, device='cuda')
place_str = str(a.place)
# restore default
paddle.device.set_device('cuda:0')
self.assertIn(
'1',
place_str,
msg=f"Expected tensor on GPU 1 but got place: {place_str}",
)
def test_empty_device_gpu_follows_set_device_cpu(self):
"""paddle.empty(device='gpu') should also respect set_device('gpu:0')."""
if not core.is_compiled_with_cuda():
return
if core.get_cuda_device_count() < 1:
return
paddle.device.set_device('gpu:0')
a = paddle.empty(1, device='gpu')
self.assertTrue(a.place.is_gpu_place())
paddle.device.set_device('cpu')
a = paddle.empty(1, device='gpu')
self.assertTrue(a.place.is_gpu_place())
if __name__ == '__main__':
unittest.main()