clover: Define helper classes for the new object model.
authorFrancisco Jerez <currojerez@riseup.net>
Sun, 6 Oct 2013 20:51:01 +0000 (13:51 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Mon, 21 Oct 2013 17:47:02 +0000 (10:47 -0700)
Tested-by: Tom Stellard <thomas.stellard@amd.com>
20 files changed:
src/gallium/state_trackers/clover/Makefile.sources
src/gallium/state_trackers/clover/api/util.hpp
src/gallium/state_trackers/clover/core/base.hpp [deleted file]
src/gallium/state_trackers/clover/core/compiler.hpp
src/gallium/state_trackers/clover/core/context.hpp
src/gallium/state_trackers/clover/core/device.hpp
src/gallium/state_trackers/clover/core/error.hpp [new file with mode: 0644]
src/gallium/state_trackers/clover/core/event.hpp
src/gallium/state_trackers/clover/core/format.hpp
src/gallium/state_trackers/clover/core/kernel.hpp
src/gallium/state_trackers/clover/core/memory.hpp
src/gallium/state_trackers/clover/core/object.hpp [new file with mode: 0644]
src/gallium/state_trackers/clover/core/platform.hpp
src/gallium/state_trackers/clover/core/program.cpp
src/gallium/state_trackers/clover/core/program.hpp
src/gallium/state_trackers/clover/core/queue.hpp
src/gallium/state_trackers/clover/core/resource.hpp
src/gallium/state_trackers/clover/core/sampler.hpp
src/gallium/state_trackers/clover/core/timestamp.hpp
src/gallium/state_trackers/clover/llvm/invocation.cpp

index 96e7a4168f9b418d1e7fc36789e49967a83482bb..b8231e2cbd9447d4226171548ecda8fba64c5fe8 100644 (file)
@@ -9,6 +9,8 @@ CPP_SOURCES := \
        util/pointer.hpp \
        util/range.hpp \
        util/tuple.hpp \
+       core/object.hpp \
+       core/error.hpp \
        core/compiler.hpp \
        core/geometry.hpp \
        core/device.hpp \
index e94b4b26a34e0013db576036f89b4cb78e02f9dc..c8f786e96a2157e3c84e51d6db52b986daf550e0 100644 (file)
 #ifndef CLOVER_API_UTIL_HPP
 #define CLOVER_API_UTIL_HPP
 
-#include <cstdint>
-#include <cstring>
-#include <algorithm>
-#include <map>
+#include <cassert>
 
-#include "core/base.hpp"
+#include "core/error.hpp"
 #include "core/property.hpp"
 #include "util/algorithm.hpp"
-#include "pipe/p_compiler.h"
 
 namespace clover {
    ///
diff --git a/src/gallium/state_trackers/clover/core/base.hpp b/src/gallium/state_trackers/clover/core/base.hpp
deleted file mode 100644 (file)
index ca42334..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-//
-// Copyright 2012 Francisco Jerez
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-// OTHER DEALINGS IN THE SOFTWARE.
-//
-
-#ifndef CLOVER_CORE_BASE_HPP
-#define CLOVER_CORE_BASE_HPP
-
-#include <stdexcept>
-#include <atomic>
-#include <cassert>
-#include <tuple>
-#include <vector>
-#include <functional>
-
-#include "CL/cl.h"
-#include "util/pointer.hpp"
-
-///
-/// Main namespace of the CL state tracker.
-///
-namespace clover {
-   ///
-   /// Class that represents an error that can be converted to an
-   /// OpenCL status code.
-   ///
-   class error : public std::runtime_error {
-   public:
-      error(cl_int code, std::string what = "") :
-         std::runtime_error(what), code(code) {
-      }
-
-      cl_int get() const {
-         return code;
-      }
-
-   protected:
-      cl_int code;
-   };
-}
-
-#endif
index 5edb056ec5985f0794e1c28e7c7a64e5457b9264..49cd0226f67934da349f84ad976f754714772d7f 100644 (file)
 #define CLOVER_CORE_COMPILER_HPP
 
 #include "util/compat.hpp"
+#include "core/error.hpp"
 #include "core/module.hpp"
 #include "pipe/p_defines.h"
 
 namespace clover {
-   class build_error {
-   public:
-      build_error(const compat::string &log) : log(log) {
-      }
-
-      virtual ~build_error() {
-      }
-
-      compat::string what() {
-         return log;
-      }
-
-   private:
-      compat::vector<char> log;
-   };
-
-   class invalid_option_error {
-   public:
-      invalid_option_error() {
-      }
-
-      virtual ~invalid_option_error() {
-      }
-   };
-
    module compile_program_llvm(const compat::string &source,
-                               enum pipe_shader_ir ir,
+                               pipe_shader_ir ir,
                                const compat::string &target,
                                const compat::string &opts);
 
index 62ad6ea0dab8ef5ba75436ee5a17aa132d662dee..a4902dd7b901a40ad9026ba50ece90686659ef0b 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef CLOVER_CORE_CONTEXT_HPP
 #define CLOVER_CORE_CONTEXT_HPP
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/device.hpp"
 
 namespace clover {
index a310001c7473bb2869364290c5801013d4ed246e..1dd47487ca55f0f10b2ff4667774966710ad8b48 100644 (file)
@@ -26,7 +26,7 @@
 #include <set>
 #include <vector>
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/format.hpp"
 #include "pipe-loader/pipe_loader.h"
 
diff --git a/src/gallium/state_trackers/clover/core/error.hpp b/src/gallium/state_trackers/clover/core/error.hpp
new file mode 100644 (file)
index 0000000..2b0b6c5
--- /dev/null
@@ -0,0 +1,196 @@
+//
+// Copyright 2013 Francisco Jerez
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#ifndef CLOVER_CORE_ERROR_HPP
+#define CLOVER_CORE_ERROR_HPP
+
+#include "CL/cl.h"
+
+#include "util/compat.hpp"
+
+namespace clover {
+   typedef struct _cl_command_queue command_queue;
+   typedef struct _cl_context context;
+   typedef struct _cl_device_id device;
+   typedef struct _cl_event event;
+   class hard_event;
+   class soft_event;
+   typedef struct _cl_kernel kernel;
+   typedef struct _cl_mem memory_obj;
+   class buffer;
+   class root_buffer;
+   class sub_buffer;
+   class image;
+   class image2d;
+   class image3d;
+   typedef struct _cl_platform_id platform;
+   typedef struct _cl_program program;
+   typedef struct _cl_sampler sampler;
+
+   ///
+   /// Class that represents an error that can be converted to an
+   /// OpenCL status code.
+   ///
+   class error : public compat::runtime_error {
+   public:
+      error(cl_int code, compat::string what = "") :
+         compat::runtime_error(what), code(code) {
+      }
+
+      cl_int get() const {
+         return code;
+      }
+
+   protected:
+      cl_int code;
+   };
+
+   class build_error : public error {
+   public:
+      build_error(const compat::string &log) :
+         error(CL_BUILD_PROGRAM_FAILURE, log) {
+      }
+   };
+
+   template<typename O>
+   class invalid_object_error;
+
+   template<>
+   class invalid_object_error<command_queue> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_COMMAND_QUEUE, what) {}
+   };
+
+   template<>
+   class invalid_object_error<context> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_CONTEXT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<device> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_DEVICE, what) {}
+   };
+
+   template<>
+   class invalid_object_error<event> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_EVENT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<soft_event> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_EVENT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<kernel> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_KERNEL, what) {}
+   };
+
+   template<>
+   class invalid_object_error<memory_obj> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_MEM_OBJECT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<buffer> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_MEM_OBJECT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<root_buffer> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_MEM_OBJECT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<sub_buffer> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_MEM_OBJECT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<image> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_MEM_OBJECT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<image2d> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_MEM_OBJECT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<image3d> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_MEM_OBJECT, what) {}
+   };
+
+   template<>
+   class invalid_object_error<platform> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_PLATFORM, what) {}
+   };
+
+   template<>
+   class invalid_object_error<program> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_PROGRAM, what) {}
+   };
+
+   template<>
+   class invalid_object_error<sampler> : public error {
+   public:
+      invalid_object_error(std::string what = "") :
+         error(CL_INVALID_SAMPLER, what) {}
+   };
+
+   class invalid_wait_list_error : public error {
+   public:
+      invalid_wait_list_error(std::string what = "") :
+         error(CL_INVALID_EVENT_WAIT_LIST, what) {}
+   };
+}
+
+#endif
index b74db32293cd4945653c0c468aad31c7e4ab2daa..d1f1dd4a5aee74380a4e1cae0fb2f5691c3b262c 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <functional>
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/queue.hpp"
 #include "core/timestamp.hpp"
 #include "util/lazy.hpp"
