11#include " source_base/kernels/math_kernel_op.h"
22namespace hsolver {
3+ namespace {
4+
5+ inline bool ppcg_contiguous_cols (const std::vector<int >& cols, int & first)
6+ {
7+ if (cols.empty ())
8+ return false ;
9+
10+ first = cols.front ();
11+ for (int j = 0 ; j < static_cast <int >(cols.size ()); ++j)
12+ {
13+ if (cols[j] != first + j)
14+ return false ;
15+ }
16+ return true ;
17+ }
18+
19+ } // anonymous namespace
320
421// =============================================================================
522// Constructor
@@ -148,6 +165,18 @@ void DiagoPPCG<T, Device>::copy_cols(const T* src,
148165{
149166 const int ncols = static_cast <int >(cols.size ());
150167 dst.resize (ld_psi_ * ncols);
168+ if (ncols == 0 )
169+ return ;
170+
171+ int first = 0 ;
172+ if (ppcg_contiguous_cols (cols, first))
173+ {
174+ std::copy (src + first * ld_psi_,
175+ src + (first + ncols) * ld_psi_,
176+ dst.begin ());
177+ return ;
178+ }
179+
151180#ifdef _OPENMP
152181#pragma omp parallel for schedule(static) if (ld_psi_ * ncols > 4096)
153182#endif
@@ -169,6 +198,18 @@ void DiagoPPCG<T, Device>::scatter_cols(
169198 const std::vector<T>& src) const
170199{
171200 const int ncols = static_cast <int >(cols.size ());
201+ if (ncols == 0 )
202+ return ;
203+
204+ int first = 0 ;
205+ if (ppcg_contiguous_cols (cols, first))
206+ {
207+ std::copy (src.begin (),
208+ src.begin () + ld_psi_ * ncols,
209+ dst + first * ld_psi_);
210+ return ;
211+ }
212+
172213#ifdef _OPENMP
173214#pragma omp parallel for schedule(static) if (ld_psi_ * ncols > 4096)
174215#endif
@@ -197,16 +238,8 @@ void DiagoPPCG<T, Device>::project_against(
197238 const int nbasis = static_cast <int >(basis_cols.size ());
198239 const int nx = static_cast <int >(x_cols.size ());
199240
200- bool contiguous_x = true ;
201- const int x_first = x_cols.front ();
202- for (int i = 0 ; i < nx; ++i)
203- {
204- if (x_cols[i] != x_first + i)
205- {
206- contiguous_x = false ;
207- break ;
208- }
209- }
241+ int x_first = 0 ;
242+ const bool contiguous_x = ppcg_contiguous_cols (x_cols, x_first);
210243
211244 std::vector<T> x_l;
212245 std::vector<T> sx_l;
@@ -220,16 +253,9 @@ void DiagoPPCG<T, Device>::project_against(
220253 sx_data = sx_l.data ();
221254 }
222255
223- bool contiguous_basis = true ;
224- const int basis_first = basis_cols.front ();
225- for (int i = 0 ; i < nbasis; ++i)
226- {
227- if (basis_cols[i] != basis_first + i)
228- {
229- contiguous_basis = false ;
230- break ;
231- }
232- }
256+ int basis_first = 0 ;
257+ const bool contiguous_basis =
258+ ppcg_contiguous_cols (basis_cols, basis_first);
233259
234260 std::vector<T> basis_l;
235261 std::vector<T> sbasis_l;
0 commit comments