Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. //
  2. // Copyright 2012 Francisco Jerez
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a
  5. // copy of this software and associated documentation files (the "Software"),
  6. // to deal in the Software without restriction, including without limitation
  7. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. // and/or sell copies of the Software, and to permit persons to whom the
  9. // Software is furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17. // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. // OTHER DEALINGS IN THE SOFTWARE.
  21. //
  22.  
  23. #ifndef CLOVER_CORE_KERNEL_HPP
  24. #define CLOVER_CORE_KERNEL_HPP
  25.  
  26. #include <memory>
  27.  
  28. #include "core/object.hpp"
  29. #include "core/program.hpp"
  30. #include "core/memory.hpp"
  31. #include "core/sampler.hpp"
  32. #include "pipe/p_state.h"
  33.  
  34. namespace clover {
  35.    class kernel : public ref_counter, public _cl_kernel {
  36.    private:
  37.       ///
  38.       /// Class containing all the state required to execute a compute
  39.       /// kernel.
  40.       ///
  41.       struct exec_context {
  42.          exec_context(kernel &kern);
  43.          ~exec_context();
  44.  
  45.          exec_context(const exec_context &) = delete;
  46.          exec_context &
  47.          operator=(const exec_context &) = delete;
  48.  
  49.          void *bind(intrusive_ptr<command_queue> _q,
  50.                     const std::vector<size_t> &grid_offset);
  51.          void unbind();
  52.  
  53.          kernel &kern;
  54.          intrusive_ptr<command_queue> q;
  55.  
  56.          std::vector<uint8_t> input;
  57.          std::vector<void *> samplers;
  58.          std::vector<pipe_sampler_view *> sviews;
  59.          std::vector<pipe_surface *> resources;
  60.          std::vector<pipe_resource *> g_buffers;
  61.          std::vector<size_t> g_handles;
  62.          size_t mem_local;
  63.  
  64.       private:
  65.          void *st;
  66.          pipe_compute_state cs;
  67.       };
  68.  
  69.    public:
  70.       class argument {
  71.       public:
  72.          static std::unique_ptr<argument>
  73.          create(const module::argument &marg);
  74.  
  75.          argument(const argument &arg) = delete;
  76.          argument &
  77.          operator=(const argument &arg) = delete;
  78.  
  79.          /// \a true if the argument has been set.
  80.          bool set() const;
  81.  
  82.          /// Storage space required for the referenced object.
  83.          virtual size_t storage() const;
  84.  
  85.          /// Set this argument to some object.
  86.          virtual void set(size_t size, const void *value) = 0;
  87.  
  88.          /// Allocate the necessary resources to bind the specified
  89.          /// object to this argument, and update \a ctx accordingly.
  90.          virtual void bind(exec_context &ctx,
  91.                            const module::argument &marg) = 0;
  92.  
  93.          /// Free any resources that were allocated in bind().
  94.          virtual void unbind(exec_context &ctx) = 0;
  95.  
  96.       protected:
  97.          argument();
  98.  
  99.          bool _set;
  100.       };
  101.  
  102.    private:
  103.       typedef adaptor_range<
  104.             derefs, std::vector<std::unique_ptr<argument>> &
  105.          > argument_range;
  106.  
  107.       typedef adaptor_range<
  108.             derefs, const std::vector<std::unique_ptr<argument>> &
  109.          > const_argument_range;
  110.  
  111.    public:
  112.       kernel(clover::program &prog, const std::string &name,
  113.              const std::vector<clover::module::argument> &margs);
  114.  
  115.       kernel(const kernel &kern) = delete;
  116.       kernel &
  117.       operator=(const kernel &kern) = delete;
  118.  
  119.       void launch(command_queue &q,
  120.                   const std::vector<size_t> &grid_offset,
  121.                   const std::vector<size_t> &grid_size,
  122.                   const std::vector<size_t> &block_size);
  123.  
  124.       size_t mem_local() const;
  125.       size_t mem_private() const;
  126.  
  127.       const std::string &name() const;
  128.  
  129.       std::vector<size_t>
  130.       optimal_block_size(const command_queue &q,
  131.                          const std::vector<size_t> &grid_size) const;
  132.       std::vector<size_t>
  133.       required_block_size() const;
  134.  
  135.       argument_range args();
  136.       const_argument_range args() const;
  137.  
  138.       const intrusive_ref<clover::program> program;
  139.  
  140.    private:
  141.       const clover::module &module(const command_queue &q) const;
  142.  
  143.       class scalar_argument : public argument {
  144.       public:
  145.          scalar_argument(size_t size);
  146.  
  147.          virtual void set(size_t size, const void *value);
  148.          virtual void bind(exec_context &ctx,
  149.                            const module::argument &marg);
  150.          virtual void unbind(exec_context &ctx);
  151.  
  152.       private:
  153.          size_t size;
  154.          std::vector<uint8_t> v;
  155.       };
  156.  
  157.       class global_argument : public argument {
  158.       public:
  159.          virtual void set(size_t size, const void *value);
  160.          virtual void bind(exec_context &ctx,
  161.                            const module::argument &marg);
  162.          virtual void unbind(exec_context &ctx);
  163.  
  164.       private:
  165.          buffer *buf;
  166.       };
  167.  
  168.       class local_argument : public argument {
  169.       public:
  170.          virtual size_t storage() const;
  171.  
  172.          virtual void set(size_t size, const void *value);
  173.          virtual void bind(exec_context &ctx,
  174.                            const module::argument &marg);
  175.          virtual void unbind(exec_context &ctx);
  176.  
  177.       private:
  178.          size_t _storage = 0;
  179.       };
  180.  
  181.       class constant_argument : public argument {
  182.       public:
  183.          virtual void set(size_t size, const void *value);
  184.          virtual void bind(exec_context &ctx,
  185.                            const module::argument &marg);
  186.          virtual void unbind(exec_context &ctx);
  187.  
  188.       private:
  189.          buffer *buf;
  190.          pipe_surface *st;
  191.       };
  192.  
  193.       class image_rd_argument : public argument {
  194.       public:
  195.          virtual void set(size_t size, const void *value);
  196.          virtual void bind(exec_context &ctx,
  197.                            const module::argument &marg);
  198.          virtual void unbind(exec_context &ctx);
  199.  
  200.       private:
  201.          image *img;
  202.          pipe_sampler_view *st;
  203.       };
  204.  
  205.       class image_wr_argument : public argument {
  206.       public:
  207.          virtual void set(size_t size, const void *value);
  208.          virtual void bind(exec_context &ctx,
  209.                            const module::argument &marg);
  210.          virtual void unbind(exec_context &ctx);
  211.  
  212.       private:
  213.          image *img;
  214.          pipe_surface *st;
  215.       };
  216.  
  217.       class sampler_argument : public argument {
  218.       public:
  219.          virtual void set(size_t size, const void *value);
  220.          virtual void bind(exec_context &ctx,
  221.                            const module::argument &marg);
  222.          virtual void unbind(exec_context &ctx);
  223.  
  224.       private:
  225.          sampler *s;
  226.          void *st;
  227.       };
  228.  
  229.       std::vector<std::unique_ptr<argument>> _args;
  230.       std::string _name;
  231.       exec_context exec;
  232.       const ref_holder program_ref;
  233.    };
  234. }
  235.  
  236. #endif
  237.