From e845a80ab8bc4c25bcf4f086e030d1ee43b96ed0 Mon Sep 17 00:00:00 2001 From: Dmitry Trifonov Date: Wed, 14 Sep 2016 13:54:49 -0700 Subject: [PATCH] added headers to program::compile --- include/boost/compute/program.hpp | 39 ++++++++++++++++++++--- test/test_program.cpp | 52 +++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/include/boost/compute/program.hpp b/include/boost/compute/program.hpp index 7573aa02..0975aa72 100644 --- a/include/boost/compute/program.hpp +++ b/include/boost/compute/program.hpp @@ -273,12 +273,14 @@ public: } #if defined(CL_VERSION_1_2) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED) - /// Compiles the program with \p options. + /// Compiles the program with \p options and \p headers. /// /// \opencl_version_warning{1,2} /// /// \see_opencl_ref{clCompileProgram} - void compile(const std::string &options = std::string()) + void compile(const std::string &options = std::string(), + const std::vector > &headers = + std::vector >()) { const char *options_string = 0; @@ -286,9 +288,36 @@ public: options_string = options.c_str(); } - cl_int ret = clCompileProgram( - m_program, 0, 0, options_string, 0, 0, 0, 0, 0 - ); + cl_int ret; + if (headers.empty()) + { + ret = clCompileProgram( + m_program, 0, 0, options_string, 0, 0, 0, 0, 0 + ); + } + else + { + std::vector header_names(headers.size()); + std::vector header_programs(headers.size()); + for (size_t i = 0; i < headers.size(); ++i) + { + header_names[i] = headers[i].first.c_str(); + header_programs[i] = headers[i].second.m_program; + } + + ret = clCompileProgram( + m_program, + 0, + 0, + options_string, + headers.size(), + header_programs.data(), + header_names.data(), + 0, + 0 + ); + } + if(ret != CL_SUCCESS){ BOOST_THROW_EXCEPTION(opencl_error(ret)); diff --git a/test/test_program.cpp b/test/test_program.cpp index 78c59204..ad43fc87 100644 --- a/test/test_program.cpp +++ b/test/test_program.cpp @@ -192,6 +192,58 @@ BOOST_AUTO_TEST_CASE(compile_and_link) linked_program.create_kernel("square_kernel"); BOOST_CHECK_EQUAL(square_kernel.name(), "square_kernel"); } + +BOOST_AUTO_TEST_CASE(compile_and_link_with_headers) +{ + REQUIRES_OPENCL_VERSION(1,2); + + if(!supports_compile_program(device) || !supports_link_program(device)) { + return; + } + + // create the header programs + const char square_header_source[] = BOOST_COMPUTE_STRINGIZE_SOURCE( + T square(T x) { return x * x; } + ); + const char div2_header_source[] = BOOST_COMPUTE_STRINGIZE_SOURCE( + T div2(T x) { return x / 2; } + ); + + compute::program square_header_program = + compute::program::create_with_source(square_header_source, context); + compute::program div2_header_program = + compute::program::create_with_source(div2_header_source, context); + + // create the kernel program + const char kernel_source[] = + "#include \"square.h\"\n" + "#include \"div2.h\"\n" + "__kernel void squareby2_kernel(__global int *x)" + "{" + " x[0] = div2(square(x[0]));" + "}"; + + compute::program square_program = + compute::program::create_with_source(kernel_source, context); + + std::vector > header_programs; + header_programs.push_back(std::make_pair("square.h", square_header_program)); + header_programs.push_back(std::make_pair("div2.h", div2_header_program)); + + square_program.compile("-DT=int", header_programs); + + // link program + std::vector programs; + programs.push_back(square_program); + + compute::program linked_program = + compute::program::link(programs, context); + + // create the square kernel + compute::kernel square_kernel = + linked_program.create_kernel("squareby2_kernel"); + BOOST_CHECK_EQUAL(square_kernel.name(), "squareby2_kernel"); +} #endif // CL_VERSION_1_2 BOOST_AUTO_TEST_CASE(build_log)