Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit df2eff3

Browse files
committedFeb 16, 2015
Fix 32 bit issue with cholmod.jl
1 parent 39516b6 commit df2eff3

File tree

2 files changed

+33
-33
lines changed

2 files changed

+33
-33
lines changed
 

‎base/sparse/cholmod.jl

+18-18
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ using Base.SparseMatrix: AbstractSparseMatrix, SparseMatrixCSC, increment, indty
2222
include("cholmod_h.jl")
2323

2424
## macro to generate the name of the C function according to the integer type
25-
macro cholmod_name(nm,typ) string("cholmod_", eval(typ) == Int64 ? "l_" : "", nm) end
25+
macro cholmod_name(nm,typ) string("cholmod_", eval(typ) == Int ? "l_" : "", nm) end
2626

2727
for Ti in IndexTypes
2828
@eval begin
@@ -198,54 +198,54 @@ end
198198

199199
### cholmod_core_h ###
200200
function allocate_dense(nrow::Integer, ncol::Integer, d::Integer, ::Type{Float64})
201-
d = Dense(ccall((:cholmod_allocate_dense, :libcholmod), Ptr{C_Dense{Float64}},
201+
d = Dense(ccall((:cholmod_l_allocate_dense, :libcholmod), Ptr{C_Dense{Float64}},
202202
(Csize_t, Csize_t, Csize_t, Cint, Ptr{Void}),
203-
nrow, ncol, d, REAL, common(Cint)))
203+
nrow, ncol, d, REAL, common(Int)))
204204
finalizer(d, free!)
205205
d
206206
end
207207
function allocate_dense(nrow::Integer, ncol::Integer, d::Integer, ::Type{Complex{Float64}})
208-
d = Dense(ccall((:cholmod_allocate_dense, :libcholmod), Ptr{C_Dense{Complex{Float64}}},
208+
d = Dense(ccall((:cholmod_l_allocate_dense, :libcholmod), Ptr{C_Dense{Complex{Float64}}},
209209
(Csize_t, Csize_t, Csize_t, Cint, Ptr{Void}),
210-
nrow, ncol, d, COMPLEX, common(Cint)))
210+
nrow, ncol, d, COMPLEX, common(Int)))
211211
finalizer(d, free!)
212212
d
213213
end
214214

215-
free_dense!{T}(p::Ptr{C_Dense{T}}) = ccall((:cholmod_free_dense, :libcholmod), Cint, (Ptr{Ptr{C_Dense{T}}}, Ptr{Void}), &p, common(Cint))
215+
free_dense!{T}(p::Ptr{C_Dense{T}}) = ccall((:cholmod_l_free_dense, :libcholmod), Cint, (Ptr{Ptr{C_Dense{T}}}, Ptr{Void}), &p, common(Cint))
216216

217217
function zeros{T<:VTypes}(m::Integer, n::Integer, ::Type{T})
218-
d = Dense(ccall((:cholmod_zeros, :libcholmod), Ptr{C_Dense{T}},
218+
d = Dense(ccall((:cholmod_l_zeros, :libcholmod), Ptr{C_Dense{T}},
219219
(Csize_t, Csize_t, Cint, Ptr{UInt8}),
220-
m, n, xtyp(T), common(Cint)))
220+
m, n, xtyp(T), common(Int)))
221221
finalizer(d, free!)
222222
d
223223
end
224224
zeros(m::Integer, n::Integer) = zeros(m, n, Float64)
225225

226226
function ones{T<:VTypes}(m::Integer, n::Integer, ::Type{T})
227-
d = Dense(ccall((:cholmod_ones, :libcholmod), Ptr{C_Dense{T}},
227+
d = Dense(ccall((:cholmod_l_ones, :libcholmod), Ptr{C_Dense{T}},
228228
(Csize_t, Csize_t, Cint, Ptr{UInt8}),
229-
m, n, xtyp(T), common(Cint)))
229+
m, n, xtyp(T), common(Int)))
230230
finalizer(d, free!)
231231
d
232232
end
233233
ones(m::Integer, n::Integer) = ones(m, n, Float64)
234234

235235
function eye{T<:VTypes}(m::Integer, n::Integer, ::Type{T})
236-
d = Dense(ccall((:cholmod_eye, :libcholmod), Ptr{C_Dense{T}},
236+
d = Dense(ccall((:cholmod_l_eye, :libcholmod), Ptr{C_Dense{T}},
237237
(Csize_t, Csize_t, Cint, Ptr{UInt8}),
238-
m, n, xtyp(T), common(Cint)))
238+
m, n, xtyp(T), common(Int)))
239239
finalizer(d, free!)
240240
d
241241
end
242242
eye(m::Integer, n::Integer) = eye(m, n, Float64)
243243
eye(n::Integer) = eye(n, n, Float64)
244244

