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_argument : public argument { 194 public: get() const195 const image *get() const { 196 return img; 197 } 198 protected: 199 image *img; 200 }; 201 202 class image_rd_argument : public image_argument { 203 public: 204 virtual void set(size_t size, const void *value); 205 virtual void bind(exec_context &ctx, 206 const module::argument &marg); 207 virtual void unbind(exec_context &ctx); 208 209 private: 210 pipe_sampler_view *st; 211 }; 212 213 class image_wr_argument : public image_argument { 214 public: 215 virtual void set(size_t size, const void *value); 216 virtual void bind(exec_context &ctx, 217 const module::argument &marg); 218 virtual void unbind(exec_context &ctx); 219 220 private: 221 pipe_surface *st; 222 }; 223 224 class sampler_argument : public argument { 225 public: 226 virtual void set(size_t size, const void *value); 227 virtual void bind(exec_context &ctx, 228 const module::argument &marg); 229 virtual void unbind(exec_context &ctx); 230 231 private: 232 sampler *s; 233 void *st; 234 }; 235 236 std::vector<std::unique_ptr<argument>> _args; 237 std::string _name; 238 exec_context exec; 239 const ref_holder program_ref; 240 }; 241 } 242 243 #endif 244