use mkl_sparse_?_mm with COO format but return "invalid value" - sparse-matrix

I am trying to use MKL for some sprase matrix-matrix tests. The interface is mkl_sparse_?_mm. According to the doc, it should support all formats with the configurations of SPARSE_INDEX_BASE_ONE and SPARSE_LAYOUT_COLUMN_MAJOR of the sparse matrix.
But, it always returns the error of "invalid value" when I set the descr with SPARSE_MATRIX_TYPE_TR
IANGULAR. Anyone knows why?
My appreciation.
Here are some C codes.
sparse_operation_t transA = SPARSE_OPERATION_NON_TRANSPOSE;
sparse_layout_t layout = SPARSE_LAYOUT_COLUMN_MAJOR;
sparse_index_base_t indexing = SPARSE_INDEX_BASE_ONE;
struct matrix_descr descr = SPARSE_MATRIX_TYPE_TRIANGULAR;
sparse_matrix_t coo;
mkl_sparse_s_create_coo(&coo, indexing, m, k, nnz, row_index, col_index, values);
mkl_sparse_s_mm(transA, alpha, coo, descr, layout, x, columns, ldx, beta, y, ldy);

You may ensure your row_index and col_index are actually one-based and in your case SPARSE_MATRIX_TYPE_TRIANGULAR needs m==k.

Related

Conduct AngleAxisToRotationMatirx on part of a double arrray in Ceres?