245245
function copy_dense{Tv<:VTypes}(A::Dense{Tv})
246-
d = Dense(ccall((:cholmod_copy_dense, :libcholmod), Ptr{C_Dense{Tv}},
246+
d = Dense(ccall((:cholmod_l_copy_dense, :libcholmod), Ptr{C_Dense{Tv}},
247247
(Ptr{C_Dense{Tv}}, Ptr{UInt8}),
248-
A.p, common(Cint)))
248+
A.p, common(Int)))
249249
finalizer(d, free!)
250250
d
251251
end
@@ -260,16 +260,16 @@ function norm_dense{Tv<:VTypes}(D::Dense{Tv}, p::Integer)
260260
elseif p != 0 && p != 1
261261
throw(ArgumentError("second argument must be either 0 (Inf norm), 1, or 2"))
262262
end
263-
ccall((:cholmod_norm_dense, :libcholmod), Cdouble,
263+
ccall((:cholmod_l_norm_dense, :libcholmod), Cdouble,
264264
(Ptr{C_Dense{Tv}}, Cint, Ptr{UInt8}),
265-
D.p, p, common(Cint))
265+
D.p, p, common(Int))
266266
end
267267

268268
### cholmod_check.h ###
269269
function check_dense{T<:VTypes}(A::Dense{T})
270-
bool(ccall((:cholmod_check_dense, :libcholmod), Cint,
270+
bool(ccall((:cholmod_l_check_dense, :libcholmod), Cint,
271271
(Ptr{C_Dense{T}}, Ptr{UInt8}),
272-
A.p, common(Cint)))
272+
A.p, common(Int)))
273273
end
274274

275275
# Non-Dense wrappers (which all depend on IType)

‎test/sparsedir/cholmod.jl

+15-15
Original file line numberDiff line numberDiff line change
@@ -194,51 +194,51 @@ run(`rm tmp.mtx`)
194194
# test that Sparse(Ptr) constructor throws the right places
195195
## The struct pointer must be constructed by the library constructor and then modified afterwards to checks that the method throws
196196
### illegal dtype (for now but should be supprted at some point)
197-
p = ccall((:cholmod_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
197+
p = ccall((:cholmod_l_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
198198
(Csize_t, Csize_t, Csize_t, Cint, Cint, Cint, Cint, Ptr{Void}),
199-
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Cint))
199+
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Int))
200200
puint = convert(Ptr{Uint32}, p)
201201
unsafe_store!(puint, CHOLMOD.SINGLE, 3*div(sizeof(Csize_t), 4) + 5*div(sizeof(Ptr{Void}), 4) + 4)
202202
@test_throws CHOLMOD.CHOLMODException CHOLMOD.Sparse(p)
203203

204204
### illegal dtype
205-
p = ccall((:cholmod_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
205+
p = ccall((:cholmod_l_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
206206
(Csize_t, Csize_t, Csize_t, Cint, Cint, Cint, Cint, Ptr{Void}),
207-
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Cint))
207+
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Int))
208208
puint = convert(Ptr{Uint32}, p)
209209
unsafe_store!(puint, 5, 3*div(sizeof(Csize_t), 4) + 5*div(sizeof(Ptr{Void}), 4) + 4)
210210
@test_throws CHOLMOD.CHOLMODException CHOLMOD.Sparse(p)
211211

212212
### illegal xtype
213-
p = ccall((:cholmod_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
213+
p = ccall((:cholmod_l_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
214214
(Csize_t, Csize_t, Csize_t, Cint, Cint, Cint, Cint, Ptr{Void}),
215-
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Cint))
215+
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Int))
216216
puint = convert(Ptr{Uint32}, p)
217217
unsafe_store!(puint, 3, 3*div(sizeof(Csize_t), 4) + 5*div(sizeof(Ptr{Void}), 4) + 3)
218218
@test_throws CHOLMOD.CHOLMODException CHOLMOD.Sparse(p)
219219

