57 int64_t n = Ti_ps.GetLength();
58 if (Tj_qs.GetLength() != n || Ri_normal_ps.GetLength() != n) {
60 "Unable to setup linear system: input length mismatch.");
68 float *AtA_local_ptr =
static_cast<float *
>(AtA_local.
GetDataPtr());
69 float *Atb_local_ptr =
static_cast<float *
>(Atb_local.GetDataPtr());
70 float *residual_ptr =
static_cast<float *
>(residual.GetDataPtr());
72 const float *Ti_ps_ptr =
static_cast<const float *
>(Ti_ps.GetDataPtr());
73 const float *Tj_qs_ptr =
static_cast<const float *
>(Tj_qs.GetDataPtr());
74 const float *Ri_normal_ps_ptr =
75 static_cast<const float *
>(Ri_normal_ps.GetDataPtr());
78#if !defined(__CUDACC__)
79 tbb::spin_mutex fill_alignment_mutex;
80 tbb::profiling::set_name(fill_alignment_mutex,
81 "FillInRigidAlignmentTermCPU");
82#define LOCAL_LAMBDA_CAPTURE =, &fill_alignment_mutex
84#define LOCAL_LAMBDA_CAPTURE =
90 const float *p_prime = Ti_ps_ptr + 3 * workload_idx;
91 const float *q_prime = Tj_qs_ptr + 3 * workload_idx;
92 const float *normal_p_prime =
93 Ri_normal_ps_ptr + 3 * workload_idx;
95 float r = (p_prime[0] - q_prime[0]) * normal_p_prime[0] +
96 (p_prime[1] - q_prime[1]) * normal_p_prime[1] +
97 (p_prime[2] - q_prime[2]) * normal_p_prime[2];
98 if (abs(r) > threshold)
return;
104#if defined(BUILD_CUDA_MODULE) && defined(__CUDACC__)
105 for (
int i_local = 0; i_local < 12; ++i_local) {
106 for (
int j_local = 0; j_local < 12; ++j_local) {
107 atomicAdd(&AtA_local_ptr[i_local * 12 + j_local],
108 J_ij[i_local] * J_ij[j_local]);
110 atomicAdd(&Atb_local_ptr[i_local], J_ij[i_local] * r);
112 atomicAdd(residual_ptr, r * r);
115 tbb::spin_mutex::scoped_lock lock(fill_alignment_mutex);
116 for (
int i_local = 0; i_local < 12; ++i_local) {
117 for (
int j_local = 0; j_local < 12; ++j_local) {
118 AtA_local_ptr[i_local * 12 + j_local] +=
119 J_ij[i_local] * J_ij[j_local];
121 Atb_local_ptr[i_local] += J_ij[i_local] * r;
123 *residual_ptr += r * r;
127#undef LOCAL_LAMBDA_CAPTURE
130 std::vector<int64_t> indices_vec(12);
131 for (
int k = 0; k < 6; ++k) {
132 indices_vec[k] = i * 6 + k;
133 indices_vec[k + 6] = j * 6 + k;
136 std::vector<int64_t> indices_i_vec;
137 std::vector<int64_t> indices_j_vec;
138 for (
int local_i = 0; local_i < 12; ++local_i) {
139 for (
int local_j = 0; local_j < 12; ++local_j) {
140 indices_i_vec.push_back(indices_vec[local_i]);
141 indices_j_vec.push_back(indices_vec[local_j]);
150 AtA.
IndexSet({indices_i, indices_j}, AtA_sub + AtA_local.
View({12 * 12}));
177 int64_t n = Ti_Cps.GetLength();
178 if (Tj_Cqs.GetLength() != n || Cnormal_ps.GetLength() != n ||
179 Ri_Cnormal_ps.GetLength() != n || RjT_Ri_Cnormal_ps.GetLength() != n ||
180 cgrid_idx_ps.GetLength() != n || cgrid_ratio_ps.GetLength() != n ||
181 cgrid_idx_qs.GetLength() != n || cgrid_ratio_qs.GetLength() != n) {
183 "Unable to setup linear system: input length mismatch.");
186 int n_vars = Atb.GetLength();
187 float *AtA_ptr =
static_cast<float *
>(AtA.GetDataPtr());
188 float *Atb_ptr =
static_cast<float *
>(Atb.GetDataPtr());
189 float *residual_ptr =
static_cast<float *
>(residual.GetDataPtr());
192 const float *Ti_Cps_ptr =
static_cast<const float *
>(Ti_Cps.GetDataPtr());
193 const float *Tj_Cqs_ptr =
static_cast<const float *
>(Tj_Cqs.GetDataPtr());
194 const float *Cnormal_ps_ptr =
195 static_cast<const float *
>(Cnormal_ps.GetDataPtr());
196 const float *Ri_Cnormal_ps_ptr =
197 static_cast<const float *
>(Ri_Cnormal_ps.GetDataPtr());
198 const float *RjT_Ri_Cnormal_ps_ptr =
199 static_cast<const float *
>(RjT_Ri_Cnormal_ps.GetDataPtr());
202 const int *cgrid_idx_ps_ptr =
203 static_cast<const int *
>(cgrid_idx_ps.GetDataPtr());
204 const int *cgrid_idx_qs_ptr =
205 static_cast<const int *
>(cgrid_idx_qs.GetDataPtr());
206 const float *cgrid_ratio_ps_ptr =
207 static_cast<const float *
>(cgrid_ratio_ps.GetDataPtr());
208 const float *cgrid_ratio_qs_ptr =
209 static_cast<const float *
>(cgrid_ratio_qs.GetDataPtr());
211#if !defined(__CUDACC__)
212 tbb::spin_mutex fill_alignment_mutex;
213 tbb::profiling::set_name(fill_alignment_mutex,
214 "FillInSLACAlignmentTermCPU");
215#define LOCAL_LAMBDA_CAPTURE =, &fill_alignment_mutex
217#define LOCAL_LAMBDA_CAPTURE =
223 const float *Ti_Cp = Ti_Cps_ptr + 3 * workload_idx;
224 const float *Tj_Cq = Tj_Cqs_ptr + 3 * workload_idx;
225 const float *Cnormal_p = Cnormal_ps_ptr + 3 * workload_idx;
226 const float *Ri_Cnormal_p =
227 Ri_Cnormal_ps_ptr + 3 * workload_idx;
228 const float *RjTRi_Cnormal_p =
229 RjT_Ri_Cnormal_ps_ptr + 3 * workload_idx;
231 const int *cgrid_idx_p = cgrid_idx_ps_ptr + 8 * workload_idx;
232 const int *cgrid_idx_q = cgrid_idx_qs_ptr + 8 * workload_idx;
233 const float *cgrid_ratio_p =
234 cgrid_ratio_ps_ptr + 8 * workload_idx;
235 const float *cgrid_ratio_q =
236 cgrid_ratio_qs_ptr + 8 * workload_idx;
238 float r = (Ti_Cp[0] - Tj_Cq[0]) * Ri_Cnormal_p[0] +
239 (Ti_Cp[1] - Tj_Cq[1]) * Ri_Cnormal_p[1] +
240 (Ti_Cp[2] - Tj_Cq[2]) * Ri_Cnormal_p[2];
241 if (abs(r) > threshold)
return;
248 J[0] = -Tj_Cq[2] * Ri_Cnormal_p[1] + Tj_Cq[1] * Ri_Cnormal_p[2];
249 J[1] = Tj_Cq[2] * Ri_Cnormal_p[0] - Tj_Cq[0] * Ri_Cnormal_p[2];
250 J[2] = -Tj_Cq[1] * Ri_Cnormal_p[0] + Tj_Cq[0] * Ri_Cnormal_p[1];
251 J[3] = Ri_Cnormal_p[0];
252 J[4] = Ri_Cnormal_p[1];
253 J[5] = Ri_Cnormal_p[2];
256 for (
int k = 0; k < 6; ++k) {
259 idx[k + 0] = 6 * i + k;
260 idx[k + 6] = 6 * j + k;
264 for (
int k = 0; k < 8; ++k) {
265 J[12 + k * 3 + 0] = cgrid_ratio_p[k] * Cnormal_p[0];
266 J[12 + k * 3 + 1] = cgrid_ratio_p[k] * Cnormal_p[1];
267 J[12 + k * 3 + 2] = cgrid_ratio_p[k] * Cnormal_p[2];
269 idx[12 + k * 3 + 0] = 6 * n_frags + cgrid_idx_p[k] * 3 + 0;
270 idx[12 + k * 3 + 1] = 6 * n_frags + cgrid_idx_p[k] * 3 + 1;
271 idx[12 + k * 3 + 2] = 6 * n_frags + cgrid_idx_p[k] * 3 + 2;
275 for (
int k = 0; k < 8; ++k) {
276 J[36 + k * 3 + 0] = -cgrid_ratio_q[k] * RjTRi_Cnormal_p[0];
277 J[36 + k * 3 + 1] = -cgrid_ratio_q[k] * RjTRi_Cnormal_p[1];
278 J[36 + k * 3 + 2] = -cgrid_ratio_q[k] * RjTRi_Cnormal_p[2];
280 idx[36 + k * 3 + 0] = 6 * n_frags + cgrid_idx_q[k] * 3 + 0;
281 idx[36 + k * 3 + 1] = 6 * n_frags + cgrid_idx_q[k] * 3 + 1;
282 idx[36 + k * 3 + 2] = 6 * n_frags + cgrid_idx_q[k] * 3 + 2;
286#if defined(__CUDACC__)
287 for (
int ki = 0; ki < 60; ++ki) {
288 for (
int kj = 0; kj < 60; ++kj) {
289 float AtA_ij = J[ki] * J[kj];
290 int ij = idx[ki] * n_vars + idx[kj];
291 atomicAdd(AtA_ptr + ij, AtA_ij);
293 float Atb_i = J[ki] * r;
294 atomicAdd(Atb_ptr + idx[ki], Atb_i);
296 atomicAdd(residual_ptr, r * r);
299 tbb::spin_mutex::scoped_lock lock(fill_alignment_mutex);
300 for (
int ki = 0; ki < 60; ++ki) {
301 for (
int kj = 0; kj < 60; ++kj) {
302 AtA_ptr[idx[ki] * n_vars + idx[kj]] +=
305 Atb_ptr[idx[ki]] += J[ki] * r;
307 *residual_ptr += r * r;
311#undef LOCAL_LAMBDA_CAPTURE
331 int64_t n = grid_idx.GetLength();
332 int64_t n_vars = Atb.GetLength();
334 float *AtA_ptr =
static_cast<float *
>(AtA.GetDataPtr());
335 float *Atb_ptr =
static_cast<float *
>(Atb.GetDataPtr());
336 float *residual_ptr =
static_cast<float *
>(residual.GetDataPtr());
338 const int *grid_idx_ptr =
static_cast<const int *
>(grid_idx.GetDataPtr());
339 const int *grid_nbs_idx_ptr =
340 static_cast<const int *
>(grid_nbs_idx.GetDataPtr());
341 const bool *grid_nbs_mask_ptr =
342 static_cast<const bool *
>(grid_nbs_mask.GetDataPtr());
344 const float *positions_init_ptr =
345 static_cast<const float *
>(positions_init.GetDataPtr());
346 const float *positions_curr_ptr =
347 static_cast<const float *
>(positions_curr.GetDataPtr());
349#if !defined(__CUDACC__)
350 tbb::spin_mutex fill_alignment_mutex;
351 tbb::profiling::set_name(fill_alignment_mutex,
352 "FillInSLACRegularizerTermCPU");
353#define LOCAL_LAMBDA_CAPTURE =, &fill_alignment_mutex
355#define LOCAL_LAMBDA_CAPTURE =
362 int idx_i = grid_idx_ptr[workload_idx];
364 const int *idx_nbs = grid_nbs_idx_ptr + 6 * workload_idx;
365 const bool *mask_nbs = grid_nbs_mask_ptr + 6 * workload_idx;
368 float cov[3][3] = {{0}};
369 float U[3][3], V[3][3], S[3];
372 for (
int k = 0; k < 6; ++k) {
373 bool mask_k = mask_nbs[k];
374 if (!mask_k)
continue;
376 int idx_k = idx_nbs[k];
379 float diff_ik_init[3] = {
380 positions_init_ptr[idx_i * 3 + 0] -
381 positions_init_ptr[idx_k * 3 + 0],
382 positions_init_ptr[idx_i * 3 + 1] -
383 positions_init_ptr[idx_k * 3 + 1],
384 positions_init_ptr[idx_i * 3 + 2] -
385 positions_init_ptr[idx_k * 3 + 2]};
386 float diff_ik_curr[3] = {
387 positions_curr_ptr[idx_i * 3 + 0] -
388 positions_curr_ptr[idx_k * 3 + 0],
389 positions_curr_ptr[idx_i * 3 + 1] -
390 positions_curr_ptr[idx_k * 3 + 1],
391 positions_curr_ptr[idx_i * 3 + 2] -
392 positions_curr_ptr[idx_k * 3 + 2]};
396 for (
int i = 0; i < 3; ++i) {
397 for (
int j = 0; j < 3; ++j) {
398 cov[i][j] += diff_ik_init[i] * diff_ik_curr[j];
425 if (idx_i == anchor_idx) {
426 R[0][0] = R[1][1] = R[2][2] = 1;
427 R[0][1] = R[0][2] = R[1][0] = R[1][2] = R[2][0] = R[2][1] =
430 for (
int k = 0; k < 6; ++k) {
431 bool mask_k = mask_nbs[k];
434 int idx_k = idx_nbs[k];
436 float diff_ik_init[3] = {
437 positions_init_ptr[idx_i * 3 + 0] -
438 positions_init_ptr[idx_k * 3 + 0],
439 positions_init_ptr[idx_i * 3 + 1] -
440 positions_init_ptr[idx_k * 3 + 1],
441 positions_init_ptr[idx_i * 3 + 2] -
442 positions_init_ptr[idx_k * 3 + 2]};
443 float diff_ik_curr[3] = {
444 positions_curr_ptr[idx_i * 3 + 0] -
445 positions_curr_ptr[idx_k * 3 + 0],
446 positions_curr_ptr[idx_i * 3 + 1] -
447 positions_curr_ptr[idx_k * 3 + 1],
448 positions_curr_ptr[idx_i * 3 + 2] -
449 positions_curr_ptr[idx_k * 3 + 2]};
450 float R_diff_ik_curr[3];
452 core::linalg::kernel::matmul3x3_3x1(*R, diff_ik_init,
456 local_r[0] = diff_ik_curr[0] - R_diff_ik_curr[0];
457 local_r[1] = diff_ik_curr[1] - R_diff_ik_curr[1];
458 local_r[2] = diff_ik_curr[2] - R_diff_ik_curr[2];
460 int offset_idx_i = 3 * idx_i + 6 * n_frags;
461 int offset_idx_k = 3 * idx_k + 6 * n_frags;
463#if defined(__CUDACC__)
465 atomicAdd(residual_ptr,
466 weight * (local_r[0] * local_r[0] +
467 local_r[1] * local_r[1] +
468 local_r[2] * local_r[2]));
470 for (
int axis = 0; axis < 3; ++axis) {
472 atomicAdd(&AtA_ptr[(offset_idx_i + axis) * n_vars +
473 offset_idx_i + axis],
475 atomicAdd(&AtA_ptr[(offset_idx_k + axis) * n_vars +
476 offset_idx_k + axis],
478 atomicAdd(&AtA_ptr[(offset_idx_i + axis) * n_vars +
479 offset_idx_k + axis],
481 atomicAdd(&AtA_ptr[(offset_idx_k + axis) * n_vars +
482 offset_idx_i + axis],
486 atomicAdd(&Atb_ptr[offset_idx_i + axis],
488 atomicAdd(&Atb_ptr[offset_idx_k + axis],
493 tbb::spin_mutex::scoped_lock lock(
494 fill_alignment_mutex);
496 *residual_ptr +=
weight * (local_r[0] * local_r[0] +
497 local_r[1] * local_r[1] +
498 local_r[2] * local_r[2]);
500 for (
int axis = 0; axis < 3; ++axis) {
502 AtA_ptr[(offset_idx_i + axis) * n_vars +
503 offset_idx_i + axis] +=
weight;
504 AtA_ptr[(offset_idx_k + axis) * n_vars +
505 offset_idx_k + axis] +=
weight;
507 AtA_ptr[(offset_idx_i + axis) * n_vars +
508 offset_idx_k + axis] -=
weight;
509 AtA_ptr[(offset_idx_k + axis) * n_vars +
510 offset_idx_i + axis] -=
weight;
513 Atb_ptr[offset_idx_i + axis] +=
515 Atb_ptr[offset_idx_k + axis] -=
523#undef LOCAL_LAMBDA_CAPTURE
void FillInSLACAlignmentTermCPU(core::Tensor &AtA, core::Tensor &Atb, core::Tensor &residual, const core::Tensor &Ti_qs, const core::Tensor &Tj_qs, const core::Tensor &normal_ps, const core::Tensor &Ri_normal_ps, const core::Tensor &RjT_Ri_normal_ps, const core::Tensor &cgrid_idx_ps, const core::Tensor &cgrid_idx_qs, const core::Tensor &cgrid_ratio_qs, const core::Tensor &cgrid_ratio_ps, int i, int j, int n, float threshold)
Definition FillInLinearSystemImpl.h:161
void FillInSLACRegularizerTermCPU(core::Tensor &AtA, core::Tensor &Atb, core::Tensor &residual, const core::Tensor &grid_idx, const core::Tensor &grid_nbs_idx, const core::Tensor &grid_nbs_mask, const core::Tensor &positions_init, const core::Tensor &positions_curr, float weight, int n, int anchor_idx)
Definition FillInLinearSystemImpl.h:319