Initial public release.
[OpenCLIPER] / examples / MRIReconSOS.cpp
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
34 #include <LPISupport/InfoItems.hpp>
35 #include <cstdio>
36 #include <cstdlib>
37 #include <fstream>
38 #include <iostream>
39 #include <string>
40 #include <iterator>
41 #include <vector>
42 #include <array>
43 #include <chrono> // Para medir tiempos de ejecución
44 using namespace std;
45 using namespace std::chrono;
46 #include <iomanip> // Para std::setprecision
47 #include <OpenCLIPER/OpenCLIPERDataModel.hpp>
48 #include <../performanceTests/PerformanceTestArrayOpParallel.hpp>
49 #include <utility>
50
51 using namespace OpenCLIPER;
52
53 int main (int argc, char* argv[]) {
54
55     unsigned long numberOfIterations = 10;
56     std::shared_ptr<LPISupport::SampleCollection> pSamples = std::make_shared<LPISupport::SampleCollection>("execution time");
57     
58     // Step 0: get a new OpenCLIPER app
59     std::shared_ptr<CLapp> pCLapp = std::make_shared<CLapp>();
60
61     try {
62         PerformanceTestArrayOpParallel* pPerfTest = new PerformanceTestArrayOpParallel(argc, argv);
63         auto pConfigTraits = std::dynamic_pointer_cast<PerformanceTestArrayOpParallel::ConfigTraits>(pPerfTest->getConfigTraits());
64         numberOfIterations = pConfigTraits->repetitions;
65
66
67         // Step 1: initialize computing device
68         CLapp::PlatformTraits platformTraits;
69         CLapp::DeviceTraits deviceTraits;
70 #ifdef USE_GPU
71         deviceTraits.type=CLapp::DEVICE_TYPE_GPU;
72         if (!(pConfigTraits->deviceName.empty())) {
73             deviceTraits.name = pConfigTraits->deviceName;
74         }
75 #else
76         deviceTraits.type=CLapp::DEVICE_TYPE_CPU;
77 #endif
78         deviceTraits.queueProperties = cl::QueueProperties(CL_QUEUE_PROFILING_ENABLE);
79         pCLapp->init(platformTraits,deviceTraits);
80
81         // Step 2: load OpenCL kernel(s)
82         pCLapp->loadKernels("rss.cl");
83
84         const unsigned int SHOW_SIZE = 10;
85         const unsigned int PRECISION_DIGITS = 10;
86
87         cerr << argv[0] << " performance measurement" << std::endl;
88         cout << "Starting program... " << flush;
89
90         // Step 3: load input data from Matlab file
91         vector<string> matlabVars = {"KData", "SensitivityMaps"};
92         std::shared_ptr<Data> pInputKData(new KData("MRIdataSOS.mat", matlabVars));
93
94         // Step 4: create output with suitable size
95         std::shared_ptr<Data> pOutputXData(new XData(dynamic_pointer_cast<KData>(pInputKData)));
96        
97
98         // Set 5: register input and output in our CL app
99         DataHandle inHandle = pCLapp->addData(pInputKData);
100         DataHandle outHandle = pCLapp->addData(pOutputXData);
101
102         cout << "Done." << endl;
103
104         // Step 6: create new process bound to our CL app
105         // and set its input/output data sets
106         std::unique_ptr<Process> pProcess(new SimpleMRIReconSOS(pCLapp));
107         pProcess->setInHandle(inHandle);
108         pProcess->setOutHandle(outHandle);
109
110         // Step 7: initialize process
111         pProcess->init();
112
113         cerr << "Executing " << numberOfIterations << " iteration(s)\n";
114         LPISupport::InfoItems infoItems;
115         cerr << pCLapp->getHWSWInfo().to_string(pConfigTraits->outputFormat);
116         TIME_DIFF_TYPE diffT2T1 = 0;
117         std::stringstream strstr;
118         strstr << setprecision(PRECISION_DIGITS);
119         cout << "Starting product... " << endl;
120         for (unsigned long iteration = 0; iteration < numberOfIterations; iteration++) {
121             cout << "Iteration #" << iteration << std::endl;
122             BEGIN_TIME(t1);
123             // Step 7.2 launch process
124             Process::ProfileParameters profileParameters;
125             // Enable gpu profiling
126             profileParameters.profilingEnabled = true;
127             profileParameters.numOfRepetitions = 1;
128
129             pProcess->launch(profileParameters); // Enable gpu profiling
130             pCLapp->getCommandQueue().finish();
131
132             END_TIME(t2);
133             TIME_DIFF(diffT2T1, t1, t2);
134             pSamples->appendSample(diffT2T1);
135         }
136         
137         
138         // Step 8: get data back from computing device
139         pCLapp->device2Host(outHandle, SyncSource::BUFFER_ONLY);
140         
141         // Step 9: store output data into matlab file
142         auto outputData=dynamic_pointer_cast<XData>(pCLapp->getData(outHandle));
143         outputData->matlabSave("outputFramesSOS.mat", "XData", SyncSource::BUFFER_ONLY);
144
145
146         LPISupport::InfoItems infoItemsProfilingGPU;
147         infoItemsProfilingGPU.append(pProcess->getSamplesGPUExecTime()->to_infoItems(PRECISION_DIGITS));
148
149         cerr << infoItemsProfilingGPU.to_string(LPISupport::InfoItems::OutputFormat::HUMAN);
150
151         LPISupport::InfoItems infoItemsProfilingGPUAndCPU;
152         infoItemsProfilingGPUAndCPU.append(pProcess->getSamplesGPU_CPUExecTime()->to_infoItems(PRECISION_DIGITS));
153         cerr << infoItemsProfilingGPUAndCPU.to_string(LPISupport::InfoItems::OutputFormat::HUMAN);
154
155         pConfigTraits->deviceType = pCLapp->getDeviceTypeAsString();
156         pConfigTraits->deviceName = pCLapp->getDeviceVendor() +  " " + pCLapp->getDeviceName();
157 #if USE_GPU
158         pPerfTest->buildTestInfo(pProcess->getSamplesGPU_CPUExecTime());
159 #else
160         pPerfTest->buildTestInfo(pProcess->getSamplesGPU_CPUExecTime());
161 #endif
162         pPerfTest->saveOrPrint();
163
164         // Step 10: clean up
165         pProcess.reset(nullptr);
166         pCLapp->delData(inHandle);
167         pCLapp->delData(outHandle);
168         pCLapp = nullptr;
169         pSamples = nullptr;
170
171
172     } catch(string msg) {
173         cerr << "Exception caught in main(): " << msg << endl;
174         //cleanupHost();
175     }
176 }