Skip to content

Commit f21217c

Browse files
authored
Tighten loose CSR allocation bounds (#92)
* Tighten loose CSR allocation bounds across 7 sites * comment
1 parent 8b11ba7 commit f21217c

7 files changed

Lines changed: 21 additions & 11 deletions

File tree

src/atoms/affine/hstack.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "utils/CSR_sum.h"
2121
#include "utils/sparse_matrix.h"
2222
#include "utils/tracked_alloc.h"
23+
#include "utils/utils.h"
2324
#include <assert.h>
2425
#include <stdio.h>
2526
#include <stdlib.h>
@@ -114,9 +115,10 @@ static void wsum_hess_init_impl(expr *node)
114115
}
115116

116117
/* worst-case scenario the nnz of node->wsum_hess is the sum of children's
117-
nnz */
118-
CSR_matrix *H = new_CSR_matrix(node->n_vars, node->n_vars, nnz);
119-
hnode->CSR_work = new_CSR_matrix(node->n_vars, node->n_vars, nnz);
118+
nnz, capped by the output cell count */
119+
int nnz_ub = MIN(nnz, node->n_vars * node->n_vars);
120+
CSR_matrix *H = new_CSR_matrix(node->n_vars, node->n_vars, nnz_ub);
121+
hnode->CSR_work = new_CSR_matrix(node->n_vars, node->n_vars, nnz_ub);
120122

121123
/* fill sparsity pattern */
122124
H->nnz = 0;

src/atoms/affine/sum.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ static void jacobian_init_impl(expr *node)
9191
jacobian_init(x);
9292
CSR_matrix *Jx = x->jacobian->to_csr(x->jacobian);
9393

94-
/* we never have to store more than the child's nnz */
95-
CSR_matrix *jac = new_CSR_matrix(node->size, node->n_vars, Jx->nnz);
94+
/* we never have to store more than the child's nnz, nor more than the
95+
output's cell count */
96+
int max_nnz = MIN(Jx->nnz, node->size * node->n_vars);
97+
CSR_matrix *jac = new_CSR_matrix(node->size, node->n_vars, max_nnz);
9698
node->work->iwork = sp_malloc(MAX(jac->n, Jx->nnz) * sizeof(int));
9799
snode->idx_map = sp_malloc(Jx->nnz * sizeof(int));
98100

src/atoms/affine/trace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static void jacobian_init_impl(expr *node)
6666
total_nnz += A->p[row + 1] - A->p[row];
6767
}
6868

69-
CSR_matrix *jac = new_CSR_matrix(1, node->n_vars, total_nnz);
69+
CSR_matrix *jac = new_CSR_matrix(1, node->n_vars, MIN(total_nnz, node->n_vars));
7070

7171
// ---------------------------------------------------------------
7272
// fill sparsity pattern and idx_map

src/atoms/bivariate_full_dom/matmul.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ static void jacobian_init_chain_rule(expr *node)
241241
mnode->term1_CSR = YT_kron_I_alloc(m, k, n, f->work->jacobian_csc);
242242
mnode->term2_CSR = I_kron_X_alloc(m, k, n, g->work->jacobian_csc);
243243
int max_nnz = mnode->term1_CSR->nnz + mnode->term2_CSR->nnz;
244+
max_nnz = MIN(max_nnz, node->size * node->n_vars);
244245
CSR_matrix *jac = new_CSR_matrix(node->size, node->n_vars, max_nnz);
245246
sum_csr_alloc(mnode->term1_CSR, mnode->term2_CSR, jac);
246247
node->jacobian = new_sparse_matrix(jac);

src/problem.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,16 @@ void problem_init_hessian(problem *prob)
251251
nnz += prob->constraints[i]->wsum_hess->nnz;
252252
}
253253

254-
prob->lagrange_hessian = new_CSR_matrix(prob->n_vars, prob->n_vars, nnz);
255-
memset(prob->lagrange_hessian->x, 0, nnz * sizeof(double)); /* affine shortcut */
256-
prob->stats.nnz_hessian = nnz;
254+
int hess_nnz_ub = MIN(nnz, prob->n_vars * prob->n_vars);
255+
prob->lagrange_hessian = new_CSR_matrix(prob->n_vars, prob->n_vars, hess_nnz_ub);
256+
257+
/* affine shortcut */
258+
memset(prob->lagrange_hessian->x, 0, hess_nnz_ub * sizeof(double));
259+
257260
prob->hess_idx_map = (int *) sp_malloc(nnz * sizeof(int));
258261
int *iwork = (int *) sp_malloc(MAX(nnz, prob->n_vars) * sizeof(int));
259262
problem_lagrange_hess_fill_sparsity(prob, iwork);
263+
prob->stats.nnz_hessian = prob->lagrange_hessian->nnz;
260264
free(iwork);
261265

262266
clock_gettime(CLOCK_MONOTONIC, &timer.end);

src/utils/CSR_sum.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ CSR_matrix *sum_4_csr_alloc(const CSR_matrix *A, const CSR_matrix *B,
367367
const CSR_matrix *inputs[4] = {A, B, C, D};
368368
int m = A->m;
369369
int n = A->n;
370-
int nnz_ub = A->nnz + B->nnz + C->nnz + D->nnz;
370+
int nnz_ub = MIN(A->nnz + B->nnz + C->nnz + D->nnz, m * n);
371371

372372
/* allocate output and index maps */
373373
CSR_matrix *out = new_CSR_matrix(m, n, nnz_ub);

src/utils/sparse_matrix.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "utils/matrix.h"
2323
#include "utils/mini_numpy.h"
2424
#include "utils/tracked_alloc.h"
25+
#include "utils/utils.h"
2526
#include <stdlib.h>
2627
#include <string.h>
2728

@@ -122,7 +123,7 @@ static void sparse_transpose_fill_values(const matrix *self, matrix *out)
122123
static matrix *sparse_index_alloc(matrix *self, const int *indices, int n_idxs)
123124
{
124125
CSR_matrix *Jx = ((sparse_matrix *) self)->csr;
125-
CSR_matrix *J = new_CSR_matrix(n_idxs, self->n, Jx->nnz);
126+
CSR_matrix *J = new_CSR_matrix(n_idxs, self->n, MIN(Jx->nnz, n_idxs * self->n));
126127

127128
J->p[0] = 0;
128129
for (int i = 0; i < n_idxs; i++)

0 commit comments

Comments
 (0)