[Mesa-dev,v3,2/2] clover: add GetKernelArgInfo (CL 1.2)

Submitted by Francisco Jerez on Dec. 12, 2016, 1:48 a.m.

Details

Message ID 87bmwhhq7o.fsf@riseup.net
State New
Headers show
Series "clover: add GetKernelArgInfo (CL 1.2)" ( rev: 4 ) in Mesa

Not browsing as part of any series.

Commit Message

Francisco Jerez Dec. 12, 2016, 1:48 a.m.
Serge Martin <edb+mesa@sigluy.net> writes:

> ---
>  src/gallium/state_trackers/clover/api/kernel.cpp   | 92 +++++++++++++++++++++-
>  src/gallium/state_trackers/clover/core/module.cpp  | 14 ++++
>  src/gallium/state_trackers/clover/core/module.hpp  | 11 +++
>  .../state_trackers/clover/llvm/codegen/common.cpp  | 11 +++
>  4 files changed, 125 insertions(+), 3 deletions(-)
>
> diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp
> index 73ba34a..81a4a38 100644
> --- a/src/gallium/state_trackers/clover/api/kernel.cpp
> +++ b/src/gallium/state_trackers/clover/api/kernel.cpp
> @@ -192,9 +192,95 @@ clGetKernelWorkGroupInfo(cl_kernel d_kern, cl_device_id d_dev,
>  CLOVER_API cl_int
>  clGetKernelArgInfo(cl_kernel d_kern,
>                     cl_uint idx, cl_kernel_arg_info param,
> -                   size_t size, void *r_buf, size_t *r_size) {
> -   CLOVER_NOT_SUPPORTED_UNTIL("1.2");
> -   return CL_KERNEL_ARG_INFO_NOT_AVAILABLE;
> +                   size_t size, void *r_buf, size_t *r_size) try {
> +   property_buffer buf { r_buf, size, r_size };
> +   const auto &kern = obj(d_kern);
> +
> +   const auto args =
> +      find(name_equals(kern.name()), kern.program().symbols()).args;
> +
> +   if (args.at(0).arg_info.arg_name.empty())
> +      throw error(CL_KERNEL_ARG_INFO_NOT_AVAILABLE);
> +
> +   const auto &arg = find([&](const clover::module::argument &arg) {
> +                           return arg.arg_info.index == idx;
> +                        }, args);
> +
> +   switch (param) {
> +   case CL_KERNEL_ARG_ADDRESS_QUALIFIER: {
> +      cl_kernel_arg_address_qualifier v;
> +      switch (arg.type) {
> +         case module::argument::local:
> +            v = CL_KERNEL_ARG_ADDRESS_LOCAL;
> +            break;
> +         case module::argument::constant:
> +            v = CL_KERNEL_ARG_ADDRESS_CONSTANT;
> +            break;
> +         case module::argument::global:
> +         case module::argument::image2d_rd:
> +         case module::argument::image2d_wr:
> +         case module::argument::image3d_rd:
> +         case module::argument::image3d_wr:
> +            v = CL_KERNEL_ARG_ADDRESS_GLOBAL;
> +            break;
> +         default:
> +            v = CL_KERNEL_ARG_ADDRESS_PRIVATE;
> +         }
> +      buf.as_scalar<cl_kernel_arg_address_qualifier>() = v;
> +      break;
> +   }
> +
> +   case CL_KERNEL_ARG_ACCESS_QUALIFIER: {
> +      cl_kernel_arg_access_qualifier v;
> +      switch (arg.type) {
> +         case module::argument::image2d_rd:
> +         case module::argument::image3d_rd:
> +            v = CL_KERNEL_ARG_ACCESS_READ_ONLY;
> +            break;
> +         case module::argument::image2d_wr:
> +         case module::argument::image3d_wr:
> +            v = CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
> +            break;
> +         default:
> +            v = CL_KERNEL_ARG_ACCESS_NONE;
> +         }
> +      buf.as_scalar<cl_kernel_arg_access_qualifier>() = v;
> +      break;
> +   }
> +
> +   case CL_KERNEL_ARG_TYPE_NAME:
> +      buf.as_string() = arg.arg_info.type_name;
> +      break;
> +
> +   case CL_KERNEL_ARG_TYPE_QUALIFIER: {
> +      cl_kernel_arg_type_qualifier v = CL_KERNEL_ARG_TYPE_NONE;
> +
> +      if (arg.arg_info.type_qualifier.find("const") != std::string::npos)
> +         v |= CL_KERNEL_ARG_TYPE_CONST;
> +      if (arg.arg_info.type_qualifier.find("restrict") != std::string::npos)
> +         v |= CL_KERNEL_ARG_TYPE_RESTRICT;
> +      if (arg.arg_info.type_qualifier.find("volatile") != std::string::npos)
> +         v |= CL_KERNEL_ARG_TYPE_VOLATILE;
> +
> +      buf.as_scalar<cl_kernel_arg_type_qualifier>() = v;
> +      break;
> +   }
> +
> +   case CL_KERNEL_ARG_NAME:
> +      buf.as_string() = arg.arg_info.arg_name;
> +      break;
> +
> +   default:
> +      throw error(CL_INVALID_VALUE);
> +   }
> +
> +   return CL_SUCCESS;
> +
> +} catch (std::out_of_range &e) {
> +   return CL_INVALID_ARG_INDEX;
> +
> +} catch (error &e) {
> +   return e.get();
>  }
>  
>  namespace {
> diff --git a/src/gallium/state_trackers/clover/core/module.cpp b/src/gallium/state_trackers/clover/core/module.cpp
> index a6c5b98..1b6b642 100644
> --- a/src/gallium/state_trackers/clover/core/module.cpp
> +++ b/src/gallium/state_trackers/clover/core/module.cpp
> @@ -168,6 +168,19 @@ namespace {
>        }
>     };
>  
> +   /// (De)serialize a module::argument::info
> +   template<>
> +   struct _serializer<module::argument::info> {
> +      template<typename S, typename QT>
> +      static void
> +      proc(S &s, QT &x) {
> +         _proc(s, x.index);
> +         _proc(s, x.type_name);
> +         _proc(s, x.type_qualifier);
> +         _proc(s, x.arg_name);
> +      }
> +   };
> +
>     /// (De)serialize a module::argument.
>     template<>
>     struct _serializer<module::argument> {
> @@ -180,6 +193,7 @@ namespace {
>           _proc(s, x.target_align);
>           _proc(s, x.ext_type);
>           _proc(s, x.semantic);
> +         _proc(s, x.arg_info);
>        }
>     };
>  
> diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp
> index 2ddd264..4425df9 100644
> --- a/src/gallium/state_trackers/clover/core/module.hpp
> +++ b/src/gallium/state_trackers/clover/core/module.hpp
> @@ -54,6 +54,16 @@ namespace clover {
>        };
>  
>        struct argument {
> +         struct info {
> +            info() :
> +            index(-1), type_name(""), type_qualifier(""), arg_name("") { }
> +
> +            size_t index;
> +            std::string type_name;
> +            std::string type_qualifier;
> +            std::string arg_name;
> +         };
> +
>           enum type {
>              scalar,
>              constant,
> @@ -102,6 +112,7 @@ namespace clover {
>           size_t target_align;
>           ext_type ext_type;
>           semantic semantic;
> +         info arg_info;
>        };
>  
>        struct symbol {
> diff --git a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
> index aa6ca50..03b9a88 100644
> --- a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
> +++ b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
> @@ -69,6 +69,7 @@ namespace {
>     std::vector<module::argument>
>     make_kernel_args(const Module &mod, const std::string &kernel_name,
>                      const clang::CompilerInstance &c) {
> +      const bool get_args_infos = c.getCodeGenOpts().EmitOpenCLArgMetadata;
>        std::vector<module::argument> args;
>        const auto address_spaces = c.getTarget().getAddressSpaceMap();
>        const Function &f = *mod.getFunction(kernel_name);
> @@ -161,6 +162,16 @@ namespace {
>                                    module::argument::zero_ext));
>              }
>           }
> +
> +         if (get_args_infos) {
> +            struct module::argument::info i;
> +            i.index = arg.getArgNo();
> +            i.type_name = get_argument_metadata(f, arg, "kernel_arg_type");
> +            i.type_qualifier = get_argument_metadata(f, arg, "kernel_arg_type_qual");
> +            i.arg_name = get_argument_metadata(f, arg, "kernel_arg_name");
> +            args.back().arg_info = i;
> +         }
> +
>        }
>  
>        // Append implicit arguments.  XXX - The types, ordering and

With the attached clean-up patch squashed in this gets my:

Reviewed-by: Francisco Jerez <currojerez@riseup.net>

> -- 
> 2.5.5

Patch hide | download patch | download mbox

From c4b87b6ea47cc0c32403b418ba41f8c52af4e91f Mon Sep 17 00:00:00 2001
From: Francisco Jerez <currojerez@riseup.net>
Date: Sun, 11 Dec 2016 17:30:49 -0800
Subject: [PATCH] SQUASH: clover: Add GetKernelArgInfo (CL 1.2)

[ Francisco Jerez: Refactor computation of
  cl_kernel_arg_address_qualifier, cl_kernel_arg_access_qualifier and
  cl_kernel_arg_type_qualifier bitfields.  Drop unnecessary
  argument::info::index field from binary module format.  Misc
  clean-up. ]

Reviewed-by: Francisco Jerez <currojerez@riseup.net>
---
 src/gallium/state_trackers/clover/api/kernel.cpp   | 121 +++++++++++----------
 src/gallium/state_trackers/clover/core/module.cpp  |   5 +-
 src/gallium/state_trackers/clover/core/module.hpp  |  10 +-
 .../state_trackers/clover/llvm/codegen/common.cpp  |  15 +--
 4 files changed, 75 insertions(+), 76 deletions(-)

diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp
index 81a4a38..0ab4aa9 100644
--- a/src/gallium/state_trackers/clover/api/kernel.cpp
+++ b/src/gallium/state_trackers/clover/api/kernel.cpp
@@ -189,85 +189,88 @@  clGetKernelWorkGroupInfo(cl_kernel d_kern, cl_device_id d_dev,
    return CL_INVALID_DEVICE;
 }
 
+namespace {
+   cl_kernel_arg_address_qualifier
+   get_kernel_arg_address_qualifier(const module::argument &arg) {
+      switch (arg.type) {
+      case module::argument::local:
+         return CL_KERNEL_ARG_ADDRESS_LOCAL;
+      case module::argument::constant:
+         return CL_KERNEL_ARG_ADDRESS_CONSTANT;
+      case module::argument::global:
+      case module::argument::image2d_rd:
+      case module::argument::image2d_wr:
+      case module::argument::image3d_rd:
+      case module::argument::image3d_wr:
+         return CL_KERNEL_ARG_ADDRESS_GLOBAL;
+      default:
+         return CL_KERNEL_ARG_ADDRESS_PRIVATE;
+      }
+   }
+
+   cl_kernel_arg_access_qualifier
+   get_kernel_arg_access_qualifier(const module::argument &arg) {
+      switch (arg.type) {
+      case module::argument::image2d_rd:
+      case module::argument::image3d_rd:
+         return CL_KERNEL_ARG_ACCESS_READ_ONLY;
+      case module::argument::image2d_wr:
+      case module::argument::image3d_wr:
+         return CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
+      default:
+         return CL_KERNEL_ARG_ACCESS_NONE;
+      }
+   }
+
+   cl_kernel_arg_type_qualifier
+   get_kernel_arg_type_qualifier(const module::argument &arg) {
+      const auto &qs = arg.info.type_qualifier;
+      return (qs.find("const") == std::string::npos ? 0 :
+              CL_KERNEL_ARG_TYPE_CONST) |
+             (qs.find("restrict") == std::string::npos ? 0 :
+              CL_KERNEL_ARG_TYPE_RESTRICT) |
+             (qs.find("volatile") == std::string::npos ? 0 :
+              CL_KERNEL_ARG_TYPE_VOLATILE);
+   }
+}
+
 CLOVER_API cl_int
 clGetKernelArgInfo(cl_kernel d_kern,
                    cl_uint idx, cl_kernel_arg_info param,
                    size_t size, void *r_buf, size_t *r_size) try {
    property_buffer buf { r_buf, size, r_size };
    const auto &kern = obj(d_kern);
+   const auto &args = find(name_equals(kern.name()),
+                           kern.program().symbols()).args;
+   const auto &arg = find([=](const clover::module::argument &arg) mutable {
+         return arg.semantic == module::argument::general && idx-- == 0;
+      }, args);
 
-   const auto args =
-      find(name_equals(kern.name()), kern.program().symbols()).args;
-
-   if (args.at(0).arg_info.arg_name.empty())
+   if (arg.info.arg_name.empty())
       throw error(CL_KERNEL_ARG_INFO_NOT_AVAILABLE);
 
-   const auto &arg = find([&](const clover::module::argument &arg) {
-                           return arg.arg_info.index == idx;
-                        }, args);
-
    switch (param) {
-   case CL_KERNEL_ARG_ADDRESS_QUALIFIER: {
-      cl_kernel_arg_address_qualifier v;
-      switch (arg.type) {
-         case module::argument::local:
-            v = CL_KERNEL_ARG_ADDRESS_LOCAL;
-            break;
-         case module::argument::constant:
-            v = CL_KERNEL_ARG_ADDRESS_CONSTANT;
-            break;
-         case module::argument::global:
-         case module::argument::image2d_rd:
-         case module::argument::image2d_wr:
-         case module::argument::image3d_rd:
-         case module::argument::image3d_wr:
-            v = CL_KERNEL_ARG_ADDRESS_GLOBAL;
-            break;
-         default:
-            v = CL_KERNEL_ARG_ADDRESS_PRIVATE;
-         }
-      buf.as_scalar<cl_kernel_arg_address_qualifier>() = v;
+   case CL_KERNEL_ARG_ADDRESS_QUALIFIER:
+      buf.as_scalar<cl_kernel_arg_address_qualifier>() =
+         get_kernel_arg_address_qualifier(arg);
       break;
-   }
 
-   case CL_KERNEL_ARG_ACCESS_QUALIFIER: {
-      cl_kernel_arg_access_qualifier v;
-      switch (arg.type) {
-         case module::argument::image2d_rd:
-         case module::argument::image3d_rd:
-            v = CL_KERNEL_ARG_ACCESS_READ_ONLY;
-            break;
-         case module::argument::image2d_wr:
-         case module::argument::image3d_wr:
-            v = CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
-            break;
-         default:
-            v = CL_KERNEL_ARG_ACCESS_NONE;
-         }
-      buf.as_scalar<cl_kernel_arg_access_qualifier>() = v;
+   case CL_KERNEL_ARG_ACCESS_QUALIFIER:
+      buf.as_scalar<cl_kernel_arg_access_qualifier>() =
+         get_kernel_arg_access_qualifier(arg);
       break;
-   }
 
    case CL_KERNEL_ARG_TYPE_NAME:
-      buf.as_string() = arg.arg_info.type_name;
+      buf.as_string() = arg.info.type_name;
       break;
 
-   case CL_KERNEL_ARG_TYPE_QUALIFIER: {
-      cl_kernel_arg_type_qualifier v = CL_KERNEL_ARG_TYPE_NONE;
-
-      if (arg.arg_info.type_qualifier.find("const") != std::string::npos)
-         v |= CL_KERNEL_ARG_TYPE_CONST;
-      if (arg.arg_info.type_qualifier.find("restrict") != std::string::npos)
-         v |= CL_KERNEL_ARG_TYPE_RESTRICT;
-      if (arg.arg_info.type_qualifier.find("volatile") != std::string::npos)
-         v |= CL_KERNEL_ARG_TYPE_VOLATILE;
-
-      buf.as_scalar<cl_kernel_arg_type_qualifier>() = v;
+   case CL_KERNEL_ARG_TYPE_QUALIFIER:
+      buf.as_scalar<cl_kernel_arg_type_qualifier>() =
+         get_kernel_arg_type_qualifier(arg);
       break;
-   }
 
    case CL_KERNEL_ARG_NAME:
-      buf.as_string() = arg.arg_info.arg_name;
+      buf.as_string() = arg.info.arg_name;
       break;
 
    default:
diff --git a/src/gallium/state_trackers/clover/core/module.cpp b/src/gallium/state_trackers/clover/core/module.cpp
index 1b6b642..f16eaf6 100644
--- a/src/gallium/state_trackers/clover/core/module.cpp
+++ b/src/gallium/state_trackers/clover/core/module.cpp
@@ -170,11 +170,10 @@  namespace {
 
    /// (De)serialize a module::argument::info
    template<>
-   struct _serializer<module::argument::info> {
+   struct _serializer<struct module::argument::info> {
       template<typename S, typename QT>
       static void
       proc(S &s, QT &x) {
-         _proc(s, x.index);
          _proc(s, x.type_name);
          _proc(s, x.type_qualifier);
          _proc(s, x.arg_name);
@@ -193,7 +192,7 @@  namespace {
          _proc(s, x.target_align);
          _proc(s, x.ext_type);
          _proc(s, x.semantic);
-         _proc(s, x.arg_info);
+         _proc(s, x.info);
       }
    };
 
diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp
index 4425df9..cb62bb2 100644
--- a/src/gallium/state_trackers/clover/core/module.hpp
+++ b/src/gallium/state_trackers/clover/core/module.hpp
@@ -55,10 +55,12 @@  namespace clover {
 
       struct argument {
          struct info {
-            info() :
-            index(-1), type_name(""), type_qualifier(""), arg_name("") { }
+            info() { }
+            info(const std::string &type_name, const std::string &type_qual,
+                 const std::string &arg_name) :
+               type_name(type_name), type_qualifier(type_qual),
+               arg_name(arg_name) { }
 
-            size_t index;
             std::string type_name;
             std::string type_qualifier;
             std::string arg_name;
@@ -112,7 +114,7 @@  namespace clover {
          size_t target_align;
          ext_type ext_type;
          semantic semantic;
-         info arg_info;
+         info info;
       };
 
       struct symbol {
diff --git a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
index 03b9a88..b8a282f 100644
--- a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
+++ b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
@@ -69,7 +69,6 @@  namespace {
    std::vector<module::argument>
    make_kernel_args(const Module &mod, const std::string &kernel_name,
                     const clang::CompilerInstance &c) {
-      const bool get_args_infos = c.getCodeGenOpts().EmitOpenCLArgMetadata;
       std::vector<module::argument> args;
       const auto address_spaces = c.getTarget().getAddressSpaceMap();
       const Function &f = *mod.getFunction(kernel_name);
@@ -163,15 +162,11 @@  namespace {
             }
          }
 
-         if (get_args_infos) {
-            struct module::argument::info i;
-            i.index = arg.getArgNo();
-            i.type_name = get_argument_metadata(f, arg, "kernel_arg_type");
-            i.type_qualifier = get_argument_metadata(f, arg, "kernel_arg_type_qual");
-            i.arg_name = get_argument_metadata(f, arg, "kernel_arg_name");
-            args.back().arg_info = i;
-         }
-
+         if (c.getCodeGenOpts().EmitOpenCLArgMetadata)
+            args.back().info = typename module::argument::info(
+               get_argument_metadata(f, arg, "kernel_arg_type"),
+               get_argument_metadata(f, arg, "kernel_arg_type_qual"),
+               get_argument_metadata(f, arg, "kernel_arg_name"));
       }
 
       // Append implicit arguments.  XXX - The types, ordering and
-- 
2.10.2