30 const Number *current_vector,
31 const std::vector<const Number *> &orthogonal_vectors,
39 static constexpr unsigned int n_lanes =
43 for (
unsigned int i = 0; i < n_vectors; ++i)
46 correct[delayed_reorthogonalization ? 129 : 1];
47 if (delayed_reorthogonalization)
48 for (
unsigned int i = 0; i < n_vectors + 1; ++i)
53 constexpr unsigned int inner_batch_size =
54 delayed_reorthogonalization ? 6 : 12;
56 const unsigned int loop_length_c =
120 for (
unsigned int c_block = 0; c_block < (loop_length_c + 63) / 64;
122 for (
unsigned int i_block = 0; i_block < (n_vectors + 7) / 8;
124 for (c = c_block * 64, j = c * n_lanes * inner_batch_size;
125 c <
std::min(loop_length_c, (c_block + 1) * 64);
126 ++c, j += n_lanes * inner_batch_size)
129 for (
unsigned int k = 0; k < inner_batch_size; ++k)
130 vvec[k].load(current_vector + j + k * n_lanes);
132 if (delayed_reorthogonalization || i_block == 0)
133 for (
unsigned int k = 0; k < inner_batch_size; ++k)
134 prev_vector[k].load(orthogonal_vectors[n_vectors - 1] +
140 prev_vector[0] * vvec[0];
142 prev_vector[0] * prev_vector[0];
144 for (
unsigned int k = 1; k < inner_batch_size; ++k)
146 local_sum_0 += prev_vector[k] * vvec[k];
147 if (delayed_reorthogonalization)
149 local_sum_1 += prev_vector[k] * prev_vector[k];
150 local_sum_2 += vvec[k] * vvec[k];
153 hs[n_vectors - 1] += local_sum_0;
154 if (delayed_reorthogonalization)
156 correct[n_vectors - 1] += local_sum_1;
157 correct[n_vectors] += local_sum_2;
161 for (
unsigned int i = i_block * 8;
162 i <
std::min(n_vectors - 1, (i_block + 1) * 8);
169 temp.
load(orthogonal_vectors[i] + j);
172 delayed_reorthogonalization ? temp * prev_vector[0] :
174 for (
unsigned int k = 1; k < inner_batch_size; ++k)
176 temp.
load(orthogonal_vectors[i] + j + k * n_lanes);
177 local_sum_0 += temp * vvec[k];
178 if (delayed_reorthogonalization)
179 local_sum_1 += temp * prev_vector[k];
181 hs[i] += local_sum_0;
182 if (delayed_reorthogonalization)
183 correct[i] += local_sum_1;
187 c *= inner_batch_size;
191 vvec.
load(current_vector + j);
192 prev_vector.
load(orthogonal_vectors[n_vectors - 1] + j);
193 hs[n_vectors - 1] += prev_vector * vvec;
194 if (delayed_reorthogonalization)
196 correct[n_vectors - 1] += prev_vector * prev_vector;
197 correct[n_vectors] += vvec * vvec;
200 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
203 temp.
load(orthogonal_vectors[i] + j);
204 hs[i] += temp * vvec;
205 if (delayed_reorthogonalization)
206 correct[i] += temp * prev_vector;
210 for (
unsigned int i = 0; i < n_vectors; ++i)
213 if (delayed_reorthogonalization)
214 h(i + n_vectors) += correct[i].
sum();
216 if (delayed_reorthogonalization)
217 h(n_vectors + n_vectors) += correct[n_vectors].
sum();
224 const double vvec = current_vector[j];
225 const double prev_vector = orthogonal_vectors[n_vectors - 1][j];
226 h(n_vectors - 1) += prev_vector * vvec;
227 if (delayed_reorthogonalization)
229 h(n_vectors + n_vectors - 1) += prev_vector * prev_vector;
230 h(n_vectors + n_vectors) += vvec * vvec;
232 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
234 const double temp = orthogonal_vectors[i][j];
236 if (delayed_reorthogonalization)
237 h(n_vectors + i) += temp * prev_vector;
248 const std::vector<const Number *> &orthogonal_vectors,
250 Number *current_vector)
252 double norm_vv_temp = 0;
254 Number *previous_vector =
255 const_cast<Number *
>(orthogonal_vectors[n_vectors - 1]);
256 const double inverse_norm_previous =
257 delayed_reorthogonalization ? 1. / h(n_vectors + n_vectors - 1) : 0.;
258 const double scaling_factor_vv =
259 delayed_reorthogonalization ?
260 (h(n_vectors + n_vectors) > 0.0 ?
261 inverse_norm_previous / h(n_vectors + n_vectors) :
262 inverse_norm_previous / h(n_vectors + n_vectors - 1)) :
264 const double last_factor = h(n_vectors - 1);
269 constexpr unsigned int inner_batch_size =
270 delayed_reorthogonalization ? 6 : 12;
278 const unsigned int loop_length_c =
280 const unsigned int loop_length_i = (n_vectors + 7) / 8;
281 for (
unsigned int c_block = 0; c_block < (loop_length_c + 63) / 64;
283 for (
unsigned int i_block = 0; i_block < (n_vectors + 7) / 8; ++i_block)
284 for (c = c_block * 64, j = c * n_lanes * inner_batch_size;
285 c <
std::min(loop_length_c, (c_block + 1) * 64);
286 ++c, j += n_lanes * inner_batch_size)
289 for (
unsigned int k = 0; k < inner_batch_size; ++k)
290 temp[k].load(current_vector + j + k * n_lanes);
292 if (delayed_reorthogonalization)
293 for (
unsigned int k = 0; k < inner_batch_size; ++k)
294 prev_vector[k].load(previous_vector + j + k * n_lanes);
296 for (
unsigned int i = i_block * 8;
297 i <
std::min(n_vectors - 1, (i_block + 1) * 8);
300 const double factor = h(i);
301 const double correction_factor =
302 (delayed_reorthogonalization ? h(n_vectors + i) : 0.0);
303 for (
unsigned int k = 0; k < inner_batch_size; ++k)
306 vec.
load(orthogonal_vectors[i] + j + k * n_lanes);
307 temp[k] -= factor * vec;
308 if (delayed_reorthogonalization)
309 prev_vector[k] -= correction_factor * vec;
313 if (delayed_reorthogonalization)
315 if (i_block + 1 == loop_length_i)
316 for (
unsigned int k = 0; k < inner_batch_size; ++k)
318 prev_vector[k] = prev_vector[k] * inverse_norm_previous;
319 prev_vector[k].
store(previous_vector + j + k * n_lanes);
320 temp[k] -= last_factor * prev_vector[k];
321 temp[k] = temp[k] * scaling_factor_vv;
322 temp[k].
store(current_vector + j + k * n_lanes);
325 for (
unsigned int k = 0; k < inner_batch_size; ++k)
327 prev_vector[k].
store(previous_vector + j + k * n_lanes);
328 temp[k].
store(current_vector + j + k * n_lanes);
333 if (i_block + 1 == loop_length_i)
334 for (
unsigned int k = 0; k < inner_batch_size; ++k)
336 prev_vector[k].
load(previous_vector + j + k * n_lanes);
337 temp[k] -= last_factor * prev_vector[k];
338 temp[k].
store(current_vector + j + k * n_lanes);
339 norm_vv_temp_vectorized += temp[k] * temp[k];
342 for (
unsigned int k = 0; k < inner_batch_size; ++k)
343 temp[k].store(current_vector + j + k * n_lanes);
347 c *= inner_batch_size;
351 temp.
load(current_vector + j);
352 prev_vector.
load(previous_vector + j);
353 if (!delayed_reorthogonalization)
354 temp -= h(n_vectors - 1) * prev_vector;
356 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
359 vec.
load(orthogonal_vectors[i] + j);
361 if (delayed_reorthogonalization)
362 prev_vector -= h(n_vectors + i) * vec;
365 if (delayed_reorthogonalization)
367 prev_vector = prev_vector * inverse_norm_previous;
368 prev_vector.
store(previous_vector + j);
369 temp -= h(n_vectors - 1) * prev_vector;
370 temp = temp * scaling_factor_vv;
371 temp.
store(current_vector + j);
375 temp.
store(current_vector + j);
376 norm_vv_temp_vectorized += temp * temp;
380 if (!delayed_reorthogonalization)
381 norm_vv_temp += norm_vv_temp_vectorized.
sum();
385 double temp = current_vector[j];
386 double prev_vector = previous_vector[j];
387 if (delayed_reorthogonalization)
389 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
391 const double vec = orthogonal_vectors[i][j];
393 prev_vector -= h(n_vectors + i) * vec;
395 prev_vector *= inverse_norm_previous;
396 previous_vector[j] = prev_vector;
397 temp -= h(n_vectors - 1) * prev_vector;
398 temp *= scaling_factor_vv;
402 temp -= h(n_vectors - 1) * prev_vector;
403 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
404 temp -= h(i) * orthogonal_vectors[i][j];
405 norm_vv_temp += temp * temp;
407 current_vector[j] = temp;
419 const std::vector<const Number *> &tmp_vectors,
425 constexpr unsigned int inner_batch_size = 12;
430 ++c, j += n_lanes * inner_batch_size)
437 for (
unsigned int k = 0; k < inner_batch_size; ++k)
438 temp[k].load(output + j + k * n_lanes);
440 for (
unsigned int i = 0; i < n_vectors; ++i)
442 const double h_i = h(i);
443 for (
unsigned int k = 0; k < inner_batch_size; ++k)
446 v_ij.
load(tmp_vectors[i] + j + k * n_lanes);
447 temp[k] += v_ij * h_i;
451 for (
unsigned int k = 0; k < inner_batch_size; ++k)
452 temp[k].store(output + j + k * n_lanes);
455 c *= inner_batch_size;
460 temp.
load(output + j);
462 for (
unsigned int i = 0; i < n_vectors; ++i)
465 v_ij.
load(tmp_vectors[i] + j);
469 temp.
store(output + j);
474 double temp = zero_out ? 0.0 : output[j];
475 for (
unsigned int i = 0; i < n_vectors; ++i)
476 temp += tmp_vectors[i][j] * h(i);