53 int64_t n = Ti_ps.GetLength();
54 if (Tj_qs.GetLength() != n || Ri_normal_ps.GetLength() != n) {
56 "Unable to setup linear system: input length mismatch.");
64 float *AtA_local_ptr =
static_cast<float *
>(AtA_local.
GetDataPtr());
65 float *Atb_local_ptr =
static_cast<float *
>(Atb_local.GetDataPtr());
66 float *residual_ptr =
static_cast<float *
>(residual.GetDataPtr());
68 const float *Ti_ps_ptr =
static_cast<const float *
>(Ti_ps.GetDataPtr());
69 const float *Tj_qs_ptr =
static_cast<const float *
>(Tj_qs.GetDataPtr());
70 const float *Ri_normal_ps_ptr =
71 static_cast<const float *
>(Ri_normal_ps.GetDataPtr());
75 const float *p_prime = Ti_ps_ptr + 3 * workload_idx;
76 const float *q_prime = Tj_qs_ptr + 3 * workload_idx;
77 const float *normal_p_prime =
78 Ri_normal_ps_ptr + 3 * workload_idx;
80 float r = (p_prime[0] - q_prime[0]) * normal_p_prime[0] +
81 (p_prime[1] - q_prime[1]) * normal_p_prime[1] +
82 (p_prime[2] - q_prime[2]) * normal_p_prime[2];
83 if (abs(r) > threshold)
return;
89#if defined(BUILD_CUDA_MODULE) && defined(__CUDACC__)
90 for (
int i_local = 0; i_local < 12; ++i_local) {
91 for (
int j_local = 0; j_local < 12; ++j_local) {
92 atomicAdd(&AtA_local_ptr[i_local * 12 + j_local],
93 J_ij[i_local] * J_ij[j_local]);
95 atomicAdd(&Atb_local_ptr[i_local], J_ij[i_local] * r);
97 atomicAdd(residual_ptr, r * r);
99#pragma omp critical(FillInRigidAlignmentTermCPU)
101 for (
int i_local = 0; i_local < 12; ++i_local) {
102 for (
int j_local = 0; j_local < 12; ++j_local) {
103 AtA_local_ptr[i_local * 12 + j_local]
104 += J_ij[i_local] * J_ij[j_local];
106 Atb_local_ptr[i_local] += J_ij[i_local] * r;
108 *residual_ptr += r * r;
114 std::vector<int64_t> indices_vec(12);
115 for (
int k = 0; k < 6; ++k) {
116 indices_vec[k] = i * 6 + k;
117 indices_vec[k + 6] = j * 6 + k;
120 std::vector<int64_t> indices_i_vec;
121 std::vector<int64_t> indices_j_vec;
122 for (
int local_i = 0; local_i < 12; ++local_i) {
123 for (
int local_j = 0; local_j < 12; ++local_j) {
124 indices_i_vec.push_back(indices_vec[local_i]);
125 indices_j_vec.push_back(indices_vec[local_j]);
134 AtA.
IndexSet({indices_i, indices_j}, AtA_sub + AtA_local.
View({12 * 12}));
161 int64_t n = Ti_Cps.GetLength();
162 if (Tj_Cqs.GetLength() != n || Cnormal_ps.GetLength() != n ||
163 Ri_Cnormal_ps.GetLength() != n || RjT_Ri_Cnormal_ps.GetLength() != n ||
164 cgrid_idx_ps.GetLength() != n || cgrid_ratio_ps.GetLength() != n ||
165 cgrid_idx_qs.GetLength() != n || cgrid_ratio_qs.GetLength() != n) {
167 "Unable to setup linear system: input length mismatch.");
170 int n_vars = Atb.GetLength();
171 float *AtA_ptr =
static_cast<float *
>(AtA.GetDataPtr());
172 float *Atb_ptr =
static_cast<float *
>(Atb.GetDataPtr());
173 float *residual_ptr =
static_cast<float *
>(residual.GetDataPtr());
176 const float *Ti_Cps_ptr =
static_cast<const float *
>(Ti_Cps.GetDataPtr());
177 const float *Tj_Cqs_ptr =
static_cast<const float *
>(Tj_Cqs.GetDataPtr());
178 const float *Cnormal_ps_ptr =
179 static_cast<const float *
>(Cnormal_ps.GetDataPtr());
180 const float *Ri_Cnormal_ps_ptr =
181 static_cast<const float *
>(Ri_Cnormal_ps.GetDataPtr());
182 const float *RjT_Ri_Cnormal_ps_ptr =
183 static_cast<const float *
>(RjT_Ri_Cnormal_ps.GetDataPtr());
186 const int *cgrid_idx_ps_ptr =
187 static_cast<const int *
>(cgrid_idx_ps.GetDataPtr());
188 const int *cgrid_idx_qs_ptr =
189 static_cast<const int *
>(cgrid_idx_qs.GetDataPtr());
190 const float *cgrid_ratio_ps_ptr =
191 static_cast<const float *
>(cgrid_ratio_ps.GetDataPtr());
192 const float *cgrid_ratio_qs_ptr =
193 static_cast<const float *
>(cgrid_ratio_qs.GetDataPtr());
196 AtA.GetDevice(), n, [=]
OPEN3D_DEVICE(int64_t workload_idx) {
197 const float *Ti_Cp = Ti_Cps_ptr + 3 * workload_idx;
198 const float *Tj_Cq = Tj_Cqs_ptr + 3 * workload_idx;
199 const float *Cnormal_p = Cnormal_ps_ptr + 3 * workload_idx;
200 const float *Ri_Cnormal_p =
201 Ri_Cnormal_ps_ptr + 3 * workload_idx;
202 const float *RjTRi_Cnormal_p =
203 RjT_Ri_Cnormal_ps_ptr + 3 * workload_idx;
205 const int *cgrid_idx_p = cgrid_idx_ps_ptr + 8 * workload_idx;
206 const int *cgrid_idx_q = cgrid_idx_qs_ptr + 8 * workload_idx;
207 const float *cgrid_ratio_p =
208 cgrid_ratio_ps_ptr + 8 * workload_idx;
209 const float *cgrid_ratio_q =
210 cgrid_ratio_qs_ptr + 8 * workload_idx;
212 float r = (Ti_Cp[0] - Tj_Cq[0]) * Ri_Cnormal_p[0] +
213 (Ti_Cp[1] - Tj_Cq[1]) * Ri_Cnormal_p[1] +
214 (Ti_Cp[2] - Tj_Cq[2]) * Ri_Cnormal_p[2];
215 if (abs(r) > threshold)
return;
222 J[0] = -Tj_Cq[2] * Ri_Cnormal_p[1] + Tj_Cq[1] * Ri_Cnormal_p[2];
223 J[1] = Tj_Cq[2] * Ri_Cnormal_p[0] - Tj_Cq[0] * Ri_Cnormal_p[2];
224 J[2] = -Tj_Cq[1] * Ri_Cnormal_p[0] + Tj_Cq[0] * Ri_Cnormal_p[1];
225 J[3] = Ri_Cnormal_p[0];
226 J[4] = Ri_Cnormal_p[1];
227 J[5] = Ri_Cnormal_p[2];
230 for (
int k = 0; k < 6; ++k) {
233 idx[k + 0] = 6 * i + k;
234 idx[k + 6] = 6 * j + k;
238 for (
int k = 0; k < 8; ++k) {
239 J[12 + k * 3 + 0] = cgrid_ratio_p[k] * Cnormal_p[0];
240 J[12 + k * 3 + 1] = cgrid_ratio_p[k] * Cnormal_p[1];
241 J[12 + k * 3 + 2] = cgrid_ratio_p[k] * Cnormal_p[2];
243 idx[12 + k * 3 + 0] = 6 * n_frags + cgrid_idx_p[k] * 3 + 0;
244 idx[12 + k * 3 + 1] = 6 * n_frags + cgrid_idx_p[k] * 3 + 1;
245 idx[12 + k * 3 + 2] = 6 * n_frags + cgrid_idx_p[k] * 3 + 2;
249 for (
int k = 0; k < 8; ++k) {
250 J[36 + k * 3 + 0] = -cgrid_ratio_q[k] * RjTRi_Cnormal_p[0];
251 J[36 + k * 3 + 1] = -cgrid_ratio_q[k] * RjTRi_Cnormal_p[1];
252 J[36 + k * 3 + 2] = -cgrid_ratio_q[k] * RjTRi_Cnormal_p[2];
254 idx[36 + k * 3 + 0] = 6 * n_frags + cgrid_idx_q[k] * 3 + 0;
255 idx[36 + k * 3 + 1] = 6 * n_frags + cgrid_idx_q[k] * 3 + 1;
256 idx[36 + k * 3 + 2] = 6 * n_frags + cgrid_idx_q[k] * 3 + 2;
260#if defined(__CUDACC__)
261 for (
int ki = 0; ki < 60; ++ki) {
262 for (
int kj = 0; kj < 60; ++kj) {
263 float AtA_ij = J[ki] * J[kj];
264 int ij = idx[ki] * n_vars + idx[kj];
265 atomicAdd(AtA_ptr + ij, AtA_ij);
267 float Atb_i = J[ki] * r;
268 atomicAdd(Atb_ptr + idx[ki], Atb_i);
270 atomicAdd(residual_ptr, r * r);
272#pragma omp critical(FillInSLACAlignmentTermCPU)
274 for (
int ki = 0; ki < 60; ++ki) {
275 for (
int kj = 0; kj < 60; ++kj) {
276 AtA_ptr[idx[ki] * n_vars + idx[kj]]
279 Atb_ptr[idx[ki]] += J[ki] * r;
281 *residual_ptr += r * r;
304 int64_t n = grid_idx.GetLength();
305 int64_t n_vars = Atb.GetLength();
307 float *AtA_ptr =
static_cast<float *
>(AtA.GetDataPtr());
308 float *Atb_ptr =
static_cast<float *
>(Atb.GetDataPtr());
309 float *residual_ptr =
static_cast<float *
>(residual.GetDataPtr());
311 const int *grid_idx_ptr =
static_cast<const int *
>(grid_idx.GetDataPtr());
312 const int *grid_nbs_idx_ptr =
313 static_cast<const int *
>(grid_nbs_idx.GetDataPtr());
314 const bool *grid_nbs_mask_ptr =
315 static_cast<const bool *
>(grid_nbs_mask.GetDataPtr());
317 const float *positions_init_ptr =
318 static_cast<const float *
>(positions_init.GetDataPtr());
319 const float *positions_curr_ptr =
320 static_cast<const float *
>(positions_curr.GetDataPtr());
323 AtA.GetDevice(), n, [=]
OPEN3D_DEVICE(int64_t workload_idx) {
325 int idx_i = grid_idx_ptr[workload_idx];
327 const int *idx_nbs = grid_nbs_idx_ptr + 6 * workload_idx;
328 const bool *mask_nbs = grid_nbs_mask_ptr + 6 * workload_idx;
331 float cov[3][3] = {{0}};
332 float U[3][3], V[3][3], S[3];
335 for (
int k = 0; k < 6; ++k) {
336 bool mask_k = mask_nbs[k];
337 if (!mask_k)
continue;
339 int idx_k = idx_nbs[k];
342 float diff_ik_init[3] = {
343 positions_init_ptr[idx_i * 3 + 0] -
344 positions_init_ptr[idx_k * 3 + 0],
345 positions_init_ptr[idx_i * 3 + 1] -
346 positions_init_ptr[idx_k * 3 + 1],
347 positions_init_ptr[idx_i * 3 + 2] -
348 positions_init_ptr[idx_k * 3 + 2]};
349 float diff_ik_curr[3] = {
350 positions_curr_ptr[idx_i * 3 + 0] -
351 positions_curr_ptr[idx_k * 3 + 0],
352 positions_curr_ptr[idx_i * 3 + 1] -
353 positions_curr_ptr[idx_k * 3 + 1],
354 positions_curr_ptr[idx_i * 3 + 2] -
355 positions_curr_ptr[idx_k * 3 + 2]};
359 for (
int i = 0; i < 3; ++i) {
360 for (
int j = 0; j < 3; ++j) {
361 cov[i][j] += diff_ik_init[i] * diff_ik_curr[j];
388 if (idx_i == anchor_idx) {
389 R[0][0] = R[1][1] = R[2][2] = 1;
390 R[0][1] = R[0][2] = R[1][0] = R[1][2] = R[2][0] = R[2][1] =
393 for (
int k = 0; k < 6; ++k) {
394 bool mask_k = mask_nbs[k];
397 int idx_k = idx_nbs[k];
399 float diff_ik_init[3] = {
400 positions_init_ptr[idx_i * 3 + 0] -
401 positions_init_ptr[idx_k * 3 + 0],
402 positions_init_ptr[idx_i * 3 + 1] -
403 positions_init_ptr[idx_k * 3 + 1],
404 positions_init_ptr[idx_i * 3 + 2] -
405 positions_init_ptr[idx_k * 3 + 2]};
406 float diff_ik_curr[3] = {
407 positions_curr_ptr[idx_i * 3 + 0] -
408 positions_curr_ptr[idx_k * 3 + 0],
409 positions_curr_ptr[idx_i * 3 + 1] -
410 positions_curr_ptr[idx_k * 3 + 1],
411 positions_curr_ptr[idx_i * 3 + 2] -
412 positions_curr_ptr[idx_k * 3 + 2]};
413 float R_diff_ik_curr[3];
415 core::linalg::kernel::matmul3x3_3x1(*R, diff_ik_init,
419 local_r[0] = diff_ik_curr[0] - R_diff_ik_curr[0];
420 local_r[1] = diff_ik_curr[1] - R_diff_ik_curr[1];
421 local_r[2] = diff_ik_curr[2] - R_diff_ik_curr[2];
423 int offset_idx_i = 3 * idx_i + 6 * n_frags;
424 int offset_idx_k = 3 * idx_k + 6 * n_frags;
426#if defined(__CUDACC__)
428 atomicAdd(residual_ptr,
429 weight * (local_r[0] * local_r[0] +
430 local_r[1] * local_r[1] +
431 local_r[2] * local_r[2]));
433 for (
int axis = 0; axis < 3; ++axis) {
435 atomicAdd(&AtA_ptr[(offset_idx_i + axis) * n_vars +
436 offset_idx_i + axis],
438 atomicAdd(&AtA_ptr[(offset_idx_k + axis) * n_vars +
439 offset_idx_k + axis],
441 atomicAdd(&AtA_ptr[(offset_idx_i + axis) * n_vars +
442 offset_idx_k + axis],
444 atomicAdd(&AtA_ptr[(offset_idx_k + axis) * n_vars +
445 offset_idx_i + axis],
449 atomicAdd(&Atb_ptr[offset_idx_i + axis],
451 atomicAdd(&Atb_ptr[offset_idx_k + axis],
455#pragma omp critical(FillInSLACRegularizerTermCPU)
458 *residual_ptr +=
weight * (local_r[0] * local_r[0] +
459 local_r[1] * local_r[1] +
460 local_r[2] * local_r[2]);
462 for (
int axis = 0; axis < 3; ++axis) {
464 AtA_ptr[(offset_idx_i + axis) * n_vars +
465 offset_idx_i + axis] +=
weight;
466 AtA_ptr[(offset_idx_k + axis) * n_vars +
467 offset_idx_k + axis] +=
weight;
469 AtA_ptr[(offset_idx_i + axis) * n_vars +
470 offset_idx_k + axis] -=
weight;
471 AtA_ptr[(offset_idx_k + axis) * n_vars +
472 offset_idx_i + axis] -=
weight;
475 Atb_ptr[offset_idx_i + axis] +=
weight * local_r[axis];
476 Atb_ptr[offset_idx_k + axis] -=
weight * local_r[axis];
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:145
void FillInRigidAlignmentTermCPU(core::Tensor &AtA, core::Tensor &Atb, core::Tensor &residual, const core::Tensor &Ti_qs, const core::Tensor &Tj_qs, const core::Tensor &Ri_normal_ps, int i, int j, float threshold)
Definition FillInLinearSystemImpl.h:42
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:292