I'm having a problem calling a local library through Rcpp with R Studio Server. It's a bit perplexing, since I have no issues when I call it from R at the command line.
I've written an analytics library which uses boost's threadpool functionality for running multiple threads. I've stripped everything down to the bare essentials, the minimum code which will cause the problem -- this code just starts the threads in the threadpool, then exits them:
#include <Rcpp.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/thread/thread.hpp>
RcppExport SEXP test_thread()
{
BEGIN_RCPP
double retdbl = 10.4;
boost::shared_ptr<boost::asio::io_service::work> threadpool_work;
boost::asio::io_service threadpool_io_service;
boost::thread_group threadpool_threads;
threadpool_work.reset( new
boost::asio::io_service::work(threadpool_io_service) );
for (int i = 0; i < 6; ++i) {
threadpool_threads.create_thread(
boost::bind(&boost::asio::io_service::run, &threadpool_io_service));
}
threadpool_io_service.stop();
threadpool_work.reset();
threadpool_threads.join_all();
return( Rcpp::wrap(retdbl) );
END_RCPP
}
When I run from command-line R, there's no problem. I get the double returned. However, when I run through R Studio Server, it either hangs endlessly, or it crashes when it gets to the create_thread statement.
My version info is:
R: R version 3.1.1 (2014-07-10) -- "Sock it to Me"
R Studio: 0.99.489
Linux: Linux Debian-Jessie 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u6 (2015-11-09) x86_64 GNU/Linux
boost: 1.55
That may just be your cost of running inside RStudio with threaded code. RStudio itself is using Boost for this, and also talking to R -- so it seems that two event queues are getting mixed up. I think short of talking to them there is little you can do.
I really do like littler for running bigger jobs as scripts on the command-line. It has been part of Debian since 2006 too as is just an apt-get away for you.
Edit: As an Rcpp aside you can write your function more compactly as
// [[Rcpp::export]]
double test_thread() {
double retdbl = 10.4;
boost::shared_ptr<boost::asio::io_service::work> threadpool_work;
boost::asio::io_service threadpool_io_service;
boost::thread_group threadpool_threads;
threadpool_work.reset( new
boost::asio::io_service::work(threadpool_io_service) );
for (int i = 0; i < 6; ++i) {
threadpool_threads.create_thread(
boost::bind(&boost::asio::io_service::run, &threadpool_io_service));
}
threadpool_io_service.stop();
threadpool_work.reset();
threadpool_threads.join_all();
return(retdbl);
}
See the vignette Rcpp Attributes for details; you probably want to call compileAttributes() in the package directory; RStudio will do it to your source package.
Related
I have to compile Locally Aware NMS (lanms) in my remote server LINUX based with an user account without root access.
In lanms there is a script named adapter.cpp , I have to convert it to .pyd so that it works with python. I have given the code described here.
#include "pybind11/pybind11.h"
#include "pybind11/numpy.h"
#include "pybind11/stl.h"
#include "pybind11/stl_bind.h"
#include "lanms.h"
namespace py = pybind11;
namespace lanms_adaptor {
std::vector<std::vector<float>> polys2floats(const std::vector<lanms::Polygon> &polys) {
std::vector<std::vector<float>> ret;
for (size_t i = 0; i < polys.size(); i ++) {
auto &p = polys[i];
auto &poly = p.poly;
ret.emplace_back(std::vector<float>{
float(poly[0].X), float(poly[0].Y),
float(poly[1].X), float(poly[1].Y),
float(poly[2].X), float(poly[2].Y),
float(poly[3].X), float(poly[3].Y),
float(p.score),
});
}
return ret;
}
/**
*
* \param quad_n9 an n-by-9 numpy array, where first 8 numbers denote the
* quadrangle, and the last one is the score
* \param iou_threshold two quadrangles with iou score above this threshold
* will be merged
*
* \return an n-by-9 numpy array, the merged quadrangles
*/
std::vector<std::vector<float>> merge_quadrangle_n9(
py::array_t<float, py::array::c_style | py::array::forcecast> quad_n9,
float iou_threshold) {
auto pbuf = quad_n9.request();
if (pbuf.ndim != 2 || pbuf.shape[1] != 9)
throw std::runtime_error("quadrangles must have a shape of (n, 9)");
auto n = pbuf.shape[0];
auto ptr = static_cast<float *>(pbuf.ptr);
return polys2floats(lanms::merge_quadrangle_n9(ptr, n, iou_threshold));
}
}
PYBIND11_PLUGIN(adaptor) {
py::module m("adaptor", "NMS");
m.def("merge_quadrangle_n9", &lanms_adaptor::merge_quadrangle_n9,
"merge quadrangels");
return m.ptr();
}
To convert it I have used the following command.
cl adaptor.cpp ./include/clipper/clipper.cpp /I ./include /I "C:\ProgramData\Anaconda3\include" /LD /Fe:adaptor.pyd /link/LIBPATH:"C:\ProgramData\Anaconda3\libs"
It shows an error:
Command 'cl' not found, but can be installed with:
apt install cl-launch
Please ask your administrator.
Furthermore, I don't have the root access. Is there any other way to install "cl" without administrator privileges?
The other way to compile lanms is need to install the g++ compiler in order to compile the adaptar.cpp file.
sudo apt-get install build-essential
It is also asking for the administrator privileges.
I'm afraid, that it is almost impossible to compile your code on a machine that doesn't have a compiler installed.
The best option, that I can come up with, would be to set up a virtual machine, that runs the same version of the same linux distribution as the server. In that virtual machine, you have root access and can install a compiler. After compiling the code you just copy the program/library to the server. It is however not guaranteed, that the program compiled in the virtual machine will run without problems on the real server.
I want to be able to execute programs on my computer. I installed CGAL using Macports, I am not sure how to proceed next. Can anybody tell me how to execute the program, I am desperately trying to run the following program but don't know how to:
#include <iostream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/convex_hull_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
int main()
{
Point_2 points[5] = { Point_2(0,0), Point_2(10,0), Point_2(10,10), Point_2(6,5), Point_2(4,1) };
Point_2 result[5];
Point_2 *ptr = CGAL::convex_hull_2( points, points+5, result );
std::cout << ptr - result << " points on the convex hull:" << std::endl;
for(int i = 0; i < ptr - result; i++){
std::cout << result[i] << std::endl;
}
return 0;
}
CGAL comes with a script called cgal_create_cmake_script that should be run where you saved your example file.
Then run cmake . and make
CGAl gets installed on the directory :
opt/local/include/cgal
steps:
Write your program into a text file and save excutable.cpp
In the command line go to the directory of the executable( use cd command)
then write the following commands
cgal_create_CMakeLists -s executable //without .cpp!!
cmake -DCGAL_DIR = opt/local/include/cgal
make
go to the folder where you saved executable.cpp and then click on the executable file(has a black square icon)
and your done :)
NOTE: only works if you installed using macports. if you installed using homebrew directories change,the procedure remains the same :)
You also need command line tools installed.
I've been writing a program that needs a wine version of 2.6 or later. I'd like to get it as a boolean, so I've been trying to use the code below:
#include <string>
#include <iostream>
#include "WineCheck.h"
#include <cstdlib>
using namespace std;
bool checkForWine()
{
// Create variables for checking wine state
bool wineIsThere = false;
bool wineIsVersion = false;
// Check dpkg if wine is there
if (string(system("dpkg -l | cut -c 4-9 | grep \\ wine\\ ")) == " wine ")
{
wineIsThere = true;
// Check version
if (double(system("wine --version | cut -c 6-8")) >= 2.6)
wineIsVersion = true;
}
// Return
if (wineIsThere && wineIsVersion)
return true;
else
return false;
}
First, it's my opinion you shouldn't bother with this. Wine 2.6 should just be included as a dependency in your configuration script, and/or your package file. Targeting a specific package management system in your program source code is not a good idea if you want to maintain portability to other GNU/Linux distributions that don't use that packager.
To answer your question though. There are two ways I found you can do this. You can check /var/lib/dpkg/status. Read through the file line by line until you get to this section. If you don't find the section, or the Status: ... line doesn't say installed then wine is not installed. The Version: ... line will tell you what version is installed. I verified this method works by installing and uninstalling Wine on Debian Wheezy. You didn't say what distro you're working with, but it's obvious you're using the Debian Packaging system, so this should work on Ubuntu and other Debian based distributions as well.
$cat /var/lib/dpkg/status
...
Package: wine
Status: install ok installed
Priority: optional
Section: otherosf
Installed-Size: 80
Maintainer: Debian Wine Party <pkg-wine-party#lists.alioth.debian.org>
Architecture: amd64
Version: 1.4.1-4
...
The other option is use libdpkg. I found an example that lists all installed packages.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/pkg-array.h>
#include "filesdb.h"
const char thisname[] = "example1";
int
main(int argc, const char *const *argv)
{
struct pkg_array array;
struct pkginfo *pkg;
int i;
enum modstatdb_rw msdb_status;
standard_startup();
filesdbinit();
msdb_status = modstatdb_open(msdbrw_readonly);
pkg_infodb_init(msdb_status);
pkg_array_init_from_db(&array);
pkg_array_sort(&array, pkg_sorter_by_name);
for (i = 0; i < array.n_pkgs; i++) {
pkg = array.pkgs[i];
if (pkg->status == stat_notinstalled)
continue;
printf("Package --> %s\n", pkg->set->name);
}
pkg_array_destroy(&array);
modstatdb_shutdown();
standard_shutdown();
}
I'm experimenting with the PUSH/PULL pattern for distributed computing in a local network.
Up to now everything seemed to work out, however, I had o discover that upon the startup of the 31 worker (server) the client (the ventilator and the collector) application crashes.
Is there a limit for the connections to a certain port on windows (on MacOs X this seems not to be the case). I'm using tcp trans port and ports 5555 and 5556 as in the zeromq example. The behavior is observer for remote and local workers.
Thx
Update: heres the code (modified sample from the zmq guide)
#include <zmq.hpp>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <sstream>
int main (int argc, char *argv[])
{
zmq::context_t context(1);
int number_of_sockets=32; // 32 will crash, 30 will pass
zmq::socket_t** receiver=new zmq::socket_t*[number_of_sockets];
zmq::socket_t** sender=new zmq::socket_t*[number_of_sockets];
std::cout<< "go"<<std::endl;
for (int i=0;i<number_of_sockets; i++)
{
receiver[i]=new zmq::socket_t(context, ZMQ_PULL);
receiver[i]->connect("tcp://localhost:5555");
}
std::cout<< "ok"<<std::endl;
for (int i=0;i<number_of_sockets; i++)
{
sender[i]=new zmq::socket_t(context, ZMQ_PUSH);
sender[i]->connect("tcp://localhost:5556");
}
std::cout << "done" <<std::endl;
return 0;
}
I build using Mingw-w64-tdm (4.5) by the command:
g++ -o worker.exe taskworker.cpp -L/./lib -lzmq -L/./lib/zeromq/libzmq.la -liphlpapi -lrpcrt4 -lws2_32 -lpthread
Ok. I pinned it down to this issue here. The problem is, that on windows by default there is a FD_SETSIZE limit of 64. (This makes the code crash - actually for the 32. worker). FD_SETSIZE can be modified during building 0mq (CPPFLAG="-DFD_SETSIZE=1024").
Now the crashes are gone.
I have some code of my application that makes usage of boost inteprocess scoped lock with timers. When a mutex is acquired in one thread, a second thread tyring to acquire it for few milliseconds will fail and will log something to screeen.
I don't know why but with the version of boost 1.50 this doens't work anymore.
The code below I can see that the thread #2 doesn't print "ERROR" but is completely stuck.
Am I missing something here?
I am using LINUX kernel 2.6.32 with g++.
COuld it be something to deal with UTC? I read o boost that the time used by such lock is UTC and in date time I am reading right now about local_adjustor and conversion from local to utc and vice-versa.
AFG
#include <iostream>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
namespace bi = boost::interprocess;
void lock_test( bi::named_mutex& mt, bool long_sleep ) {
boost::posix_time::ptime pt =
boost::posix_time::microsec_clock::local_time()
+ boost::posix_time::milliseconds(100);
bi::scoped_lock<bi::named_mutex> l( mt, pt );
if( l.owns() ){
std::cout << "Locked"<<std::endl;
}
else{
std::cout << "ERROR" << std::endl;
std::cout.flush();
return ;
}
if(long_sleep){
while(true) {sleep(1);std::cout<<"[]";std::cout.flush();}
}
}
int main(){
bi::named_mutex m_mutex( bi::open_or_create, "ciao"
, bi::permissions( 0666 ));
boost::thread t1 = boost::thread( &lock_test
, boost::ref( m_mutex), true );
sleep(4);
boost::thread t2 = boost::thread( &lock_test
, boost::ref(m_mutex), false );
while(true){sleep(1);}
}
It looks that if I switch from boost::posix_time::microsec_clock::local_time() to
boost::posix_time::microsec_clock::universal_time()
everything works fine.
You should use boost::get_system_time(), there are quite a few examples with it. Though I can't find the authoritative source, I use microsec_clock exactly as you do and get similar problems. Just discovered the bug though, will update when I'll test the fix.
Usage of boost::unique_lock::timed_lock