Compadre 1.5.5
Loading...
Searching...
No Matches
Compadre_Evaluator.hpp
Go to the documentation of this file.
1#ifndef _COMPADRE_EVALUATOR_HPP_
2#define _COMPADRE_EVALUATOR_HPP_
3
5#include "Compadre_GMLS.hpp"
7
8namespace Compadre {
9
10//! Creates 1D subviews of data from a 2D view, generally constructed with CreateNDSliceOnDeviceView
11template<typename T, typename T2, typename T3=void>
12struct 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();
53 }
54
55};
56
57//! Creates 1D subviews of data from a 1D view, generally constructed with CreateNDSliceOnDeviceView
58template<typename T, typename T2>
59struct 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();
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.
97template <typename T>
98auto 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)
116
117private:
118
120
121
122public:
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->_h_ss.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->getSolutionSetDevice()->getAlphas();
161 auto sampling_data_device = sampling_subview_maker.get1DView(column_of_input);
162
163 auto alpha_index = _gmls->_h_ss.getAlphaIndex(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_local_index [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->_h_ss.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 nla = *(_gmls->getNeighborLists());
213 auto solution_set = *(_gmls->getSolutionSetDevice());
214 compadre_assert_release(solution_set._contains_valid_alphas &&
215 "application of alphas called before generateAlphas() was called.");
216 auto prestencil_weights = _gmls->getPrestencilWeights();
217
218 const int num_targets = nla.getNumberOfTargets();
219
220 // make sure input and output views have same memory space
221 compadre_assert_debug((std::is_same<typename view_type_data_out::memory_space, typename view_type_data_in::memory_space>::value) &&
222 "output_data_single_column view and input_data_single_column view have difference memory spaces.");
223
224 bool weight_with_pre_T = (pre_transform_local_index>=0 && pre_transform_global_index>=0) ? true : false;
225 bool target_plus_neighbor_staggered_schema = sro.use_target_site_weights;
226
227 // loops over target indices
228 Kokkos::parallel_for(team_policy(num_targets, Kokkos::AUTO),
229 KOKKOS_LAMBDA(const member_type& teamMember) {
230
231 const int target_index = teamMember.league_rank();
232 teamMember.team_barrier();
233
234
235 const double previous_value = output_data_single_column(target_index);
236
237 // loops over neighbors of target_index
238 auto alpha_index = solution_set.getAlphaIndex(target_index, alpha_input_output_component_index);
239 double gmls_value = 0;
240 Kokkos::parallel_reduce(Kokkos::TeamThreadRange(teamMember, nla.getNumberOfNeighborsDevice(target_index)), [&](const int i, double& t_value) {
241 const double neighbor_varying_pre_T = (weight_with_pre_T && vary_on_neighbor) ?
242 prestencil_weights(0, target_index, i, pre_transform_local_index, pre_transform_global_index)
243 : 1.0;
244
245 t_value += neighbor_varying_pre_T * sampling_data_single_column(nla.getNeighborDevice(target_index, i))
246 *solution_set._alphas(alpha_index + i);
247
248 }, gmls_value );
249
250 // data contract for sampling functional
251 double pre_T = 1.0;
252 if (weight_with_pre_T) {
253 if (!vary_on_neighbor && vary_on_target) {
254 pre_T = prestencil_weights(0, target_index, 0, pre_transform_local_index,
255 pre_transform_global_index);
256 } else if (!vary_on_target) { // doesn't vary on target or neighbor
257 pre_T = prestencil_weights(0, 0, 0, pre_transform_local_index,
258 pre_transform_global_index);
259 }
260 }
261
262 double staggered_value_from_targets = 0;
263 double pre_T_staggered = 1.0;
264 auto alpha_index2 = solution_set.getAlphaIndex(target_index, alpha_input_output_component_index2);
265 // loops over target_index for each neighbor for staggered approaches
266 if (target_plus_neighbor_staggered_schema) {
267 Kokkos::parallel_reduce(Kokkos::TeamThreadRange(teamMember, nla.getNumberOfNeighborsDevice(target_index)), [&](const int i, double& t_value) {
268 const double neighbor_varying_pre_T_staggered = (weight_with_pre_T && vary_on_neighbor) ?
269 prestencil_weights(1, target_index, i, pre_transform_local_index, pre_transform_global_index)
270 : 1.0;
271
272 t_value += neighbor_varying_pre_T_staggered * sampling_data_single_column(nla.getNeighborDevice(target_index, 0))
273 *solution_set._alphas(alpha_index2 + i);
274
275 }, staggered_value_from_targets );
276
277 // for staggered approaches that transform source data for the target and neighbors
278 if (weight_with_pre_T) {
279 if (!vary_on_neighbor && vary_on_target) {
280 pre_T_staggered = prestencil_weights(1, target_index, 0, pre_transform_local_index,
281 pre_transform_global_index);
282 } else if (!vary_on_target) { // doesn't vary on target or neighbor
283 pre_T_staggered = prestencil_weights(1, 0, 0, pre_transform_local_index,
284 pre_transform_global_index);
285 }
286 }
287 }
288
289 double added_value = pre_T*gmls_value + pre_T_staggered*staggered_value_from_targets;
290 Kokkos::single(Kokkos::PerTeam(teamMember), [&] () {
291 output_data_single_column(target_index) = previous_value + added_value;
292 });
293 });
294 Kokkos::fence();
295 }
296
297 //! Postprocessing for manifolds. Maps local chart vector solutions to ambient space.
298 //! THE SAMPLING DATA and OUTPUT VIEW MUST BE ON THE DEVICE!
299 //!
300 //! Only supports one output component / input component at a time. The user will need to loop over the output
301 //! components in order to transform a vector target.
302 //!
303 //! Assumptions on input data:
304 //! \param output_data_single_column [out] - 1D Kokkos View (memory space must be device_memory_space())
305 //! \param sampling_data_single_column [in] - 1D Kokkos View (memory space must match output_data_single_column)
306 //! \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
307 //! \param global_dim_index [in] - For manifold problems, this is the global coordinate direction that sampling data can be represented in
308 template <typename view_type_data_out, typename view_type_data_in>
309 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 {
310
311 // Does T transpose times a vector
312 auto global_dimensions = _gmls->getGlobalDimensions();
313
314 // gather needed information for evaluation
315 auto nla = *(_gmls->getNeighborLists());
316 const int num_targets = nla.getNumberOfTargets();
317
318 auto tangent_directions = *(_gmls->getTangentDirections());
319
320 // make sure input and output views have same memory space
321 compadre_assert_debug((std::is_same<typename view_type_data_out::memory_space, typename view_type_data_in::memory_space>::value) &&
322 "output_data_single_column view and input_data_single_column view have difference memory spaces.");
323
324 // loops over target indices
325 Kokkos::parallel_for(team_policy(num_targets, Kokkos::AUTO),
326 KOKKOS_LAMBDA(const member_type& teamMember) {
327
328 const int target_index = teamMember.league_rank();
329
331 (tangent_directions.data() + TO_GLOBAL(target_index)*TO_GLOBAL(global_dimensions)*TO_GLOBAL(global_dimensions),
332 global_dimensions, global_dimensions);
333 teamMember.team_barrier();
334
335
336 const double previous_value = output_data_single_column(target_index);
337
338 double added_value = T(local_dim_index, global_dim_index)*sampling_data_single_column(target_index);
339 Kokkos::single(Kokkos::PerTeam(teamMember), [&] () {
340 output_data_single_column(target_index) = previous_value + added_value;
341 });
342 });
343 Kokkos::fence();
344 }
345
346 //! Transformation of data under GMLS (allocates memory for output)
347 //!
348 //! 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.
349 //!
350 //! Produces a Kokkos View as output with a Kokkos memory_space provided as a template tag by the caller.
351 //! The data type (double* or double**) must also be specified as a template type if one wish to get a 1D
352 //! Kokkos View back that can be indexed into with only one ordinal.
353 //!
354 //! Assumptions on input data:
355 //! \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.
356 //! \param lro [in] - Target operation from the TargetOperation enum
357 //! \param sro_in [in] - Sampling functional from the SamplingFunctional enum
358 //! \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
359 //! \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
360 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>
361 Kokkos::View<output_data_type, output_array_layout, output_memory_space> // shares layout of input by default
362 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 {
363 // gather needed information for evaluation
364 auto nla = *(_gmls->getNeighborLists());
365
366 // determines the number of columns needed for output after action of the target functional
367 auto local_dimensions = _gmls->getLocalDimensions();
368 auto global_dimensions = _gmls->getGlobalDimensions();
369 int output_dimensions = getOutputDimensionOfOperation(lro, local_dimensions);
370 auto problem_type = _gmls->getProblemType();
371
372 typedef Kokkos::View<output_data_type, output_array_layout, output_memory_space> output_view_type;
373 // create view on whatever memory space the user specified with their template argument when calling this function
374 output_view_type target_output = createView<output_view_type>("output of target operation",
375 nla.getNumberOfTargets(), output_dimensions);
376
377 output_view_type ambient_target_output;
378 bool transform_gmls_output_to_ambient = (problem_type==MANIFOLD && getTargetOutputTensorRank(lro)==1);
379 if (transform_gmls_output_to_ambient) {
380 ambient_target_output = createView<output_view_type>("output of transform to ambient space",
381 nla.getNumberOfTargets(), global_dimensions);
382 }
383
384 applyAlphasToDataAllComponentsAllTargetSites(target_output, ambient_target_output, sampling_data, lro, sro_in, scalar_as_vector_if_needed, evaluation_site_local_index);
385
386 if (transform_gmls_output_to_ambient) {
387 return ambient_target_output;
388 } else {
389 return target_output;
390 }
391
392 }
393
394 //! Transformation of data under GMLS (does not allocate memory for output)
395 //!
396 //! 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.
397 //!
398 //! Fills a Kokkos View of output.
399 //!
400 //! Assumptions on input data:
401 //! \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.
402 //! \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)
403 //! \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.
404 //! \param lro [in] - Target operation from the TargetOperation enum
405 //! \param sro_in [in] - Sampling functional from the SamplingFunctional enum
406 //! \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
407 //! \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
408 template <typename view_type_output_data, typename view_type_input_data, typename output_array_layout = typename view_type_input_data::array_layout>
409 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 {
410
411
412 // output can be device or host
413 // input can be device or host
414 // move everything to device and calculate there, then move back to host if necessary
415
416
417 auto problem_type = _gmls->getProblemType();
418 auto global_dimensions = _gmls->getGlobalDimensions();
419 auto local_dimensions = _gmls->getLocalDimensions();
420 int output_dimension1_of_operator = (getTargetOutputTensorRank(lro)<2) ? getOutputDimensionOfOperation(lro, local_dimensions) : std::sqrt(getOutputDimensionOfOperation(lro, local_dimensions));
421 int output_dimension2_of_operator = (getTargetOutputTensorRank(lro)<2) ? 1 : std::sqrt(getOutputDimensionOfOperation(lro, local_dimensions));
422
423 // gather needed information for evaluation
424 auto nla = *(_gmls->getNeighborLists());
425
426 // determines the number of columns needed for output after action of the target functional
427 int output_dimensions = getOutputDimensionOfOperation(lro, local_dimensions);
428
429 // special case for VectorPointSample, because if it is on a manifold it includes data transform to local charts
430 auto sro = (problem_type==MANIFOLD && sro_in==VectorPointSample) ? ManifoldVectorPointSample : sro_in;
431 int input_dimension_of_operator = getInputDimensionOfOperation(lro, _gmls->_data_sampling_functional, local_dimensions);
432
433 compadre_assert_debug(target_output.extent(0)==(size_t)nla.getNumberOfTargets()
434 && "First dimension of target_output is incorrect size.\n");
435 compadre_assert_debug(target_output.extent(1)==(size_t)output_dimensions
436 && "Second dimension of target_output is incorrect size.\n");
437
438 // make sure input and output columns make sense under the target operation
439 compadre_assert_debug(((output_dimensions==1 && view_type_output_data::rank==1) || view_type_output_data::rank!=1) &&
440 "Output view is requested as rank 1, but the target requires a rank larger than 1. Try double** as template argument.");
441
442 // we need to specialize a template on the rank of the output view type and the input view type
443 auto sampling_subview_maker = CreateNDSliceOnDeviceView(sampling_data, scalar_as_vector_if_needed);
444 auto output_subview_maker = CreateNDSliceOnDeviceView(target_output, false); // output will always be the correct dimension
445
446 // figure out preprocessing and postprocessing
447 auto prestencil_weights = _gmls->getPrestencilWeights();
448
449 // all loop logic based on transforming data under a sampling functional
450 // into something that is valid input for GMLS
451 bool vary_on_target = false, vary_on_neighbor = false;
452 auto sro_style = sro.transform_type;
453 bool loop_global_dimensions = sro.input_rank>0 && sro_style!=Identity;
454
456 && "SamplingFunctional requested for Evaluator does not match GMLS data sampling functional or is not of type 'Identity'.");
457
458 if (sro.transform_type == Identity || sro.transform_type == SameForAll) {
459 vary_on_target = false;
460 vary_on_neighbor = false;
461 } else if (sro.transform_type == DifferentEachTarget) {
462 vary_on_target = true;
463 vary_on_neighbor = false;
464 } else if (sro.transform_type == DifferentEachNeighbor) {
465 vary_on_target = true;
466 vary_on_neighbor = true;
467 }
468
469
470 // only written for up to rank 1 to rank 2 (in / out)
471 // loop over components of output of the target operation
472 for (int axes1=0; axes1<output_dimension1_of_operator; ++axes1) {
473 const int output_component_axis_1 = axes1;
474 for (int axes2=0; axes2<output_dimension2_of_operator; ++axes2) {
475 const int output_component_axis_2 = axes2;
476 // loop over components of input of the target operation
477 for (int j=0; j<input_dimension_of_operator; ++j) {
478 const int input_component_axis_1 = j;
479 const int input_component_axis_2 = 0;
480
481 if (loop_global_dimensions) {
482 for (int k=0; k<global_dimensions; ++k) { // loop for handling sampling functional
484 output_subview_maker.get1DView(axes1*output_dimension2_of_operator+axes2),
485 sampling_subview_maker.get1DView(k), lro, sro,
486 evaluation_site_local_index, output_component_axis_1, output_component_axis_2, input_component_axis_1,
487 input_component_axis_2, j, k, -1, -1,
488 vary_on_target, vary_on_neighbor);
489 }
490 } else if (sro_style != Identity) {
492 output_subview_maker.get1DView(axes1*output_dimension2_of_operator+axes2),
493 sampling_subview_maker.get1DView(j), lro, sro,
494 evaluation_site_local_index, output_component_axis_1, output_component_axis_2, input_component_axis_1,
495 input_component_axis_2, 0, 0, -1, -1,
496 vary_on_target, vary_on_neighbor);
497 } else { // standard
499 output_subview_maker.get1DView(axes1*output_dimension2_of_operator+axes2),
500 sampling_subview_maker.get1DView(j), lro, sro,
501 evaluation_site_local_index, output_component_axis_1, output_component_axis_2, input_component_axis_1,
502 input_component_axis_2);
503 }
504 }
505 }
506 }
507
508 bool transform_gmls_output_to_ambient = (problem_type==MANIFOLD && getTargetOutputTensorRank(lro)==1);
509 if (transform_gmls_output_to_ambient) {
510 Kokkos::fence();
511
512 compadre_assert_debug(ambient_target_output.extent(0)==(size_t)nla.getNumberOfTargets()
513 && "First dimension of target_output is incorrect size.\n");
514 compadre_assert_debug(ambient_target_output.extent(1)==(size_t)global_dimensions
515 && "Second dimension of target_output is incorrect size.\n");
516 auto transformed_output_subview_maker = CreateNDSliceOnDeviceView(ambient_target_output, false);
517 // output will always be the correct dimension
518 for (int i=0; i<global_dimensions; ++i) {
519 for (int j=0; j<output_dimensions; ++j) {
521 transformed_output_subview_maker.get1DView(i), output_subview_maker.get1DView(j), j, i);
522 }
523 }
524 // copy back to whatever memory space the user requester through templating from the device
525 Kokkos::deep_copy(ambient_target_output, transformed_output_subview_maker.copyToAndReturnOriginalView());
526 }
527
528 // copy back to whatever memory space the user requester through templating from the device
529 Kokkos::deep_copy(target_output, output_subview_maker.copyToAndReturnOriginalView());
530 }
531
532
533 //! Dot product of data with full polynomial coefficient basis where sampling data is in a 1D/2D Kokkos View and output view is also
534 //! a 1D/2D Kokkos View, however THE SAMPLING DATA and OUTPUT VIEW MUST BE ON THE DEVICE!
535 //!
536 //! This function is to be used when the polynomial coefficient basis has already been calculated and stored for use.
537 //!
538 //! Only supports one output component / input component at a time. The user will need to loop over the output
539 //! components in order to fill a vector target or matrix target.
540 //!
541 //! Assumptions on input data:
542 //! \param output_data_block_column [out] - 2D Kokkos View (memory space must be device_memory_space())
543 //! \param sampling_data_single_column [in] - 1D Kokkos View (memory space must match output_data_single_column)
544 //! \param sro [in] - Sampling functional from the SamplingFunctional enum
545 //! \param target_index [in] - Target # user wants to reconstruct target functional at, corresponds to row number of neighbor_lists
546 //! \param output_component_axis_1 [in] - Row for a rank 2 tensor or rank 1 tensor, 0 for a scalar output
547 //! \param output_component_axis_2 [in] - Columns for a rank 2 tensor, 0 for rank less than 2 output tensor
548 //! \param input_component_axis_1 [in] - Row for a rank 2 tensor or rank 1 tensor, 0 for a scalar input
549 //! \param input_component_axis_2 [in] - Columns for a rank 2 tensor, 0 for rank less than 2 input tensor
550 //! \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
551 //! \param pre_transform_global_index [in] - For manifold problems, this is the global coordinate direction that sampling data can be represented in
552 //! \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
553 //! \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
554 //! \param vary_on_target [in] - Whether the sampling functional has a tensor to act on sampling data that varies with each target site
555 //! \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
556 template <typename view_type_data_out, typename view_type_data_in>
557 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 {
558
559 auto nla = *(_gmls->getNeighborLists());
560
561 auto coefficient_matrix_dims = _gmls->getPolynomialCoefficientsDomainRangeSize();
562 auto coefficient_memory_layout_dims = _gmls->getPolynomialCoefficientsMemorySize();
563 auto coefficient_memory_layout_dims_device =
564 Kokkos::create_mirror_view_and_copy(device_memory_space(), coefficient_memory_layout_dims);
565
566 auto global_dimensions = _gmls->getGlobalDimensions();
567
568 // gather needed information for evaluation
570 auto tangent_directions = *(_gmls->getTangentDirections());
571 auto prestencil_weights = _gmls->getPrestencilWeights();
572
573 const int num_targets = nla.getNumberOfTargets();
574
575 // make sure input and output views have same memory space
576 compadre_assert_debug((std::is_same<typename view_type_data_out::memory_space, typename view_type_data_in::memory_space>::value) &&
577 "output_data_block_column view and input_data_single_column view have difference memory spaces.");
578
579 bool weight_with_pre_T = (pre_transform_local_index>=0 && pre_transform_global_index>=0) ? true : false;
580 bool target_plus_neighbor_staggered_schema = sro.use_target_site_weights;
581
582 // loops over target indices
583 for (int j=0; j<coefficient_matrix_dims(0); ++j) {
584 Kokkos::parallel_for(team_policy(num_targets, Kokkos::AUTO),
585 KOKKOS_LAMBDA(const member_type& teamMember) {
586
587 const int target_index = teamMember.league_rank();
588
589 scratch_matrix_right_type T (tangent_directions.data()
590 + TO_GLOBAL(target_index)*TO_GLOBAL(global_dimensions)*TO_GLOBAL(global_dimensions),
591 global_dimensions, global_dimensions);
592
594 Coeffs = scratch_matrix_right_type(coeffs.data()
595 + TO_GLOBAL(target_index)*TO_GLOBAL(coefficient_memory_layout_dims_device(0))
596 *TO_GLOBAL(coefficient_memory_layout_dims_device(1)),
597 coefficient_memory_layout_dims_device(0), coefficient_memory_layout_dims_device(1));
598
599 teamMember.team_barrier();
600
601
602 const double previous_value = output_data_block_column(target_index, j);
603
604 // loops over neighbors of target_index
605 double gmls_value = 0;
606 Kokkos::parallel_reduce(Kokkos::TeamThreadRange(teamMember, nla.getNumberOfNeighborsDevice(target_index)), [&](const int i, double& t_value) {
607 const double neighbor_varying_pre_T = (weight_with_pre_T && vary_on_neighbor) ?
608 prestencil_weights(0, target_index, i, pre_transform_local_index, pre_transform_global_index)
609 : 1.0;
610
611 t_value += neighbor_varying_pre_T * sampling_data_single_column(nla.getNeighborDevice(target_index, i))
612 *Coeffs(j, i+input_component_axis_1*nla.getNumberOfNeighborsDevice(target_index));
613
614 }, gmls_value );
615
616 // data contract for sampling functional
617 double pre_T = 1.0;
618 if (weight_with_pre_T) {
619 if (!vary_on_neighbor && vary_on_target) {
620 pre_T = prestencil_weights(0, target_index, 0, pre_transform_local_index,
621 pre_transform_global_index);
622 } else if (!vary_on_target) { // doesn't vary on target or neighbor
623 pre_T = prestencil_weights(0, 0, 0, pre_transform_local_index,
624 pre_transform_global_index);
625 }
626 }
627
628 double staggered_value_from_targets = 0;
629 double pre_T_staggered = 1.0;
630 // loops over target_index for each neighbor for staggered approaches
631 if (target_plus_neighbor_staggered_schema) {
632 Kokkos::parallel_reduce(Kokkos::TeamThreadRange(teamMember, nla.getNumberOfNeighborsDevice(target_index)), [&](const int i, double& t_value) {
633 const double neighbor_varying_pre_T_staggered = (weight_with_pre_T && vary_on_neighbor) ?
634 prestencil_weights(1, target_index, i, pre_transform_local_index, pre_transform_global_index)
635 : 1.0;
636
637 t_value += neighbor_varying_pre_T_staggered * sampling_data_single_column(nla.getNeighborDevice(target_index, 0))
638 *Coeffs(j, i+input_component_axis_1*nla.getNumberOfNeighborsDevice(target_index));
639
640 }, staggered_value_from_targets );
641
642 // for staggered approaches that transform source data for the target and neighbors
643 if (weight_with_pre_T) {
644 if (!vary_on_neighbor && vary_on_target) {
645 pre_T_staggered = prestencil_weights(1, target_index, 0, pre_transform_local_index,
646 pre_transform_global_index);
647 } else if (!vary_on_target) { // doesn't vary on target or neighbor
648 pre_T_staggered = prestencil_weights(1, 0, 0, pre_transform_local_index,
649 pre_transform_global_index);
650 }
651 }
652 }
653
654 double added_value = (pre_T*gmls_value + pre_T_staggered*staggered_value_from_targets);
655 Kokkos::single(Kokkos::PerTeam(teamMember), [&] () {
656 output_data_block_column(target_index, j) = previous_value + added_value;
657 });
658 });
659 Kokkos::fence();
660 }
661 }
662
663 //! Generation of polynomial reconstruction coefficients by applying to data in GMLS (allocates memory for output)
664 //!
665 //! 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.
666 //!
667 //! Produces a Kokkos View as output with a Kokkos memory_space provided as a template tag by the caller.
668 //! The data type (double* or double**) must also be specified as a template type if one wish to get a 1D
669 //! Kokkos View back that can be indexed into with only one ordinal.
670 //!
671 //! Assumptions on input data:
672 //! \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.
673 //! \param sro [in] - Sampling functional from the SamplingFunctional enum
674 //! \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
675 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>
676 Kokkos::View<output_data_type, output_array_layout, output_memory_space> // shares layout of input by default
677 applyFullPolynomialCoefficientsBasisToDataAllComponents(view_type_input_data sampling_data, bool scalar_as_vector_if_needed = true) const {
678
679 auto local_dimensions = _gmls->getLocalDimensions();
680 auto output_dimension_of_reconstruction_space = calculateBasisMultiplier(_gmls->getReconstructionSpace(), local_dimensions);
681 auto coefficient_matrix_dims = _gmls->getPolynomialCoefficientsDomainRangeSize();
682
683 // gather needed information for evaluation
684 auto nla = *(_gmls->getNeighborLists());
685
686 // determines the number of columns needed for output
687 int output_dimensions = output_dimension_of_reconstruction_space;
688
689 typedef Kokkos::View<output_data_type, output_array_layout, output_memory_space> output_view_type;
690 // create view on whatever memory space the user specified with their template argument when calling this function
691 output_view_type coefficient_output("output coefficients", nla.getNumberOfTargets(),
692 output_dimensions*_gmls->getPolynomialCoefficientsSize() /* number of coefficients */);
693
694 applyFullPolynomialCoefficientsBasisToDataAllComponents(coefficient_output, sampling_data, scalar_as_vector_if_needed);
695
696 return coefficient_output;
697
698 }
699
700 //! Generation of polynomial reconstruction coefficients by applying to data in GMLS (does not allocate memory for output)
701 //!
702 //! 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.
703 //!
704 //! Produces a Kokkos View as output with a Kokkos memory_space provided as a template tag by the caller.
705 //! The data type (double* or double**) must also be specified as a template type if one wish to get a 1D
706 //! Kokkos View back that can be indexed into with only one ordinal.
707 //!
708 //! Assumptions on input data:
709 //! \param coefficient_output [in] - 1D or 2D Kokkos View that has the layout #targets * #coefficients. Memory space for data can be host or device.
710 //! \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.
711 //! \param sro [in] - Sampling functional from the SamplingFunctional enum
712 //! \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
713 template <typename view_type_coefficient_output, typename view_type_input_data>
714 void applyFullPolynomialCoefficientsBasisToDataAllComponents(view_type_coefficient_output coefficient_output,
715 view_type_input_data sampling_data, bool scalar_as_vector_if_needed = true) const {
716
717 // output can be device or host
718 // input can be device or host
719 // move everything to device and calculate there, then move back to host if necessary
720
721 auto global_dimensions = _gmls->getGlobalDimensions();
722 auto local_dimensions = _gmls->getLocalDimensions();
723 auto output_dimension_of_reconstruction_space = calculateBasisMultiplier(_gmls->getReconstructionSpace(), local_dimensions);
724 auto input_dimension_of_reconstruction_space = calculateSamplingMultiplier(_gmls->getReconstructionSpace(), _gmls->getPolynomialSamplingFunctional(), local_dimensions);
725 auto coefficient_matrix_dims = _gmls->getPolynomialCoefficientsDomainRangeSize();
726
727 // gather needed information for evaluation
728 auto nla = *(_gmls->getNeighborLists());
729
731
732 compadre_assert_debug(coefficient_output.extent(0)==(size_t)nla.getNumberOfTargets()
733 && "First dimension of coefficient_output is incorrect size.\n");
734 // determines the number of columns needed for output
736 coefficient_output.extent(1)==(size_t)output_dimension_of_reconstruction_space*_gmls->getPolynomialCoefficientsSize()
737 /* number of coefficients */ && "Second dimension of coefficient_output is incorrect size.\n");
738
739 // make sure input and output columns make sense under the target operation
740 compadre_assert_debug(((output_dimension_of_reconstruction_space==1 && view_type_coefficient_output::rank==1) || view_type_coefficient_output::rank!=1) &&
741 "Output view is requested as rank 1, but the target requires a rank larger than 1. Try double** as template argument.");
742
743 // we need to specialize a template on the rank of the output view type and the input view type
744 auto sampling_subview_maker = CreateNDSliceOnDeviceView(sampling_data, scalar_as_vector_if_needed);
745 auto output_subview_maker = CreateNDSliceOnDeviceView(coefficient_output, false); // output will always be the correct dimension
746
747 // figure out preprocessing and postprocessing
748 auto prestencil_weights = _gmls->getPrestencilWeights();
749
750 // all loop logic based on transforming data under a sampling functional
751 // into something that is valid input for GMLS
752 bool vary_on_target = false, vary_on_neighbor = false;
753 auto sro_style = sro.transform_type;
754 bool loop_global_dimensions = sro.input_rank>0 && sro_style!=Identity;
755
756
757 if (sro.transform_type == Identity || sro.transform_type == SameForAll) {
758 vary_on_target = false;
759 vary_on_neighbor = false;
760 } else if (sro.transform_type == DifferentEachTarget) {
761 vary_on_target = true;
762 vary_on_neighbor = false;
763 } else if (sro.transform_type == DifferentEachNeighbor) {
764 vary_on_target = true;
765 vary_on_neighbor = true;
766 }
767
768 // written for up to rank 1 to rank 0 (in / out)
769 // loop over components of output of the target operation
770 for (int i=0; i<output_dimension_of_reconstruction_space; ++i) {
771 const int output_component_axis_1 = i;
772 const int output_component_axis_2 = 0;
773 // loop over components of input of the target operation
774 for (int j=0; j<input_dimension_of_reconstruction_space; ++j) {
775 const int input_component_axis_1 = j;
776 const int input_component_axis_2 = 0;
777
778 if (loop_global_dimensions) {
779 for (int k=0; k<global_dimensions; ++k) { // loop for handling sampling functional
781 output_subview_maker.get2DView(i,_gmls->getPolynomialCoefficientsSize()),
782 sampling_subview_maker.get1DView(k), sro,
783 output_component_axis_1, output_component_axis_2, input_component_axis_1,
784 input_component_axis_2, j, k, -1, -1,
785 vary_on_target, vary_on_neighbor);
786 }
787 } else if (sro_style != Identity) {
789 output_subview_maker.get2DView(i,_gmls->getPolynomialCoefficientsSize()),
790 sampling_subview_maker.get1DView(j), sro,
791 output_component_axis_1, output_component_axis_2, input_component_axis_1,
792 input_component_axis_2, 0, 0, -1, -1,
793 vary_on_target, vary_on_neighbor);
794 } else { // standard
796 output_subview_maker.get2DView(i,_gmls->getPolynomialCoefficientsSize()),
797 sampling_subview_maker.get1DView(j), sro,
798 output_component_axis_1, output_component_axis_2, input_component_axis_1,
799 input_component_axis_2);
800 }
801 }
802 }
803
804 // copy back to whatever memory space the user requester through templating from the device
805 Kokkos::deep_copy(coefficient_output, output_subview_maker.copyToAndReturnOriginalView());
806 }
807
808}; // Evaluator
809
810} // Compadre
811
812#endif
Kokkos::TeamPolicy< device_execution_space > team_policy
typename std::enable_if< B, T >::type enable_if_t
team_policy::member_type member_type
device_execution_space::memory_space device_memory_space
#define compadre_assert_debug(condition)
compadre_assert_debug is used for assertions that are checked in loops, as these significantly impact...
#define TO_GLOBAL(variable)
Kokkos::View< double **, layout_right, Kokkos::MemoryTraits< Kokkos::Unmanaged > > scratch_matrix_right_type
#define compadre_assert_release(condition)
compadre_assert_release is used for assertions that should always be checked, but generally are not e...
Lightweight Evaluator Helper This class is a lightweight wrapper for extracting and applying all rele...
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...
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)
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.
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...
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...
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::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...
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)
Generalized Moving Least Squares (GMLS)
neighbor_lists_type * getNeighborLists() const
Get neighbor list accessor.
host_managed_local_index_type getPolynomialCoefficientsMemorySize() const
Returns 2D array size in memory on which coefficients are stored.
decltype(_RHS) getFullPolynomialCoefficientsBasis() const
Get a view (device) of all polynomial coefficients basis.
int getLocalDimensions() const
Local dimension of the GMLS problem (less than global dimension if on a manifold),...
ReconstructionSpace getReconstructionSpace() const
Get the reconstruction space specified at instantiation.
int getPolynomialCoefficientsSize() const
Returns size of the basis used in instance's polynomial reconstruction.
int getGlobalDimensions() const
Dimension of the GMLS problem's point data (spatial description of points in ambient space),...
decltype(_d_ss) * getSolutionSetDevice(bool alpha_validity_check=true)
Get solution set on device.
SamplingFunctional _data_sampling_functional
generally the same as _polynomial_sampling_functional, but can differ if specified at
SolutionSet< host_memory_space > _h_ss
Solution Set (contains all alpha values from solution and alpha layout methods)
SamplingFunctional getDataSamplingFunctional() const
Get the data sampling functional specified at instantiation (often the same as the polynomial samplin...
decltype(_T) * getTangentDirections()
Get a view (device) of all tangent direction bundles.
SamplingFunctional getPolynomialSamplingFunctional() const
Get the polynomial sampling functional specified at instantiation.
ProblemType getProblemType() const
Get problem type.
host_managed_local_index_type getPolynomialCoefficientsDomainRangeSize() const
Returns (size of the basis used in instance's polynomial reconstruction) x (data input dimension)
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...
@ MANIFOLD
Solve GMLS problem on a manifold (will use QR or SVD to solve the resultant GMLS problem dependent on...
KOKKOS_INLINE_FUNCTION int getTargetOutputTensorRank(const int &index)
Rank of target functional output for each TargetOperation Rank of target functional input for each Ta...
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.
constexpr SamplingFunctional PointSample
Available sampling functionals.
KOKKOS_INLINE_FUNCTION int calculateBasisMultiplier(const ReconstructionSpace rs, const int local_dimensions)
Calculate basis_multiplier.
TargetOperation
Available target functionals.
KOKKOS_INLINE_FUNCTION int calculateSamplingMultiplier(const ReconstructionSpace rs, const SamplingFunctional sro, const int local_dimensions)
Calculate sampling_multiplier.
@ DifferentEachNeighbor
Each target applies a different transform for each neighbor.
@ DifferentEachTarget
Each target applies a different data transform, but the same to each neighbor.
@ SameForAll
Each neighbor for each target all apply the same transform.
@ Identity
No action performed on data before GMLS target operation.
constexpr SamplingFunctional ManifoldVectorPointSample
Point evaluations of the entire vector source function (but on a manifold, so it includes a transform...
KOKKOS_INLINE_FUNCTION int getOutputDimensionOfOperation(TargetOperation lro, const int local_dimensions)
Dimensions ^ output rank for target operation.
constexpr SamplingFunctional VectorPointSample
Point evaluations of the entire vector source function.
KOKKOS_INLINE_FUNCTION int getInputDimensionOfOperation(TargetOperation lro, SamplingFunctional sro, const int local_dimensions)
Dimensions ^ input rank for target operation (always in local chart if on a manifold,...
int transform_type
Describes the SamplingFunction relationship to targets, neighbors.
bool use_target_site_weights
Whether or not the SamplingTensor acts on the target site as well as the neighbors.
int input_rank
Rank of sampling functional input for each SamplingFunctional.
KOKKOS_INLINE_FUNCTION global_index_type getAlphaIndex(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_INLINE_FUNCTION 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 evaluation_site_local_index=0) const
Retrieves the offset for an operator based on input and output component, generic to row (but still m...
auto get2DView(const int column_num, const int block_size) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL))
auto get1DView(const int column_num) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL))
SubviewND(T data_in, T2 data_original_view, bool scalar_as_vector_if_needed)
Creates 1D subviews of data from a 2D view, generally constructed with CreateNDSliceOnDeviceView.
SubviewND(T data_in, T2 data_original_view, bool scalar_as_vector_if_needed)
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)))
auto get1DView(const int column_num) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL, column_num))