Compiler error when using vectorise on a sparse matrix - armadillo

I was trying to create a vector from the non-zero entries of a sparse matrix and thought that the 'vectorise' function would do the trick.
The Armadillo documentation indicates that the 'vectorise' function has supported the sparse matrix format since version 9.400, however when I try to compile the code below I get an error:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec flatten_matrix(){
arma::sp_mat A = arma::sprandu(1000, 2000, 0.01);
arma::vec B = arma::vectorise(A);
return B;
}
error: conversion from 'arma::enable_if2, arma::spop_vectorise_col> >::result {aka const arma::SpOp, arma::spop_vectorise_col>}' to non-scalar type 'arma::vec {aka arma::Col}' requested
arma::vec B = arma::vectorise(A);
My Armadillo installation comes via the RcppArmadillo R package, which I have at version 0.9.700.2.0.
Am I the problem, or is this a bug?

Related

Drake matrix indexing issue

This code errors in Drake:
forces_matrix = np.zeros((T - 1, O, O, D))
tril_indices = np.tril_indices(O, m=O, k=-1)
forces_matrix[:, tril_indices[0], tril_indices[1]] = f_oo
But it works in PyTorch / Numpy.
The LHS and RHS are both 9, 1, 1 shape numpy tensors.
Is this type of operation not supported in Drake?
EDIT: No more syntax error if the initial forces_matrix is OBJECT type. However, I am not sure if the computation graph is being built correctly connecting f_oo and forces_matrix. Is this type of operation supported?

Type error when use apex.amp O1 in PyTorch

When I try to use NVIDIA apex.amp O1 to accelerate my training, it report an error in my code logits = einsum('b x y d, r d -> b x y r', q, rel_k):
RuntimeError: RuntimeErrorRuntimeErrorexpected scalar type Half but found Float: :
expected scalar type Half but found Float
It means that rel_kshould be torch.HalfTensor.
rel_k is defined as follow: self.rel_height = nn.Parameter(torch.randn(height * 2 - 1, dim_head) * scale)
But when I specify the type of rel_kto be torch.HalfTensor, it report an error that I should not specify dtype manually
RuntimeErrorRuntimeError: : Found param encoder.layers.0.blocks.0.attn.rel_pos_emb.rel_height with type torch.cuda.HalfTensor, expected torch.cuda.FloatTensor.
When using amp.initialize, you do not need to call .half() on your model
before passing it, no matter what optimization level you choose.Found param encoder.layers.0.blocks.0.attn.rel_pos_emb.rel_height with type torch.cuda.HalfTensor, expected torch.cuda.FloatTensor.
When using amp.initialize, you do not need to call .half() on your model
before passing it, no matter what optimization level you choose.
How should I do to use amp O1 correctly in my code?

How to redefine OpenCV's Mat type

Using g++, I tried to redefine the Opencv's Mat type as
#define CV_32FC1 CV_TYPE_1
But I have error as invalid arguments at
Mat LO_Coefs;
LO_Coefs.create(1, cnt, CV_TYPE_1);

OpenCV3, SIFT compute with vector<vector<KeyPoint>>

According to the document, SIFT object could use the function below to compute descriptors for multiple images:
virtual void compute (InputArrayOfArrays images, std::vector< std::vector< KeyPoint > > &keypoints, OutputArrayOfArrays descriptors)
I'm trying to compute the SIFT descriptors for multiple images with the code below:
Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
vector<vector<KeyPoint>> train_keypoints;
f2d->detect(train_imgs, train_keypoints);
vector<Mat> train_descriptors;
f2d->compute(train_imgs, train_keypoints, train_descriptors);
It could be compiled under Mac OS 10.10.5 with opencv3, while it might terminate during execution with error:
libc++abi.dylib: terminating with uncaught exception of type std::length_error: vector
Or I could change the type of train_descriptors into Mat (instead of vector< Mat >), it'll still fail during execution with another error:
OpenCV Error: Assertion failed (_descriptors.kind() == _InputArray::STD_VECTOR_MAT) in compute, file /tmp/opencv320151228-32931-2p5ggk/opencv-3.1.0/modules/features2d/src/feature2d.cpp, line 126 libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /tmp/opencv320151228-32931-2p5ggk/opencv-3.1.0/modules/features2d/src/feature2d.cpp:126: error: (-215) _descriptors.kind() == _InputArray::STD_VECTOR_MAT in function compute
What type of train_descriptors should I use to make this code compile and run correctly?
Could anyone told me what's the difference between vector< Mat > and OutputArrayOfArrays?
Your code
Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
vector<vector<KeyPoint>> train_keypoints;
f2d->detect(train_imgs, train_keypoints);
vector<Mat> train_descriptors;
f2d->compute(train_imgs, train_keypoints, train_descriptors);
works well if train_imgs is a vector<Mat>.
You don't need to create a vector of 50000 elements, simply use vector<Mat> train_descriptors;.
OutputArrayOfArrays, like InputArray, OutputArray and the like, are an abstraction layer that OpenCV uses to allow to pass to a function both cv::Mat and std::vector. You should never use these classes explicitly. From OpenCV doc:
The class is designed solely for passing parameters. That is, normally you should not declare class members, local and global variables of this type.
Also, note that OutputArrayOfArrays is just a typedef of OutputArray.
This code could work I guess:
Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
vector<vector<KeyPoint>> train_keypoints;
f2d->detect(train_imgs, train_keypoints);
vector<Mat> train_descriptors = vector<Mat>(5e4);
f2d->compute(train_imgs, train_keypoints, train_descriptors);

How to access an element on cv::gpu::GpuMat matrix using CUDA and OpenCV?

I'm working on a project which implement face detection algorithm on CUDA platform.
Currently I'd to access an element on GpuMat instance.
I have tried the following conventional methods:
Trying to make induction from cv:Mat, GpuMat doesn't have a <T>.at method.
I have tried using CV_MAT_ELEM , I receive an error.
Here is my code on FaceDetection.cu file:
int DetectFacesGPU(cv::gpu::GpuMat * sumMat ,cv::gpu::GpuMat * qSumMat , float factor)
{
//
int i = CV_MAT_ELEM(*sumMat,int ,0,0);
//
I receive an error
Error 29 error : expression must have class type C:\Users\Shahar\Dropbox\OpenCV2.3\OpenCV2.3\FaceDetectionLatest\FaceDetectionCuda\FaceDetectionLatest\FaceDetection.cu 139
You have to download it to a cv::Mat and then access it with the standard way.
I think downloading it is as simple as:
cv::Mat mat;
sumMat->download(mat); // or something like that.
From the definition of CV_MAT_ELEM, CV_MAT_ELEM(*sumMat, int, 0, 0); is expanded to:
*(int*)CV_MAT_ELEM_PTR_FAST(*sumMat, 0, 0, 4));
and in turn expanded to:
*(int*)(assert ( 0 < (*sumMat).rows && 0 < (*sumMat).cols ),
(*sumMat).data.ptr + (size_t)(*sumMat).step*0 + 4*0);
Assuming that your DetectFacesGPU function is defined as a device code, the above statement is faulty because you can't dereference sumMat in device code. By doing so you're accessing host memory from device code. You have to be careful because GpuMat class itself is allocated in host memory. It is only the actual matrix data that is allocated in device memory.
So GpuMat class itself is, in general, not passed to kernel. To access individual pixels of GpuMat in kernel, you have to pass the pointer referencing the actual matrix data (which is in device memory) to the kernel and do pointer arithmetic on that pointer.

Resources