XGC1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
view_arithmetic.hpp
Go to the documentation of this file.
1 #ifndef VIEW_ARITHMETIC_HPP
2 #define VIEW_ARITHMETIC_HPP
3 #include "space_settings.hpp"
4 #include "globals.hpp"
5 
6 // Functions to facilitate element-wise addition and subtraction of Views. Could try overloading views, but this works and is simple enough
7 
8 // Struct to hold raw device pointers (At some point there was an OMP bug that disallowed raw pointers sent in lambdas
9 template<typename T>
11  T* x;
12  T* y;
13 
14  ViewArithmeticPointers(T* x, T* y) : x(x), y(y){}
15 };
16 
17 // Add added_view*coeff to dest_view
18 template<typename V1, typename V2, typename T>
19 inline void host_add_ay_to_x(V1& dest_view, const V2& added_view, T coeff){
20  if (dest_view.size() != added_view.size()) exit_XGC("\nWARNING: dest_view and added_view are not the same size");
21 
22  // Access raw pointer of View so that we can loop over the whole array without worrying about dimensions
23  const ViewArithmeticPointers<T> ptrs(dest_view.data(), added_view.data());
24  Kokkos::parallel_for("host_add_ay_to_x", Kokkos::RangePolicy<HostExSpace>( 0, dest_view.size()), KOKKOS_LAMBDA(const int idx){
25  ptrs.x[idx] += coeff*ptrs.y[idx];
26  });
27 }
28 
29 // Multiply x by y
30 template<typename V1, typename V2>
31 inline void host_multiply_x_by_y(V1& dest_view, const V2& multiplier_view){
32  if (dest_view.size() != multiplier_view.size()) exit_XGC("\nWARNING: dest_view and multiplier_view are not the same size");
33 
34  // Access raw pointer of View so that we can loop over the whole array without worrying about dimensions
35  const ViewArithmeticPointers<double> ptrs(dest_view.data(), multiplier_view.data());
36  Kokkos::parallel_for("host_multiply_x_by_y", Kokkos::RangePolicy<HostExSpace>( 0, dest_view.size()), KOKKOS_LAMBDA(const int idx){
37  ptrs.x[idx] *= ptrs.y[idx];
38  });
39 }
40 
41 // Divide x by y
42 template<typename V1, typename V2>
43 inline void host_divide_x_by_y(V1& dest_view, const V2& divisor_view){
44  if (dest_view.size() != divisor_view.size()) exit_XGC("\nWARNING: dest_view and divisor_view are not the same size");
45 
46  // Access raw pointer of View so that we can loop over the whole array without worrying about dimensions
47  const ViewArithmeticPointers<double> ptrs(dest_view.data(), divisor_view.data());
48  Kokkos::parallel_for("host_divide_x_by_y", Kokkos::RangePolicy<HostExSpace>( 0, dest_view.size()), KOKKOS_LAMBDA(const int idx){
49  ptrs.x[idx] /= ptrs.y[idx];
50  });
51 }
52 
53 // Divide x by a. a is converted to a double to take the inverse, so it must be convertible. The view value type must be multipliable by a double.
54 template<typename V1, typename T>
55 inline void divide_x_by_a(const V1& dest_view, T coeff){
56  double coeff_inv = 1.0/coeff;
57 
58  // Cast to 1D with an unmanaged view for a generic element-wise operation
59  View<typename V1::value_type*,CLayout, typename V1::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged>> view_1D(dest_view.data(), dest_view.size());
60 
61  // Multiply each element by inverse of coeff
62  Kokkos::parallel_for("divide_x_by_a", Kokkos::RangePolicy<typename V1::execution_space>( 0, view_1D.size()), KOKKOS_LAMBDA(const int idx){
63  view_1D(idx) *= coeff_inv;
64  });
65  Kokkos::fence();
66 }
67 
68 // Add device view to host view. Copies device view to a temporary host view, then adds them
69 template<typename V1, typename V2>
70 inline void add_device_view_to_host_view(V1& dest_view, const V2& device_view){
71  if (dest_view.size() != device_view.size()) exit_XGC("\nWARNING: dest_view and device_view are not the same size");
72 
73  // Create 1D host view and copy device data
74  View<double*,CLayout,HostType> view_tmp_h(NoInit("view_tmp_h"), device_view.size());
75  View<double*,CLayout,typename V2::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged>> view_tmp_d(device_view.data(),device_view.size());
76  Kokkos::deep_copy(view_tmp_h, view_tmp_d);
77 
78  // Access raw pointer of View so that we can loop over the whole array without worrying about dimensions
79  const ViewArithmeticPointers<double> ptrs(dest_view.data(), view_tmp_h.data());
80  Kokkos::parallel_for("host_view_sum", Kokkos::RangePolicy<HostExSpace>( 0, dest_view.size()), KOKKOS_LAMBDA(const int idx){
81  ptrs.x[idx] += ptrs.y[idx];
82  });
83 }
84 
85 // Sums all elements of a view of any shape
86 template<typename T>
87 inline typename T::value_type sum_view(const T& view){
88  // Cast to 1D with an unmanaged view for a generic element-wise operation
89  View<typename T::value_type*,CLayout, typename T::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged>> view_1D(view.data(), view.size());
90 
91  typename T::value_type sum = 0;
92  Kokkos::parallel_reduce("sum", Kokkos::RangePolicy<typename T::execution_space>( 0,view.size() ), KOKKOS_LAMBDA( const int i, typename T::value_type& sum_l){
93  sum_l += view_1D(i);
94  }, sum);
95  Kokkos::fence();
96 
97  return sum;
98 }
99 
100 // Finds the max of all elements of a view of any shape
101 template<typename T>
102 inline typename T::value_type max_view(const T& view){
103  // Cast to 1D with an unmanaged view for a generic element-wise operation
104  View<typename T::value_type*,CLayout, typename T::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged>> view_1D(view.data(), view.size());
105 
106  typename T::value_type maxval = 0;
107  Kokkos::parallel_reduce("maxval", Kokkos::RangePolicy<typename T::execution_space>( 0,view.size() ), KOKKOS_LAMBDA( const int i, typename T::value_type& maxval_l){
108  maxval_l = max(maxval_l, view_1D(i));
109  }, Kokkos::Max<typename T::value_type,HostType>(maxval));
110  Kokkos::fence();
111 
112  return maxval;
113 }
114 
115 #endif
void host_divide_x_by_y(V1 &dest_view, const V2 &divisor_view)
Definition: view_arithmetic.hpp:43
void host_multiply_x_by_y(V1 &dest_view, const V2 &multiplier_view)
Definition: view_arithmetic.hpp:31
T::value_type max_view(const T &view)
Definition: view_arithmetic.hpp:102
void add_device_view_to_host_view(V1 &dest_view, const V2 &device_view)
Definition: view_arithmetic.hpp:70
void host_add_ay_to_x(V1 &dest_view, const V2 &added_view, T coeff)
Definition: view_arithmetic.hpp:19
T * y
Definition: view_arithmetic.hpp:12
ViewArithmeticPointers(T *x, T *y)
Definition: view_arithmetic.hpp:14
T::value_type sum_view(const T &view)
Definition: view_arithmetic.hpp:87
void exit_XGC(std::string msg)
Definition: globals.hpp:37
void parallel_for(const std::string name, int n_ptl, Function func, Option option, HostAoSoA aosoa_h, DeviceAoSoA aosoa_d)
Definition: streamed_parallel_for.hpp:252
Definition: view_arithmetic.hpp:10
T * x
Definition: view_arithmetic.hpp:11
Kokkos::ViewAllocateWithoutInitializing NoInit
Definition: space_settings.hpp:68
void divide_x_by_a(const V1 &dest_view, T coeff)
Definition: view_arithmetic.hpp:55