1 /*
2  * Copyright (c) 2019,2020 NVIDIA CORPORATION.
3  *
4  * Copyright 2018-2019 BlazingDB, Inc.
5  *     Copyright 2018 Christian Noboa Mardini <christian@blazingdb.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef GB_JIT_LAUNCHER_H
21 #define GB_JIT_LAUNCHER_H
22 
23 #include <GB_jit_cache.h>
24 #include <unordered_map>
25 #include <memory>
26 #include <string>
27 #include <fstream>
28 
29 #define JITIFY_PRINT_INSTANTIATION 0
30 #define JITIFY_PRINT_SOURCE 1
31 #define JITIFY_PRINT_LOG 1
32 #define JITIFY_PRINT_PTX 1
33 #define JITIFY_PRINT_LINKER_LOG 0
34 #define JITIFY_PRINT_LAUNCH 1
35 #include <jitify.hpp>
36 
37 const std::vector<std::string> compiler_flags{
38    "-std=c++14",
39    "--use_fast_math",
40    "-remove-unused-globals",
41    "-w",
42    "-D__CUDACC_RTC__",
43    "-I.",
44    "-I..",
45    "-I../../Include",
46    "-I../../Source",
47    "-I../../Source/Template",
48    "-Ilocal_cub/block",
49    "-Itemplates",
50    "-I/usr/local/cuda/include"
51 };
52 
53 namespace jit {
54 
55 /**
56  * @brief Class used to handle compilation and execution of JIT kernels
57  *
58  */
59 class launcher {
60  public:
61   launcher() = delete;
62 
63   /**
64    * @brief C'tor of the launcher class
65    *
66    * Method to generate vector containing all template types for a JIT kernel.
67    *  This vector is used to get the compiled kernel for one set of types and set
68    *  it as the kernel to launch using this launcher.
69    *
70    * @param hash The hash to be used as the key for caching
71    * @param cuda_code The CUDA code that contains the kernel to be launched
72    * @param header_names Strings of header_names or strings that contain content
73    * of the header files
74    * @param compiler_flags Strings of compiler flags
75    * @param file_callback a function that returns header file contents given header
76    * file names.
77    * @param stream The non-owned stream to use for execution
78    */
79   launcher(
80     const std::string& hash,
81     const std::string& cuda_source,
82     const std::vector<std::string>& header_names,
83     const std::vector<std::string>& compiler_flags,
84     jitify::experimental::file_callback_type file_callback,
85     cudaStream_t stream = 0
86   );
87   launcher(launcher&&);
88   launcher(const launcher&) = delete;
89   launcher& operator=(launcher&&) = delete;
90   launcher& operator=(const launcher&) = delete;
91 
92   /**
93    * @brief Sets the kernel to launch using this launcher
94    *
95    * Method to generate vector containing all template types for a JIT kernel.
96    *  This vector is used to get the compiled kernel for one set of types and set
97    *  it as the kernel to launch using this launcher.
98    *
99    * @param kernel_name The kernel to be launched
100    * @param arguments   The template arguments to be used to instantiate the kernel
101    * @return launcher& ref to this launcehr object
102    */
set_kernel_inst(const std::string & kernel_name,const std::vector<std::string> & arguments)103   launcher& set_kernel_inst(
104     const std::string& kernel_name,
105     const std::vector<std::string>& arguments
106   )
107   { // program is a member variable of the launcher
108     kernel_inst = cache_instance.getKernelInstantiation(kernel_name, program, arguments);
109     return *this;
110   }
111 
112   /**
113    * @brief Handle the Jitify API to launch using information
114    *  contained in the members of `this`
115    *
116    * @tparam grid and block sizes
117    * @return Return launcher reference if successful
118    */
configure(dim3 grid,dim3 block)119   jitify::experimental::KernelLauncher configure( dim3 grid, dim3 block){
120     return get_kernel().configure( grid, block);
121     //return get_kernel().configure_1d_max_occupancy( max_block_size=block.x);
122   }
123 
124 
125   /**
126    * @brief Handle the Jitify API to launch using information
127    *  contained in the members of `this`
128    *
129    * @tparam All parameters to launch the kernel
130    * @return Return GDF_SUCCESS if successful
131    */
132   template <typename ... Args>
launch(Args...args)133   void launch(Args ... args){
134     get_kernel().configure_1d_max_occupancy(32, 0, 0, stream).launch(args...);
135   }
136 
137  private:
138   jit::GBJitCache& cache_instance;
139   jit::named_prog<jitify::experimental::Program> program;
140   jit::named_prog<jitify::experimental::KernelInstantiation> kernel_inst;
141   cudaStream_t stream;
142 
get_kernel()143   jitify::experimental::KernelInstantiation& get_kernel() { return *std::get<1>(kernel_inst); }
144 };
145 
146 } // namespace jit
147 
148 #endif
149