[Mesa-dev] [PATCH 3/3] clover: add clCompile
Tom Stellard
tom at stellard.net
Thu Oct 9 06:29:40 PDT 2014
On Sun, Sep 28, 2014 at 12:57:22PM +0200, EdB wrote:
> ---
> src/gallium/state_trackers/clover/api/dispatch.cpp | 2 +-
> src/gallium/state_trackers/clover/api/program.cpp | 39 +++++++++++++++++++---
> .../state_trackers/clover/core/compiler.hpp | 12 ++++---
> src/gallium/state_trackers/clover/core/error.hpp | 2 +-
> src/gallium/state_trackers/clover/core/program.cpp | 14 ++++++--
> src/gallium/state_trackers/clover/core/program.hpp | 5 ++-
> .../state_trackers/clover/llvm/invocation.cpp | 39 ++++++++++++++++++----
> 7 files changed, 93 insertions(+), 20 deletions(-)
>
> diff --git a/src/gallium/state_trackers/clover/api/dispatch.cpp b/src/gallium/state_trackers/clover/api/dispatch.cpp
> index 35d150d..b5a4094 100644
> --- a/src/gallium/state_trackers/clover/api/dispatch.cpp
> +++ b/src/gallium/state_trackers/clover/api/dispatch.cpp
> @@ -122,7 +122,7 @@ namespace clover {
> clReleaseDevice,
> clCreateImage,
> clCreateProgramWithBuiltInKernels,
> - NULL, // clCompileProgram
> + clCompileProgram,
> NULL, // clLinkProgram
> clUnloadPlatformCompiler,
> NULL, // clGetKernelArgInfo
> diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp
> index 6771735..33df0cd 100644
> --- a/src/gallium/state_trackers/clover/api/program.cpp
> +++ b/src/gallium/state_trackers/clover/api/program.cpp
> @@ -152,14 +152,34 @@ CLOVER_API cl_int
> clBuildProgram(cl_program d_prog, cl_uint num_devs,
> const cl_device_id *d_devs, const char *p_opts,
> void (*pfn_notify)(cl_program, void *),
> - void *user_data) try {
> + void *user_data) {
> + cl_int error = clCompileProgram(d_prog, num_devs, d_devs, p_opts,
> + 0, 0, 0,
> + pfn_notify, user_data);
> + return error == CL_COMPILE_PROGRAM_FAILURE ?
> + CL_BUILD_PROGRAM_FAILURE : error;
> +}
> +
> +CLOVER_API cl_int
> +clCompileProgram(cl_program d_prog, cl_uint num_devs,
> + const cl_device_id *d_devs, const char *p_opts,
> + cl_uint num_headers, const cl_program *d_header_progs,
> + const char **header_names,
> + void (*pfn_notify)(cl_program, void *),
> + void *user_data) try {
> auto &prog = obj(d_prog);
> auto devs = (d_devs ? objs(d_devs, num_devs) :
> ref_vector<device>(prog.context().devices()));
> auto opts = (p_opts ? p_opts : "");
>
> - if (bool(num_devs) != bool(d_devs) ||
> - (!pfn_notify && user_data))
> + if (bool(num_devs) != bool(d_devs))
> + throw error(CL_INVALID_VALUE);
> +
> + if (!pfn_notify && user_data)
> + throw error(CL_INVALID_VALUE);
> +
> + if (bool(num_headers) != bool(header_names) ||
> + bool(num_headers) != bool(d_header_progs))
> throw error(CL_INVALID_VALUE);
>
> if (any_of([&](const device &dev) {
> @@ -170,7 +190,18 @@ clBuildProgram(cl_program d_prog, cl_uint num_devs,
> if (prog.kernel_ref_count())
> throw error(CL_INVALID_OPERATION);
>
> - prog.build(devs, opts);
> + std::map<const std::string, const std::string> headers;
> + for (cl_uint i = 0; i < num_headers; ++i) {
> + auto h_name = std::string(header_names[i]);
> + auto &h_prog = obj(d_header_progs[i]);
> +
> + if (!h_prog.has_source)
> + throw error(CL_INVALID_OPERATION);
> +
> + headers.insert(make_pair(h_name, h_prog.source()));
> + }
> +
> + prog.build(devs, opts, headers);
> return CL_SUCCESS;
>
> } catch (error &e) {
> diff --git a/src/gallium/state_trackers/clover/core/compiler.hpp b/src/gallium/state_trackers/clover/core/compiler.hpp
> index 6ef84d1..c2c4063 100644
> --- a/src/gallium/state_trackers/clover/core/compiler.hpp
> +++ b/src/gallium/state_trackers/clover/core/compiler.hpp
> @@ -29,11 +29,15 @@
> #include "pipe/p_defines.h"
>
> namespace clover {
> + typedef compat::pair<compat::vector_ref<const char>,
> + compat::vector_ref<const char> > vector_ref_pair;
> +
> module compile_program_llvm(const compat::string &source,
> - pipe_shader_ir ir,
> - const compat::string &target,
> - const compat::string &opts,
> - compat::string &r_log);
> + const compat::vector<vector_ref_pair> &headers,
> + pipe_shader_ir ir,
> + const compat::string &target,
> + const compat::string &opts,
> + compat::string &r_log);
>
> module compile_program_tgsi(const compat::string &source);
> }
> diff --git a/src/gallium/state_trackers/clover/core/error.hpp b/src/gallium/state_trackers/clover/core/error.hpp
> index cecbe9b..7b010f1 100644
> --- a/src/gallium/state_trackers/clover/core/error.hpp
> +++ b/src/gallium/state_trackers/clover/core/error.hpp
> @@ -67,7 +67,7 @@ namespace clover {
> class build_error : public error {
> public:
> build_error(const compat::string &what = "") :
> - error(CL_BUILD_PROGRAM_FAILURE, what) {
> + error(CL_COMPILE_PROGRAM_FAILURE, what) {
> }
> };
>
> diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp
> index 6c224db..0940697 100644
> --- a/src/gallium/state_trackers/clover/core/program.cpp
> +++ b/src/gallium/state_trackers/clover/core/program.cpp
> @@ -41,7 +41,8 @@ program::program(clover::context &ctx,
> }
>
> void
> -program::build(const ref_vector<device> &devs, const char *opts) {
> +program::build(const ref_vector<device> &devs, const char *opts,
> + const string_map &headers) {
> if (has_source) {
> _devices = devs;
>
> @@ -54,10 +55,19 @@ program::build(const ref_vector<device> &devs, const char *opts) {
>
> compat::string log;
>
> + compat::vector<vector_ref_pair> cpt_headers;
> + for (auto &header : headers) {
> + vector_ref_pair h;
> + h.first = header.first;
> + h.second = header.second;
> + cpt_headers.push_back(h);
> + }
> +
> try {
> auto module = (dev.ir_format() == PIPE_SHADER_IR_TGSI ?
> compile_program_tgsi(_source) :
> - compile_program_llvm(_source, dev.ir_format(),
> + compile_program_llvm(_source, cpt_headers,
> + dev.ir_format(),
> dev.ir_target(), build_opts(dev),
> log));
> _binaries.insert({ &dev, module });
> diff --git a/src/gallium/state_trackers/clover/core/program.hpp b/src/gallium/state_trackers/clover/core/program.hpp
> index 4bb5b68..8e05075 100644
> --- a/src/gallium/state_trackers/clover/core/program.hpp
> +++ b/src/gallium/state_trackers/clover/core/program.hpp
> @@ -29,6 +29,8 @@
> #include "core/context.hpp"
> #include "core/module.hpp"
>
> +typedef std::map<const std::string, const std::string> string_map;
> +
> namespace clover {
> class program : public ref_counter, public _cl_program {
> private:
> @@ -46,7 +48,8 @@ namespace clover {
> program &
> operator=(const program &prog) = delete;
>
> - void build(const ref_vector<device> &devs, const char *opts);
> + void build(const ref_vector<device> &devs, const char *opts,
> + const string_map &headers);
>
> const bool has_source;
> const std::string &source() const;
> diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
> index 7bca0d6..9f16adc 100644
> --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
> +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
> @@ -118,6 +118,7 @@ namespace {
>
> llvm::Module *
> compile(llvm::LLVMContext &llvm_ctx, const std::string &source,
> + const compat::vector<vector_ref_pair> &headers,
> const std::string &name, const std::string &triple,
> const std::string &processor, const std::string &opts,
> clang::LangAS::Map& address_spaces, compat::string &r_log) {
> @@ -213,12 +214,35 @@ namespace {
>
> #if HAVE_LLVM >= 0x0306
> c.getPreprocessorOpts().addRemappedFile(name,
> - llvm::MemoryBuffer::getMemBuffer(source).release());
> + llvm::MemoryBuffer::getMemBuffer(source).release());
Unnecessary whitespace change.
> #else
> c.getPreprocessorOpts().addRemappedFile(name,
> llvm::MemoryBuffer::getMemBuffer(source));
> #endif
>
> + if (headers.size()) {
> + const std::string tmp_header_path = "/tmp/clover/";
> +
Why are we using a /tmp/clover here? Aren't the headers stored in memory?
-Tom
> + c.getHeaderSearchOpts().AddPath(tmp_header_path,
> + clang::frontend::Angled,
> + false, false
> + #if HAVE_LLVM < 0x0303
> + , false
> + #endif
> + );
> +
> + for (size_t i = 0; i < headers.size(); ++i) {
> + vector_ref_pair header = headers[i];
> + const std::string path = tmp_header_path + std::string(header.first.begin());
> + c.getPreprocessorOpts().addRemappedFile(path,
> +#if HAVE_LLVM >= 0x0306
> + llvm::MemoryBuffer::getMemBuffer(header.second.begin()).release());
> +#else
> + llvm::MemoryBuffer::getMemBuffer(header.second.begin()));
> +#endif
> + }
> + }
> +
> // Setting this attribute tells clang to link this file before
> // performing any optimizations. This is required so that
> // we can replace calls to the OpenCL C barrier() builtin
> @@ -401,10 +425,11 @@ namespace {
>
> module
> clover::compile_program_llvm(const compat::string &source,
> - enum pipe_shader_ir ir,
> - const compat::string &target,
> - const compat::string &opts,
> - compat::string &r_log) {
> + const compat::vector<vector_ref_pair> &headers,
> + enum pipe_shader_ir ir,
> + const compat::string &target,
> + const compat::string &opts,
> + compat::string &r_log) {
>
> std::vector<llvm::Function *> kernels;
> size_t processor_str_len = std::string(target.begin()).find_first_of("-");
> @@ -417,8 +442,8 @@ clover::compile_program_llvm(const compat::string &source,
>
> // The input file name must have the .cl extension in order for the
> // CompilerInvocation class to recognize it as an OpenCL source file.
> - llvm::Module *mod = compile(llvm_ctx, source, "input.cl", triple, processor,
> - opts, address_spaces, r_log);
> + llvm::Module *mod = compile(llvm_ctx, source, headers, "input.cl",
> + triple, processor, opts, address_spaces, r_log);
>
> find_kernels(mod, kernels);
>
> --
> 2.1.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list