Skip to content

Commit 7d9df8c

Browse files
yuvaltassacopybara-github
authored andcommitted
Fill-in qM CSR matrix structure on mjData (currently unused).
PiperOrigin-RevId: 733258529 Change-Id: I903548ae60139e4858550194e1aedf0efa2f3033
1 parent c72c83a commit 7d9df8c

File tree

2 files changed

+75
-23
lines changed

2 files changed

+75
-23
lines changed

src/engine/engine_io.c

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@ int mj_sizeModel(const mjModel* m) {
928928
// construct sparse representation of dof-dof matrix
929929
static void makeDofDofSparse(const mjModel* m, mjData* d,
930930
int* rownnz, int* rowadr, int* diag, int* colind,
931-
int reduced) {
931+
int reduced, int upper) {
932932
int nv = m->nv;
933933

934934
// no dofs, nothing to do
@@ -947,13 +947,13 @@ static void makeDofDofSparse(const mjModel* m, mjData* d,
947947
rownnz[i]++;
948948

949949
// process below diagonal unless reduced and dof is simple
950-
if (!reduced || !m->dof_simplenum[i]) {
950+
if (!(reduced && m->dof_simplenum[i])) {
951951
while ((j = m->dof_parentid[j]) >= 0) {
952952
// both reduced and non-reduced have lower triangle
953953
rownnz[i]++;
954954

955-
// only non-reduced has upper triangle
956-
if (!reduced) rownnz[j]++;
955+
// add upper triangle if requested
956+
if (upper) rownnz[j]++;
957957
}
958958
}
959959
}
@@ -972,14 +972,14 @@ static void makeDofDofSparse(const mjModel* m, mjData* d,
972972
colind[rowadr[i] + remaining[i]] = i;
973973

974974
// process below diagonal unless reduced and dof is simple
975-
if (!reduced || !m->dof_simplenum[i]) {
975+
if (!(reduced && m->dof_simplenum[i])) {
976976
int j = i;
977977
while ((j = m->dof_parentid[j]) >= 0) {
978978
remaining[i]--;
979979
colind[rowadr[i] + remaining[i]] = j;
980980

981-
// only non-reduced has upper triangle
982-
if (!reduced) {
981+
// add upper triangle if requested
982+
if (upper) {
983983
remaining[j]--;
984984
colind[rowadr[j] + remaining[j]] = i;
985985
}
@@ -995,7 +995,8 @@ static void makeDofDofSparse(const mjModel* m, mjData* d,
995995
}
996996

997997
// check total nnz; SHOULD NOT OCCUR
998-
if (rowadr[nv - 1] + rownnz[nv - 1] != (reduced ? m->nC : m->nD)) {
998+
int expected_nnz = upper ? m->nD : (reduced ? m->nC : m->nM);
999+
if (rowadr[nv - 1] + rownnz[nv - 1] != expected_nnz) {
9991000
mjERROR("sum of rownnz different from expected");
10001001
}
10011002

@@ -1131,18 +1132,23 @@ static void checkDBSparse(const mjModel* m, mjData* d) {
11311132

11321133

11331134

1134-
// integer valued dst[D or C] = src[M], handle different sparsity representations
1135+
// integer valued dst[D or C or M] = src[M (legacy)], handle different sparsity representations
11351136
static void copyM2Sparse(const mjModel* m, mjData* d, int* dst, const int* src,
1136-
int reduced) {
1137+
int reduced, int upper) {
11371138
int nv = m->nv;
11381139
const int* rownnz;
11391140
const int* rowadr;
1140-
if (reduced) {
1141+
if (reduced && !upper) {
11411142
rownnz = d->C_rownnz;
11421143
rowadr = d->C_rowadr;
1143-
} else {
1144+
} else if (!reduced && !upper) {
1145+
rownnz = d->M_rownnz;
1146+
rowadr = d->M_rowadr;
1147+
} else if (!reduced && upper) {
11441148
rownnz = d->D_rownnz;
11451149
rowadr = d->D_rowadr;
1150+
} else {
1151+
mjERROR("unsupported sparsity structure (reduced + upper)");
11461152
}
11471153

11481154
mj_markStack(d);
@@ -1160,14 +1166,14 @@ static void copyM2Sparse(const mjModel* m, mjData* d, int* dst, const int* src,
11601166
adr++;
11611167

11621168
// process below diagonal unless reduced and dof is simple
1163-
if (!reduced || !m->dof_simplenum[i]) {
1169+
if (!(reduced && m->dof_simplenum[i])) {
11641170
int j = i;
11651171
while ((j = m->dof_parentid[j]) >= 0) {
11661172
remaining[i]--;
11671173
dst[rowadr[i] + remaining[i]] = src[adr];
11681174

1169-
// only non-reduced has upper triangle
1170-
if (!reduced) {
1175+
// add upper triangle if requested
1176+
if (upper) {
11711177
remaining[j]--;
11721178
dst[rowadr[j] + remaining[j]] = src[adr];
11731179
}
@@ -1213,16 +1219,16 @@ static void copyD2MSparse(const mjModel* m, const mjData* d, int* dst, const int
12131219

12141220

12151221

1216-
// construct index mappings between M <-> D and M -> C
1217-
static void makeDofDofmap(const mjModel* m, mjData* d) {
1222+
// construct index mappings between M <-> D, M -> C, M (legacy) -> M (CSR)
1223+
static void makeDofDofmaps(const mjModel* m, mjData* d) {
12181224
int nM = m->nM, nC = m->nC, nD = m->nD;
12191225
mj_markStack(d);
12201226

12211227
// make mapM2D
12221228
int* M = mjSTACKALLOC(d, nM, int);
12231229
for (int i=0; i < nM; i++) M[i] = i;
12241230
for (int i=0; i < nD; i++) d->mapM2D[i] = -1;
1225-
copyM2Sparse(m, d, d->mapM2D, M, /*reduced=*/0);
1231+
copyM2Sparse(m, d, d->mapM2D, M, /*reduced=*/0, /*upper=*/1);
12261232

12271233
// check that all indices are filled in
12281234
for (int i=0; i < nD; i++) {
@@ -1246,7 +1252,7 @@ static void makeDofDofmap(const mjModel* m, mjData* d) {
12461252

12471253
// make mapM2C
12481254
for (int i=0; i < nC; i++) d->mapM2C[i] = -1;
1249-
copyM2Sparse(m, d, d->mapM2C, M, /*reduced=*/1);
1255+
copyM2Sparse(m, d, d->mapM2C, M, /*reduced=*/1, /*upper=*/0);
12501256

12511257
// check that all indices are filled in
12521258
for (int i=0; i < nC; i++) {
@@ -1255,6 +1261,17 @@ static void makeDofDofmap(const mjModel* m, mjData* d) {
12551261
}
12561262
}
12571263

1264+
// make mapM2M
1265+
for (int i=0; i < nM; i++) d->mapM2M[i] = -1;
1266+
copyM2Sparse(m, d, d->mapM2M, M, /*reduced=*/0, /*upper=*/0);
1267+
1268+
// check that all indices are filled in
1269+
for (int i=0; i < nM; i++) {
1270+
if (d->mapM2M[i] < 0) {
1271+
mjERROR("unassigned index in mapM2M");
1272+
}
1273+
}
1274+
12581275
mj_freeStack(d);
12591276
}
12601277

@@ -1965,15 +1982,19 @@ static void _resetData(const mjModel* m, mjData* d, unsigned char debug_value) {
19651982
// construct sparse matrix representations
19661983
if (m->body_dofadr) {
19671984
// make D
1968-
makeDofDofSparse(m, d, d->D_rownnz, d->D_rowadr, d->D_diag, d->D_colind, /*reduced=*/0);
1985+
makeDofDofSparse(m, d, d->D_rownnz, d->D_rowadr, d->D_diag, d->D_colind,
1986+
/*reduced=*/0, /*upper=*/1);
19691987

19701988
// make B, check D and B
19711989
makeBSparse(m, d);
19721990
checkDBSparse(m, d);
19731991

1974-
// make C
1975-
makeDofDofSparse(m, d, d->C_rownnz, d->C_rowadr, NULL, d->C_colind, /*reduced=*/1);
1976-
makeDofDofmap(m, d);
1992+
// make M, C
1993+
makeDofDofSparse(m, d, d->M_rownnz, d->M_rowadr, NULL, d->M_colind, /*reduced=*/0, /*upper=*/0);
1994+
makeDofDofSparse(m, d, d->C_rownnz, d->C_rowadr, NULL, d->C_colind, /*reduced=*/1, /*upper=*/0);
1995+
1996+
// make index mappings: mapM2D, mapD2M, mapM2C, mapM2M
1997+
makeDofDofmaps(m, d);
19771998
}
19781999

19792000
// restore pluginstate and plugindata

src/engine/engine_print.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,37 @@ void mj_printFormattedData(const mjModel* m, const mjData* d, const char* filena
11611161
}
11621162
fprintf(fp, "\n\n");
11631163

1164+
// M sparse structure
1165+
mj_printSparsity("M: inertia matrix", m->nv, m->nv, d->M_rowadr, NULL, d->M_rownnz,
1166+
NULL, d->M_colind, fp);
1167+
1168+
fprintf(fp, NAME_FORMAT, "M_rownnz");
1169+
for (int i = 0; i < m->nv; i++) {
1170+
fprintf(fp, " %d", d->M_rownnz[i]);
1171+
}
1172+
fprintf(fp, "\n\n");
1173+
1174+
// M_rowadr
1175+
fprintf(fp, NAME_FORMAT, "M_rowadr");
1176+
for (int i = 0; i < m->nv; i++) {
1177+
fprintf(fp, " %d", d->M_rowadr[i]);
1178+
}
1179+
fprintf(fp, "\n\n");
1180+
1181+
// M_colind
1182+
fprintf(fp, NAME_FORMAT, "M_colind");
1183+
for (int i = 0; i < m->nM; i++) {
1184+
fprintf(fp, " %d", d->M_colind[i]);
1185+
}
1186+
fprintf(fp, "\n\n");
1187+
1188+
// mapM2M
1189+
fprintf(fp, NAME_FORMAT, "mapM2M");
1190+
for (int i = 0; i < m->nM; i++) {
1191+
fprintf(fp, " %d", d->mapM2M[i]);
1192+
}
1193+
fprintf(fp, "\n\n");
1194+
11641195
// C sparse structure
11651196
mj_printSparsity("C: reduced dof-dof matrix", m->nv, m->nv, d->C_rowadr, NULL, d->C_rownnz,
11661197
NULL, d->C_colind, fp);

0 commit comments

Comments
 (0)