如何抑制OpenCL构建错误输出到标准错误流?
解决OpenCL编译时标准错误流干扰问题
针对Ubuntu+Nvidia环境下,OpenCL编译无效程序时nvcc直接向标准错误流输出2 errors generated.的问题,以下是两种可靠解决方案:
方案一:临时重定向标准错误流到/dev/null
通过系统调用临时保存当前stderr的文件描述符,将其重定向到/dev/null,编译完成后再恢复。这种方法能彻底拦截所有直接写入stderr的输出:
#include <unistd.h> #include <fcntl.h> std::optional<cl::Program> buildProgram(cl::Context & context, std::ostream * log) { if(log == nullptr) { log = &std::cerr; } cl::Program program{context, programSrc5, false}; // 保存原始stderr文件描述符 int originalStderr = dup(STDERR_FILENO); // 打开/dev/null int devNull = open("/dev/null", O_WRONLY); // 将stderr重定向到/dev/null dup2(devNull, STDERR_FILENO); close(devNull); try { program.build("-w"); // 恢复原始stderr dup2(originalStderr, STDERR_FILENO); close(originalStderr); return program; } catch (cl::Error const& e) { // 恢复原始stderr dup2(originalStderr, STDERR_FILENO); close(originalStderr); *log << e.what() << ": " << e.err() << std::endl; auto devices = context.getInfo<CL_CONTEXT_DEVICES>(); for(auto const& device : devices) { *log << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device); } return {}; } }
方案二:使用Nvidia编译器专属静默选项
Nvidia的OpenCL编译器支持通过-Xnvcc传递nvcc自身的参数,其中-quiet可以抑制编译器的冗余输出:
std::optional<cl::Program> buildProgram(cl::Context & context, std::ostream * log) { if(log == nullptr) { log = &std::cerr; } cl::Program program{context, programSrc5, false}; try { // 添加-Xnvcc -quiet抑制nvcc的stderr输出 program.build("-w -Xnvcc -quiet"); return program; } catch (cl::Error const& e) { *log << e.what() << ": " << e.err() << std::endl; auto devices = context.getInfo<CL_CONTEXT_DEVICES>(); for(auto const& device : devices) { *log << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device); } return {}; } }
方案对比
- 方案一:通用性强,适用于所有直接写入stderr的外部工具,不依赖编译器特性,但需要处理系统文件描述符,注意资源释放。
- 方案二:更简洁,针对Nvidia环境定制,无需操作系统调用,但仅对Nvidia的OpenCL编译器有效。
内容的提问来源于stack exchange,提问作者Xirema
相关产品推荐
相关产品推荐

