为何两块RTX3090分属不同平台?SYCL上下文绑定报错求助
问题描述
我有两块RTX3090 GPU,尝试用以下SYCL代码将它们绑定到同一个上下文:
int main() { std::vector<sycl::device> devices = sycl::device::get_devices(); std::vector<sycl::device> gpu_devices; for (const auto& device : devices) { std::cout<<device.get_info<sycl::info::device::name>()<<std::endl; if (device.get_info<sycl::info::device::name>().find("3090") != std::string::npos) { gpu_devices.push_back(device); } } sycl::context ctx(gpu_devices); return 0; }
运行时抛出错误:
what(): Can't add devices across platforms to a single context. -33 (PI_ERROR_INVALID_DEVICE)
代码当前输出:
Platform: Intel(R) OpenCL Device: Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz Platform: Intel(R) OpenCL Device: Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz Platform: Intel(R) FPGA Emulation Platform for OpenCL(TM) Device: Intel(R) FPGA Emulation Device Platform: NVIDIA CUDA BACKEND Device: NVIDIA GeForce RTX 3090 Platform: NVIDIA CUDA BACKEND Device: NVIDIA GeForce RTX 3090
我的预期输出:
Platform: NVIDIA CUDA BACKEND Device: NVIDIA GeForce RTX 3090 Device: NVIDIA GeForce RTX 3090
核心疑问:为何同款GPU会显示分属不同平台?
原因分析与解决办法
为何同款GPU显示分属不同平台?
这是输出格式的误导——两块RTX3090实际属于同一个NVIDIA CUDA BACKEND平台,只是原代码在遍历设备时,每输出一个设备就重复打印了一次所属平台的信息,并非GPU分属不同平台。
报错的真正原因
原代码逻辑存在漏洞:sycl::device::get_devices()默认返回所有平台的所有设备(包括Intel CPU、FPGA模拟器等),仅通过设备名称筛选"3090"的逻辑,可能误将其他平台名称含"3090"的设备混入列表,导致创建上下文时触发跨平台设备的错误。
修复后的代码
要正确筛选同一平台下的NVIDIA GPU并创建上下文,应先定位到NVIDIA CUDA平台,再获取该平台下的GPU设备:
#include <sycl/sycl.hpp> #include <iostream> #include <vector> int main() { // 遍历所有平台,定位NVIDIA CUDA BACKEND平台 std::vector<sycl::platform> platforms = sycl::platform::get_platforms(); sycl::platform nvidia_platform; for (const auto& plt : platforms) { std::string plt_name = plt.get_info<sycl::info::platform::name>(); if (plt_name.find("NVIDIA CUDA BACKEND") != std::string::npos) { nvidia_platform = plt; break; } } // 获取该平台下的所有GPU设备 std::vector<sycl::device> gpu_devices = nvidia_platform.get_devices(sycl::info::device_type::gpu); // 按预期格式打印平台与设备信息 std::cout << "Platform: " << nvidia_platform.get_info<sycl::info::platform::name>() << std::endl; for (const auto& dev : gpu_devices) { std::cout << "Device: " << dev.get_info<sycl::info::device::name>() << std::endl; } // 创建跨GPU的上下文 sycl::context ctx(gpu_devices); std::cout << "Successfully created context with " << gpu_devices.size() << " NVIDIA GPUs" << std::endl; return 0; }
修复说明
- 先定位目标平台,确保后续获取的所有设备都属于同一平台,从根源避免跨平台设备混入
- 直接通过平台获取GPU设备,比遍历所有设备更高效、准确
- 按预期格式打印信息,不会重复输出平台名称
内容的提问来源于stack exchange,提问作者Alice Pedom
相关产品推荐
相关产品推荐