index 804a84ddda72509e140b608932039c8b45dc153e..dd4e7a544f772be111755c110b54071164087e76 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <set>
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "pipe/p_defines.h"
 #include "pipe/p_format.h"
 
index 44f7b4887e172896617ed14b3475e1b5daa45bb3..984e2139c7ba24cca9e324875d345d2d155fecc7 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <memory>
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/program.hpp"
 #include "core/memory.hpp"
 #include "core/sampler.hpp"
index a72ad8b0662985f9919c255655585afab42c5b4b..f495c45ed33b5316855a5900485c0f3cdd38890f 100644 (file)
@@ -27,7 +27,7 @@
 #include <map>
 #include <memory>
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/queue.hpp"
 
 namespace clover {
diff --git a/src/gallium/state_trackers/clover/core/object.hpp b/src/gallium/state_trackers/clover/core/object.hpp
new file mode 100644 (file)
index 0000000..807e2f9
--- /dev/null
@@ -0,0 +1,182 @@
+//
+// Copyright 2013 Francisco Jerez
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#ifndef CLOVER_CORE_OBJECT_HPP
+#define CLOVER_CORE_OBJECT_HPP
+
+#include <cassert>
+#include <functional>
+#include <vector>
+
+#include "CL/cl.h"
+
+#include "core/error.hpp"
+#include "core/property.hpp"
+
+///
+/// Main namespace of the CL state tracker.
+///
+namespace clover {
+   ///
+   /// Class that represents a CL API object.
+   ///
+   template<typename T, typename S>
+   struct descriptor {
+      typedef T object_type;
+      typedef S descriptor_type;
+   };
+
+   struct default_tag;
+   struct wait_list_tag;
+   struct property_list_tag;
+
+   namespace detail {
+      template<typename T, typename D>
+      struct descriptor_traits {
+         typedef T object_type;
+
+         static void
+         validate(D *d) {
+            auto o = static_cast<typename D::object_type *>(d);
+            if (!o || !dynamic_cast<object_type *>(o))
+               throw invalid_object_error<T>();
+         }
+
+         static void
+         validate_list(D * const *ds, size_t n) {
+            if (!ds || !n)
+               throw error(CL_INVALID_VALUE);
+         }
+      };
+
+      template<typename D>
+      struct descriptor_traits<default_tag, D> {
+         typedef typename D::object_type object_type;
+
+         static void
+         validate(D *d) {
+            if (!d)
+               throw invalid_object_error<object_type>();
+         }
+
+         static void
+         validate_list(D *const *ds, size_t n) {
+            if (!ds || !n)
+               throw error(CL_INVALID_VALUE);
+         }
+      };
+
+      template<typename D>
+      struct descriptor_traits<wait_list_tag, D> {
+         typedef typename D::object_type object_type;
+
+         static void
+         validate(D *d) {
+            if (!d)
+               throw invalid_wait_list_error();
+         }
+
+         static void
+         validate_list(D *const *ds, size_t n) {
+            if (bool(ds) != bool(n))
+               throw invalid_wait_list_error();
+         }
+      };
+   }
+
+   ///
+   /// Get a Clover object from an API object.
+   ///
+   /// \a T can either be the Clover object type to return or a \a tag
+   /// object to select some special validation behavior by means of a
+   /// specialization of the detail::descriptor_traits template.  The
+   /// default behavior is to infer the most general Clover object
+   /// type for the given API object.
+   ///
+   template<typename T = default_tag, typename D>
+   typename detail::descriptor_traits<T, D>::object_type &
+   obj(D *d) {
+      detail::descriptor_traits<T, D>::validate(d);
+
+      return static_cast<
+         typename detail::descriptor_traits<T, D>::object_type &>(*d);
+   }
+
+   ///
+   /// Get a pointer to a Clover object from an API object. Returns
+   /// \c NULL if its argument is \c NULL.
+   ///
+   /// \sa obj
+   ///
+   template<typename T = default_tag, typename D>
+   typename detail::descriptor_traits<T, D>::object_type *
+   pobj(D *d) {
+      if (d)
+         detail::descriptor_traits<T, D>::validate(d);
+
+      return static_cast<
+         typename detail::descriptor_traits<T, D>::object_type *>(d);
+   }
+
+   ///
+   /// Get an API object from a Clover object.
+   ///
+   template<typename O>
+   typename O::descriptor_type *
+   desc(O &o) {
+      return static_cast<typename O::descriptor_type *>(&o);
+   }
+
+   ///
+   /// Get an API object from a pointer to a Clover object.
+   ///
+   template<typename O>
+   typename O::descriptor_type *
+   desc(O *o) {
+      return static_cast<typename O::descriptor_type *>(o);
+   }
+
+   ///
+   /// Get a range of Clover objects from a range of API objects.
+   ///
+   /// \sa obj
+   ///
+   template<typename T = default_tag, typename D>
+   ref_vector<typename detail::descriptor_traits<T, D>::object_type>
+   objs(D *const *ds, size_t n) {
+      detail::descriptor_traits<T, D>::validate_list(ds, n);
+      return map(obj<T, D>, range(ds, n));
+   }
+
+   ///
+   /// Get a range of API objects from a range of Clover objects.
+   ///
+   template<typename Os>
+   std::vector<typename Os::value_type::descriptor_type *>
+   descs(const Os &os) {
+      return map([](typename Os::value_type &o) {
+            return desc(o);
+         }, os);
+   }
+}
+
+#endif
index d0e521ad914ce83d80f1df40789d67e00c7b5224..af588cc57019ec771ce295403fbd2e98e6cc4fcd 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <vector>
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/device.hpp"
 
 namespace clover {
index 8cf1337f7ac4aefcf8b073a92838edf02f5610fe..42b301497b5fcb3581c5481d56ffe11cb7f0d73b 100644 (file)
@@ -60,9 +60,7 @@ _cl_program::build(const std::vector<clover::device *> &devs,
 
       } catch (build_error &e) {
          _logs.insert({ dev, e.what() });
-         throw error(CL_BUILD_PROGRAM_FAILURE);
-      } catch (invalid_option_error &e) {
-         throw error(CL_INVALID_BUILD_OPTIONS);
+         throw;
       }
    }
 }
