Detailed description |
This bug concerns the following line of code, in the newest version of the Matrix package available on http://matrix.r-forge.r-project.org/doxygen.
-------------------------------------
FILE: chm_common.c
CONTAINER: CHM_SP as_cholmod_sparse (CHM_SP ans, SEXP x, Rboolean check_Udiag, Rboolean sort_in_place)
LINE: 235
CODE:
ans->itype = CHOLMOD_LONG; /* characteristics of the system */
-------------------------------------
From the definition, itype == CHOLMOD_LONG means that the variables 'p' and 'i' are UF_long:
-------------------------------------
FILE: cholmod.h
CONTAINER: typedef struct cholmod_sparse_struct
LINE: 626
CODE:
int itype ; /* CHOLMOD_INT: p, i, and nz are int.
* CHOLMOD_INTLONG: p is UF_long, i and nz are int.
* CHOLMOD_LONG: p, i, and nz are UF_long. */
-------------------------------------
That is, the variables are of type long as seen here:
-------------------------------------
FILE: cholmod.h
CONTAINER: none
LINE: 11
CODE:
#define UF_long long
-------------------------------------
This does not correspond to the initialization of the variables in the Matrix package:
-------------------------------------
FILE: chm_common.c
CONTAINER: CHM_SP as_cholmod_sparse (CHM_SP ans, SEXP x, Rboolean check_Udiag, Rboolean sort_in_place)
LINE: 239
CODE:
ans->i = INTEGER(islot);
ans->p = INTEGER(GET_SLOT(x, Matrix_pSym));
/* dimensions and nzmax */
-------------------------------------
This, I guess, is because INTEGER assumes the datatype int:
-------------------------------------
FILE: Rinternals.h
CONTAINER: none
LINE: 274
CODE:
#define INTEGER(x) ((int *) DATAPTR(x))
-------------------------------------
This bug is not seen when the size of int and long are equal, but that is not the case on the system I am currently using. To illustrate the problem I have made the following example. First I define a dgCMatrix in R.
-------------------------------------
> A <- Matrix(c(1,2,3,0,4,5,0,6,7,0,8,9,0,10,11,0), nrow=4, sparse=TRUE)
> str(A)
Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
..@ i : int [1:11] 0 1 2 0 1 3 0 2 3 1 ...
..@ p : int [1:5] 0 3 6 9 11
..@ Dim : int [1:2] 4 4
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ x : num [1:11] 1 2 3 4 5 6 7 8 9 10 ...
..@ factors : list()
-------------------------------------
Then I write a package in C++ containing the following important piece of code:
-------------------------------------
// read variable SEXP inputA from .Call function
CHM_SP A = new cholmod_sparse;
M_as_cholmod_sparse(A, inputA, (Rboolean)FALSE, (Rboolean)FALSE);
if (A->itype == CHOLMOD_LONG) {
if (sizeof(int) != sizeof(UF_long)) {
Rprintf("Wrongly assuming CHOLMOD_INT\n");
for (int j=0; j<=A->ncol; j++) {
Rprintf(tostring(((int*)A->p)[j]) + "\n");
}
Rprintf("Correctly assuming CHOLDMOD_LONG\n");
for (int j=0; j<=A->ncol; j++) {
Rprintf(tostring(((UF_long*)A->p)[j]) + "\n");
}
}
}
// At some point later.. delete A;
-------------------------------------
The package is built using "R CMD build", and running this package with the constructed dgCMatrix A as input, I get the following output:
-------------------------------------
Wrongly assuming CHOLMOD_INT
0
3
6
9
11
Correctly assuming CHOLDMOD_LONG
12884901888
38654705670
11
17592186044928
9897215262864
-------------------------------------
From this it is obvious that the data stored in variable 'p' is not of type long, even though the Matrix package claims so. I hope you are able to fix this portability problem, or tell me the recommended course of action.
Best wishes,
Henrik |
|