1/*
2 * debug.hpp
3 *
4 * Created on: Oct 17, 2018
5 * Author: i-bird
6 */
7
8#ifndef DEBUG_HPP_
9#define DEBUG_HPP_
10
11enum debug_run
12{
13 HOST,
14 DEVICE
15};
16
17enum debug_iterator
18{
19 DOMAIN_IT,
20 DOMAIN_GHOST_IT,
21 GHOST_IT,
22};
23
24
25
26/*! \brief Find in a vector dist particles if "certain conditions"
27 *
28 * This function in in general used to debug. Many time in order to discover problem we want to control if particles/grid points has zeros or out of range values.
29 * You can implement these check, by creating the loops manually or using the function debug_find with a lambda function.
30 *
31 *
32 * @param vd distributed vector
33 * @param fun_test function that define the test
34 * @param fun_print function to print a message
35 * @param it iterator type domain, domain + ghost, ghost
36 * @param type_of_run optionally can do the scan on device
37 *
38 * /return This function return true if the debug function has been triggered
39 *
40 */
41template<typename vector_dist_type, typename functor_test, typename functor_print>
42bool debug_find(vector_dist_type & vd, functor_test fun_test, functor_print fun_print,
43 debug_iterator it = debug_iterator::DOMAIN_IT, debug_run type_of_run = debug_run::HOST,
44 bool print = true)
45{
46 vector_dist_iterator ite(0,0);
47
48 if (it == debug_iterator::DOMAIN_IT)
49 {ite = vd.getDomainIterator();}
50 else if (it == debug_iterator::DOMAIN_GHOST_IT)
51 {ite = vd.getDomainAndGhostIterator();}
52 else
53 {ite = vd.getGhostIterator();}
54
55 bool test_tot = false;
56
57 while (ite.isNext())
58 {
59 bool test = fun_test(ite.get().getKey());
60 test_tot |= test;
61
62 if (test == true && print == true)
63 {std::cout << fun_print(ite.get().getKey()) << std::endl;}
64
65 ++ite;
66 }
67
68 return test_tot;
69}
70
71/*! \brief Find in a vector dist particles if "certain conditions"
72 *
73 * This function in in general used to debug. Many time in order to discover problem we want to control if particles/grid points has zeros or out of range values.
74 * You can implement these check, by creating the loops manually or using the function debug_find with a lambda function.
75 *
76 *
77 * @param vd distributed vector
78 * @param fun_test function that define the test
79 * @param fun_print function to print a message
80 * @param it iterator type domain, domain + ghost, ghost
81 * @param type_of_run optionally can do the scan on device
82 *
83 * /return This function return true if the debug function has been triggered
84 *
85 */
86template<typename vector_type, typename functor_test, typename functor_print>
87bool debug_find_single(vector_type vd, functor_test fun_test, functor_print fun_print,
88 size_t g_m, debug_iterator it = debug_iterator::DOMAIN_IT, debug_run type_of_run = debug_run::HOST,
89 bool print = true)
90{
91 openfpm::vector_key_iterator ite(0,0);
92
93 if (it == debug_iterator::DOMAIN_IT)
94 {ite = vd.getIteratorTo(g_m);}
95 else if (it == debug_iterator::DOMAIN_GHOST_IT)
96 {ite = vd.getIterator();}
97 else
98 {ite = vd.getIteratorFrom(g_m);}
99
100 bool test_tot = false;
101
102 while (ite.isNext())
103 {
104 bool test = fun_test(ite.get());
105 test_tot |= test;
106
107 if (test == true && print == true)
108 {std::cout << fun_print(ite.get()) << std::endl;}
109
110 ++ite;
111 }
112
113 return test_tot;
114}
115
116/*! \brief scan for a particle inside a box
117 *
118 *
119 * \param vd vector_dist
120 * \param box box
121 * \param it iterator type
122 * \param type_of_run check host or device memory
123 * \return true if one or more is detected
124 */
125template<typename vector_dist_type>
126bool debug_is_in_box(vector_dist_type & vd, Box<vector_dist_type::dims, typename vector_dist_type::stype> box,
127 debug_iterator it = debug_iterator::DOMAIN_IT, debug_run type_of_run = debug_run::HOST,
128 bool print = true)
129{
130 auto fun_test = [&vd,&box](unsigned int p){return box.isInside(vd.getPos(p));};
131 auto fun_print = [&vd,&box](unsigned int p)
132 {
133 std::stringstream message;
134 message << "Debug info: detected particle p=" << p << " inside box: " << box.toString() << std::endl;
135 return message.str();
136 };
137
138 return debug_find(vd,fun_test,fun_print,it,type_of_run,print);
139}
140
141
142/*! \brief scan for a particle inside a box
143 *
144 *
145 * \param vd vector_dist
146 * \param box box
147 * \param it iterator type
148 * \param type_of_run check host or device memory
149 * \return true if one or more is detected
150 */
151template<typename vector_type>
152bool debug_is_in_box_single(vector_type & vd, Box<vector_type::value_type::dims, typename vector_type::value_type::coord_type> box,
153 size_t g_m, std::string message = std::string() , debug_iterator it = debug_iterator::DOMAIN_IT, debug_run type_of_run = debug_run::HOST,
154 bool print = true)
155{
156 auto fun_test = [&vd,&box](unsigned int p){return box.isInside(vd.template get<0>(p));};
157 auto fun_print = [&vd,&box,&message](unsigned int p)
158 {
159 std::stringstream message_srm;
160 message_srm << "Debug info: " << message << " detected particle p=" << p << " inside box: " << box.toString() << std::endl;
161 return message_srm.str();
162 };
163
164 return debug_find_single(vd,fun_test,fun_print,g_m,it,type_of_run,print);
165}
166
167#endif /* DEBUG_HPP_ */
168