HiGHS.jl icon indicating copy to clipboard operation
HiGHS.jl copied to clipboard

Add a macro to trace ccall for debugging

Open odow opened this issue 1 year ago • 4 comments

x-ref #257

I don't necessarily think we should merge this, but it could be super useful for debugging.

Code like this:

using JuMP, HiGHS
HiGHS.HIGHS_LOG_FILE() = "/tmp/highs.log"
model = direct_model(HiGHS.Optimizer())
@variable(model, x >= 1, Int)
@objective(model, Min, 2 * x + 3)
@constraint(model, x <= 2)
optimize!(model)
termination_status(model)
@constraint(model, x <= 0.4)
optimize!(model)
model = nothing
GC.gc()
HiGHS.HIGHS_LOG_FILE() = nothing
model = direct_model(HiGHS.Optimizer())

gives

# === New call ===
ret = Highs_create()
# ret = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
offset = 0.0
ret = Highs_changeObjectiveOffset(highs, offset)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# offset = 0.0

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
offset = Base.RefValue{Float64}(0.0)
ret = Highs_getObjectiveOffset(highs, offset)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# offset = Base.RefValue{Float64}(0.0)

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getNumCols(highs)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getNumRows(highs)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
cost = 0.0
lower = 1.0
upper = Inf
num_new_nz = 0
index = Ptr{Nothing} @0x0000000000000000
value = Ptr{Nothing} @0x0000000000000000
ret = Highs_addCol(highs, cost, lower, upper, num_new_nz, index, value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# cost = 0.0
# lower = 1.0
# upper = Inf
# num_new_nz = 0
# index = Ptr{Nothing} @0x0000000000000000
# value = Ptr{Nothing} @0x0000000000000000

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
col = 0
integrality = 1
ret = Highs_changeColIntegrality(highs, col, integrality)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# col = 0
# integrality = 1

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
sense = 1
ret = Highs_changeObjectiveSense(highs, sense)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# sense = 1

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
from_col = 0
to_col = 0
cost = [2.0]
ret = Highs_changeColsCostByRange(highs, from_col, to_col, cost)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# from_col = 0
# to_col = 0
# cost = [2.0]

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
offset = 3.0
ret = Highs_changeObjectiveOffset(highs, offset)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# offset = 3.0

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
lower = -Inf
upper = 2.0
num_new_nz = 1
index = Int32[0]
value = [1.0]
ret = Highs_addRow(highs, lower, upper, num_new_nz, index, value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# lower = -Inf
# upper = 2.0
# num_new_nz = 1
# index = Int32[0]
# value = [1.0]

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
from_row = 0
to_row = 0
num_row = Base.RefValue{Int32}(0)
lower = Base.RefValue{Float64}(5.0e-324)
upper = Base.RefValue{Float64}(2.2334351274e-314)
num_nz = Base.RefValue{Int32}(0)
matrix_start = Base.RefValue{Int32}(0)
matrix_index = Ptr{Nothing} @0x0000000000000000
matrix_value = Ptr{Nothing} @0x0000000000000000
ret = Highs_getRowsByRange(highs, from_row, to_row, num_row, lower, upper, num_nz, matrix_start, matrix_index, matrix_value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# from_row = 0
# to_row = 0
# num_row = Base.RefValue{Int32}(1)
# lower = Base.RefValue{Float64}(-Inf)
# upper = Base.RefValue{Float64}(2.0)
# num_nz = Base.RefValue{Int32}(1)
# matrix_start = Base.RefValue{Int32}(0)
# matrix_index = Ptr{Nothing} @0x0000000000000000
# matrix_value = Ptr{Nothing} @0x0000000000000000

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
from_row = 0
to_row = 0
num_row = Base.RefValue{Int32}(1)
lower = Base.RefValue{Float64}(-Inf)
upper = Base.RefValue{Float64}(2.0)
num_nz = Base.RefValue{Int32}(1)
matrix_start = Base.RefValue{Int32}(0)
matrix_index = Int32[954744816]
matrix_value = [1.05820275752e-312]
ret = Highs_getRowsByRange(highs, from_row, to_row, num_row, lower, upper, num_nz, matrix_start, matrix_index, matrix_value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# from_row = 0
# to_row = 0
# num_row = Base.RefValue{Int32}(1)
# lower = Base.RefValue{Float64}(-Inf)
# upper = Base.RefValue{Float64}(2.0)
# num_nz = Base.RefValue{Int32}(1)
# matrix_start = Base.RefValue{Int32}(0)
# matrix_index = Int32[0]
# matrix_value = [1.0]

# === New call ===
ret = Highs_versionMajor()
# ret = 1

# === New call ===
ret = Highs_versionMinor()
# ret = 8

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_zeroAllClocks(highs)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_run(highs)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getNumCols(highs)
# ret = 1
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getNumRows(highs)
# ret = 1
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getModelStatus(highs)
# ret = 7
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
info = "primal_solution_status"
value = Base.RefValue{Int32}(1064750752)
ret = Highs_getIntInfoValue(highs, info, value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# info = "primal_solution_status"
# value = Base.RefValue{Int32}(2)

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
info = "dual_solution_status"
value = Base.RefValue{Int32}(2)
ret = Highs_getIntInfoValue(highs, info, value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# info = "dual_solution_status"
# value = Base.RefValue{Int32}(0)

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
col_value = [2.4085422886e-314]
col_dual = [2.408542332e-314]
row_value = [2.4085423716e-314]
row_dual = [2.408542411e-314]
ret = Highs_getSolution(highs, col_value, col_dual, row_value, row_dual)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# col_value = [1.0]
# col_dual = [0.0]
# row_value = [1.0]
# row_dual = [0.0]

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
col_status = Int32[180390544]
row_status = Int32[561686864]
ret = Highs_getBasis(highs, col_status, row_status)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# col_status = Int32[0]
# row_status = Int32[0]

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
lower = -Inf
upper = 0.4
num_new_nz = 1
index = Int32[0]
value = [1.0]
ret = Highs_addRow(highs, lower, upper, num_new_nz, index, value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# lower = -Inf
# upper = 0.4
# num_new_nz = 1
# index = Int32[0]
# value = [1.0]

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
from_row = 1
to_row = 1
num_row = Base.RefValue{Int32}(0)
lower = Base.RefValue{Float64}(2.145810613e-314)
upper = Base.RefValue{Float64}(2.145810613e-314)
num_nz = Base.RefValue{Int32}(0)
matrix_start = Base.RefValue{Int32}(0)
matrix_index = Ptr{Nothing} @0x0000000000000000
matrix_value = Ptr{Nothing} @0x0000000000000000
ret = Highs_getRowsByRange(highs, from_row, to_row, num_row, lower, upper, num_nz, matrix_start, matrix_index, matrix_value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# from_row = 1
# to_row = 1
# num_row = Base.RefValue{Int32}(1)
# lower = Base.RefValue{Float64}(-Inf)
# upper = Base.RefValue{Float64}(0.4)
# num_nz = Base.RefValue{Int32}(1)
# matrix_start = Base.RefValue{Int32}(0)
# matrix_index = Ptr{Nothing} @0x0000000000000000
# matrix_value = Ptr{Nothing} @0x0000000000000000

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
from_row = 1
to_row = 1
num_row = Base.RefValue{Int32}(1)
lower = Base.RefValue{Float64}(-Inf)
upper = Base.RefValue{Float64}(0.4)
num_nz = Base.RefValue{Int32}(1)
matrix_start = Base.RefValue{Int32}(0)
matrix_index = Int32[564017504]
matrix_value = [2.4006574633e-314]
ret = Highs_getRowsByRange(highs, from_row, to_row, num_row, lower, upper, num_nz, matrix_start, matrix_index, matrix_value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# from_row = 1
# to_row = 1
# num_row = Base.RefValue{Int32}(1)
# lower = Base.RefValue{Float64}(-Inf)
# upper = Base.RefValue{Float64}(0.4)
# num_nz = Base.RefValue{Int32}(1)
# matrix_start = Base.RefValue{Int32}(0)
# matrix_index = Int32[0]
# matrix_value = [1.0]

# === New call ===
ret = Highs_versionMajor()
# ret = 1

# === New call ===
ret = Highs_versionMinor()
# ret = 8

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_zeroAllClocks(highs)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_run(highs)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getNumCols(highs)
# ret = 1
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getNumRows(highs)
# ret = 2
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getModelStatus(highs)
# ret = 8
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
has_dual_ray = Base.RefValue{Int32}(1071479280)
dual_ray_value = [0.0, 1.5e-323]
ret = Highs_getDualRay(highs, has_dual_ray, dual_ray_value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# has_dual_ray = Base.RefValue{Int32}(1)
# dual_ray_value = [0.0, -1.0]

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getNumRows(highs)
# ret = 2
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
ret = Highs_getNumCols(highs)
# ret = 1
# highs = Ptr{Nothing} @0x00000001161de200

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
from_col = 0
to_col = 0
num_col = Base.RefValue{Int32}(0)
costs = Ptr{Nothing} @0x0000000000000000
lower = Ptr{Nothing} @0x0000000000000000
upper = Ptr{Nothing} @0x0000000000000000
num_nz = Base.RefValue{Int32}(0)
matrix_start = Ptr{Nothing} @0x0000000000000000
matrix_index = Ptr{Nothing} @0x0000000000000000
matrix_value = Ptr{Nothing} @0x0000000000000000
ret = Highs_getColsByRange(highs, from_col, to_col, num_col, costs, lower, upper, num_nz, matrix_start, matrix_index, matrix_value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# from_col = 0
# to_col = 0
# num_col = Base.RefValue{Int32}(1)
# costs = Ptr{Nothing} @0x0000000000000000
# lower = Ptr{Nothing} @0x0000000000000000
# upper = Ptr{Nothing} @0x0000000000000000
# num_nz = Base.RefValue{Int32}(2)
# matrix_start = Ptr{Nothing} @0x0000000000000000
# matrix_index = Ptr{Nothing} @0x0000000000000000
# matrix_value = Ptr{Nothing} @0x0000000000000000

# === New call ===
highs = Ptr{Nothing} @0x00000001161de200
from_col = 0
to_col = 0
num_col = Base.RefValue{Int32}(1)
costs = Ptr{Nothing} @0x0000000000000000
lower = [0.0]
upper = [0.0]
num_nz = Base.RefValue{Int32}(2)
matrix_start = Int32[0, 2]
matrix_index = Int32[0, 0]
matrix_value = [0.0, 0.0]
ret = Highs_getColsByRange(highs, from_col, to_col, num_col, costs, lower, upper, num_nz, matrix_start, matrix_index, matrix_value)
# ret = 0
# highs = Ptr{Nothing} @0x00000001161de200
# from_col = 0
# to_col = 0
# num_col = Base.RefValue{Int32}(1)
# costs = Ptr{Nothing} @0x0000000000000000
# lower = [1.0]
# upper = [Inf]
# num_nz = Base.RefValue{Int32}(2)
# matrix_start = Int32[0, 2]
# matrix_index = Int32[0, 1]
# matrix_value = [1.0, 1.0]

# === New call ===
highs = Ptr{Nothing} @0x0000000117023a00
ret = Highs_destroy(highs)
# ret = nothing
# highs = Ptr{Nothing} @0x0000000117023a00

odow avatar Dec 09 '24 02:12 odow

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 100.00%. Comparing base (c7e2fbd) to head (bf44959).

Additional details and impacted files
@@            Coverage Diff            @@
##            master      #258   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         1           
  Lines         1471      1471           
=========================================
  Hits          1471      1471           

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

codecov[bot] avatar Dec 09 '24 02:12 codecov[bot]

If the macro was: @trace ccall(...), using it would be a simple replace all. I'm not sure how easy it would be.

joaquimg avatar Jan 07 '25 18:01 joaquimg

This might be useful to add to a JuMP extension package for debugging and linting. I have, too often, manually traced the C API when building a MWE for Gurobi et al.

odow avatar Jan 07 '25 22:01 odow

More changes. As evidence, it helped me get a MWE for https://github.com/jump-dev/HiGHS.jl/issues/202

odow avatar Jan 08 '25 03:01 odow