SHOGUN  6.1.3
ComputationManager.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) The Shogun Machine Learning Toolbox
3  * Written (w) 2016 - 2017 Soumyajit De
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are those
27  * of the authors and should not be interpreted as representing official policies,
28  * either expressed or implied, of the Shogun Development Team.
29  */
30 
31 #include <shogun/lib/SGMatrix.h>
33 
34 using namespace shogun;
35 using namespace internal;
36 
37 ComputationManager::ComputationManager()
38 {
39 }
40 
41 ComputationManager::~ComputationManager()
42 {
43 }
44 
45 void ComputationManager::num_data(index_t n)
46 {
47  data_array.resize(n);
48 }
49 
50 SGMatrix<float32_t>& ComputationManager::data(index_t i)
51 {
52  return data_array[i];
53 }
54 
55 void ComputationManager::enqueue_job(std::function<float32_t(SGMatrix<float32_t>)> job)
56 {
57  job_array.push_back(job);
58 }
59 
60 void ComputationManager::compute_data_parallel_jobs()
61 {
62  // this is used when there are more number of data blocks to be processed
63  // than there are jobs
64  result_array.resize(job_array.size());
65  for (size_t j=0; j<job_array.size(); ++j)
66  result_array[j].resize(data_array.size());
67 
68  if (gpu)
69  {
70  // TODO current_job_results = compute_job.compute_using_gpu(data_array);
71  }
72  else
73  {
74 #pragma omp parallel for
75  for (int64_t i=0; i<(int64_t)data_array.size(); ++i)
76  {
77  // using a temporary vector to hold the result, because it is
78  // cache friendly, since the original result matrix would lead
79  // to several cache misses, specially because the data is also
80  // being used here
81  std::vector<float32_t> current_data_results(job_array.size());
82  for (size_t j=0; j<job_array.size(); ++j)
83  {
84  const auto& compute_job=job_array[j];
85  current_data_results[j]=compute_job(data_array[i]);
86  }
87  // data is no more required, less cache miss when we just have to
88  // store the results
89  for (size_t j=0; j<current_data_results.size(); ++j)
90  result_array[j][i]=current_data_results[j];
91  }
92  }
93 }
94 
95 void ComputationManager::compute_task_parallel_jobs()
96 {
97  // this is used when there are more number of jobs to be processed
98  // than there are data blocks
99  result_array.resize(job_array.size());
100  for (size_t j=0; j<job_array.size(); ++j)
101  result_array[j].resize(data_array.size());
102 
103  if (gpu)
104  {
105  // TODO current_job_results = compute_job.compute_using_gpu(data_array);
106  }
107  else
108  {
109  // TODO figure out other ways to deal with the parallelization in presence of
110  // eigen3. presently due to that, using OpenMP here messes things up!
111 //#pragma omp parallel for
112  for (size_t j=0; j<job_array.size(); ++j)
113  {
114  const auto& compute_job=job_array[j];
115  // result_array[j][i] is contiguous, cache miss is minimized
116  for (size_t i=0; i<data_array.size(); ++i)
117  result_array[j][i]=compute_job(data_array[i]);
118  }
119  }
120 }
121 
122 void ComputationManager::done()
123 {
124  job_array.resize(0);
125  result_array.resize(0);
126 }
127 
128 std::vector<float32_t>& ComputationManager::result(index_t i)
129 {
130  return result_array[i];
131 }
132 
133 ComputationManager& ComputationManager::use_gpu()
134 {
135  gpu=true;
136  return *this;
137 }
138 
139 ComputationManager& ComputationManager::use_cpu()
140 {
141  gpu=false;
142  return *this;
143 }
int32_t index_t
Definition: common.h:72
float float32_t
Definition: common.h:59
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18

SHOGUN Machine Learning Toolbox - Documentation