220220
### illegal itype
221-
p = ccall((:cholmod_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
221+
p = ccall((:cholmod_l_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
222222
(Csize_t, Csize_t, Csize_t, Cint, Cint, Cint, Cint, Ptr{Void}),
223-
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Cint))
223+
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Int))
224224
puint = convert(Ptr{Uint32}, p)
225225
unsafe_store!(puint, CHOLMOD.INTLONG, 3*div(sizeof(Csize_t), 4) + 5*div(sizeof(Ptr{Void}), 4) + 2)
226226
@test_throws CHOLMOD.CHOLMODException CHOLMOD.Sparse(p)
227227

228228
### illegal itype
229-
p = ccall((:cholmod_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
229+
p = ccall((:cholmod_l_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
230230
(Csize_t, Csize_t, Csize_t, Cint, Cint, Cint, Cint, Ptr{Void}),
231-
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Cint))
231+
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Int))
232232
puint = convert(Ptr{Uint32}, p)
233233
unsafe_store!(puint, 5, 3*div(sizeof(Csize_t), 4) + 5*div(sizeof(Ptr{Void}), 4) + 2)
234234
@test_throws CHOLMOD.CHOLMODException CHOLMOD.Sparse(p)
235235

236236
# test that Sparse(Ptr) works for SuiteSparse_long (on 64 bit systems)
237237
if CHOLMOD.SuiteSparse_long == Int64
238-
p = ccall((:cholmod_l_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
238+
p = ccall((:cholmod_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_SparseVoid},
239239
(Csize_t, Csize_t, Csize_t, Cint, Cint, Cint, Cint, Ptr{Void}),
240-
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(CHOLMOD.SuiteSparse_long))
241-
@test isa(CHOLMOD.Sparse(p), CHOLMOD.Sparse{Float64,CHOLMOD.SuiteSparse_long})
240+
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Int32))
241+
@test isa(CHOLMOD.Sparse(p), CHOLMOD.Sparse{Float64,Int32})
242242
end
243243

244244
# Test Dense wrappers (only Float64 supported a present)
@@ -283,9 +283,9 @@ end
283283

284284
# Test Sparse and Factor
285285
## test free_sparse!
286-
p = ccall((:cholmod_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_Sparse{Float64,Cint}},
286+
p = ccall((:cholmod_l_allocate_sparse, :libcholmod), Ptr{CHOLMOD.C_Sparse{Float64,Cint}},
287287
(Csize_t, Csize_t, Csize_t, Cint, Cint, Cint, Cint, Ptr{Void}),
288-
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Cint))
288+
1, 1, 1, true, true, 0, CHOLMOD.REAL, CHOLMOD.common(Int))
289289
@test CHOLMOD.free_sparse!(p)
290290

291291
for elty in (Float64, Complex{Float64})

7 commit comments

Comments
 (7)

tkelman commented on Feb 16, 2015

@tkelman
Contributor

This looks completely backwards

andreasnoack commented on Feb 16, 2015

@andreasnoack
MemberAuthor

The SuiteSparse_long is similar to our Int, i.e. determined by the architecture. On 64 bit, CHOLMOD and UMFPACK let you use Cint/Int32 for the integers, but this option is not there for SPQR which call the _l_ versions of the functions. On 32 bit there is really no difference between the _l_ and the non-_l_ version, but they cannot be mixed so therefore I had to change our default such that we now call the _l_ versions whenever the chosen integer type is the same as Int. Does it make sense?

tkelman commented on Feb 16, 2015

@tkelman
Contributor

I think so, but please include this kind of information in the commit message, comments, or both.

The SuiteSparse_long is similar to our Int, i.e. determined by the architecture.

Mostly. It's set to long on all architectures except for Win64, where it's set to __int64. I don't believe we're overwriting this behavior anywhere.

andreasnoack commented on Feb 16, 2015

@andreasnoack
MemberAuthor

Isn't our Int always a 32 bit integer type on 32 bit systems and a 64 bit integer type on 64 bit systems just like SuiteSparse_long? I believe I'm relying on this assumption in the cholmod_name macro.

tkelman commented on Feb 16, 2015

@tkelman
Contributor

With the default configuration of suitesparse, yes. However when we're using system versions of this library we're at the mercy of how suitesparse was configured. I'd prefer we make as few assumptions as possible, and rely on the information that we actually get from the library (our wrapper, anyway) about how it was configured.

andreasnoack commented on Feb 16, 2015

@andreasnoack
MemberAuthor

Okay. Thanks for the comments. I've changed the dependence on Int to SuiteSparse_long which is detected from the linked library. I'll push as soon as the tests pass locally.

ViralBShah commented on Feb 16, 2015

@ViralBShah
Member

This is certainly a better way to go about it.

Please sign in to comment.