Compadre  1.3.3
Compadre_Evaluator.hpp
Go to the documentation of this file.
1 #ifndef _COMPADRE_EVALUATOR_HPP_
2 #define _COMPADRE_EVALUATOR_HPP_
3 
4 #include "Compadre_Typedefs.hpp"
5 #include "Compadre_GMLS.hpp"
7 
8 namespace Compadre {
9 
10 //! Creates 1D subviews of data from a 2D view, generally constructed with CreateNDSliceOnDeviceView
11 template<typename T, typename T2, typename T3=void>
12 struct SubviewND {
13 
17 
18  SubviewND(T data_in, T2 data_original_view, bool scalar_as_vector_if_needed) {
19  _data_in = data_in;
20  _data_original_view = data_original_view;
21  _scalar_as_vector_if_needed = scalar_as_vector_if_needed;
22  }
23 
24  auto get1DView(const int column_num) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL, column_num)) {
26  compadre_assert_debug(((size_t)column_num<_data_in.extent(1))
27  && "Subview asked for column > second dimension of input data.");
28  }
29  if ((size_t)column_num<_data_in.extent(1))
30  return Kokkos::subview(_data_in, Kokkos::ALL, column_num);
31  else // scalar treated as a vector (being reused for each component of the vector input that was expected)
32  return Kokkos::subview(_data_in, Kokkos::ALL, 0);
33  }
34 
35  auto get2DView(const int column_num, const int block_size) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL,
36  Kokkos::make_pair(column_num*block_size, (column_num+1)*block_size))) {
38  compadre_assert_debug(((size_t)((column_num+1)*block_size-1)<_data_in.extent(1))
39  && "Subview asked for column > second dimension of input data.");
40  }
41  if ((size_t)((column_num+1)*block_size-1)<_data_in.extent(1)) {
42  return Kokkos::subview(_data_in, Kokkos::ALL, Kokkos::make_pair(column_num*block_size, (column_num+1)*block_size));
43  } else {
44  compadre_assert_debug(((size_t)(block_size-1)<_data_in.extent(1)) && "Subview asked for column > second dimension of input data.");
45  return Kokkos::subview(_data_in, Kokkos::ALL, Kokkos::make_pair(0,block_size));
46  }
47  }
48 
50  Kokkos::deep_copy(_data_original_view, _data_in);
51  Kokkos::fence();
52  return _data_original_view;
53  }
54 
55 };
56 
57 //! Creates 1D subviews of data from a 1D view, generally constructed with CreateNDSliceOnDeviceView
58 template<typename T, typename T2>
59 struct SubviewND<T, T2, enable_if_t<(T::rank<2)> >
60 {
61 
65 
66  SubviewND(T data_in, T2 data_original_view, bool scalar_as_vector_if_needed) {
67  _data_in = data_in;
68  _data_original_view = data_original_view;
69  _scalar_as_vector_if_needed = scalar_as_vector_if_needed;
70  }
71 
72  auto get1DView(const int column_num) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL)) {
73  // TODO: There is a valid use case for violating this assert, so in the future we may want
74  // to add other logic to the evaluator function calling this so that it knows to do nothing with
75  // this data.
77  compadre_assert_debug((column_num==0) && "Subview asked for column column_num!=0, but _data_in is rank 1.");
78  }
79  return Kokkos::subview(_data_in, Kokkos::ALL);
80  }
81 
82  auto get2DView(const int column_num, const int block_size) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL)) {
83  compadre_assert_release((block_size==1) && "2D subview requested not compatible with one column.");
84  return Kokkos::subview(_data_in, Kokkos::ALL);
85  }
86 
88  Kokkos::deep_copy(_data_original_view, _data_in);
89  Kokkos::fence();
90  return _data_original_view;
91  }
92 
93 };
94 
95 //! Copies data_in to the device, and then allows for access to 1D columns of data on device.
96 //! Handles either 2D or 1D views as input, and they can be on the host or the device.
97 template <typename T>
98 auto CreateNDSliceOnDeviceView(T sampling_input_data_host_or_device, bool scalar_as_vector_if_needed) -> SubviewND<decltype(Kokkos::create_mirror_view(
99  device_memory_space(), sampling_input_data_host_or_device)), T> {
100 
101  // makes view on the device (does nothing if already on the device)
102  auto sampling_input_data_device = Kokkos::create_mirror_view(
103  device_memory_space(), sampling_input_data_host_or_device);
104  Kokkos::deep_copy(sampling_input_data_device, sampling_input_data_host_or_device);
105  Kokkos::fence();
106 
107  return SubviewND<decltype(sampling_input_data_device),T>(sampling_input_data_device,
108  sampling_input_data_host_or_device, scalar_as_vector_if_needed);
109 }
110 
111 //! \brief Lightweight Evaluator Helper
112 //! This class is a lightweight wrapper for extracting and applying all relevant data from a GMLS class
113 //! in order to transform data into a form that can be acted on by the GMLS operator, apply the action of
114 //! the GMLS operator, and then transform data again (only if on a manifold)
115 class Evaluator {
116 
117 private:
118 
120 
121 
122 public:
123 
124  Evaluator(GMLS *gmls) : _gmls(gmls) {
125  Kokkos::fence();
126  };
127 
129 
130  //! Dot product of alphas with sampling data, FOR A SINGLE target_index, where sampling data is in a 1D/2D Kokkos View
131  //!
132  //! This function is to be used when the alpha values have already been calculated and stored for use
133  //!
134  //! Only supports one output component / input component at a time. The user will need to loop over the output
135  //! components in order to fill a vector target or matrix target.
136  //!
137  //! Assumptions on input data:
138  //! \param sampling_input_data [in] - 1D/2D Kokkos View (no restriction on memory space)
139  //! \param column_of_input [in] - Column of sampling_input_data to use for this input component
140  //! \param lro [in] - Target operation from the TargetOperation enum
141  //! \param target_index [in] - Target # user wants to reconstruct target functional at, corresponds to row number of neighbor_lists
142  //! \param output_component_axis_1 [in] - Row for a rank 2 tensor or rank 1 tensor, 0 for a scalar output
143  //! \param output_component_axis_2 [in] - Columns for a rank 2 tensor, 0 for rank less than 2 output tensor
144  //! \param input_component_axis_1 [in] - Row for a rank 2 tensor or rank 1 tensor, 0 for a scalar input
145  //! \param input_component_axis_2 [in] - Columns for a rank 2 tensor, 0 for rank less than 2 input tensor
146  //! \param scalar_as_vector_if_needed [in] - If a 1D view is given, where a 2D view is expected (scalar values given where a vector was expected), then the scalar will be repeated for as many components as the vector has
147  template <typename view_type_data>
148  double applyAlphasToDataSingleComponentSingleTargetSite(view_type_data sampling_input_data, const int column_of_input, TargetOperation lro, const int target_index, const int evaluation_site_local_index, const int output_component_axis_1, const int output_component_axis_2, const int input_component_axis_1, const int input_component_axis_2, bool scalar_as_vector_if_needed = true) const {
149 
150  double value = 0;
151 
152  const int alpha_input_output_component_index = _gmls->getAlphaColumnOffset(lro, output_component_axis_1,
153  output_component_axis_2, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
154 
155  auto sampling_subview_maker = CreateNDSliceOnDeviceView(sampling_input_data, scalar_as_vector_if_needed);
156 
157 
158  // gather needed information for evaluation
159  auto nla = *(_gmls->getNeighborLists());
160  auto alphas = _gmls->getAlphas();
161  auto sampling_data_device = sampling_subview_maker.get1DView(column_of_input);
162 
163  auto alpha_index = _gmls->getAlphaIndexHost(target_index, alpha_input_output_component_index);
164  // loop through neighbor list for this target_index
165  // grabbing data from that entry of data
166  Kokkos::parallel_reduce("applyAlphasToData::Device",
167  Kokkos::RangePolicy<device_execution_space>(0,nla.getNumberOfNeighborsHost(target_index)),
168  KOKKOS_LAMBDA(const int i, double& t_value) {
169 
170  t_value += sampling_data_device(nla.getNeighborDevice(target_index, i))
171  *alphas(alpha_index + i);
172 
173  }, value );
174  Kokkos::fence();
175 
176  return value;
177  }
178 
179  //! Dot product of alphas with sampling data where sampling data is in a 1D/2D Kokkos View and output view is also
180  //! a 1D/2D Kokkos View, however THE SAMPLING DATA and OUTPUT VIEW MUST BE ON THE DEVICE!
181  //!
182  //! This function is to be used when the alpha values have already been calculated and stored for use.
183  //!
184  //! Only supports one output component / input component at a time. The user will need to loop over the output
185  //! components in order to fill a vector target or matrix target.
186  //!
187  //! Assumptions on input data:
188  //! \param output_data_single_column [out] - 1D Kokkos View (memory space must be device_memory_space())
189  //! \param sampling_data_single_column [in] - 1D Kokkos View (memory space must match output_data_single_column)
190  //! \param lro [in] - Target operation from the TargetOperation enum
191  //! \param sro [in] - Sampling functional from the SamplingFunctional enum
192  //! \param evaluation_site_location [in] - local column index of site from additional evaluation sites list or 0 for the target site
193  //! \param output_component_axis_1 [in] - Row for a rank 2 tensor or rank 1 tensor, 0 for a scalar output
194  //! \param output_component_axis_2 [in] - Columns for a rank 2 tensor, 0 for rank less than 2 output tensor
195  //! \param input_component_axis_1 [in] - Row for a rank 2 tensor or rank 1 tensor, 0 for a scalar input
196  //! \param input_component_axis_2 [in] - Columns for a rank 2 tensor, 0 for rank less than 2 input tensor
197  //! \param pre_transform_local_index [in] - For manifold problems, this is the local coordinate direction that sampling data may need to be transformed to before the application of GMLS
198  //! \param pre_transform_global_index [in] - For manifold problems, this is the global coordinate direction that sampling data can be represented in
199  //! \param post_transform_local_index [in] - For manifold problems, this is the local coordinate direction that vector output target functionals from GMLS will output into
200  //! \param post_transform_global_index [in] - For manifold problems, this is the global coordinate direction that the target functional output from GMLS will be transformed into
201  //! \param transform_output_ambient [in] - Whether or not a 1D output from GMLS is on the manifold and needs to be mapped to ambient space
202  //! \param vary_on_target [in] - Whether the sampling functional has a tensor to act on sampling data that varies with each target site
203  //! \param vary_on_neighbor [in] - Whether the sampling functional has a tensor to act on sampling data that varies with each neighbor site in addition to varying wit each target site
204  template <typename view_type_data_out, typename view_type_data_in>
205  void applyAlphasToDataSingleComponentAllTargetSitesWithPreAndPostTransform(view_type_data_out output_data_single_column, view_type_data_in sampling_data_single_column, TargetOperation lro, const SamplingFunctional sro, const int evaluation_site_local_index, const int output_component_axis_1, const int output_component_axis_2, const int input_component_axis_1, const int input_component_axis_2, const int pre_transform_local_index = -1, const int pre_transform_global_index = -1, const int post_transform_local_index = -1, const int post_transform_global_index = -1, bool vary_on_target = false, bool vary_on_neighbor = false) const {
206 
207  const int alpha_input_output_component_index = _gmls->getAlphaColumnOffset(lro, output_component_axis_1,
208  output_component_axis_2, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
209  const int alpha_input_output_component_index2 = alpha_input_output_component_index;
210 
211  // gather needed information for evaluation
212  auto gmls = *(_gmls);
213  auto nla = *(_gmls->getNeighborLists());
214  auto alphas = _gmls->getAlphas();
215  auto prestencil_weights = _gmls->getPrestencilWeights();
216 
217  const int num_targets = nla.getNumberOfTargets();
218 
219  // make sure input and output views have same memory space
220  compadre_assert_debug((std::is_same<typename view_type_data_out::memory_space, typename view_type_data_in::memory_space>::value) &&
221  "output_data_single_column view and input_data_single_column view have difference memory spaces.");
222 
223  bool weight_with_pre_T = (pre_transform_local_index>=0 && pre_transform_global_index>=0) ? true : false;
224  bool target_plus_neighbor_staggered_schema = sro.use_target_site_weights;
225 
226  // loops over target indices
227  Kokkos::parallel_for(team_policy(num_targets, Kokkos::AUTO),
228  KOKKOS_LAMBDA(const member_type& teamMember) {
229 
230  const int target_index = teamMember.league_rank();
231  teamMember.team_barrier();
232 
233 
234  const double previous_value = output_data_single_column(target_index);
235 
236  // loops over neighbors of target_index
237  auto alpha_index = gmls.getAlphaIndexDevice(target_index, alpha_input_output_component_index);
238  double gmls_value = 0;
239  Kokkos::parallel_reduce(Kokkos::TeamThreadRange(teamMember, nla.getNumberOfNeighborsDevice(target_index)), [=](const int i, double& t_value) {
240  const double neighbor_varying_pre_T = (weight_with_pre_T && vary_on_neighbor) ?
241  prestencil_weights(0, target_index, i, pre_transform_local_index, pre_transform_global_index)
242  : 1.0;
243 
244  t_value += neighbor_varying_pre_T * sampling_data_single_column(nla.getNeighborDevice(target_index, i))
245  *alphas(alpha_index + i);
246 
247  }, gmls_value );
248 
249  // data contract for sampling functional
250  double pre_T = 1.0;
251  if (weight_with_pre_T) {
252  if (!vary_on_neighbor && vary_on_target) {
253  pre_T = prestencil_weights(0, target_index, 0, pre_transform_local_index,
254  pre_transform_global_index);
255  } else if (!vary_on_target) { // doesn't vary on target or neighbor
256  pre_T = prestencil_weights(0, 0, 0, pre_transform_local_index,
257  pre_transform_global_index);
258  }
259  }
260 
261  double staggered_value_from_targets = 0;
262  double pre_T_staggered = 1.0;
263  auto alpha_index2 = gmls.getAlphaIndexDevice(target_index, alpha_input_output_component_index2);
264  // loops over target_index for each neighbor for staggered approaches
265  if (target_plus_neighbor_staggered_schema) {
266  Kokkos::parallel_reduce(Kokkos::TeamThreadRange(teamMember, nla.getNumberOfNeighborsDevice(target_index)), [=](const int i, double& t_value) {
267  const double neighbor_varying_pre_T_staggered = (weight_with_pre_T && vary_on_neighbor) ?
268  prestencil_weights(1, target_index, i, pre_transform_local_index, pre_transform_global_index)
269  : 1.0;
270 
271  t_value += neighbor_varying_pre_T_staggered * sampling_data_single_column(nla.getNeighborDevice(target_index, 0))
272  *alphas(alpha_index2 + i);
273 
274  }, staggered_value_from_targets );
275 
276  // for staggered approaches that transform source data for the target and neighbors
277  if (weight_with_pre_T) {
278  if (!vary_on_neighbor && vary_on_target) {
279  pre_T_staggered = prestencil_weights(1, target_index, 0, pre_transform_local_index,
280  pre_transform_global_index);
281  } else if (!vary_on_target) { // doesn't vary on target or neighbor
282  pre_T_staggered = prestencil_weights(1, 0, 0, pre_transform_local_index,
283  pre_transform_global_index);
284  }
285  }
286  }
287 
288  double added_value = pre_T*gmls_value + pre_T_staggered*staggered_value_from_targets;
289  Kokkos::single(Kokkos::PerTeam(teamMember), [=] () {
290  output_data_single_column(target_index) = previous_value + added_value;
291  });
292  });
293  Kokkos::fence();
294  }
295 
296  //! Postprocessing for manifolds. Maps local chart vector solutions to ambient space.
297  //! THE SAMPLING DATA and OUTPUT VIEW MUST BE ON THE DEVICE!
298  //!
299  //! Only supports one output component / input component at a time. The user will need to loop over the output
300  //! components in order to transform a vector target.
301  //!
302  //! Assumptions on input data:
303  //! \param output_data_single_column [out] - 1D Kokkos View (memory space must be device_memory_space())
304  //! \param sampling_data_single_column [in] - 1D Kokkos View (memory space must match output_data_single_column)
305  //! \param local_dim_index [in] - For manifold problems, this is the local coordinate direction that sampling data may need to be transformed to before the application of GMLS
306  //! \param global_dim_index [in] - For manifold problems, this is the global coordinate direction that sampling data can be represented in
307  template <typename view_type_data_out, typename view_type_data_in>
308  void applyLocalChartToAmbientSpaceTransform(view_type_data_out output_data_single_column, view_type_data_in sampling_data_single_column, const int local_dim_index, const int global_dim_index) const {
309 
310  // Does T transpose times a vector
311  auto global_dimensions = _gmls->getGlobalDimensions();
312 
313  // gather needed information for evaluation
314  auto nla = *(_gmls->getNeighborLists());
315  const int num_targets = nla.getNumberOfTargets();
316 
317  auto tangent_directions = _gmls->getTangentDirections();
318 
319  // make sure input and output views have same memory space
320  compadre_assert_debug((std::is_same<typename view_type_data_out::memory_space, typename view_type_data_in::memory_space>::value) &&
321  "output_data_single_column view and input_data_single_column view have difference memory spaces.");
322 
323  // loops over target indices
324  Kokkos::parallel_for(team_policy(num_targets, Kokkos::AUTO),
325  KOKKOS_LAMBDA(const member_type& teamMember) {
326 
327  const int target_index = teamMember.league_rank();
328 
330  (tangent_directions.data() + TO_GLOBAL(target_index)*TO_GLOBAL(global_dimensions)*TO_GLOBAL(global_dimensions),
331  global_dimensions, global_dimensions);
332  teamMember.team_barrier();
333 
334 
335  const double previous_value = output_data_single_column(target_index);
336 
337  double added_value = T(local_dim_index, global_dim_index)*sampling_data_single_column(target_index);
338  Kokkos::single(Kokkos::PerTeam(teamMember), [=] () {
339  output_data_single_column(target_index) = previous_value + added_value;
340  });
341  });
342  Kokkos::fence();
343  }
344 
345  //! Transformation of data under GMLS (allocates memory for output)
346  //!
347  //! This function is the go-to function to be used when the alpha values have already been calculated and stored for use. The sampling functional provided instructs how a data transformation tensor is to be used on source data before it is provided to the GMLS operator. Once the sampling functional (if applicable) and the GMLS operator have been applied, this function also handles mapping the local vector back to the ambient space if working on a manifold problem and a target functional who has rank 1 output.
348  //!
349  //! Produces a Kokkos View as output with a Kokkos memory_space provided as a template tag by the caller.
350  //! The data type (double* or double**) must also be specified as a template type if one wish to get a 1D
351  //! Kokkos View back that can be indexed into with only one ordinal.
352  //!
353  //! Assumptions on input data:
354  //! \param sampling_data [in] - 1D or 2D Kokkos View that has the layout #targets * columns of data. Memory space for data can be host or device.
355  //! \param lro [in] - Target operation from the TargetOperation enum
356  //! \param sro_in [in] - Sampling functional from the SamplingFunctional enum
357  //! \param scalar_as_vector_if_needed [in] - If a 1D view is given, where a 2D view is expected (scalar values given where a vector was expected), then the scalar will be repeated for as many components as the vector has
358  //! \param evaluation_site_local_index [in] - 0 corresponds to evaluating at the target site itself, while a number larger than 0 indicates evaluation at a site other than the target, and specified by calling setAdditionalEvaluationSitesData on the GMLS class
359  template <typename output_data_type = double**, typename output_memory_space, typename view_type_input_data, typename output_array_layout = typename view_type_input_data::array_layout>
360  Kokkos::View<output_data_type, output_array_layout, output_memory_space> // shares layout of input by default
361  applyAlphasToDataAllComponentsAllTargetSites(view_type_input_data sampling_data, TargetOperation lro, const SamplingFunctional sro_in = PointSample, bool scalar_as_vector_if_needed = true, const int evaluation_site_local_index = 0) const {
362  // gather needed information for evaluation
363  auto nla = *(_gmls->getNeighborLists());
364 
365  // determines the number of columns needed for output after action of the target functional
366  int output_dimensions = _gmls->getOutputDimensionOfOperation(lro);
367  auto global_dimensions = _gmls->getGlobalDimensions();
368  auto problem_type = _gmls->getProblemType();
369 
370  typedef Kokkos::View<output_data_type, output_array_layout, output_memory_space> output_view_type;
371  // create view on whatever memory space the user specified with their template argument when calling this function
372  output_view_type target_output = createView<output_view_type>("output of target operation",
373  nla.getNumberOfTargets(), output_dimensions);
374 
375  output_view_type ambient_target_output;
376  bool transform_gmls_output_to_ambient = (problem_type==MANIFOLD && TargetOutputTensorRank[(int)lro]==1);
377  if (transform_gmls_output_to_ambient) {
378  ambient_target_output = createView<output_view_type>("output of transform to ambient space",
379  nla.getNumberOfTargets(), global_dimensions);
380  }
381 
382  applyAlphasToDataAllComponentsAllTargetSites(target_output, ambient_target_output, sampling_data, lro, sro_in, scalar_as_vector_if_needed, evaluation_site_local_index);
383 
384  if (transform_gmls_output_to_ambient) {
385  return ambient_target_output;
386  } else {
387  return target_output;
388  }
389 
390  }
391 
392  //! Transformation of data under GMLS (does not allocate memory for output)
393  //!
394  //! If space for the output result is already allocated, this function will populate the output result view (and possibly ambient target output). The sampling functional provided instructs how a data transformation tensor is to be used on source data before it is provided to the GMLS operator. Once the sampling functional (if applicable) and the GMLS operator have been applied, this function also handles mapping the local vector back to the ambient space if working on a manifold problem and a target functional who has rank 1 output.
395  //!
396  //! Fills a Kokkos View of output.
397  //!
398  //! Assumptions on input data:
399  //! \param target_output [in] - 1D or 2D Kokkos View that has the resulting #targets * need output columns. Memory space for data can be host or device.
400  //! \param ambient_target_output [in] - Same view type as target_output, but dimensions should be #targets * global_dimension if this is being filled (if not being filled, then this can be an empty view)
401  //! \param sampling_data [in] - 1D or 2D Kokkos View that has the layout #targets * columns of data. Memory space for data can be host or device.
402  //! \param lro [in] - Target operation from the TargetOperation enum
403  //! \param sro_in [in] - Sampling functional from the SamplingFunctional enum
404  //! \param scalar_as_vector_if_needed [in] - If a 1D view is given, where a 2D view is expected (scalar values given where a vector was expected), then the scalar will be repeated for as many components as the vector has
405  //! \param evaluation_site_local_index [in] - 0 corresponds to evaluating at the target site itself, while a number larger than 0 indicates evaluation at a site other than the target, and specified by calling setAdditionalEvaluationSitesData on the GMLS class
406  template <typename view_type_output_data, typename view_type_input_data, typename output_array_layout = typename view_type_input_data::array_layout>
407  void applyAlphasToDataAllComponentsAllTargetSites(view_type_output_data target_output, view_type_output_data ambient_target_output, view_type_input_data sampling_data, TargetOperation lro, const SamplingFunctional sro_in = PointSample, bool scalar_as_vector_if_needed = true, const int evaluation_site_local_index = 0) const {
408 
409 
410  // output can be device or host
411  // input can be device or host
412  // move everything to device and calculate there, then move back to host if necessary
413 
414 
415  auto problem_type = _gmls->getProblemType();
416  auto global_dimensions = _gmls->getGlobalDimensions();
417  auto output_dimension1_of_operator = (TargetOutputTensorRank[lro]<2) ? _gmls->getOutputDimensionOfOperation(lro) : std::sqrt(_gmls->getOutputDimensionOfOperation(lro));
418  auto output_dimension2_of_operator = (TargetOutputTensorRank[lro]<2) ? 1 : std::sqrt(_gmls->getOutputDimensionOfOperation(lro));
419  auto input_dimension_of_operator = _gmls->getInputDimensionOfOperation(lro);
420 
421  // gather needed information for evaluation
422  auto nla = *(_gmls->getNeighborLists());
423 
424  // determines the number of columns needed for output after action of the target functional
425  int output_dimensions = _gmls->getOutputDimensionOfOperation(lro);
426 
427  // special case for VectorPointSample, because if it is on a manifold it includes data transform to local charts
428  auto sro = (problem_type==MANIFOLD && sro_in==VectorPointSample) ? ManifoldVectorPointSample : sro_in;
429 
430  compadre_assert_debug(target_output.extent(0)==(size_t)nla.getNumberOfTargets()
431  && "First dimension of target_output is incorrect size.\n");
432  compadre_assert_debug(target_output.extent(1)==(size_t)output_dimensions
433  && "Second dimension of target_output is incorrect size.\n");
434 
435  // make sure input and output columns make sense under the target operation
436  compadre_assert_debug(((output_dimensions==1 && view_type_output_data::rank==1) || view_type_output_data::rank!=1) &&
437  "Output view is requested as rank 1, but the target requires a rank larger than 1. Try double** as template argument.");
438 
439  // we need to specialize a template on the rank of the output view type and the input view type
440  auto sampling_subview_maker = CreateNDSliceOnDeviceView(sampling_data, scalar_as_vector_if_needed);
441  auto output_subview_maker = CreateNDSliceOnDeviceView(target_output, false); // output will always be the correct dimension
442 
443  // figure out preprocessing and postprocessing
444  auto prestencil_weights = _gmls->getPrestencilWeights();
445 
446  // all loop logic based on transforming data under a sampling functional
447  // into something that is valid input for GMLS
448  bool vary_on_target = false, vary_on_neighbor = false;
449  auto sro_style = sro.transform_type;
450  bool loop_global_dimensions = sro.input_rank>0 && sro_style!=Identity;
451 
453  && "SamplingFunctional requested for Evaluator does not match GMLS data sampling functional or is not of type 'Identity'.");
454 
455  if (sro.transform_type == Identity || sro.transform_type == SameForAll) {
456  vary_on_target = false;
457  vary_on_neighbor = false;
458  } else if (sro.transform_type == DifferentEachTarget) {
459  vary_on_target = true;
460  vary_on_neighbor = false;
461  } else if (sro.transform_type == DifferentEachNeighbor) {
462  vary_on_target = true;
463  vary_on_neighbor = true;
464  }
465 
466 
467  // only written for up to rank 1 to rank 2 (in / out)
468  // loop over components of output of the target operation
469  for (int axes1=0; axes1<output_dimension1_of_operator; ++axes1) {
470  const int output_component_axis_1 = axes1;
471  for (int axes2=0; axes2<output_dimension2_of_operator; ++axes2) {
472  const int output_component_axis_2 = axes2;
473  // loop over components of input of the target operation
474  for (int j=0; j<input_dimension_of_operator; ++j) {
475  const int input_component_axis_1 = j;
476  const int input_component_axis_2 = 0;
477 
478  if (loop_global_dimensions) {
479  for (int k=0; k<global_dimensions; ++k) { // loop for handling sampling functional
481  output_subview_maker.get1DView(axes1*output_dimension2_of_operator+axes2),
482  sampling_subview_maker.get1DView(k), lro, sro,
483  evaluation_site_local_index, output_component_axis_1, output_component_axis_2, input_component_axis_1,
484  input_component_axis_2, j, k, -1, -1,
485  vary_on_target, vary_on_neighbor);
486  }
487  } else if (sro_style != Identity) {
489  output_subview_maker.get1DView(axes1*output_dimension2_of_operator+axes2),
490  sampling_subview_maker.get1DView(j), lro, sro,
491  evaluation_site_local_index, output_component_axis_1, output_component_axis_2, input_component_axis_1,
492  input_component_axis_2, 0, 0, -1, -1,
493  vary_on_target, vary_on_neighbor);
494  } else { // standard
496  output_subview_maker.get1DView(axes1*output_dimension2_of_operator+axes2),
497  sampling_subview_maker.get1DView(j), lro, sro,
498  evaluation_site_local_index, output_component_axis_1, output_component_axis_2, input_component_axis_1,
499  input_component_axis_2);
500  }
501  }
502  }
503  }
504 
505  bool transform_gmls_output_to_ambient = (problem_type==MANIFOLD && TargetOutputTensorRank[(int)lro]==1);
506  if (transform_gmls_output_to_ambient) {
507  Kokkos::fence();
508 
509  compadre_assert_debug(ambient_target_output.extent(0)==(size_t)nla.getNumberOfTargets()
510  && "First dimension of target_output is incorrect size.\n");
511  compadre_assert_debug(ambient_target_output.extent(1)==(size_t)global_dimensions
512  && "Second dimension of target_output is incorrect size.\n");
513  auto transformed_output_subview_maker = CreateNDSliceOnDeviceView(ambient_target_output, false);
514  // output will always be the correct dimension
515  for (int i=0; i<global_dimensions; ++i) {
516  for (int j=0; j<output_dimensions; ++j) {
518  transformed_output_subview_maker.get1DView(i), output_subview_maker.get1DView(j), j, i);
519  }
520  }
521  // copy back to whatever memory space the user requester through templating from the device
522  Kokkos::deep_copy(ambient_target_output, transformed_output_subview_maker.copyToAndReturnOriginalView());
523  }
524 
525  // copy back to whatever memory space the user requester through templating from the device
526  Kokkos::deep_copy(target_output, output_subview_maker.copyToAndReturnOriginalView());
527  }
528 
529 
530  //! Dot product of data with full polynomial coefficient basis where sampling data is in a 1D/2D Kokkos View and output view is also
531  //! a 1D/2D Kokkos View, however THE SAMPLING DATA and OUTPUT VIEW MUST BE ON THE DEVICE!
532  //!
533  //! This function is to be used when the polynomial coefficient basis has already been calculated and stored for use.
534  //!
535  //! Only supports one output component / input component at a time. The user will need to loop over the output
536  //! components in order to fill a vector target or matrix target.
537  //!
538  //! Assumptions on input data:
539  //! \param output_data_block_column [out] - 2D Kokkos View (memory space must be device_memory_space())
540  //! \param sampling_data_single_column [in] - 1D Kokkos View (memory space must match output_data_single_column)
541  //! \param sro [in] - Sampling functional from the SamplingFunctional enum
542  //! \param target_index [in] - Target # user wants to reconstruct target functional at, corresponds to row number of neighbor_lists
543  //! \param output_component_axis_1 [in] - Row for a rank 2 tensor or rank 1 tensor, 0 for a scalar output
544  //! \param output_component_axis_2 [in] - Columns for a rank 2 tensor, 0 for rank less than 2 output tensor
545  //! \param input_component_axis_1 [in] - Row for a rank 2 tensor or rank 1 tensor, 0 for a scalar input
546  //! \param input_component_axis_2 [in] - Columns for a rank 2 tensor, 0 for rank less than 2 input tensor
547  //! \param pre_transform_local_index [in] - For manifold problems, this is the local coordinate direction that sampling data may need to be transformed to before the application of GMLS
548  //! \param pre_transform_global_index [in] - For manifold problems, this is the global coordinate direction that sampling data can be represented in
549  //! \param post_transform_local_index [in] - For manifold problems, this is the local coordinate direction that vector output target functionals from GMLS will output into
550  //! \param post_transform_global_index [in] - For manifold problems, this is the global coordinate direction that the target functional output from GMLS will be transformed into
551  //! \param vary_on_target [in] - Whether the sampling functional has a tensor to act on sampling data that varies with each target site
552  //! \param vary_on_neighbor [in] - Whether the sampling functional has a tensor to act on sampling data that varies with each neighbor site in addition to varying wit each target site
553  template <typename view_type_data_out, typename view_type_data_in>
554  void applyFullPolynomialCoefficientsBasisToDataSingleComponent(view_type_data_out output_data_block_column, view_type_data_in sampling_data_single_column, const SamplingFunctional sro, const int output_component_axis_1, const int output_component_axis_2, const int input_component_axis_1, const int input_component_axis_2, const int pre_transform_local_index = -1, const int pre_transform_global_index = -1, const int post_transform_local_index = -1, const int post_transform_global_index = -1, bool vary_on_target = false, bool vary_on_neighbor = false) const {
555 
556  auto nla = *(_gmls->getNeighborLists());
557 
558  auto coefficient_matrix_dims = _gmls->getPolynomialCoefficientsDomainRangeSize();
559  auto coefficient_memory_layout_dims = _gmls->getPolynomialCoefficientsMemorySize();
560  auto coefficient_memory_layout_dims_device =
561  Kokkos::create_mirror_view_and_copy(device_memory_space(), coefficient_memory_layout_dims);
562 
563  auto global_dimensions = _gmls->getGlobalDimensions();
564 
565  // gather needed information for evaluation
566  auto coeffs = _gmls->getFullPolynomialCoefficientsBasis();
567  auto tangent_directions = _gmls->getTangentDirections();
568  auto prestencil_weights = _gmls->getPrestencilWeights();
569 
570  const int num_targets = nla.getNumberOfTargets();
571 
572  // make sure input and output views have same memory space
573  compadre_assert_debug((std::is_same<typename view_type_data_out::memory_space, typename view_type_data_in::memory_space>::value) &&
574  "output_data_block_column view and input_data_single_column view have difference memory spaces.");
575 
576  bool weight_with_pre_T = (pre_transform_local_index>=0 && pre_transform_global_index>=0) ? true : false;
577  bool target_plus_neighbor_staggered_schema = sro.use_target_site_weights;
578 
579  // loops over target indices
580  for (int j=0; j<coefficient_matrix_dims(0); ++j) {
581  Kokkos::parallel_for(team_policy(num_targets, Kokkos::AUTO),
582  KOKKOS_LAMBDA(const member_type& teamMember) {
583 
584  const int target_index = teamMember.league_rank();
585 
586  scratch_matrix_right_type T (tangent_directions.data()
587  + TO_GLOBAL(target_index)*TO_GLOBAL(global_dimensions)*TO_GLOBAL(global_dimensions),
588  global_dimensions, global_dimensions);
589 
591  Coeffs = scratch_matrix_right_type(coeffs.data()
592  + TO_GLOBAL(target_index)*TO_GLOBAL(coefficient_memory_layout_dims_device(0))
593  *TO_GLOBAL(coefficient_memory_layout_dims_device(1)),
594  coefficient_memory_layout_dims_device(0), coefficient_memory_layout_dims_device(1));
595 
596  teamMember.team_barrier();
597 
598 
599  const double previous_value = output_data_block_column(target_index, j);
600 
601  // loops over neighbors of target_index
602  double gmls_value = 0;
603  Kokkos::parallel_reduce(Kokkos::TeamThreadRange(teamMember, nla.getNumberOfNeighborsDevice(target_index)), [=](const int i, double& t_value) {
604  const double neighbor_varying_pre_T = (weight_with_pre_T && vary_on_neighbor) ?
605  prestencil_weights(0, target_index, i, pre_transform_local_index, pre_transform_global_index)
606  : 1.0;
607 
608  t_value += neighbor_varying_pre_T * sampling_data_single_column(nla.getNeighborDevice(target_index, i))
609  *Coeffs(j, i+input_component_axis_1*nla.getNumberOfNeighborsDevice(target_index));
610 
611  }, gmls_value );
612 
613  // data contract for sampling functional
614  double pre_T = 1.0;
615  if (weight_with_pre_T) {
616  if (!vary_on_neighbor && vary_on_target) {
617  pre_T = prestencil_weights(0, target_index, 0, pre_transform_local_index,
618  pre_transform_global_index);
619  } else if (!vary_on_target) { // doesn't vary on target or neighbor
620  pre_T = prestencil_weights(0, 0, 0, pre_transform_local_index,
621  pre_transform_global_index);
622  }
623  }
624 
625  double staggered_value_from_targets = 0;
626  double pre_T_staggered = 1.0;
627  // loops over target_index for each neighbor for staggered approaches
628  if (target_plus_neighbor_staggered_schema) {
629  Kokkos::parallel_reduce(Kokkos::TeamThreadRange(teamMember, nla.getNumberOfNeighborsDevice(target_index)), [=](const int i, double& t_value) {
630  const double neighbor_varying_pre_T_staggered = (weight_with_pre_T && vary_on_neighbor) ?
631  prestencil_weights(1, target_index, i, pre_transform_local_index, pre_transform_global_index)
632  : 1.0;
633 
634  t_value += neighbor_varying_pre_T_staggered * sampling_data_single_column(nla.getNeighborDevice(target_index, 0))
635  *Coeffs(j, i+input_component_axis_1*nla.getNumberOfNeighborsDevice(target_index));
636 
637  }, staggered_value_from_targets );
638 
639  // for staggered approaches that transform source data for the target and neighbors
640  if (weight_with_pre_T) {
641  if (!vary_on_neighbor && vary_on_target) {
642  pre_T_staggered = prestencil_weights(1, target_index, 0, pre_transform_local_index,
643  pre_transform_global_index);
644  } else if (!vary_on_target) { // doesn't vary on target or neighbor
645  pre_T_staggered = prestencil_weights(1, 0, 0, pre_transform_local_index,
646  pre_transform_global_index);
647  }
648  }
649  }
650 
651  double added_value = (pre_T*gmls_value + pre_T_staggered*staggered_value_from_targets);
652  Kokkos::single(Kokkos::PerTeam(teamMember), [=] () {
653  output_data_block_column(target_index, j) = previous_value + added_value;
654  });
655  });
656  Kokkos::fence();
657  }
658  }
659 
660  //! Generation of polynomial reconstruction coefficients by applying to data in GMLS (allocates memory for output)
661  //!
662  //! Polynomial reconstruction coefficients exist for each target, but there are coefficients for each neighbor (a basis for all potentional input data). This function uses a particular choice of data to contract over this basis and return the polynomial reconstructions coefficients specific to this data.
663  //!
664  //! Produces a Kokkos View as output with a Kokkos memory_space provided as a template tag by the caller.
665  //! The data type (double* or double**) must also be specified as a template type if one wish to get a 1D
666  //! Kokkos View back that can be indexed into with only one ordinal.
667  //!
668  //! Assumptions on input data:
669  //! \param sampling_data [in] - 1D or 2D Kokkos View that has the layout #targets * columns of data. Memory space for data can be host or device.
670  //! \param sro [in] - Sampling functional from the SamplingFunctional enum
671  //! \param scalar_as_vector_if_needed [in] - If a 1D view is given, where a 2D view is expected (scalar values given where a vector was expected), then the scalar will be repeated for as many components as the vector has
672  template <typename output_data_type = double**, typename output_memory_space, typename view_type_input_data, typename output_array_layout = typename view_type_input_data::array_layout>
673  Kokkos::View<output_data_type, output_array_layout, output_memory_space> // shares layout of input by default
674  applyFullPolynomialCoefficientsBasisToDataAllComponents(view_type_input_data sampling_data, bool scalar_as_vector_if_needed = true) const {
675 
676  auto output_dimension_of_reconstruction_space = _gmls->calculateBasisMultiplier(_gmls->getReconstructionSpace());
677  auto coefficient_matrix_dims = _gmls->getPolynomialCoefficientsDomainRangeSize();
678 
679  // gather needed information for evaluation
680  auto nla = *(_gmls->getNeighborLists());
681 
682  // determines the number of columns needed for output
683  int output_dimensions = output_dimension_of_reconstruction_space;
684 
685  typedef Kokkos::View<output_data_type, output_array_layout, output_memory_space> output_view_type;
686  // create view on whatever memory space the user specified with their template argument when calling this function
687  output_view_type coefficient_output("output coefficients", nla.getNumberOfTargets(),
688  output_dimensions*_gmls->getPolynomialCoefficientsSize() /* number of coefficients */);
689 
690  applyFullPolynomialCoefficientsBasisToDataAllComponents(coefficient_output, sampling_data, scalar_as_vector_if_needed);
691 
692  return coefficient_output;
693 
694  }
695 
696  //! Generation of polynomial reconstruction coefficients by applying to data in GMLS (does not allocate memory for output)
697  //!
698  //! Polynomial reconstruction coefficients exist for each target, but there are coefficients for each neighbor (a basis for all potentional input data). This function uses a particular choice of data to contract over this basis and return the polynomial reconstructions coefficients specific to this data.
699  //!
700  //! Produces a Kokkos View as output with a Kokkos memory_space provided as a template tag by the caller.
701  //! The data type (double* or double**) must also be specified as a template type if one wish to get a 1D
702  //! Kokkos View back that can be indexed into with only one ordinal.
703  //!
704  //! Assumptions on input data:
705  //! \param coefficient_output [in] - 1D or 2D Kokkos View that has the layout #targets * #coefficients. Memory space for data can be host or device.
706  //! \param sampling_data [in] - 1D or 2D Kokkos View that has the layout #targets * columns of data. Memory space for data can be host or device.
707  //! \param sro [in] - Sampling functional from the SamplingFunctional enum
708  //! \param scalar_as_vector_if_needed [in] - If a 1D view is given, where a 2D view is expected (scalar values given where a vector was expected), then the scalar will be repeated for as many components as the vector has
709  template <typename view_type_coefficient_output, typename view_type_input_data>
710  void applyFullPolynomialCoefficientsBasisToDataAllComponents(view_type_coefficient_output coefficient_output,
711  view_type_input_data sampling_data, bool scalar_as_vector_if_needed = true) const {
712 
713  // output can be device or host
714  // input can be device or host
715  // move everything to device and calculate there, then move back to host if necessary
716 
717  auto global_dimensions = _gmls->getGlobalDimensions();
718  auto output_dimension_of_reconstruction_space = _gmls->calculateBasisMultiplier(_gmls->getReconstructionSpace());
719  auto input_dimension_of_reconstruction_space = _gmls->calculateSamplingMultiplier(_gmls->getReconstructionSpace(), _gmls->getPolynomialSamplingFunctional());
720  auto coefficient_matrix_dims = _gmls->getPolynomialCoefficientsDomainRangeSize();
721 
722  // gather needed information for evaluation
723  auto nla = *(_gmls->getNeighborLists());
724 
726 
727  compadre_assert_debug(coefficient_output.extent(0)==(size_t)nla.getNumberOfTargets()
728  && "First dimension of coefficient_output is incorrect size.\n");
729  // determines the number of columns needed for output
731  coefficient_output.extent(1)==(size_t)output_dimension_of_reconstruction_space*_gmls->getPolynomialCoefficientsSize()
732  /* number of coefficients */ && "Second dimension of coefficient_output is incorrect size.\n");
733 
734  // make sure input and output columns make sense under the target operation
735  compadre_assert_debug(((output_dimension_of_reconstruction_space==1 && view_type_coefficient_output::rank==1) || view_type_coefficient_output::rank!=1) &&
736  "Output view is requested as rank 1, but the target requires a rank larger than 1. Try double** as template argument.");
737 
738  // we need to specialize a template on the rank of the output view type and the input view type
739  auto sampling_subview_maker = CreateNDSliceOnDeviceView(sampling_data, scalar_as_vector_if_needed);
740  auto output_subview_maker = CreateNDSliceOnDeviceView(coefficient_output, false); // output will always be the correct dimension
741 
742  // figure out preprocessing and postprocessing
743  auto prestencil_weights = _gmls->getPrestencilWeights();
744 
745  // all loop logic based on transforming data under a sampling functional
746  // into something that is valid input for GMLS
747  bool vary_on_target = false, vary_on_neighbor = false;
748  auto sro_style = sro.transform_type;
749  bool loop_global_dimensions = sro.input_rank>0 && sro_style!=Identity;
750 
751 
752  if (sro.transform_type == Identity || sro.transform_type == SameForAll) {
753  vary_on_target = false;
754  vary_on_neighbor = false;
755  } else if (sro.transform_type == DifferentEachTarget) {
756  vary_on_target = true;
757  vary_on_neighbor = false;
758  } else if (sro.transform_type == DifferentEachNeighbor) {
759  vary_on_target = true;
760  vary_on_neighbor = true;
761  }
762 
763  // written for up to rank 1 to rank 0 (in / out)
764  // loop over components of output of the target operation
765  for (int i=0; i<output_dimension_of_reconstruction_space; ++i) {
766  const int output_component_axis_1 = i;
767  const int output_component_axis_2 = 0;
768  // loop over components of input of the target operation
769  for (int j=0; j<input_dimension_of_reconstruction_space; ++j) {
770  const int input_component_axis_1 = j;
771  const int input_component_axis_2 = 0;
772 
773  if (loop_global_dimensions) {
774  for (int k=0; k<global_dimensions; ++k) { // loop for handling sampling functional
776  output_subview_maker.get2DView(i,_gmls->getPolynomialCoefficientsSize()),
777  sampling_subview_maker.get1DView(k), sro,
778  output_component_axis_1, output_component_axis_2, input_component_axis_1,
779  input_component_axis_2, j, k, -1, -1,
780  vary_on_target, vary_on_neighbor);
781  }
782  } else if (sro_style != Identity) {
784  output_subview_maker.get2DView(i,_gmls->getPolynomialCoefficientsSize()),
785  sampling_subview_maker.get1DView(j), sro,
786  output_component_axis_1, output_component_axis_2, input_component_axis_1,
787  input_component_axis_2, 0, 0, -1, -1,
788  vary_on_target, vary_on_neighbor);
789  } else { // standard
791  output_subview_maker.get2DView(i,_gmls->getPolynomialCoefficientsSize()),
792  sampling_subview_maker.get1DView(j), sro,
793  output_component_axis_1, output_component_axis_2, input_component_axis_1,
794  input_component_axis_2);
795  }
796  }
797  }
798 
799  // copy back to whatever memory space the user requester through templating from the device
800  Kokkos::deep_copy(coefficient_output, output_subview_maker.copyToAndReturnOriginalView());
801  }
802 
803 }; // Evaluator
804 
805 } // Compadre
806 
807 #endif
decltype(_RHS) getFullPolynomialCoefficientsBasis() const
Get a view (device) of all polynomial coefficients basis.
ProblemType getProblemType()
Get problem type.
auto get2DView(const int column_num, const int block_size) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL, Kokkos::make_pair(column_num *block_size,(column_num+1) *block_size)))
Lightweight Evaluator Helper This class is a lightweight wrapper for extracting and applying all rele...
constexpr SamplingFunctional ManifoldVectorPointSample
Point evaluations of the entire vector source function (but on a manifold, so it includes a transform...
team_policy::member_type member_type
void applyAlphasToDataAllComponentsAllTargetSites(view_type_output_data target_output, view_type_output_data ambient_target_output, view_type_input_data sampling_data, TargetOperation lro, const SamplingFunctional sro_in=PointSample, bool scalar_as_vector_if_needed=true, const int evaluation_site_local_index=0) const
Transformation of data under GMLS (does not allocate memory for output)
Each target applies a different data transform, but the same to each neighbor.
Each target applies a different transform for each neighbor.
bool use_target_site_weights
Whether or not the SamplingTensor acts on the target site as well as the neighbors.
Solve GMLS problem on a manifold (will use QR or SVD to solve the resultant GMLS problem dependent on...
SamplingFunctional getPolynomialSamplingFunctional() const
Get the polynomial sampling functional specified at instantiation.
constexpr int TargetOutputTensorRank[]
Rank of target functional output for each TargetOperation Rank of target functional input for each Ta...
void applyFullPolynomialCoefficientsBasisToDataAllComponents(view_type_coefficient_output coefficient_output, view_type_input_data sampling_data, bool scalar_as_vector_if_needed=true) const
Generation of polynomial reconstruction coefficients by applying to data in GMLS (does not allocate m...
Kokkos::TeamPolicy< device_execution_space > team_policy
int calculateBasisMultiplier(const ReconstructionSpace rs) const
Calculate basis_multiplier.
decltype(_alphas) getAlphas() const
Get a view (device) of all alphas.
auto get1DView(const int column_num) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL))
#define TO_GLOBAL(variable)
device_execution_space::memory_space device_memory_space
int input_rank
Rank of sampling functional input for each SamplingFunctional.
SamplingFunctional getDataSamplingFunctional() const
Get the data sampling functional specified at instantiation (often the same as the polynomial samplin...
Kokkos::View< output_data_type, output_array_layout, output_memory_space > applyAlphasToDataAllComponentsAllTargetSites(view_type_input_data sampling_data, TargetOperation lro, const SamplingFunctional sro_in=PointSample, bool scalar_as_vector_if_needed=true, const int evaluation_site_local_index=0) const
Transformation of data under GMLS (allocates memory for output)
typename std::enable_if< B, T >::type enable_if_t
auto get1DView(const int column_num) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL, column_num))
decltype(_T) getTangentDirections() const
Get a view (device) of all tangent direction bundles.
host_managed_local_index_type getPolynomialCoefficientsMemorySize() const
Returns 2D array size in memory on which coefficients are stored.
Kokkos::View< double **, layout_right, Kokkos::MemoryTraits< Kokkos::Unmanaged > > scratch_matrix_right_type
Each neighbor for each target all apply the same transform.
int getAlphaColumnOffset(TargetOperation lro, const int output_component_axis_1, const int output_component_axis_2, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_local_index=0) const
Retrieves the offset for an operator based on input and output component, generic to row (but still m...
SubviewND(T data_in, T2 data_original_view, bool scalar_as_vector_if_needed)
auto CreateNDSliceOnDeviceView(T sampling_input_data_host_or_device, bool scalar_as_vector_if_needed) -> SubviewND< decltype(Kokkos::create_mirror_view(device_memory_space(), sampling_input_data_host_or_device)), T >
Copies data_in to the device, and then allows for access to 1D columns of data on device...
global_index_type getAlphaIndexHost(const int target_index, const int alpha_column_offset) const
Gives index into alphas given two axes, which when incremented by the neighbor number transforms acce...
Kokkos::View< output_data_type, output_array_layout, output_memory_space > applyFullPolynomialCoefficientsBasisToDataAllComponents(view_type_input_data sampling_data, bool scalar_as_vector_if_needed=true) const
Generation of polynomial reconstruction coefficients by applying to data in GMLS (allocates memory fo...
int getOutputDimensionOfOperation(TargetOperation lro, bool ambient=false) const
Dimensions ^ output rank for target operation.
auto get2DView(const int column_num, const int block_size) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL))
SubviewND(T data_in, T2 data_original_view, bool scalar_as_vector_if_needed)
host_managed_local_index_type getPolynomialCoefficientsDomainRangeSize() const
Returns (size of the basis used in instance&#39;s polynomial reconstruction) x (data input dimension) ...
int getPolynomialCoefficientsSize() const
Returns size of the basis used in instance&#39;s polynomial reconstruction.
Generalized Moving Least Squares (GMLS)
No action performed on data before GMLS target operation.
int getInputDimensionOfOperation(TargetOperation lro) const
Dimensions ^ input rank for target operation (always in local chart if on a manifold, never ambient space)
double applyAlphasToDataSingleComponentSingleTargetSite(view_type_data sampling_input_data, const int column_of_input, TargetOperation lro, const int target_index, const int evaluation_site_local_index, const int output_component_axis_1, const int output_component_axis_2, const int input_component_axis_1, const int input_component_axis_2, bool scalar_as_vector_if_needed=true) const
Dot product of alphas with sampling data, FOR A SINGLE target_index, where sampling data is in a 1D/2...
ReconstructionSpace getReconstructionSpace() const
Get the reconstruction space specified at instantiation.
int transform_type
Describes the SamplingFunction relationship to targets, neighbors.
constexpr SamplingFunctional PointSample
Available sampling functionals.
decltype(_neighbor_lists) * getNeighborLists()
Get neighbor list accessor.
#define compadre_assert_debug(condition)
compadre_assert_debug is used for assertions that are checked in loops, as these significantly impact...
void applyFullPolynomialCoefficientsBasisToDataSingleComponent(view_type_data_out output_data_block_column, view_type_data_in sampling_data_single_column, const SamplingFunctional sro, const int output_component_axis_1, const int output_component_axis_2, const int input_component_axis_1, const int input_component_axis_2, const int pre_transform_local_index=-1, const int pre_transform_global_index=-1, const int post_transform_local_index=-1, const int post_transform_global_index=-1, bool vary_on_target=false, bool vary_on_neighbor=false) const
Dot product of data with full polynomial coefficient basis where sampling data is in a 1D/2D Kokkos V...
int getGlobalDimensions() const
Dimension of the GMLS problem&#39;s point data (spatial description of points in ambient space)...
int calculateSamplingMultiplier(const ReconstructionSpace rs, const SamplingFunctional sro) const
Calculate sampling_multiplier.
#define compadre_assert_release(condition)
compadre_assert_release is used for assertions that should always be checked, but generally are not e...
Creates 1D subviews of data from a 2D view, generally constructed with CreateNDSliceOnDeviceView.
decltype(_prestencil_weights) getPrestencilWeights() const
Get a view (device) of all rank 2 preprocessing tensors This is a rank 5 tensor that is able to provi...
constexpr SamplingFunctional VectorPointSample
Point evaluations of the entire vector source function.
void applyAlphasToDataSingleComponentAllTargetSitesWithPreAndPostTransform(view_type_data_out output_data_single_column, view_type_data_in sampling_data_single_column, TargetOperation lro, const SamplingFunctional sro, const int evaluation_site_local_index, const int output_component_axis_1, const int output_component_axis_2, const int input_component_axis_1, const int input_component_axis_2, const int pre_transform_local_index=-1, const int pre_transform_global_index=-1, const int post_transform_local_index=-1, const int post_transform_global_index=-1, bool vary_on_target=false, bool vary_on_neighbor=false) const
Dot product of alphas with sampling data where sampling data is in a 1D/2D Kokkos View and output vie...
TargetOperation
Available target functionals.
void applyLocalChartToAmbientSpaceTransform(view_type_data_out output_data_single_column, view_type_data_in sampling_data_single_column, const int local_dim_index, const int global_dim_index) const
Postprocessing for manifolds.