28 const Number *current_vector,
29 const std::vector<const Number *> &orthogonal_vectors,
37 static constexpr unsigned int n_lanes =
41 for (
unsigned int i = 0; i < n_vectors; ++i)
44 correct[delayed_reorthogonalization ? 129 : 1];
45 if (delayed_reorthogonalization)
46 for (
unsigned int i = 0; i < n_vectors + 1; ++i)
51 constexpr unsigned int inner_batch_size =
52 delayed_reorthogonalization ? 6 : 12;
54 const unsigned int loop_length_c =
118 for (
unsigned int c_block = 0; c_block < (loop_length_c + 63) / 64;
120 for (
unsigned int i_block = 0; i_block < (n_vectors + 7) / 8;
122 for (c = c_block * 64, j = c * n_lanes * inner_batch_size;
123 c <
std::min(loop_length_c, (c_block + 1) * 64);
124 ++c, j += n_lanes * inner_batch_size)
127 for (
unsigned int k = 0; k < inner_batch_size; ++k)
128 vvec[k].load(current_vector + j + k * n_lanes);
130 if (delayed_reorthogonalization || i_block == 0)
131 for (
unsigned int k = 0; k < inner_batch_size; ++k)
132 prev_vector[k].load(orthogonal_vectors[n_vectors - 1] +
138 prev_vector[0] * vvec[0];
140 prev_vector[0] * prev_vector[0];
142 for (
unsigned int k = 1; k < inner_batch_size; ++k)
144 local_sum_0 += prev_vector[k] * vvec[k];
145 if (delayed_reorthogonalization)
147 local_sum_1 += prev_vector[k] * prev_vector[k];
148 local_sum_2 += vvec[k] * vvec[k];
151 hs[n_vectors - 1] += local_sum_0;
152 if (delayed_reorthogonalization)
154 correct[n_vectors - 1] += local_sum_1;
155 correct[n_vectors] += local_sum_2;
159 for (
unsigned int i = i_block * 8;
160 i <
std::min(n_vectors - 1, (i_block + 1) * 8);
167 temp.
load(orthogonal_vectors[i] + j);
170 delayed_reorthogonalization ? temp * prev_vector[0] :
172 for (
unsigned int k = 1; k < inner_batch_size; ++k)
174 temp.
load(orthogonal_vectors[i] + j + k * n_lanes);
175 local_sum_0 += temp * vvec[k];
176 if (delayed_reorthogonalization)
177 local_sum_1 += temp * prev_vector[k];
179 hs[i] += local_sum_0;
180 if (delayed_reorthogonalization)
181 correct[i] += local_sum_1;
185 c *= inner_batch_size;
189 vvec.
load(current_vector + j);
190 prev_vector.
load(orthogonal_vectors[n_vectors - 1] + j);
191 hs[n_vectors - 1] += prev_vector * vvec;
192 if (delayed_reorthogonalization)
194 correct[n_vectors - 1] += prev_vector * prev_vector;
195 correct[n_vectors] += vvec * vvec;
198 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
201 temp.
load(orthogonal_vectors[i] + j);
202 hs[i] += temp * vvec;
203 if (delayed_reorthogonalization)
204 correct[i] += temp * prev_vector;
208 for (
unsigned int i = 0; i < n_vectors; ++i)
211 if (delayed_reorthogonalization)
212 h(i + n_vectors) += correct[i].
sum();
214 if (delayed_reorthogonalization)
215 h(n_vectors + n_vectors) += correct[n_vectors].
sum();
222 const double vvec = current_vector[j];
223 const double prev_vector = orthogonal_vectors[n_vectors - 1][j];
224 h(n_vectors - 1) += prev_vector * vvec;
225 if (delayed_reorthogonalization)
227 h(n_vectors + n_vectors - 1) += prev_vector * prev_vector;
228 h(n_vectors + n_vectors) += vvec * vvec;
230 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
232 const double temp = orthogonal_vectors[i][j];
234 if (delayed_reorthogonalization)
235 h(n_vectors + i) += temp * prev_vector;
246 const std::vector<const Number *> &orthogonal_vectors,
248 Number *current_vector)
250 double norm_vv_temp = 0;
252 Number *previous_vector =
253 const_cast<Number *
>(orthogonal_vectors[n_vectors - 1]);
254 const double inverse_norm_previous =
255 delayed_reorthogonalization ? 1. / h(n_vectors + n_vectors - 1) : 0.;
256 const double scaling_factor_vv =
257 delayed_reorthogonalization ?
258 (h(n_vectors + n_vectors) > 0.0 ?
259 inverse_norm_previous / h(n_vectors + n_vectors) :
260 inverse_norm_previous / h(n_vectors + n_vectors - 1)) :
262 const double last_factor = h(n_vectors - 1);
267 constexpr unsigned int inner_batch_size =
268 delayed_reorthogonalization ? 6 : 12;
276 const unsigned int loop_length_c =
278 const unsigned int loop_length_i = (n_vectors + 7) / 8;
279 for (
unsigned int c_block = 0; c_block < (loop_length_c + 63) / 64;
281 for (
unsigned int i_block = 0; i_block < (n_vectors + 7) / 8; ++i_block)
282 for (c = c_block * 64, j = c * n_lanes * inner_batch_size;
283 c <
std::min(loop_length_c, (c_block + 1) * 64);
284 ++c, j += n_lanes * inner_batch_size)
287 for (
unsigned int k = 0; k < inner_batch_size; ++k)
288 temp[k].load(current_vector + j + k * n_lanes);
290 if (delayed_reorthogonalization)
291 for (
unsigned int k = 0; k < inner_batch_size; ++k)
292 prev_vector[k].load(previous_vector + j + k * n_lanes);
294 for (
unsigned int i = i_block * 8;
295 i <
std::min(n_vectors - 1, (i_block + 1) * 8);
298 const double factor = h(i);
299 const double correction_factor =
300 (delayed_reorthogonalization ? h(n_vectors + i) : 0.0);
301 for (
unsigned int k = 0; k < inner_batch_size; ++k)
304 vec.
load(orthogonal_vectors[i] + j + k * n_lanes);
305 temp[k] -= factor * vec;
306 if (delayed_reorthogonalization)
307 prev_vector[k] -= correction_factor * vec;
311 if (delayed_reorthogonalization)
313 if (i_block + 1 == loop_length_i)
314 for (
unsigned int k = 0; k < inner_batch_size; ++k)
316 prev_vector[k] = prev_vector[k] * inverse_norm_previous;
317 prev_vector[k].
store(previous_vector + j + k * n_lanes);
318 temp[k] -= last_factor * prev_vector[k];
319 temp[k] = temp[k] * scaling_factor_vv;
320 temp[k].
store(current_vector + j + k * n_lanes);
323 for (
unsigned int k = 0; k < inner_batch_size; ++k)
325 prev_vector[k].
store(previous_vector + j + k * n_lanes);
326 temp[k].
store(current_vector + j + k * n_lanes);
331 if (i_block + 1 == loop_length_i)
332 for (
unsigned int k = 0; k < inner_batch_size; ++k)
334 prev_vector[k].
load(previous_vector + j + k * n_lanes);
335 temp[k] -= last_factor * prev_vector[k];
336 temp[k].
store(current_vector + j + k * n_lanes);
337 norm_vv_temp_vectorized += temp[k] * temp[k];
340 for (
unsigned int k = 0; k < inner_batch_size; ++k)
341 temp[k].store(current_vector + j + k * n_lanes);
345 c *= inner_batch_size;
349 temp.
load(current_vector + j);
350 prev_vector.
load(previous_vector + j);
351 if (!delayed_reorthogonalization)
352 temp -= h(n_vectors - 1) * prev_vector;
354 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
357 vec.
load(orthogonal_vectors[i] + j);
359 if (delayed_reorthogonalization)
360 prev_vector -= h(n_vectors + i) * vec;
363 if (delayed_reorthogonalization)
365 prev_vector = prev_vector * inverse_norm_previous;
366 prev_vector.
store(previous_vector + j);
367 temp -= h(n_vectors - 1) * prev_vector;
368 temp = temp * scaling_factor_vv;
369 temp.
store(current_vector + j);
373 temp.
store(current_vector + j);
374 norm_vv_temp_vectorized += temp * temp;
378 if (!delayed_reorthogonalization)
379 norm_vv_temp += norm_vv_temp_vectorized.
sum();
383 double temp = current_vector[j];
384 double prev_vector = previous_vector[j];
385 if (delayed_reorthogonalization)
387 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
389 const double vec = orthogonal_vectors[i][j];
391 prev_vector -= h(n_vectors + i) * vec;
393 prev_vector *= inverse_norm_previous;
394 previous_vector[j] = prev_vector;
395 temp -= h(n_vectors - 1) * prev_vector;
396 temp *= scaling_factor_vv;
400 temp -= h(n_vectors - 1) * prev_vector;
401 for (
unsigned int i = 0; i < n_vectors - 1; ++i)
402 temp -= h(i) * orthogonal_vectors[i][j];
403 norm_vv_temp += temp * temp;
405 current_vector[j] = temp;
417 const std::vector<const Number *> &tmp_vectors,
423 constexpr unsigned int inner_batch_size = 12;
428 ++c, j += n_lanes * inner_batch_size)
435 for (
unsigned int k = 0; k < inner_batch_size; ++k)
436 temp[k].load(output + j + k * n_lanes);
438 for (
unsigned int i = 0; i < n_vectors; ++i)
440 const double h_i = h(i);
441 for (
unsigned int k = 0; k < inner_batch_size; ++k)
444 v_ij.
load(tmp_vectors[i] + j + k * n_lanes);
445 temp[k] += v_ij * h_i;
449 for (
unsigned int k = 0; k < inner_batch_size; ++k)
450 temp[k].store(output + j + k * n_lanes);
453 c *= inner_batch_size;
458 temp.
load(output + j);
460 for (
unsigned int i = 0; i < n_vectors; ++i)
463 v_ij.
load(tmp_vectors[i] + j);
467 temp.
store(output + j);
472 double temp = zero_out ? 0.0 : output[j];
473 for (
unsigned int i = 0; i < n_vectors; ++i)
474 temp += tmp_vectors[i][j] * h(i);