RTC Toolkit  1.0.0
computation.hpp
Go to the documentation of this file.
1 
12 #ifndef RTCTK_EXAMPLEDATATASK_COMPUTATION_HPP
13 #define RTCTK_EXAMPLEDATATASK_COMPUTATION_HPP
14 
19 
20 #include <chrono>
21 #include <numeric>
22 #include <string>
23 #include <vector>
24 // #include <cblas.h>
25 
26 using namespace rtctk::componentFramework;
27 
28 class Computation {
29 public:
31 
33  m_last_sample_id = 0;
34  m_sample_idx = 0;
35  m_iteration_idx = 0;
36  }
37 
38  void SetStaticConfig(unsigned to_read, unsigned n_slopes, unsigned n_modes) {
39  // read anything that is unlikely to change.
40  m_n_samples_to_read = to_read;
41  m_n_slopes = n_slopes;
42  m_n_modes = n_modes;
43 
44  // set vectors and matrix to correct size.
45  m_samples.resize(m_n_samples_to_read);
46  m_avg_slopes.resize(m_n_slopes);
47  m_s2m_matrix.resize(m_n_modes, m_n_slopes);
48  m_avg_modes.resize(m_n_modes);
49 
50  // fill with zeros where needed.
51  std::fill(m_avg_slopes.begin(), m_avg_slopes.end(), 0.0);
52  std::fill(m_avg_modes.begin(), m_avg_modes.end(), 0.0);
53 
54  // some simple debug output
55  LOG4CPLUS_DEBUG(GetLogger(), "m_n_slopes: " << m_n_slopes);
56  LOG4CPLUS_DEBUG(GetLogger(), "m_n_modes: " << m_n_modes);
57  LOG4CPLUS_DEBUG(GetLogger(), "m_n_samples_to_read: " << m_n_samples_to_read);
58  }
59 
61  m_s2m_matrix = std::move(s2m_matrix);
62 
63  if (m_n_modes != m_s2m_matrix.GetNrows() || m_n_slopes != m_s2m_matrix.GetNcols()) {
64  std::stringstream err_text;
65  err_text << "s2m wrong shape: ";
66  err_text << " "
67  << "expected : " << m_n_modes << " x " << m_n_slopes;
68  err_text << " "
69  << "received : " << m_s2m_matrix.GetNrows() << " x "
70  << m_s2m_matrix.GetNcols();
72  CII_THROW(RtctkException, err_text.str());
73  }
74  }
75 
76  void Reset() {
77  // This is invoked to clean up in case of stopped during buffering of data.
78  m_last_sample_id = 0;
79  m_sample_idx = 0;
80  m_iteration_idx = 0;
81  }
82 
83  void OnDataAvailable(TopicType const& sample) {
84  m_last_sample_id = sample.sample_id;
85  m_samples[m_sample_idx++] = sample.wfs.slopes;
86  }
87 
88  struct Result {
89  std::vector<float> const& avg_slopes;
90  std::vector<float> const& avg_modes;
91 
92  struct {
93  unsigned last_sample_id;
94  unsigned iteration_idx;
95  std::chrono::duration<double> elapsed;
96  } stats;
97  };
98 
102 
103  if (m_sample_idx != m_n_samples_to_read) {
104  CII_THROW(RtctkException, "not all data available");
105  }
106 
107  LOG4CPLUS_INFO(GetLogger(), "Computation::Compute() - samples: " << m_sample_idx);
108 
109  auto time_start = std::chrono::system_clock::now();
110 
111  ComputeAverageSlopes();
112 
113  ComputeAverageModes();
114 
115  auto elapsed = std::chrono::system_clock::now() - time_start;
116 
117  m_iteration_idx++;
118  m_sample_idx = 0;
119 
120  return {m_avg_slopes, m_avg_modes, m_last_sample_id, m_iteration_idx, elapsed};
121  }
122 
123 private:
124  void ComputeAverageSlopes() {
125  // average matrix to avg_array this is overly simplistic and not optimised
126  for (unsigned i = 0; i < m_n_samples_to_read; i++) {
127  for (unsigned j = 0; j < m_n_slopes; j++) {
128  m_avg_slopes[j] += m_samples[i][j];
129  }
130  }
131 
132  for (unsigned j = 0; j < m_n_slopes; j++) {
133  m_avg_slopes[j] /= static_cast<float>(m_n_samples_to_read);
134  }
135  }
136 
137  void ComputeAverageModes() {
138  // multiply avg_array with S2M matrix to project the average slopes onto modes.
139  // TODO: openblas not available on Centos 7 and no point in making it a dependancy.
140  // for this example I have added a very basic matrix vector multiplication of my own
141  // It is single threaded and not optimised. It is here only for demonstration purposes.
142  // cblas_sgemv(CblasRowMajor, CblasNoTrans, m_n_modes, m_n_slopes, 1.0, m_s2m_matrix.data(),
143  // m_n_slopes, m_avg_slopes.data(), 1, 0.0, m_avg_modes.data(), 1);
144  my_sgemv(
145  m_s2m_matrix.data(), m_avg_slopes.data(), m_avg_modes.data(), m_n_modes, m_n_slopes);
146  }
147 
148  // single threaded sgemv for row major matrix
149  void
150  my_sgemv(const float* mat, const float* in_vec, float* out_vec, uint32_t rows, uint32_t cols) {
151  for (uint32_t i = 0; i < rows; ++i) {
152  out_vec[i] = my_dot_product(mat + i * cols, in_vec, cols);
153  }
154  }
155 
156  // single threaded dot product
157  float my_dot_product(const float* x, const float* y, uint32_t n) {
158  double res = 0.0;
159  for (uint32_t i = 0; i < n; ++i) {
160  res += x[i] * y[i];
161  }
162  return res;
163  }
164 
165  unsigned m_last_sample_id;
166  unsigned m_iteration_idx;
167  unsigned m_sample_idx;
168 
169  unsigned m_n_slopes;
170  unsigned m_n_modes;
171  unsigned m_n_samples_to_read;
172 
173  std::vector<float> m_avg_slopes;
174  std::vector<float> m_avg_modes;
175  std::vector<decltype(decltype(TopicType::wfs)::slopes)> m_samples;
176  MatrixBuffer<float> m_s2m_matrix;
177 };
178 
179 #endif // RTCTK_EXAMPLEDATATASK_COMPUTATION_HPP
Computation::Reset
void Reset()
Definition: computation.hpp:76
rtctk::exampleTopic::ScaoLoopTopic::wfs
WfsLoopBaseTopic< N_SUBAPS > wfs
Definition: topics.hpp:29
exceptions.hpp
Provides macros and utilities for exception handling.
rtctk::componentFramework
Definition: commandReplier.cpp:20
Computation::SetDynamicConfig
void SetDynamicConfig(MatrixBuffer< float > &&s2m_matrix)
Definition: computation.hpp:60
matrixBuffer.hpp
Declaration of the MatrixBuffer template class used in APIs.
rtctk::componentFramework::RtctkException
The RtctkException class is the base class for all Rtctk exceptions.
Definition: exceptions.hpp:207
Computation::Result
Definition: computation.hpp:97
rtctk::exampleTopic::WfsLoopBaseTopic::slopes
std::array< float, 2 *NSUBAPS > slopes
Definition: topics.hpp:23
Computation::SetStaticConfig
void SetStaticConfig(unsigned to_read, unsigned n_slopes, unsigned n_modes)
Definition: computation.hpp:38
rtctk::exampleTopic::ScaoLoopTopic::sample_id
uint64_t sample_id
Definition: topics.hpp:28
rtctk::exampleTopic::ScaoLoopTopic
Definition: topics.hpp:27
Computation::OnDataAvailable
void OnDataAvailable(TopicType const &sample)
Definition: computation.hpp:83
rtctk::componentFramework::GetLogger
log4cplus::Logger & GetLogger(const std::string &name="")
Get handle to a specific logger (used with logging macros)
rtctkExampleDataTaskGenFitsData.mat
mat
Definition: rtctkExampleDataTaskGenFitsData.py:12
rtctkExampleDataTaskGenFitsData.slopes
slopes
Definition: rtctkExampleDataTaskGenFitsData.py:9
mudpi::uint32_t
unsigned int uint32_t
Definition: mudpi.h:16
logger.hpp
Logging Support Library based on log4cplus.
Computation
Definition: computation.hpp:28
Computation::Compute
Result Compute()
Definition: computation.hpp:99
Computation::Computation
Computation()
Definition: computation.hpp:32
rtctk::componentFramework::MatrixBuffer< float >
topics.hpp
Common topic definitions used in various examples.