Building off the example here Parallel Worker in namespace, I would like to employ function pointers with the Parallel Worker.
The code below produces an error along the lines of: "cannot initialize a new value of type (**) with a return value of (*)"
ExampleInternal.h
#ifndef ExampleInternal_H
#define ExampleInternal_H
namespace ExampleInternal{
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <Rcpp.h>
#include <memory>
double myfuncA(arma::vec vec_in);
double myfuncB(arma::vec vec_in);
typedef double (*funcPtr)(arma::vec);
std::shared_ptr<funcPtr> selectfunc(std::string abc){
if(abc == "A"){
return std::make_shared<funcPtr>(new funcPtr(&ExampleInternal::myfuncA));
}else {
return std::make_shared<funcPtr>(new funcPtr(&ExampleInternal::myfuncB));
}
}
struct PARALLEL_WORKER : RcppParallel::Worker{
const arma::vec &input;
std::shared_ptr<funcPtr> &Ptr;
arma::vec &output;
PARALLEL_WORKER( const arma::vec &input, std::shared_ptr<funcPtr> &Ptr, arma::vec &output);
void operator()(std::size_t begin, std::size_t end);
};
}
#endif
myfuncA.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace arma;
namespace ExampleInternal{
double myfuncA(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
} // Close namespace
myfuncB.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace arma;
namespace ExampleInternal{
double myfuncB(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])*Len;
}
} // Close namespace
Parallel_worker.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <random>
#include <memory>
#include "ExampleInternal.h"
using namespace RcppParallel;
using namespace ExampleInternal;
namespace ExampleInternal{
PARALLEL_WORKER::PARALLEL_WORKER(const arma::vec &input, std::shared_ptr<ExampleInternal::funcPtr> &Ptr, arma::vec &output) : input(input), Ptr(Ptr), output(output) {}
void PARALLEL_WORKER::operator()(std::size_t begin, std::size_t end){
std::mt19937 engine(1);
// Create a loop that runs through a selected section of the total Boot_reps
for( int k = begin; k < end; k ++){
engine.seed(k);
arma::vec index = input;
std::shuffle( index.begin(), index.end(), engine);
output[k] = Ptr(index);
}
}
} //Close Namespace
Parallel_func.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <memory>
#include "ExampleInternal.h"
using namespace ExampleInternal;
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in, std::string func_letter){
std::shared_ptr<funcPtr> df = ExampleInternal::selectfunc(func_letter);
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
ExampleInternal::PARALLEL_WORKER parallel_woker(input, df, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}
You may also need a makevars to specify c++11, on mac:
CXX_STD = CXX11
PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "RcppParallel::RcppParallelLibs()")
Ok this works. And the shared_ptr is not needed.
ExampleInternal.h
#ifndef ExampleInternal_H
#define ExampleInternal_H
namespace ExampleInternal{
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <Rcpp.h>
#include <memory>
double myfuncA(arma::vec vec_in);
double myfuncB(arma::vec vec_in);
typedef double (*funcPtr)(arma::vec);
ExampleInternal::funcPtr func_select(int abc);
struct PARALLEL_WORKER : RcppParallel::Worker{
const arma::vec &input;
ExampleInternal::funcPtr &Ptr;
arma::vec &output;
PARALLEL_WORKER( const arma::vec &input, ExampleInternal::funcPtr &Ptr, arma::vec &output);
void operator()(std::size_t begin, std::size_t end);
};
}
#endif
func_select.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
namespace ExampleInternal{
ExampleInternal::funcPtr func_select(int abc){
ExampleInternal::funcPtr df;
if(abc == 1){
df = &ExampleInternal::myfuncA;
}else{
df = &ExampleInternal::myfuncB;
}
return df;
}
} //close namespace
Parallel_func.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <memory>
#include "ExampleInternal.h"
using namespace ExampleInternal;
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in, int func_num){
ExampleInternal::funcPtr point = ExampleInternal::func_select(func_num);
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
ExampleInternal::PARALLEL_WORKER parallel_woker(input, point, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}
Related
I have been experiment with using references for speed improvements. The (not working) trivial example below, probably won't see any improvements. However, I think by not copying the data into a separate (cost) function, should save some time for a non trivial example.
As for now I have the example in an R-project as three c++ files:
header
#ifndef ExampleInternal_H
#define ExampleInternal_H
namespace ExampleInternal{
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <Rcpp.h>
void myfuncA(arma::rowvec &vec_in, arma::colvec& data){
vec_in.at(1) = vec_in.at(0)*arma::accu(data);
}
struct PARALLEL_WORKER : RcppParallel::Worker{
arma::mat &input_output;
const arma::colvec &data_in;
PARALLEL_WORKER(arma::mat &input_output, const arma::colvec &data_in);
void operator()(std::size_t begin, std::size_t end);
};
}
#endif
Function
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace ExampleInternal;
// [[Rcpp::export]]
arma::mat Parallelfunc(int Len_in, const arma::colvec data_in){
arma::mat input(Len_in, 2, arma::fill::zeros);
for(unsigned int i = 0; i < Len_in; i ++){
input.at(i, 0) =i;
}
ExampleInternal::PARALLEL_WORKER worker(input, data_in);
parallelFor(0, Len_in, worker);
return input;
}
Parallel Worker
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace RcppParallel;
using namespace ExampleInternal;
namespace ExampleInternal{
PARALLEL_WORKER::PARALLEL_WORKER(arma::mat &input_output, const arma::colvec &data_in) : input_output(input_output), data_in(data_in) {}
void PARALLEL_WORKER::operator()(std::size_t begin, std::size_t end){
for(unsigned int k = begin; k < end; k ++){
ExampleInternal::myfuncA(input_output.row(k), data_in);
}
}
}
I know the problem I have is a thread-safety issue. As the code I have now will execute with 'seThreadOptions(1)'. My question is what would be a good practice to overcome this.
I know this: Threadsafe function pointer with Rcpp and RcppParallel via std::shared_ptr Will come into play somehow. And I have also been thinking/playing around with making the internal function part of the structure for the parallel worker. Realistically, I am calling two internal functions and I would like one to be variable and the other to be constant, this tends me to think that i will need 2 solutions.
The error is that the R session, in rstudio, crashes.
Two things of note here:
1. if I 'setThreadOptions(1)' this runs fine.
2. if I move 'myfunc' into the main cpp file and make the call simply 'myfunc' this also runs fine.
Here is a detailed example:
First cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(cpp)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
// [[Rcpp::export]]
double myfunc(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
Second,cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(ParallelExample)]]
#include "RcppArmadillo.h"
#include "RcppParallel.h"
#include "ParallelExample.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace std;
struct PARALLEL_WORKER : public Worker{
const arma::vec &input;
arma::vec &output;
PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}
void operator()(std::size_t begin, std::size_t end){
std::mt19937 engine(1);
// Create a loop that runs through a selected section of the total Boot_reps
for( int k = begin; k < end; k ++){
engine.seed(k);
arma::vec index = input;
std::shuffle( index.begin(), index.end(), engine);
output[k] = ParallelExample::myfunc(index);
}
}
};
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in){
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
PARALLEL_WORKER parallel_woker(input, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}
Makevars, as I am using a macintosh:
CXX_STD = CXX11
PKG_CXXFLAGS += -I../inst/include
And Namespace:
exportPattern("^[[:alpha:]]+")
importFrom(Rcpp, evalCpp)
importFrom(RcppParallel,RcppParallelLibs)
useDynLib(ParallelExample, .registration = TRUE)
export(Parallelfunc)
When you call ParallelExample::myfunc, you are calling a function defined in inst/include/ParallelExample_RcppExport.h, which uses the R API. This is something one must not do in a parallel context. I see two possibilities:
Convert myfunc to header-only and include it in int/include/ParallelExample.h.
If the second cpp file is within the same package, put a suitable declaration for myfunc into src/first.h, include that file in both src/first.cpp and src/second.cpp, and call myfunc instead of ParallelExample::myfunc. After all, it is not necessary to register a function with R if you only want to call it within the same package. Registring with R is for functions that are called from the outside.
In some ways this kinda defeats the purpose of the built in interface cpp feature of Rcpp.
First, cpp saved as 'ExampleInternal.h':
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
namespace ExampleInternal
{
double myfunc3(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
}
and second:
#include "ParallelExample.h"
#include "ExampleInternal.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace ExampleInternal;
using namespace std;
struct PARALLEL_WORKER : public Worker{
const arma::vec &input;
arma::vec &output;
PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}
void operator()(std::size_t begin, std::size_t end){
std::mt19937 engine(1);
// Create a loop that runs through a selected section of the total Boot_reps
for( int k = begin; k < end; k ++){
engine.seed(k);
arma::vec index = input;
std::shuffle( index.begin(), index.end(), engine);
output[k] = ExampleInternal::myfunc3(index);
}
}
};
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in){
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
PARALLEL_WORKER parallel_woker(input, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}
I am writing a client server application to transfer data in linux platform. I am developing a GUI application for client side in QT.I am just a beginner in QT and please help in transferring a structure from server side to client side.
The server side code written for non-GUI environment
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#pragma pack(1)
struct basestruct
{
int element1;
int element2;
};
#pragma pack(0)
struct basestruct newstruct;
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0,n=0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
newstruct.element1=1;
newstruct.element2=2;
if((n=send(connfd,(void *)&newstruct,sizeof(struct basestruct),0))<0)
perror("Write error");
printf("sent items :%d \n",n);
close(connfd);
sleep(1);
}}`
The client side code written in QT
#include "dialog.h"
#include "ui_dialog.h"
#include <QString>
#include <QDebug>
#include <QTextStream>
#include <QByteRef>
struct basestruct
{
int element1;
int element2;
};
basestruct newstruct;
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->pushButton->setText("Connect");
ui->pushButton_2->setText("Ok");
ui->pushButton_3->setText("Close");
ui->pushButton_4->setText("Disconnect");
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::Read()
{
socket->waitForReadyRead(-1);
QByteArray byteArray;
byteArray=socket->readAll();
deserialize(byteArray);
qDebug()<<socket->readAll();
qDebug()<<"Read contents";
socket->flush();
}
void Dialog::on_pushButton_clicked()
{
socket=new QTcpSocket(this);
socket->connectToHost("127.0.0.1",5000);
qDebug()<<"Connected";
Read();
}
void Dialog::on_pushButton_4_clicked()
{
socket->close();
qDebug()<<"Disconnected";
}
void Dialog::deserialize(const QByteArray& byteArray)
{
QDataStream stream(byteArray);
stream.setVersion(QDataStream::Qt_4_0);
qDebug()<<"size received" <<byteArray.size();
stream >> newstruct.element1
>> newstruct.element2;
qDebug()<<"Element1"<<newstruct.element1<<"Element2"<<newstruct.element2;
}
When I receive the structure and print using qDebug() I am getting some garbage values. Kindly help me and point where I have gone wrong.Is there any easy alternative method to transfer structure in QT without serialising (similar to Non-GUI applications).
Thanks in advance
The Endianness problem can be overcome by specifying the Endianess as:
stream.setByteOrder(QDataStream::LittleEndian);
in the deserialise function after declaring Qdatastream.
Help, I'm using VC++ and I always get the LNK2005 and LNK1169 Error when running my script, can you guys please tell me why it's happening and how to fix it, Thank you!
Code:
In the Main.cpp
#include "stdafx.h
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "Modifier.h"
using namespace std;
HWND myconsole = GetConsoleWindow();
HDC mydc = GetDC(myconsole);
int main()
{
if (Input.beg("Hello"))
{
cout << "World";
}
cin.ignore();
}
In "Modifier.cpp"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct {
bool beg(string a)
{
string b;
getline(cin, b);
if (b == a)
{
return true;
}
else
{
}
}
} Input;
In "Modifier.h"
#include "Modifier.cpp"
You must change your header declaration: you're inadvertently declaring a different, global "Input" variable in every .cpp that includes "Modifier.h".
SUGGESTION:
// Modifier.h
#ifndef MODIFER_H
#define MODIFIER_H
struct Input {
bool beg(string a)
{
string b;
getline(cin, b);
if (b == a)
{
return true;
}
else
{
}
}
};
#endif
Then, in Modifier.cpp:
#include "Modifier.h"
struct Input globalInput;
You should not include a .cpp in a .h. You should include headers in source files, not vice versa.
And you should definitely consider using a "class" instead of a "struct". Because, frankly, that's what your "Input" is: just a method, no state/no data.
I am trying to process many picture's at a time and then make all to equal size
Mat pic = imread ("C:\\Pick");
for (int i=0;i<10;i++)
{
imshow("mainwin" , pick);
resize (pick,re_pic,size(150,100));
}
Pick is a folder which contain 10 different picture's
You can get list of images in directory and then process them.
#include <vector>
#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
//----------------------------------------------------------------------
// Get list of files
// Usage:
// string ImagesDir=tmp+"C:\\Images\\*.jpg";
// vector<string> files=listFilesInDirectory(ImagesDir);
//----------------------------------------------------------------------
vector<string> listFilesInDirectory(string directoryName)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(directoryName.c_str(), &FindFileData);
vector<string> listFileNames;
listFileNames.push_back(FindFileData.cFileName);
while (FindNextFile(hFind, &FindFileData))
listFileNames.push_back(FindFileData.cFileName);
return listFileNames;
}
...
// somewhere in main
string YourImagesDirectory="C:\\Pick\\";
vector<string> files=listFilesInDirectory(YourImagesDirectory+"*.jpg");
for(int i=0;i<files.size();i++)
{
Mat img=imread(YourImagesDirectory+files[i]);
imshow("mainwin" , img);
...
}
...