我正在尝试用triSYCL运行一个并行的for循环。这是我的代码:
#define TRISYCL_OPENCL
#define OMP_NUM_THREADS 8
#define BOOST_COMPUTE_USE_CPP11
//standart libraries
#include <iostream>
#include <functional>
//deps
#include "CL/sycl.hpp"
struct Color
{
float r, g, b, a;
friend std::ostream& operator<<(std::ostream& os, const Color& c)
{
os << "(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")";
return os;
}
};
struct Vertex
{
float x, y;
Color color;
friend std::ostream& operator<<(std::ostream& os, const Vertex& v)
{
os << "x: " << v.x << ", y: " << v.y << ", color: " << v.color;
return os;
}
};
template<typename T>
T mapNumber(T x, T a, T b, T c, T d)
{
return (x - a) / (b - a) * (d - c) + c;
}
int windowWidth = 640;
int windowHeight = 720;
int main()
{
auto exception_handler = [](cl::sycl::exception_list exceptions) {
for (std::exception_ptr const& e : exceptions)
{
try
{
std::rethrow_exception(e);
} catch (cl::sycl::exception const& e)
{
std::cout << "Caught asynchronous SYCL exception: " << e.what() << std::endl;
}
}
};
cl::sycl::default_selector defaultSelector;
cl::sycl::context context(defaultSelector, exception_handler);
cl::sycl::queue queue(context, defaultSelector, exception_handler);
auto* pixelColors = new Color[windowWidth * windowHeight];
{
cl::sycl::buffer<Color, 2> color_buffer(pixelColors, cl::sycl::range < 2 > {(unsigned long) windowWidth,
(unsigned long) windowHeight});
cl::sycl::buffer<int, 1> b_windowWidth(&windowWidth, cl::sycl::range < 1 > {1});
cl::sycl::buffer<int, 1> b_windowHeight(&windowHeight, cl::sycl::range < 1 > {1});
queue.submit([&](cl::sycl::handler& cgh) {
auto color_buffer_acc = color_buffer.get_access<cl::sycl::access::mode::write>(cgh);
auto width_buffer_acc = b_windowWidth.get_access<cl::sycl::access::mode::read>(cgh);
auto height_buffer_acc = b_windowHeight.get_access<cl::sycl::access::mode::read>(cgh);
cgh.parallel_for<class init_pixelColors>(
cl::sycl::range<2>((unsigned long) width_buffer_acc[0], (unsigned long) height_buffer_acc[0]),
[=](cl::sycl::id<2> index) {
color_buffer_acc[index[0]][index[1]] = {
mapNumber<float>(index[0], 0.f, width_buffer_acc[0], 0.f, 1.f),
mapNumber<float>(index[1], 0.f, height_buffer_acc[0], 0.f, 1.f),
0.f,
1.f};
});
});
std::cout << "cl::sycl::queue check - selected device: "
<< queue.get_device().get_info<cl::sycl::info::device::name>() << std::endl;
}//here the error appears
delete[] pixelColors;
return 0;
}我用这个CMakeLists.txt文件构建它:
cmake_minimum_required(VERSION 3.16.2)
project(acMandelbrotSet_stackoverflow)
set(CMAKE_CXX_STANDARD 17)
set(SRC_FILES
path/to/main.cpp
)
find_package(OpenCL REQUIRED)
set(Boost_INCLUDE_DIR path/to/boost)
include_directories(${Boost_INCLUDE_DIR})
include_directories(path/to/SYCL/include)
set(LIBS PRIVATE ${Boost_LIBRARIES} OpenCL::OpenCL)
add_executable(${PROJECT_NAME} ${SRC_FILES})
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX _d)
target_link_libraries(${PROJECT_NAME} ${LIBS})当我尝试运行它时,我得到这样的消息:从path/to/SYCL/include/triSYCL/command_group/detail/task.hpp行:libc++abi.dylib: terminating with uncaught exception of type trisycl::non_cl_error:278function:trisycl::detail::task::get_kernel,消息是:“无法在此上下文中使用OpenCL内核”。
我试着在内核中创建一个mapNumber的lambda,但这并没有什么不同。我还尝试在作用域结束之前使用它来捕获错误:
try
{
queue.wait_and_throw();
} catch (cl::sycl::exception const& e)
{
std::cout << "Caught synchronous SYCL exception: " << e.what() << std::endl;
}但是除了之前的错误之外,控制台中没有任何内容被打印出来。我还尝试创建queue.submit调用的一个事件,然后在作用域结束之前调用event.wait(),但仍然是完全相同的输出。
有没有人知道我还可以尝试什么?
发布于 2020-07-03 06:09:43
问题是,triSYCL是一个研究项目,它更深入地研究了SYCL的某些方面,而没有为最终用户提供全局通用的SYCL支持。我刚刚在项目的自述文件中澄清了这一点。:-(这里的问题可能是没有生成OpenCL SPIR内核。因此,您需要首先从triSYCL https://github.com/triSYCL/triSYCL/blob/master/doc/architecture.rst#trisycl-architecture-for-accelerator编译特定的(旧的) Clang & LLVM。但不幸的是,没有简单的Clang驱动程序可以使用所有特定的Clang & LLVM从SYCL源代码生成内核。正确的知道它是用一些特别糟糕的Makefile(看看https://github.com/triSYCL/triSYCL/blob/master/tests/Makefile#L360)完成的,即使你能存活下来,你也可能会遇到一些bug……
好消息是现在有几个其他的SYCL实现,它们更容易使用,更完整,错误也更少!:-)看看ComputeCpp,DPC++和hipSYCL。
https://stackoverflow.com/questions/62563116
复制相似问题