Fix printing of non-zero coeffs after cut passes#858
Fix printing of non-zero coeffs after cut passes#858mtanneau wants to merge 2 commits intoNVIDIA:mainfrom
Conversation
Signed-off-by: mtanneau <mathieu.tanneau@gmail.com>
📝 WalkthroughWalkthroughA single line in a logging statement was modified to replace accessing the nonzero count via Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~2 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
The line of code should be correct as is. I think you may be exposing another bug. Can you send the output you get that doesn't make sense? |
chris-maes
left a comment
There was a problem hiding this comment.
A.col_start[A.n] should always be equal to the number of nonzeros. I think you may be hitting another bug.
Let's fix the original bug rather than merging this change.
|
Here is the output I get on air05.mps |
|
Let me run this again and share the logs here. OK, here we go. Note the following:
Setting CUDA_MODULE_LOADING to EAGER
Reading file air05.mps
cuOpt version: 26.4.0, git hash: b3bb21e4, host arch: aarch64, device archs: 121a-real
CPU: Unknown, threads (physical/logical): 1/20, RAM: 96.08 GiB
CUDA 12.9, device: NVIDIA GB10 (ID 0), VRAM: 119.70 GiB
CUDA device UUID: 43bce240-d7d6-65e5-ca7a-e351bab5de7a
Solving a problem with 426 constraints, 7195 variables (7195 integers), and 52121 nonzeros
Problem scaling:
Objective coefficents range: [4e+01, 3e+03]
Constraint matrix coefficients range: [1e+00, 1e+00]
Constraint rhs / bounds range: [1e+00, 1e+00]
Variable bounds range: [0e+00, 1e+00]
Original problem: 426 constraints, 7195 variables, 52121 nonzeros
Calling Papilo presolver (git hash 741a2b9c)
Presolve status: reduced the problem
Presolve removed: 90 constraints, 1116 variables, 16171 nonzeros
Presolved problem: 336 constraints, 6079 variables, 35950 nonzeros
Objective function is integral
Papilo presolve time: 0.42
Objective offset 9167.000000 scaling_factor 1.000000
Model fingerprint: 0x3257a27
Running presolve!
Unused variables detected, eliminating them! Unused var count 4
After cuOpt presolve: 335 constraints, 6075 variables, objective offset 9167.000000.
cuOpt presolve time: 3.85
Solving LP root relaxation in concurrent mode
Skipping column scaling
Dual Simplex Phase 1
Dual feasible solution found.
Dual Simplex Phase 2
Iter Objective Num Inf. Sum Inf. Perturb Time
0 -8.1936000000000000e+04 277 2.31020000e+04 0.00e+00 4.51
1 -8.0926000000000000e+04 266 1.48790000e+04 0.00e+00 4.51
1000 -5.7784953825729302e+04 127 1.13852044e+02 0.00e+00 4.61
Root relaxation solution found in 1194 iterations and 0.13s by Dual Simplex
Root relaxation objective +2.58776093e+04
| Explored | Unexplored | Objective | Bound | IntInf | Depth | Iter/Node | Gap | Time |
0 0 +inf +2.588508e+04 228 0 1.2e+03 - 4.74
Gomory cuts : 1
MIR cuts : 0
Knapsack cuts : 0
Strong CG cuts : 0
Cut pool size : 211
Size with cuts : 336 constraints, 6411 variables, -1488061860 nonzeros
Strong branching using 19 threads and 228 fractional variables
Strong branching completed in 0.47s
Exploring the B&B tree using 19 threads
| Explored | Unexplored | Objective | Bound | IntInf | Depth | Iter/Node | Gap | Time |
H +4.466800e+04 +2.588508e+04 42.1% 5.28
H +4.448000e+04 +2.588508e+04 41.8% 5.28
H +4.430000e+04 +2.588508e+04 41.6% 5.29
H +4.387300e+04 +2.588508e+04 41.0% 5.29
H +4.354400e+04 +2.588508e+04 40.6% 5.30
H +4.287600e+04 +2.588508e+04 39.6% 5.31
H +4.191500e+04 +2.588508e+04 38.2% 5.32
H +4.166800e+04 +2.588508e+04 37.9% 5.34
H +4.149500e+04 +2.588508e+04 37.6% 5.35
H +4.121300e+04 +2.588508e+04 37.2% 5.37
D 42 44 +2.657100e+04 +2.591578e+04 0 16 1.4e+02 2.5% 6.78
B 44 44 +2.645600e+04 +2.591578e+04 0 19 1.3e+02 2.0% 6.78
D 62 56 +2.644800e+04 +2.591578e+04 0 30 1.3e+02 2.0% 6.85
D 71 63 +2.644500e+04 +2.595460e+04 0 30 1.3e+02 1.9% 6.87
D 71 63 +2.644100e+04 +2.595460e+04 0 29 1.3e+02 1.8% 6.87
D 77 63 +2.643900e+04 +2.595460e+04 0 27 1.3e+02 1.8% 6.88
B 170 110 +2.640200e+04 +2.610151e+04 0 12 1.1e+02 1.1% 7.16
D 342 127 +2.640000e+04 +2.624972e+04 0 19 9.6e+01 0.6% 7.60
D 344 129 +2.637500e+04 +2.624972e+04 0 17 9.6e+01 0.5% 7.61
D 348 128 +2.637400e+04 +2.626036e+04 0 17 9.6e+01 0.4% 7.62
Explored 485 nodes in 7.79s.
Absolute Gap -5.595838e+00 Objective 2.6374000000000022e+04 Lower Bound 2.6379595837897017e+04
Optimal solution found.
Solution objective: 26374.000000 , relative_mip_gap 0.000212 solution_bound 26379.595838 presolve_time 4.275866 total_solve_time 7.854454 max constraint violation 0.000000 max int violation 0.000000 max var bounds violation 0.000000 nodes 485 simplex_iterations 40126
|
|
The issue does seem to be coming from how Printing directly to console using std::cout << "( cout) nnz = " << original_lp_.A.col_start[original_lp_.A.n] << std::endl;
printf("(printf) nnz = %d\n", original_lp_.A.col_start[original_lp_.A.n]);yields the following output for me: ( cout) nnz = 42295
(printf) nnz = 459570076 # typically non-sensical value |
|
I'm able to narrow it down to the following MRE: // this displays weird output
ins_vector<i_t> x(2);
x[0] = 0;
x[1] = 1;
printf("x = [%d, %d]\n", x[0], x[1]);
// but this doesn't
std::vector<i_t> y = {10, 11};
printf("(printf) y=[%d, %d]\n", y[0], y[1]);which, on my system, outputs (printf) x=[1208483168, 1635283872]
(printf) y=[10, 11]My best guess is that when printf is passed the array element directly, it somehow sees extra data (maybe an extra pointer)? No issue occurs when extracting the numerical value and casting it to |
|
Ok. Thanks. The printing issue is likely caused by the The bigger issue is the gap is negative and lower bound is greater than the upper bound. |
|
I confirm this is caused by a nasty interaction between ins_vector, which uses an element_proxy_t object to monitor dereferences, and C-style varargs used by printf. C++ type casting dynamics usually prevent this, but varags were obviously not conceived with fancy C++ tricks in mind :) Chris' PR will resolve this naturally, as |
|
Thanks @chris-maes and @aliceb-nv for looking into this! |
Description
I tracked the issue of non-sensical number of non-zeros to this line:
cuopt/cpp/src/branch_and_bound/branch_and_bound.cpp
Line 2346 in f91f9cc
And replaced the manual access to
A.col_start[A.n]withA.nnz().For completeness, I tried the following variants:
A.nnz()printfstatement, then print it. Use templated integer type.printfstatement, then print it. Useautotype.I suspect that directly accessing
A.col_start[A.n]causes the value to be cast to the wrong type, which then causes some kind of issue insideprintf. To see this, change the printf statement above towhich should output something like
when solving the
air05.mpsinstance.I also checked that all 4 variants are displayed as expected when printed directly to
std::cout.Issue
Addresses part of #855, namely the number of non-zeros after cuts have been added
Checklist
Summary by CodeRabbit