Skip to content

Commit

Permalink
Get basic CHOLMOD calling sequence to work.
Browse files Browse the repository at this point in the history
The trick is to write C wrappers to allocate/deallocate all cholmod
objects such as cholmod_common, cholmod_sparse etc.
  • Loading branch information
ViralBShah committed Jan 3, 2012
1 parent d27ebda commit 50b468d
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 17 deletions.
12 changes: 12 additions & 0 deletions external/SuiteSparse_wrapper.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
#include <cholmod.h>

extern void
jl_cholmod_common (void **cm)
{
cholmod_common *c = (cholmod_common *) malloc (sizeof(cholmod_common));
*cm = c;
}

extern void
jl_cholmod_sparse( void **cs, /* Store return value in here */
size_t nrow, /* # of rows of A */
Expand Down Expand Up @@ -37,6 +44,11 @@ jl_cholmod_sparse( void **cs, /* Store return value in here */
return;
}

extern void
jl_cholmod_common_free(cholmod_common *c) {
free(c);
}

extern void
jl_cholmod_sparse_free(cholmod_sparse *s) {
free(s);
Expand Down
68 changes: 51 additions & 17 deletions j/linalg_suitesparse.j
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@ function (\)(A, b)
end

function _jl_cholmod_transpose(S::SparseMatrixCSC)
cm = Array(Ptr{Void}, 1)
cs = Array(Ptr{Void}, 1)
_jl_cholmod_start(cm)
cm = _jl_cholmod_start()
S = _jl_convert_to_0_based_indexing!(S)
_jl_cholmod_sparse(S, cs)
cs_T = _jl_cholmod_transpose(cs[1], cm)
cs_T = _jl_cholmod_transpose(S, cm)
S = _jl_convert_to_1_based_indexing!(S)
_jl_cholmod_finish(cm)
return cs_T
end

Expand Down Expand Up @@ -97,17 +95,40 @@ const _jl_CHOLMOD_SUPERNODAL = int32(2) # always do supernodal

## CHOLMOD functions

function _jl_cholmod_start(cm)
ccall(dlsym(_jl_libsuitesparse, :cholmod_start),
function _jl_cholmod_start()
# Allocate space for cholmod_common object
cm = Array(Ptr{Void}, 1)
ccall(dlsym(_jl_libsuitesparse_wrapper, :jl_cholmod_common),
Void,
(Ptr{Void},),
cm)

status = ccall(dlsym(_jl_libsuitesparse, :cholmod_start),
Int32,
(Ptr{Void}, ),
cm[1]);
if status != int32(1); error("Error calling cholmod_start"); end
return cm
end

function _jl_cholmod_finish(cm::Array{Ptr{Void}, 1})
status = ccall(dlsym(_jl_libsuitesparse, :cholmod_finish),
Int32,
(Ptr{Void}, ),
cm[1]);

ccall(dlsym(_jl_libsuitesparse_wrapper, :jl_cholmod_common_free),
Void,
(Ptr{Void}, ),
cm);
return
(Ptr{Void},),
cm[1])
end


## Call wrapper function to create cholmod_sparse objects
## Assumes that S has been converted to 0-based indexing in caller
function _jl_cholmod_sparse{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, cs::Array{Ptr{Void},1})
function _jl_cholmod_sparse{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti})
cs = Array(Ptr{Void}, 1)

if Ti == Int32; itype = _jl_CHOLMOD_INT;
elseif Ti == Int64; itype = _jl_CHOLMOD_LONG; end

Expand All @@ -128,12 +149,25 @@ function _jl_cholmod_sparse{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, cs::Array{Ptr{Void
return cs
end

function _jl_cholmod_transpose(cs::Ptr{Void}, cm::Ptr{Void})
t = ccall(dlsym(_jl_libsuitesparse, :cholmod_transpose),
Ptr{Void},
(Ptr{Void}, Int32, Ptr{Void}),
cs, int32(2), cm);
return t
function _jl_cholmod_sparse_free(cs::Array{Ptr{Void}, 1})
ccall(dlsym(_jl_libsuitesparse_wrapper, :jl_cholmod_sparse_free),
Void,
(Ptr{Void},),
cs[1])
end

function _jl_cholmod_transpose(S, cm::Array{Ptr{Void}, 1})
# Allocate space for a cholmod_sparse object
cs = _jl_cholmod_sparse(S)

cs_t = ccall(dlsym(_jl_libsuitesparse, :cholmod_transpose),
Ptr{Void},
(Ptr{Void}, Int32, Ptr{Void}),
cs[1], int32(2), cm[1]);

_jl_cholmod_sparse_free(cs)

return cs_t
end

## UMFPACK
Expand Down

0 comments on commit 50b468d

Please sign in to comment.