HOPS
HOPS class reference
MHO_SelectRepack.hh
Go to the documentation of this file.
1 #ifndef MHO_SelectRepack_HH__
2 #define MHO_SelectRepack_HH__
3 
4 #include <map>
5 #include <vector>
6 
7 #include "MHO_NDArrayWrapper.hh"
8 #include "MHO_UnaryOperator.hh"
9 
11 
12 namespace hops
13 {
14 
29 template< class XArgType > class MHO_SelectRepack: public MHO_UnaryOperator< XArgType >
30 {
31  public:
33  {
34  fInitialized = false;
35  fAxisSelectionMap.clear();
36  };
37 
38  virtual ~MHO_SelectRepack(){};
39 
43  void Reset() { fAxisSelectionMap.clear(); }
44 
51  void SelectAxisItems(std::size_t axis_index, const std::vector< std::size_t >& valid_indexes)
52  {
53  fAxisSelectionMap[axis_index] = valid_indexes;
54  //sort to make sure the selected elements are given in increasing order
55  std::sort(fAxisSelectionMap[axis_index].begin(), fAxisSelectionMap[axis_index].end());
56  fInitialized = false;
57  }
58 
59  protected:
67  virtual bool InitializeInPlace(XArgType* in) override { return InitializeOutOfPlace(in, &fWorkspace); }
68 
76  virtual bool ExecuteInPlace(XArgType* in) override
77  {
78  bool status = ExecuteOutOfPlace(in, &fWorkspace);
79  //"in-place" execution requires a copy from the workspace back to the object we are modifying
80  in->Copy(fWorkspace);
81  return status;
82  }
83 
92  virtual bool InitializeOutOfPlace(const XArgType* in, XArgType* out) override
93  {
94  if(in != nullptr && out != nullptr)
95  {
96  std::array< std::size_t, XArgType::rank::value > out_dim = DetermineOutputDimensions(in);
97  ConditionallyResizeOutput(out_dim, out);
98  fInitialized = true;
99  return true;
100  }
101  else
102  {
103  fInitialized = false;
104  return false;
105  }
106  }
107 
116  virtual bool ExecuteOutOfPlace(const XArgType* in, XArgType* out) override
117  {
118  if(fInitialized)
119  {
120  profiler_scope();
121  std::array< std::size_t, XArgType::rank::value > out_dim;
122  std::array< std::size_t, XArgType::rank::value > out_loc;
123  std::array< std::size_t, XArgType::rank::value > in_loc;
124 
125  out->GetDimensions(&(out_dim[0]));
126  std::size_t total_size = out->GetSize();
127 
128  if(fAxisSelectionMap.size() == 0)
129  {
130  //no axis has indices specified, so by default all data is selected
131  out->Copy(*in);
132  }
133  else if(fAxisSelectionMap.size() == XArgType::rank::value)
134  {
135  //all axes have data selected that we need to extract
136  for(std::size_t i = 0; i < total_size; i++)
137  {
138  //compute the indexes into the 'out' array
139  MHO_NDArrayMath::RowMajorIndexFromOffset< XArgType::rank::value >(i, &(out_dim[0]), &(out_loc[0]));
140 
141  //compute the indexes into the 'in' array, remapping where needed
142  //from the selections
143  for(std::size_t a = 0; a < XArgType::rank::value; a++)
144  {
145  in_loc[a] = (fAxisSelectionMap[a])[out_loc[a]];
146  }
147  out->ValueAt(out_loc) = in->ValueAt(in_loc);
148  }
149  IfTableSelectOnAxes(in, out);
150  }
151  else
152  {
153  //some axes have data selected, and some do not (meaning all is passed)
154  //so we need to sort through the mess
155  for(std::size_t i = 0; i < total_size; i++)
156  {
157  //compute the indexes into the 'out' array
158  MHO_NDArrayMath::RowMajorIndexFromOffset< XArgType::rank::value >(i, &(out_dim[0]), &(out_loc[0]));
159 
160  //compute the indexes into the 'in' array, remapping where needed
161  //from the selections
162  for(std::size_t a = 0; a < XArgType::rank::value; a++)
163  {
164  if(fAxisSelectionMap.count(a) == 0)
165  {
166  in_loc[a] = out_loc[a];
167  }
168  else
169  {
170  in_loc[a] = (fAxisSelectionMap[a])[out_loc[a]];
171  }
172  }
173  out->ValueAt(out_loc) = in->ValueAt(in_loc);
174  }
175  }
176 
177  IfTableSelectOnAxes(in, out);
178 
179  return true;
180  }
181  else
182  {
183  return false;
184  }
185  }
186 
187  private:
194  std::array< std::size_t, XArgType::rank::value > DetermineOutputDimensions(const XArgType* in)
195  {
196  std::array< std::size_t, XArgType::rank::value > out_dim;
197  in->GetDimensions(&(out_dim[0])); //initialize all dimensions to be the same as input
198  for(std::size_t a = 0; a < XArgType::rank::value; a++)
199  {
200  //reduce output dimensions for those axes which have selections
201  if(fAxisSelectionMap.count(a) != 0)
202  {
203  out_dim[a] = fAxisSelectionMap[a].size();
204  }
205  }
206  return out_dim;
207  }
208 
215  void ConditionallyResizeOutput(const std::array< std::size_t, XArgType::rank::value >& dims, XArgType* out)
216  {
217  auto out_dim = out->GetDimensionArray();
218  bool have_to_resize = false;
219  for(std::size_t i = 0; i < XArgType::rank::value; i++)
220  {
221  if(out_dim[i] != dims[i])
222  {
223  have_to_resize = true;
224  }
225  }
226  if(have_to_resize)
227  {
228  out->Resize(&(dims[0]));
229  }
230  }
231 
232  //default...does nothing
240  template< typename XCheckType = XArgType >
241  typename std::enable_if< !std::is_base_of< MHO_TableContainerBase, XCheckType >::value, void >::type
242  IfTableSelectOnAxes(const XArgType* , XArgType* ){};
243 
244  //use SFINAE to generate specialization for MHO_TableContainer types
252  template< typename XCheckType = XArgType >
253  typename std::enable_if< std::is_base_of< MHO_TableContainerBase, XCheckType >::value, void >::type
254  IfTableSelectOnAxes(const XArgType* in, XArgType* out)
255  {
256  for(std::size_t a = 0; a < XArgType::rank::value; a++) //apply to all axes
257  {
258  //look up via find(), as the operator[] does an implicit insertion on a unfound element
259  //possibly corrupting the selection map for later executions
260  std::vector< std::size_t > selection;
261  auto sel_iter = fAxisSelectionMap.find(a);
262  if(sel_iter != fAxisSelectionMap.end())
263  {
264  selection = sel_iter->second;
265  }
266  SelectOnAxis axis_sub_sampler(selection);
267  apply_at2< typename XArgType::axis_pack_tuple_type, SelectOnAxis >(*in, *out, a, axis_sub_sampler);
268  }
269  out->CopyTags(*in); //make sure the table tags get copied
270  }
271 
275  class SelectOnAxis
276  {
277  public:
278  SelectOnAxis(std::vector< std::size_t > selection): fSelection(selection){};
279  ~SelectOnAxis(){};
280 
281  template< typename XAxisType > void operator()(const XAxisType& axis1, XAxisType& axis2)
282  {
283  if(fSelection.size() != 0)
284  {
285  //copy all of the axis meta data
286  axis2.CopyTags(axis1);
287  //then remove the index labels
288  axis2.ClearIndexLabels();
289  //now copy back the selected index labels
290  for(std::size_t i = 0; i < fSelection.size(); i++)
291  {
292  axis2(i) = axis1(fSelection[i]);
293  mho_json obj = axis1.GetLabelObject(fSelection[i]);
294  axis2.SetLabelObject(obj, i);
295  }
296 
297  TODO_FIXME_MSG("TODO FIXME -- ensure that only the proper interval tags are selected/copied here.")
298  //axis2.ClearIntervalLabels();
299  //it doesn't make sense to copy the original interval labels since we have changed the organization of this axis
300  //what ought to do is figure out the overlap between previous interval labels and items of the new axis
301  //and create new overlapping intervals with the appropriate tags.
302  }
303  else
304  {
305  axis2.Copy(axis1); //no selection done on this axis, just copy everything
306  }
307  }
308 
309  private:
310  std::vector< std::size_t > fSelection;
311  };
312 
313  bool fInitialized;
314  XArgType fWorkspace;
315 
316  //map which holds the indexes selected from each axis
317  //if no item is present for a particular axis, the assumption is that all pre-existing
318  //elements are selected/passed in the selection process
319  std::map< std::size_t, std::vector< std::size_t > > fAxisSelectionMap;
320 };
321 
322 }; // namespace hops
323 
324 #endif
nlohmann::json mho_json
Definition: MHO_JSONHeaderWrapper.hh:5
#define TODO_FIXME_MSG(x)
Definition: MHO_Message.hh:35
#define profiler_scope()
Definition: MHO_Profiler.hh:237
Class MHO_SelectRepack.
Definition: MHO_SelectRepack.hh:30
virtual bool ExecuteOutOfPlace(const XArgType *in, XArgType *out) override
Function ExecuteOutOfPlace.
Definition: MHO_SelectRepack.hh:116
virtual ~MHO_SelectRepack()
Definition: MHO_SelectRepack.hh:38
virtual bool ExecuteInPlace(XArgType *in) override
Executes operation in-place by calling ExecuteOutOfPlace and copying result back to input.
Definition: MHO_SelectRepack.hh:76
virtual bool InitializeInPlace(XArgType *in) override
Initializes in-place by calling InitializeOutOfPlace with workspace.
Definition: MHO_SelectRepack.hh:67
virtual bool InitializeOutOfPlace(const XArgType *in, XArgType *out) override
Initializes out-of-place processing for given input and output arguments.
Definition: MHO_SelectRepack.hh:92
void SelectAxisItems(std::size_t axis_index, const std::vector< std::size_t > &valid_indexes)
Stores valid indexes for a given axis and marks selection as uninitialized.
Definition: MHO_SelectRepack.hh:51
MHO_SelectRepack()
Definition: MHO_SelectRepack.hh:32
void Reset()
Clears all entries from fAxisSelectionMap.
Definition: MHO_SelectRepack.hh:43
Class MHO_UnaryOperator.
Definition: MHO_UnaryOperator.hh:24
struct type_status status
Definition: fourfit3.c:53
Definition: MHO_AdhocFlagging.hh:18