Nowadays I'm working with Ceres and Eigen. And I have a 6x3 = 18-d double array, let's call it xs, which is defined as:
double xs[6*3];
Basically xs contains the 6 rotations expressed in angle-axis format. And I need to turn each rotation of all 6 into rotation matrix format, then matrix multiplication will be conducted.
struct F1 {
template <typename T> bool operator()(const T* const xs,
T* residual) const {
Eigen::Map<const Eigen::Matrix<T,3,1> > m0(xs, 3);
T m[9], res[3];
ceres::AngleAxisToRotationMatrix(m0, m);
residual[0] = res[0];
residual[1] = res[1];
residual[2] = res[2];
}
Here in the example code I extract first 3 elements of xs via Eigen::Map, then I applied AngleAxisToRotationMatrix on it. But I keep receiving such errors:
error: no matching function for call to ‘AngleAxisToRotationMatrix(Eigen::Map<const Eigen::Matrix<ceres::Jet<double, 18>, 3, 1, 0, 3, 1>, 0, Eigen::Stride<0, 0> >&, ceres::Jet<double, 1> [9])’
Can somebody lend me a hand here? I'm pretty new to Ceres and Eigen, it really drove me almost to crazy.
Thanks!
ceres::AngleAxisToRotationMatrix expects raw pointers:
AngleAxisToRotationMatrix(xs, m);

making 3d array with arma::cube in Rcpp shows cube error

I am making a Rcpp code for Gibbs sampling. Inside the code, I first want to make a 3 dimensional array with row number= number of iteration (500), column number=number of parameter(4) and slice number= number of chain(3). I wrote it in this way:
#include <RcppArmadillo.h>
#include <math.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace std;
using namespace arma;
//Gibbs sampling code starts here
Rcpp::List mcmc(const int iter,const int chains, const NumericVector data){
arma::cube posteriorC = arma::zeros(iter, 5, chains);
\\ rest of the codes
List out(Rcpp::List::create(Rcpp::Named("posteriorC") =posteriorC));
return out;
}
. While compelling it does not show any error. But when I want to run the code with:
res<- mcmc(iter=500,chains=2,data)
it shows the error:
Error: Cube::operator(): index out of bounds
. I want to know if there any mistake while making the 3D array. Please note that I want to get estimates of 5 parameters of my model.
You need to specify the template for arma::zeros to correctly fill an arma::cube, c.f. arma::zeros<template>
Generate a vector, matrix or cube with the elements set to zero
Usage:
vector_type v = zeros<vector_type>( n_elem )
matrix_type X = zeros<matrix_type>( n_rows, n_cols )
matrix_type Y = zeros<matrix_type>( size(X) )
cube_type Q = zeros<cube_type>( n_rows, n_cols, n_slices )
cube_type R = zeros<cube_type>( size(Q) )
Thus, in your case it would be:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
Rcpp::List mcmc(const int iter, const int chains,
const Rcpp::NumericVector data){
arma::cube posteriorC = arma::zeros<arma::cube>(iter, 5, chains);
// --------------------------------- ^^^^^^^^
// Not Shown
Rcpp::List out = Rcpp::List::create(Rcpp::Named("posteriorC") =posteriorC);
return out;
}
Two final notes:
You explicitly state that the code as it stands now will create 4 columns to store 4 variables. However, you explicitly mention that you needed to estimate 5 parameters. You may need to increase this to prevent an out of bounds when saving into the arma::cube slices.
The way the Rcpp::List out is being created isn't quite correct. In general, the best way to create the list is to do: Rcpp::List out = Rcpp::List::create(Rcpp::Named("Blah"), Blah);

Error Returning Modelica Record from External C Function

I have written a C dll function that I want to call from Modelica, and want it to return a Modelica record.
Based upon the data mapping described in the "Modelica by Example" book, I defined a structure in my C header and my function returns a pointer to the structure. You can see the header contents below:
#ifdef NZ1MAP_EXPORTS
#define NZ1MAP_API __declspec(dllexport)
#else
#define NZ1MAP_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
// Define struct to match the SpeedlineVectors record in Modelica.
typedef struct
{
double Mach;
double PRVposition;
double DiffuserGap;
double Theta[24];
double Omega[24];
double MapEfficiency[24];
double OmegaStall[24];
} SpeedlineVectors;
NZ1MAP_API SpeedlineVectors* GetNZ1SpeedlineVectors_External(double Mach, double DiffuserGapFraction);
#ifdef __cplusplus
}
#endif
In Dymola, I created the record below:
record SpeedlineVectors
"Mach, PRV position, Diffuser Gap, and Vectors of Theta, Omega, Map Efficiency, Omega Stall"
Real Mach "impeller machine Mach";
Real PRVposition "PRV position, 0 = fully closed, 1 = fully open";
Real DiffuserGap
"Diffuser gap, 0 = fully closed, 1 = fully open, typical minimum = 0.05";
Real Theta[24] "vector of non-dimensional flow coefficients along speed line";
Real Omega[24] "vector of non-dimensional head coefficients along speed line";
Real MapEfficiency[24]
"vector of isentropic efficiency normalized to tip Reynolds number of 1E6 along speed line";
Real OmegaStall[24]
"vector of non-dimensional head where stall is expected to begin along speed line";
end SpeedlineVectors;
And I created the function that should call the external C dll and return a "SpeedlineVectors" record:
function GetNZ1SpeedlineVectors_External
"Get NZ1 speedline array from external C function"
input Real operatingMach "Machine Mach number";
input Real diffuserGapFraction "Diffuser gap open fraction, 0 to 1";
output SpeedlineVectors speedlineVectors "speedlineVectors record";
external "C" speedlineVectors = GetNZ1SpeedlineVectors_External(operatingMach, diffuserGapFraction);
annotation(Include="#include <NZ1Map.h>", Library="NZ1Map");
end GetNZ1SpeedlineVectors_External;
I built the simple test model below:
model GetNZ1SpeedlineVectors_Tester
Real mach = 1.32;
Real diffuserGapFraction = 0.50;
SpeedlineVectors myVectors;
equation
myVectors = GetNZ1SpeedlineVectors_External(mach, diffuserGapFraction);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end GetNZ1SpeedlineVectors_Tester;
When I try to run the test model, I receive the following error messages from Dymola:
Compiling and linking the model (Visual C++).
dsmodel.c
dsmodel.c(74) : error C2440: '=' : cannot convert from 'SpeedlineVectors *' to 'DymStruc0'
Error generating Dymosim.
I also tried adjusting the C function return so that it returns the struct directly rather than a pointer to the struct, but I receive a similar error message:
dsmodel.c(74) : error C2440: '=' : cannot convert from 'SpeedlineVectors' to 'DymStruc0'
Any tips on what must be done to return a Modelica record from an external C function?
Thanks,
Justin
According to the Modelica specification section 12.9.1.3 arrays in a record cannot be mapped when returned from an external function. You could also try using the ExternalObject: https://build.openmodelica.org/Documentation/ModelicaReference.Classes.ExternalObject.html
As a workaround for my case, I was able to solve the problem by changing the external function. Instead of returning the arrays in a struct that is mapped to a record (thanks to Shaga for pointing out that this is not supported per the modelica specification), the function was changed to return void with four output arrays.
The new function definition in the C header is:
NZ1MAP_API void GetNZ1SpeedlineVectors_External(double Mach, double DiffuserGapFraction, double ThetaVector[], size_t SizeOfThetaVector, double OmegaVector[], size_t SizeOfOmegaVector, double MapEfficiencyVector[], size_t SizeOfMapEfficiencyVector, double OmegaStallVector[], size_t SizeOfOmegaStallVector);
The C function definition in the C file is:
NZ1MAP_API void GetNZ1SpeedlineVectors_External(double Mach, double DiffuserGapFraction,
double thetaVector[], size_t thetaVectorSize, // thetaVector[] is equivalent to double* thetaVector
double omegaVector[], size_t omegaVectorSize,
double efficiencyVector[], size_t efficiencyVectorSize,
double omegaStallVector[], size_t omegaStallVectorSize)
The modelica function is shown below:
function GetNZ1SpeedlineVectors_External
"Get NZ1 speedline array from external C function"
input Real operatingMach "Machine Mach number";
input Real diffuserGapFraction "Diffuser gap open fraction, 0 to 1";
output Real ThetaVector[24]
"vector of non-dimensional flow coefficients along speedline";
output Real OmegaVector[24]
"vector of non-dimensional head coefficients along speedline";
output Real MapEfficiencyVector[24]
"vector of non-dimensional map efficiency along speedline";
output Real OmegaStallVector[24] "vector of omega stall along speedline";
external "C" GetNZ1SpeedlineVectors_External(operatingMach, diffuserGapFraction, ThetaVector, size(ThetaVector,1), OmegaVector, size(OmegaVector,1), MapEfficiencyVector, size(MapEfficiencyVector,1), OmegaStallVector, size(OmegaStallVector, 1));
annotation(Include = "#include <NZ1Map.h>", Library="NZ1Map");
end GetNZ1SpeedlineVectors_External;
And a test model that calls the modelica function is:
model NZ1_External "NZ1 External Dll"
extends SpeedlineVectorsBase;
parameter Real inputMach = 1.4;
parameter Real inputDiffuserGapFraction = 1;
equation
Mach = inputMach;
PRVposition = 1;
DiffuserGapFraction = inputDiffuserGapFraction;
(ThetaVector, OmegaVector, MapEfficiencyVector, OmegaStallVector) =
GetNZ1SpeedlineVectors_External(Mach, DiffuserGapFraction);
end NZ1_External;
I hope this helps someone else see how they can return multiple arrays from an external function to modelica, since modelica will not map arrays returned as part of a struct.
Thanks,
Justin
You can hide the multiple arrays from the users of the Modelica function, by having hierarchical names in the external function call.
function GetNZ1SpeedlineVectors_External
input Real operatingMach "Machine Mach number";
input Real diffuserGapFraction "Diffuser gap open fraction, 0 to 1";
output SpeedlineVectors speedlineVectors "speedlineVectors record";
external "C" GetNZ1SpeedlineVectors_External(operatingMach,diffuserGapFraction, speedLineVectors.ThetaVector, size(speedLineVectors.ThetaVector,1), ...);
annotation(Include="#include <NZ1Map.h>", Library="NZ1Map");
end GetNZ1SpeedlineVectors_External;
This is a new feature added in Modelica 3.3 Revision 1, https://trac.modelica.org/Modelica/ticket/351
and should be available since Dymola 2015.

