【发布时间】:2014-08-29 18:48:08
【问题描述】:
我是 OpenCL 的新手。在配备 Intel(R) HD Graphics 4000、运行 Windows 7 的 Core i5 机器上工作。我安装了支持 OpenCL 的最新 Intel 驱动程序。 GpuCapsViewer 确认我有 OpenCL 支持设置。我使用英特尔 OpenCL SDK 开发了一个简单的 HelloWorld 程序。我成功编译了程序,但是在运行时,它在调用 clGetPlatformIDs() 时崩溃,并出现分段错误。这是我的代码:
#include <iostream>
#include <CL/opencl.h>
int main() {
std::cout << "Test OCL without driver" << std::endl;
cl_int err;
cl_uint num_platforms;
err = clGetPlatformIDs(0, NULL, &num_platforms);
if (err == CL_SUCCESS) {
std::cout << "Success. Platforms available: " << num_platforms
<< std::endl;
} else {
std::cout << "Error. Platforms available: " << num_platforms
<< std::endl;
}
std::cout << "Test OCL without driver" << std::endl;
std::cout << "Press button to exit." << std::endl;
std::cin.get();
return 0;
}
GpuCapsViewer 怎么会成功确认 OpenCL 支持并可以使用它来运行它的演示,但我无法运行我的代码?两者必须使用相同的功能,对吧?
这几天一直在努力。甚至尝试重新安装驱动程序。有什么想法吗?
GpuCapsViewer 说:
驱动程序:R295.93 (r295_00-233) / 10.18.10.3496 (3-11-2014)
OpenGL:OpenGL 4.2(GeForce GT 630M/PCIe/SSE2 with 290 ext.)
OPENCL:OpenCL 1.1,GeForce GT 630M 计算单元:2@950MHz
CUDA:GeForce GT 630M CC:2.1,多处理器:2@950MHz
PHYSX:GPU PhysX (NVIDIA GeForce GT 630M)
多 GPU:不支持多 GPU(2 个物理 GPU)
更新:
编译行:
g++ -I"C:\Program Files (x86)\Intel\OpenCL SDK\4.4\include" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"Test3.d" -MT"Test3.d" -o "Test3.o" "../Test3.cpp"
Finished building: ../Test3.cpp
链接器行:
g++ -L"C:\Program Files (x86)\Intel\OpenCL SDK\4.4\lib\x64" -o "TestOpenCL" ./HelloWorld.o ./HelloWorld2.o ./Test3.o -lOpenCL
Finished building target: TestOpenCL
操作系统:Windows 7 Ultimate 版本 6.1(内部版本 7601:Service Pack 1)
更新 2,崩溃信息:
Problem Event Name: APPCRASH
Application Name: TestOpenCL.exe
Application Version: 0.0.0.0
Application Timestamp: 53bc6ac5
Fault Module Name: TestOpenCL.exe
Fault Module Version: 0.0.0.0
Fault Module Timestamp: 53bc6ac5
Exception Code: c0000005
Exception Offset: 0000000000002cc0
OS Version: 6.1.7601.2.1.0.256.1
Locale ID: 1033
Additional Information 1: 56e3
Additional Information 2: 56e3743a8a234df3bdeba0b507471c44
Additional Information 3: 8fe0
Additional Information 4: 8fe0ef5706153941955de850e5612393
更新 3:
使用 DependencyWalker(http://dependencywalker.com/) 作为垃圾箱的替代品。它会生成以下警告:
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
警告似乎是指以下 DLL,这些 DLL 均标有“打开文件时出错。系统找不到指定的文件 (2)”错误消息。
API-MS-WIN-CORE-COM-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ERROR-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ROBUFFER-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL
API-MS-WIN-SHCORE-SCALING-L1-1-0.DLL
DCOMP.DLL
IESHIMS.DLL
更新 4,GDB 回溯:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000402cc0 in clGetPlatformIDs ()
(gdb) backtrace full
#0 0x0000000000402cc0 in clGetPlatformIDs ()
No symbol table info available.
#1 0x0000000000402af3 in main () at ../Test3.cpp:11
err = 0
num_platforms = 0
platform = 0x0
(gdb) backtrace
#0 0x0000000000402cc0 in clGetPlatformIDs ()
#1 0x0000000000402af3 in main () at ../Test3.cpp:11
更新 5,GDB DISASS:
(gdb) disass
Dump of assembler code for function clGetPlatformIDs:
=> 0x0000000000402cc0 <+0>: jmpq *0x4b74e8(%rip) # 0x8ba1ae
0x0000000000402cc6 <+6>: nop
0x0000000000402cc7 <+7>: nop
End of assembler dump.
更新 6,共享 GDB 信息:
(gdb) INFO SHARED
From To Syms Read Shared Object Library
0x0000000077191000 0x00000000773384e0 Yes (*) C:\Windows\system32\ntdll.dll
0x0000000077071000 0x000000007718eab4 Yes (*) C:\Windows\system32\kernel32.dll
0x000007fefc081000 0x000007fefc0eb13c Yes (*) C:\Windows\system32\KernelBase.dll
0x000007fedf8d1000 0x000007fedf8e96aa Yes (*) C:\Windows\system32\OpenCL.dll
0x000007fefe101000 0x000007fefe1da628 Yes (*) C:\Windows\system32\advapi32.dll
0x000007fefe061000 0x000007fefe0fe4bc Yes (*) C:\Windows\system32\msvcrt.dll
0x000007fefdcc1000 0x000007fefdcde39a Yes (*) C:\Windows\SYSTEM32\sechost.dll
0x000007fefc6a1000 0x000007fefc7cc914 Yes (*) C:\Windows\system32\rpcrt4.dll
(*): Shared library is missing debugging information.
二进制文件、x64 和包含文件夹:
https://drive.google.com/file/d/0BxKA63T2GnKMRW02QWZnam5lSGM/edit?usp=sharing
更新 7,GPUcaps 情况:
GPUcaps 检测到 2 个 GPU:
- GPU 1:Intel(R) HD Graphics 4000
- GPU 2:NVIDIA GeForce GT 630M
你可以在这里看到截图:
https://drive.google.com/file/d/0BxKA63T2GnKMa00tU1gydGNJeXc/edit?usp=sharing
更新 8:
根据@antiduh 的回答,我一直在尝试直接链接 Windows\System32 文件夹中的 OpenCL.dll。我正在使用mingw64。我明白了:
Invoking: Cross G++ Linker
g++ -L"C:\Windows\System32" -o "TestOpenCL" ./HelloWorld.o ./HelloWorld2.o ./Test3.o -lOpenCL
d:/ws/apps_inst/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.7.1/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Windows\System32/OpenCL.dll when searching for -lOpenCL
d:/ws/apps_inst/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.7.1/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Windows\System32/OpenCL.dll when searching for -lOpenCL
d:/ws/apps_inst/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.7.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lOpenCL
d:/ws/apps_inst/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.7.1/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Windows\System32/msvcrt.dll when searching for -lmsvcrt
d:/ws/apps_inst/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.7.1/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Windows\System32/advapi32.dll when searching for -ladvapi32
d:/ws/apps_inst/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.7.1/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Windows\System32/shell32.dll when searching for -lshell32
d:/ws/apps_inst/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.7.1/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Windows\System32/user32.dll when searching for -luser32
d:/ws/apps_inst/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.7.1/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Windows\System32/kernel32.dll when searching for -lkernel32
d:/ws/apps_inst/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.7.1/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Windows\System32/msvcrt.dll when searching for -lmsvcrt
更新 9: 我现在可以使用以下行手动编译、链接和运行示例代码。
g++ -I. s.cpp -L. -lOpenCL
我简化了所有内容,而且效果很好。这显然与 Eclipse 使用的编译和链接命令有很大不同。知道eclipse使用的哪些参数会导致问题吗?还有,为什么 eclipse 先编译成目标文件,然后再尝试链接它们,分两个独立的步骤?
【问题讨论】:
-
我在黑暗中刺伤,但是:在第一次调用 clGetPlatformIds 之前,
num_platforms是否需要设置为零?您是否需要在传递之前将“0”第一个参数强制转换为 cl_int?您的编译行和链接器行是什么?您是否链接到正确版本的库? -
您使用的是什么平台(Windows、Linux)?如果是 linux,ldd 对你的二进制文件有什么看法?这与您希望从哪里获取库相符吗?
-
可能在这里找到了您的答案:stackoverflow.com/a/20033042/344638 - 您的 OpenCL SDK 可能无法处理
(0, NULL, &numPlatforms)的情况。尝试使用对 cl_platform_id 变量的有效引用执行它,例如clGetPlatformIDs(1, &platform, &numPlatforms)并查看它是否正确设置了 numPlatforms。 -
@antiduh 使用 Windows。尝试将 num_platforms 设置为 0,并且还传递了有效的 cl_platform_id 引用。不用找了。用您要求的信息更新了问题。感谢您的宝贵时间。
-
您的代码在我看来是正确的(我使用 OpenCL)。 antiduh 的评论可能很好,但规范很清楚
0, NULL, &num_platforms应该是函数的好参数。您能否显示实际的崩溃信息(例如,“错误”地访问了哪个地址?)[注意,我不为英特尔工作,因此对他们的产品没有特别的了解]