1 /*******************************************************************************
2 * Copyright 2019-2021 Intel Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16 
17 #ifndef GPU_OCL_OCL_GPU_KERNEL_HPP
18 #define GPU_OCL_OCL_GPU_KERNEL_HPP
19 
20 #include <assert.h>
21 #include <atomic>
22 #include <string>
23 #include <CL/cl.h>
24 
25 #include "gpu/compute/compute.hpp"
26 #include "gpu/ocl/ocl_utils.hpp"
27 
28 namespace dnnl {
29 namespace impl {
30 namespace gpu {
31 namespace ocl {
32 
33 class ocl_gpu_kernel_t : public compute::kernel_impl_t {
34 public:
ocl_gpu_kernel_t(const std::shared_ptr<compute::binary_t> & binary,const std::string & kernel_name,const std::vector<gpu::compute::scalar_type_t> & arg_types)35     ocl_gpu_kernel_t(const std::shared_ptr<compute::binary_t> &binary,
36             const std::string &kernel_name,
37             const std::vector<gpu::compute::scalar_type_t> &arg_types)
38         : state_(state_t::binary)
39         , ocl_kernel_(nullptr)
40         , binary_(binary)
41         , kernel_name_(kernel_name)
42         , arg_types_(arg_types) {
43         MAYBE_UNUSED(state_);
44     }
45 
46     ~ocl_gpu_kernel_t() override;
47 
ocl_kernel() const48     cl_kernel ocl_kernel() const {
49         assert(state_ == state_t::kernel);
50         return ocl_kernel_;
51     }
52 
53     status_t parallel_for(stream_t &stream, const compute::nd_range_t &range,
54             const compute::kernel_arg_list_t &arg_list) override;
55 
56     status_t realize(compute::kernel_t *kernel, const engine_t *engine,
57             compute::program_list_t *programs) const override;
58 
name() const59     const char *name() const {
60         assert(state_ == state_t::binary);
61         return kernel_name_.c_str();
62     }
63 
binary() const64     const std::shared_ptr<compute::binary_t> &binary() const {
65         assert(state_ == state_t::binary);
66         return binary_;
67     }
68 
arg_types() const69     const std::vector<gpu::compute::scalar_type_t> &arg_types() const {
70         return arg_types_;
71     }
72 
clear()73     void clear() override {
74         assert(state_ == state_t::binary);
75         binary_->clear();
76         kernel_name_.clear();
77         arg_types_.clear();
78     }
79     enum class state_t { binary, kernel };
80 
81 protected:
ocl_gpu_kernel_t(cl_kernel ocl_kernel,const std::vector<gpu::compute::scalar_type_t> & arg_types)82     ocl_gpu_kernel_t(cl_kernel ocl_kernel,
83             const std::vector<gpu::compute::scalar_type_t> &arg_types)
84         : state_(state_t::kernel)
85         , ocl_kernel_(ocl_kernel)
86         , arg_types_(arg_types) {
87         OCL_CHECK_V(clRetainKernel(ocl_kernel_));
88     }
89 
90     state_t state_;
91     cl_kernel ocl_kernel_;
92     std::shared_ptr<compute::binary_t> binary_;
93     std::string kernel_name_;
94 
95     std::vector<gpu::compute::scalar_type_t> arg_types_;
96 
97     // Used to protect cl_kernel before enqueueing to set arguments.
98     std::atomic<bool> is_locked_ {false};
99 };
100 
101 } // namespace ocl
102 } // namespace gpu
103 } // namespace impl
104 } // namespace dnnl
105 
106 #endif // GPU_OCL_OCL_GPU_KERNEL_HPP
107