openCV k-means call assertion failed

I'm have read c++ sample from samples folder of openCV source distribution, and, if omit random picture generation, kmeans call looks pretty simple – author even doesn't allocate centers/labels arrays (you can find it here). However, I can't do the same in C. If I don't allocate labels, I get assertion error:
OpenCV Error: Assertion failed (labels.isContinuous() && labels.type()
== CV_32S && (labels.cols == 1 || labels.rows == 1) && labels.cols + labels.rows - 1 == data.rows) in cvKMeans2, file
/tmp/opencv-xiht/opencv-2.4.9/modules/core/src/matrix.cpp, line 3094
Ok, I tried to create empty labels matrix, but assertion message don't changes at all.
IplImage* image = cvLoadImage("test.jpg", -1);
IplImage* normal = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, image->nChannels);
cvConvertScale(image, normal, 1/255.0, 0);
CvMat* points = cvCreateMat(image->width, image->height, CV_32F);
points->data.fl = normal->imageData;
CvMat* labels = cvCreateMat(1, points->cols, CV_32S);
CvMat* centers = NULL;
CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0);
// KMEANS_PP_CENTERS is undefined
int KMEANS_PP_CENTERS = 2;
cvKMeans2(points, 4, labels, criteria, 3, NULL, KMEANS_PP_CENTERS, centers, 0);
The thing that drives me nuts:
CvMat* labels = cvCreateMat(1, points->cols, CV_32S);
int good = labels->type == CV_32S; // FALSE here
It's obviously one (not sure if the only) issue that causes assertion fail. How this supposed to work? I can't use С++ API since whole application is in plain C.
the assertion tells you:
type must be CV_32S which seems to be the case in your code, maybe your if-statement is false because the type is changed to CV_32SC1 automatically? no idea...
you can either place each point in a row or in a column, so rows/cols is set to 1 and the other dimension must be set to data.rows which indicates that data holds the points you want to cluster in the format that each point is placed in a row, leading to #points rows. So your error seems to be CvMat* labels = cvCreateMat(1, points->cols, CV_32S); which should be CvMat* labels = cvCreateMat(1, points->rows, CV_32S); instead, to make the assertion go away, but your use of points seems to be conceptually wrong.
You probably have to hold your points (you want to cluster) in a cvMat with n rows and 2 cols of type CV_32FC1 or 1 col and type CV_32FC2 (maybe both versions work, maybe only one, or maybe I'm wrong there at all).
edit: I've written a short code snippet that works for me:
// here create the data array where your input points will be hold:
CvMat* points = cvCreateMat( numberOfPoints , 2 /* 2D points*/ , CV_32F);
// this is a float array of the
float* pointsDataPtr = points->data.fl;
// fill the mat:
for(unsigned int r=0; r<samples.size(); ++r)
{
pointsDataPtr[2*r] = samples.at(r).x; // this is the x coordinate of your r-th point
pointsDataPtr[2*r+1] = samples.at(r).y; // this is the y coordinate of your r-th point
}
// this is the data array for the labels, which will be the output of the method.
CvMat* labels = cvCreateMat(1, points->rows, CV_32S);
// this is the quit criteria, which I did neither check nor modify, just used your version here.
CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0);
// call the method for 2 cluster
cvKMeans2(points, 2, labels, criteria);
// now labels holds numberOfPoints labels which have either value 0 or 1 since we searched for 2 cluster
int* labelData = labels->data.i; // array to the labels
for(unsigned int r=0; r<samples.size(); ++r)
{
int labelOfPointR = labelData[r]; // this is the value of the label of point number r
// here I use c++ API to draw the points, do whatever else you want to do with the label information (in C API). I choose different color for different labels.
cv::Scalar outputColor;
switch(labelOfPointR)
{
case 0: outputColor = cv::Scalar(0,255,0); break;
case 1: outputColor = cv::Scalar(0,0,255); break;
default: outputColor = cv::Scalar(255,0,255); break; // this should never happen for 2 clusters...
}
cv::circle(outputMat, samples.at(r), 2, outputColor);
}
giving me this result for some generated point data:
Maybe you need the centers too, the C API gives you the option to return them, but didnt check how it works.

