Initial public release.
[OpenCLIPER] / include / OpenCLIPER / Process.hpp
1 /* Copyright (C) 2018 Federico Simmross Wattenberg,
2  *                    Manuel Rodríguez Cayetano,
3  *                    Javier Royuela del Val,
4  *                    Elena Martín González,
5  *                    Elisa Moya Sáez,
6  *                    Marcos Martín Fernández and
7  *                    Carlos Alberola López
8  *
9  * This file is part of OpenCLIPER.
10  *
11  * OpenCLIPER is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; version 3 of the License.
14  *
15  * OpenCLIPER is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with OpenCLIPER; If not, see <http://www.gnu.org/licenses/>.
22  *
23  *
24  *  Contact:
25  *
26  *  Federico Simmross Wattenberg
27  *  E.T.S.I. Telecomunicación
28  *  Universidad de Valladolid
29  *  Paseo de Belén 15
30  *  47011 Valladolid, Spain.
31  *  fedsim@tel.uva.es
32  */
33 // Avoiding compiler errors due to multiple include of header files
34 #ifndef __Process
35 #define __Process
36
37 #include <OpenCLIPER/OpenCLIPERDataModelCommonDefs.hpp>
38 #include <OpenCLIPER/Data.hpp>
39 #include <LPISupport/SampleCollection.hpp>
40 #include <LPISupport/InfoItems.hpp>
41
42 #include <iostream> // std::cout, std::fixed
43 #include <iomanip> // std::setprecision
44
45 // Needed for kernels to find includes outside "kernels" subdirectory
46 #define KERNELCOMPILEOPTS "-I../include/"
47
48 namespace OpenCLIPER {
49
50 class CLapp;
51 class Data;
52
53 /**
54  * @brief Class representing common data and behaviour for all the processes in charge of operations on data.
55  * 
56  */
57 class Process {
58 public:
59     Process(std::shared_ptr<CLapp> pCLapp);
60     /// Destructor
61     virtual ~Process();
62
63     /// Structure with initialization parameters (can be redefined in the subclass, if needed)
64     struct InitParameters {
65         /// @brief Destructor
66         virtual ~InitParameters() {}
67     };
68
69     /// Structure with launch parameters (can be redefined in the subclass, if needed)
70     struct LaunchParameters {
71         /// @brief Destructor
72         virtual ~LaunchParameters() {}
73     };
74
75     /// Structure with profiling parameters (can be redefined in the subclass, if needed)
76     struct ProfileParameters {
77         /// If profiling is enabled (true)
78         bool profilingEnabled = false;
79         /// Number of kernel execution repetitions
80         unsigned long numOfRepetitions = 1;
81         /**
82          * @brief Default constructor for struct fields initialization.
83          *
84          * @param profEnabled boolean true if profiling is enabled
85          * @param numReps number of repetitions of kernel execution
86          */
87         ProfileParameters(bool profEnabled = false, unsigned long numReps = 1): 
88             profilingEnabled(profEnabled), numOfRepetitions(numReps) {}
89     };
90
91     /** 
92      * @brief Returns a SampleCollection object containing values of host+device execution times
93      * @returns object of SampleCollection class
94      */
95     std::shared_ptr<LPISupport::SampleCollection> getSamplesGPU_CPUExecTime() {
96         return pSamplesGPU_CPUExecutionTime;
97     }
98
99     /** 
100      * @brief Returns a SampleCollection object containing values of device execution times
101      * @returns object of SampleCollection class
102      */
103     std::shared_ptr<LPISupport::SampleCollection> getSamplesGPUExecTime() {
104         return pSamplesGPUExecutionTime;
105     }
106
107     /** 
108      * @brief Returns pointer to init parameters
109      * @returns smart shared pointer to InitParameters object
110      */
111     virtual const shared_ptr<InitParameters> getInitParameters() const {
112         return pInitParameters;
113     }
114
115     /** 
116      * @brief Returns pointer to launch parameters
117      * @returns smart shared pointer to LaunchParameters object
118      */
119     virtual const shared_ptr<LaunchParameters> getLaunchParameters() const {
120         return pLaunchParameters;
121     }
122
123     void setApp(std::shared_ptr<CLapp> pCLapp);
124
125     void setInHandle(DataHandle pInputDataHandle);
126     void setOutHandle(DataHandle pOutputDataHandle);
127
128     /**
129      * @brief Sets initialization parameters for a Process object (this method can be redefined in a Process subclass).
130      * @param[in] p structure with initialization parameters for a Process object
131      */
132     virtual void setInitParameters(const shared_ptr<InitParameters>& p) {
133         pInitParameters=p;
134     }
135
136     /**
137      * @brief Sets launch parameters for a Process object (this method can be redefined in a Process subclass).
138      * @param[in] p structure with launch parameters of a Process object
139      */
140     virtual void setLaunchParameters(const shared_ptr<LaunchParameters>& p) {
141         pLaunchParameters=p;
142     }
143
144     /**
145      * @brief Method for Process object initialization (intialization is specific of Process subclasses).
146      */
147     virtual void init() {checkValidCLapp(this->pCLapp, "Process::init");}
148
149     /**
150      * @brief Method that sets OpenCL kernel parameters and executes it (method specific of Process object subclasses)
151      * @param[in] profileParameters parameters related to profiling of kernel execution
152      */
153     virtual void launch(ProfileParameters profileParameters = {false, 1}) = 0;
154
155     /**
156      * @brief Gets infoItems class variable value
157      * 
158      * @return the value of infoItems class variable
159      */
160     LPISupport::InfoItems getInfoItems() {
161       return infoItems;
162     }
163
164
165 protected:
166     // Visible for all subclasses
167
168     void checkValidCLapp(std::shared_ptr<OpenCLIPER::CLapp> pCLapp, string errorMsgPrefix);
169
170     /**
171      * @brief Get value of shared pointer to CLapp process assigned to this object
172      * @return shared pointer to CLapp object
173      */
174     const std::shared_ptr<CLapp> getApp() const {
175         return pCLapp;
176     }
177
178     /**
179      * @brief Returns a shared pointer to input data
180      * @return shared pointer to input data
181      */
182     std::shared_ptr<Data> getInput() {
183         return pInputData;
184     }
185
186     /**
187      * @brief Returns handle associated to input data
188      * @return handle to input data
189      */
190     DataHandle getInHandle() {
191         return inHandle;
192     }
193
194     /**
195      * @brief Returns a shared pointer to output data
196      * @return shared pointer to output data
197      */
198     std::shared_ptr<Data> getOutput() {
199         return pOutputData;
200     }
201
202     /**
203      * @brief Returns handle associated to output data
204      * @return handle to output data
205      */
206     DataHandle getOutHandle() {
207         return outHandle;
208     }
209     
210     void checkCommonLaunchParameters();
211     void checkXDataLaunchParameters(SyncSource syncSource = SYNCSOURCEDEFAULT);
212     void startProfiling(bool profilingEnabled);
213     void stopProfiling(bool profilingEnabled);
214     void startHostCodeProfiling(bool profilingEnabled);
215     void stopHostCodeProfiling(bool profilingEnabled);
216     void startKernelProfiling(bool profilingEnabled);
217     void stopKernelProfiling(bool profilingEnabled);
218     void buildKernelProfilingInfo(bool profilingEnabled);
219     void getKernelGroupExecutionTimes(std::vector<cl::Event> eventList, std::string itemTitle, std::string totalsTitle);
220     void addGlobalAndLocalWorkItemSizeInfo(cl::NDRange globalSizes, cl::NDRange localSizes, bool profilingEnabled);
221
222     /// Smart shared pointer to init parameters
223     std::shared_ptr<InitParameters> pInitParameters;
224     /// Smart shared pointer to launch parameters
225     std::shared_ptr<LaunchParameters> pLaunchParameters;
226     /// OpenCL Command queue
227     cl::CommandQueue queue;
228     /// Boolean that shows if selected device supports kernel profiling
229     bool profilingSupported = false;
230     /// Kernel
231     cl::Kernel kernel;
232     /// Name of the kernel function to be executed
233     std::string kernelName;
234     /// Storage for error strings
235     std::string errStr;
236     /// Vector with InfoItems data (list of pairs title, value storing profiling information).
237     LPISupport::InfoItems infoItems;
238     /// Vector with values of GPU execution times
239     std::shared_ptr<LPISupport::SampleCollection> pSamplesGPUExecutionTime;
240     /// Vector with values of GPU+CPU execution times
241     std::shared_ptr<LPISupport::SampleCollection> pSamplesGPU_CPUExecutionTime;
242     /// Vector with events for profiling kernel execuion times
243     std::vector<cl::Event> eventsVector;
244 private:
245     /// Smart shared pointer to Data object with input data
246     std::shared_ptr<Data> pInputData = nullptr;
247     /// Handle associated to input data
248     DataHandle inHandle = INVALIDDATAHANDLE;
249     /// Smart shared pointer to Data object with output data
250     std::shared_ptr<Data> pOutputData = nullptr;
251     /// Handle associated to output data
252     DataHandle outHandle = INVALIDDATAHANDLE;
253     /// Smart shared pointer to object with OpenCL context
254     std::shared_ptr<CLapp> pCLapp = nullptr;
255     /// Event for kernel execution start (used for profiling kernel execution times).
256     cl::Event start_ev;
257     /// Event for kernel execution stop (used for profiling kernel execution times).
258     cl::Event stop_ev;
259     /// clock at CPU starting execution of host Process code
260     std::chrono::high_resolution_clock::time_point beginCPUExecTime;
261     /// clock at CPU ending execution of host Process code
262     std::chrono::high_resolution_clock::time_point endCPUExecTime;
263 };
264 } /* namespace OpenCLIPER */
265 #endif