17 std::span<const T> chunk,
size_t chunk_index, std::span<
const std::array<size_t, N>> separators,
20 size_t num_chunks = separators.size();
22 std::array<size_t, N> offsets{};
23 for (
size_t i = 0; i < N; ++i)
24 for (
size_t c = 0; c < chunk_index; ++c)
25 offsets[i] += separators[c][i];
26 for (
size_t i = 0; i < N - 1; ++i)
27 for (
size_t c = chunk_index; c < num_chunks; ++c)
28 offsets[i + 1] += separators[c][i];
29 std::copy(chunk.begin(), chunk.begin() + separators[chunk_index][0], out.begin() + offsets[0]);
30 for (
size_t i = 1; i < N; ++i)
31 std::copy(chunk.begin() + separators[chunk_index][i - 1],
32 chunk.begin() + separators[chunk_index][i], out.begin() + offsets[i]);
44 const index_t ny_M = std::max(
ocp.ny,
ocp.ny_0 +
ocp.ny_N);
45 ctx.run_single_sync([&] {
46 const index_t m =
ocp.ceil_N() * ny_M;
47 breakpoints.resize(2 * m);
53 const index_t ti =
ocp.riccati_thread_assignment(ctx);
54 const index_t bpt_per_thr = 2 * ny_M *
ocp.n *
ocp.v;
60 const auto brkpts_simd = [&](
auto Σi,
auto yi,
auto Adi,
auto Axi,
auto li,
auto ui) {
61 const auto s = sqrt(Σi);
62 const auto δ2 = s * Adi, δ1 = -δ2;
63 const auto α1 = (yi + Σi * (Axi - li)) / s, α2 = (Σi * (ui - Axi) - yi) / s;
64 const auto t1 = α1 / δ1, t2 = α2 / δ2;
66 *(isfinite(t1[l]) ? fin++ : --inf) = {.t = t1[l], .δ = δ1[l]};
67 *(isfinite(t2[l]) ? fin++ : --inf) = {.t = t2[l], .δ = δ2[l]};
71 const auto brkpts_batch = [&]([[maybe_unused]]
auto j,
auto,
auto Σj,
auto yj,
auto Adj,
72 auto Axj,
auto b_min_j,
auto b_max_j) {
76 ocp.foreach_stage(ctx, brkpts_batch, Σ, y, Ad, Ax, b_min, b_max);
80 auto [pos, large] = [&] {
81 GUANAQO_TRACE(
"linesearch breakpoints cyqlone partition", ti);
84 return std::pair{pos, large};
87 thr_parts[ti][0] = pos - fin_0;
88 thr_parts[ti][1] = large - fin_0;
89 thr_parts[ti][2] = fin - fin_0;
90 thr_parts[ti][3] = inf_0 - fin_0;
91 auto thr_parts_done = ctx.arrive();
94 .pos_bp = std::span{pos, fin}};
97 ctx.wait(std::move(thr_parts_done));
102 auto ab_neg_and_merge_done = ctx.arrive_reduce(ab_neg, std::plus<>{});
104 auto first_pos = std::accumulate(thr_parts.begin(), thr_parts.end(), breakpoints.begin(),
105 [](
auto it,
auto &i) { return it += i[0]; }),
106 first_inf = std::accumulate(thr_parts.begin(), thr_parts.end(), breakpoints.begin(),
107 [](
auto it,
auto &i) { return it += i[2]; });
109 ab_neg = ctx.wait_reduce(std::move(ab_neg_and_merge_done));
110 return {.bp = {.neg_bp = std::span{breakpoints.begin(), first_pos},
111 .pos_bp = std::span{first_pos, first_inf}},
BreakpointsResult compute_partition_breakpoints(Context &ctx, std::vector< Breakpoint > &breakpoints, const ineq_constr_vec_t &Σ, const ineq_constr_vec_t &y, const ineq_constr_vec_t &Ad, const ineq_constr_vec_t &Ax, const ineq_constr_vec_t &b_min, const ineq_constr_vec_t &b_max)