Understanding how .Internal C functions are handled in R

I wonder if anyone can illustrate to me how R executes a C call from an R command typed at the console prompt. I am particularly confused by R's treatment of a) function arguments and b) the function call itself.
Let's take an example, in this case set.seed(). Wondering how it works I type the name in at the prompt, get the source (look here for more on that), see there is eventually a .Internal(set.seed(seed, i.knd, normal.kind), so dutifully look up the relevant function name in the .Internals section of /src/names.c, find it is called do_setseed and is in RNG.c which leads me to...
SEXP attribute_hidden do_setseed (SEXP call, SEXP op, SEXP args, SEXP env)
{
SEXP skind, nkind;
int seed;
checkArity(op, args);
if(!isNull(CAR(args))) {
seed = asInteger(CAR(args));
if (seed == NA_INTEGER)
error(_("supplied seed is not a valid integer"));
} else seed = TimeToSeed();
skind = CADR(args);
nkind = CADDR(args);
//...
//DO RNG here
//...
return R_NilValue;
}
What are CAR, CADR, CADDR? My research leads me to believe they are a Lisp influenced construct concerning lists but beyond that I do not understand what these functions do or why they are needed.
What does checkArity() do?
SEXP args seems self explanatory, but is this a list of the
arguments that is passed in the function call?
What does SEXP op represent? I take this to mean operator (like in binary functions such as +), but then what is the SEXP call for?
Is anyone able to flow through what happens when I type
set.seed(1)
at the R console prompt, up to the point at which skind and nkind are defined? I find I am not able to well understand the source code at this level and path from interpreter to C function.
CAR and CDR are how you access pairlist objects, as explained in section 2.1.11 of R Language Definition. CAR contains the first element, and CDR contains the remaining elements. An example is given in section 5.10.2 of Writing R Extensions:
#include <R.h>
#include <Rinternals.h>
SEXP convolveE(SEXP args)
{
int i, j, na, nb, nab;
double *xa, *xb, *xab;
SEXP a, b, ab;
a = PROTECT(coerceVector(CADR(args), REALSXP));
b = PROTECT(coerceVector(CADDR(args), REALSXP));
...
}
/* The macros: */
first = CADR(args);
second = CADDR(args);
third = CADDDR(args);
fourth = CAD4R(args);
/* provide convenient ways to access the first four arguments.
* More generally we can use the CDR and CAR macros as in: */
args = CDR(args); a = CAR(args);
args = CDR(args); b = CAR(args);
There's also a TAG macro to access the names given to the actual arguments.
checkArity ensures that the number of arguments passed to the function is correct. args are the actual arguments passed to the function. op is offset pointer "used for C functions that deal with more than one R function" (quoted from src/main/names.c, which also contains the table showing the offset and arity for each function).
For example, do_colsum handles col/rowSums and col/rowMeans.
/* Table of .Internal(.) and .Primitive(.) R functions
* ===== ========= ==========
* Each entry is a line with
*
* printname c-entry offset eval arity pp-kind precedence rightassoc
* --------- ------- ------ ---- ----- ------- ---------- ----------
{"colSums", do_colsum, 0, 11, 4, {PP_FUNCALL, PREC_FN, 0}},
{"colMeans", do_colsum, 1, 11, 4, {PP_FUNCALL, PREC_FN, 0}},
{"rowSums", do_colsum, 2, 11, 4, {PP_FUNCALL, PREC_FN, 0}},
{"rowMeans", do_colsum, 3, 11, 4, {PP_FUNCALL, PREC_FN, 0}},
Note that arity in the above table is 4 because (even though rowSums et al only have 3 arguments) do_colsum has 4, which you can see from the .Internal call in rowSums:
> rowSums
function (x, na.rm = FALSE, dims = 1L)
{
if (is.data.frame(x))
x <- as.matrix(x)
if (!is.array(x) || length(dn <- dim(x)) < 2L)
stop("'x' must be an array of at least two dimensions")
if (dims < 1L || dims > length(dn) - 1L)
stop("invalid 'dims'")
p <- prod(dn[-(1L:dims)])
dn <- dn[1L:dims]
z <- if (is.complex(x))
.Internal(rowSums(Re(x), prod(dn), p, na.rm)) + (0+1i) *
.Internal(rowSums(Im(x), prod(dn), p, na.rm))
else .Internal(rowSums(x, prod(dn), p, na.rm))
if (length(dn) > 1L) {
dim(z) <- dn
dimnames(z) <- dimnames(x)[1L:dims]
}
else names(z) <- dimnames(x)[[1L]]
z
}
The basic C-level pairlist extraction functions are CAR and CDR. (Pairlists are very similar to lists but are implemented as a linked-list and are used internally for argument lists). They have simple R equivalents: x[[1]] and x[-1]. R also provides lots of combinations of the two:
CAAR(x) = CAR(CAR(x)) which is equivalent to x[[1]][[1]]
CADR(x) = CAR(CDR(x)) which is equivalent to x[-1][[1]], i.e. x[[2]]
CADDR(x) = CAR(CDR(CDR(x)) is equivalent to x[-1][-1][[1]], i.e. x[[3]]
and so on
Accessing the nth element of a pairlist is an O(n) operation, unlike accessing the nth element of a list which is O(1). This is why there aren't nicer functions for accessing the nth element of a pairlist.
Internal/primitive functions don't do matching by name, they only use positional matching, which is why they can use this simple system for extracting the arguments.
Next you need to understand what the arguments to the C function are. I'm not sure where these are documented, so I might not be completely right about the structure, but I should be the general pieces:
call: the complete call, as might be captured by match.call()
op: the index of the .Internal function called from R. This is needed because there is a many-to-1 mapping from .Internal functions to C functions. (e.g. do_summary implements sum, mean, min, max and prod). The number is the third entry in names.c - it's always 0 for do_setseed and hence never used
args: a pair list of the arguments supplied to the function.
env: the environment from which the function was called.
checkArity is a macro which calls Rf_checkArityCall, which basically looks up the number of arguments (the fifth column in names.c is arity) and make sure the supplied number matches. You have to follow through quite a few macros and functions in C to see what's going on - it's very helpful to have a local copy of R-source that you can grep through.

Resources