index ddebe2068d77cfe0f5121d114b369fa349f5b4ed..0d7bf372f6dfc88ea3ceb43acaf579ff8485aad6 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <map>
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/context.hpp"
 #include "core/module.hpp"
 
index fb6f656cb47311ed13d6a8d9ba3d8ecb49a4268d..a02de95cf8f079b644df6f712ada657498124f66 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef CLOVER_CORE_QUEUE_HPP
 #define CLOVER_CORE_QUEUE_HPP
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/context.hpp"
 #include "core/timestamp.hpp"
 #include "pipe/p_context.h"
index 90a68d099acb1cba409678a3dac34ffca7a06c66..b2eddc08fa6619113afdeae06943db081846abcc 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <list>
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/memory.hpp"
 #include "util/algebra.hpp"
 #include "pipe/p_state.h"
index 26fcadb9e637f21f841859c7e670317610858bcc..9716aabd22b3b3fb574a4e1b12a51cb1cf4e1e6a 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef CLOVER_CORE_SAMPLER_HPP
 #define CLOVER_CORE_SAMPLER_HPP
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 #include "core/queue.hpp"
 
 namespace clover {
index 7fbc6e4c27ce20c0671ae4346d928651c035ba96..bf9e204108b8c7d1aeeb0d65c17fffbabe8b3b7b 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef CLOVER_CORE_TIMESTAMP_HPP
 #define CLOVER_CORE_TIMESTAMP_HPP
 
-#include "core/base.hpp"
+#include "core/object.hpp"
 
 struct pipe_query;
 
index f14222b44e4d524fb8a640283aac55a32e841680..4ae496ffb2118449add8a0e3d25bd3a5f5ad6ae7 100644 (file)
@@ -157,7 +157,7 @@ namespace {
                                         opts_carray.data() + opts_carray.size(),
                                         Diags);
       if (!Success) {
-         throw invalid_option_error();
+         throw error(CL_INVALID_BUILD_OPTIONS);
       }
       c.getFrontendOpts().ProgramAction = clang::frontend::EmitLLVMOnly;
       c.getHeaderSearchOpts().UseBuiltinIncludes = true;