XGCa
nan_check.hpp
Go to the documentation of this file.
1 #ifndef NAN_CHECK_HPP
2 #define NAN_CHECK_HPP
3 
4 #include "space_settings.hpp"
5 
6 template <typename T>
7 inline void nan_check_by_dim(const T& view, std::string name) {
8  constexpr int Rank = T::rank;
9  using value_type = typename T::value_type;
10 
11  // Allocate one bool array per dimension
12  size_t max_ndim = 0;
13  for (int d = 0; d < Rank; d++) max_ndim = std::max(max_ndim, view.extent(d));
14  View<bool**,CLayout,typename T::device_type> dim_nan_flags(NoInit("dim_nan_flags"), Rank, max_ndim);
15  Kokkos::deep_copy(dim_nan_flags, false);
16 
17  // Compute flattened range for simplicity
18  const size_t N = view.size();
19 
20  if constexpr (Rank == 1) {
21  Kokkos::parallel_for("nan_check_by_dim", Kokkos::RangePolicy<typename T::execution_space>(0, N), KOKKOS_LAMBDA(size_t idx_flat) {
22  int i = idx_flat;
23  if (!isfinite(view(i))) {
24  dim_nan_flags(0,i) = true;
25  }
26  });
27  } else if constexpr (Rank == 2) {
28  Kokkos::parallel_for("nan_check_by_dim", Kokkos::RangePolicy<typename T::execution_space>(0, N), KOKKOS_LAMBDA(size_t idx_flat) {
29  int e1 = view.extent(1);
30  int i = idx_flat / e1;
31  int j = idx_flat % e1;
32  if (!isfinite(view(i, j))) {
33  dim_nan_flags(0,i) = true;
34  dim_nan_flags(1,j) = true;
35  }
36  });
37  } else if constexpr (Rank == 3) {
38  Kokkos::parallel_for("nan_check_by_dim", Kokkos::RangePolicy<typename T::execution_space>(0, N), KOKKOS_LAMBDA(size_t idx_flat) {
39  int e1 = view.extent(1), e2 = view.extent(2);
40  int i = idx_flat / (e1 * e2);
41  int j = (idx_flat / e2) % e1;
42  int k = idx_flat % e2;
43  if (!isfinite(view(i, j, k))) {
44  dim_nan_flags(0,i) = true;
45  dim_nan_flags(1,j) = true;
46  dim_nan_flags(2,k) = true;
47  }
48  });
49  } else if constexpr (Rank == 4) {
50  Kokkos::parallel_for("nan_check_by_dim", Kokkos::RangePolicy<typename T::execution_space>(0, N), KOKKOS_LAMBDA(size_t idx_flat) {
51  int e1 = view.extent(1), e2 = view.extent(2), e3 = view.extent(3);
52  int i = idx_flat / (e1 * e2 * e3);
53  int j = (idx_flat / (e2 * e3)) % e1;
54  int k = (idx_flat / e3) % e2;
55  int l = idx_flat % e3;
56  if (!isfinite(view(i, j, k, l))) {
57  dim_nan_flags(0,i) = true;
58  dim_nan_flags(1,j) = true;
59  dim_nan_flags(2,k) = true;
60  dim_nan_flags(3,l) = true;
61  }
62  });
63  }
64  Kokkos::fence();
65 
66  // Copy flags back to host and print results
67  auto flags_host = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), dim_nan_flags);
68  for (int d = 0; d < Rank; d++) {
69  std::cout << "Dimension " << d << ": Found NaNs in: {";
70  int range_start = -1;
71  bool inside_range = false;
72  for (size_t i = 0; i < view.extent(d); i++) {
73  if(flags_host(d,i)) {
74  if(!inside_range) range_start = i;
75  inside_range = true;
76  }else{
77  if(inside_range){
78  // Just left range
79  inside_range = false;
80 
81  if(i>range_start+1){
82  // Print range if there are consecutive values
83  std::cout << range_start << "-" << i-1 << ", ";
84  }else{
85  // Otherwise just print the value
86  std::cout << range_start << ", ";
87  }
88  }
89  }
90  }
91  if(inside_range){
92  std::cout << range_start << "-" << view.extent(d)-1;
93  }
94  std::cout << "}\n";
95  }
96 }
97 
98 
99 
100 // Sums all elements of a view of any shape
101 template<typename T>
102 inline int nan_check(const T& view, std::string name){
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  int n_nan = 0;
107  Kokkos::parallel_reduce("nan_check", Kokkos::RangePolicy<typename T::execution_space>( 0,view.size() ), KOKKOS_LAMBDA( const int i, int& n_nan_l){
108  n_nan_l += (!isfinite(view_1D(i)) ? 1 : 0);
109  }, n_nan);
110  Kokkos::fence();
111 
112  // No NaNs found
113  if(n_nan==0) return 0;
114 
115  printf("Warning: %d NaNs found in %s!!\n", n_nan, name.c_str());
116 
117  // NaNs found
118  // This should never happen. Do some analysis without worrying about performance.
119  nan_check_by_dim(view, name);
120 
121  return 1;
122 }
123 
124 #endif
KOKKOS_INLINE_FUNCTION bool isfinite(const Field< VarType::Vector, PhiInterpType::Planes > &f)
Definition: field.hpp:114
@ N
Definition: col_grid.hpp:35
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
int nan_check(const T &view, std::string name)
Definition: nan_check.hpp:102
void nan_check_by_dim(const T &view, std::string name)
Definition: nan_check.hpp:7
Kokkos::ViewAllocateWithoutInitializing NoInit
Definition: space_settings.hpp:69