EIGEN library with MKL rvalue references warning - c++11

I am trying to the use the EIGEN library linked with the MKL library (icc version 17.0.4) with the code:
#define EIGEN_USE_MKL_ALL
#define lapack_complex_float std::complex<float>
#define lapack_complex_double std::complex<double>
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/Eigenvalues>
#include <complex>
#include <Eigen/PardisoSupport>
using namespace Eigen;
using Eigen::MatrixXd;
int main()
{
int size = 3;
MatrixXd A(size,size);
A(0,0)=1.0; A(0,1)=-0.5; A(0,2)=0.2;
A(1,0)=0.7; A(1,1)=-1.3; A(1,2)=-2.0;
A(2,0)=0.7; A(2,1)=-1.3; A(2,2)=-2.0;
std::cout << A << std::endl;
VectorXd vec(3);
vec(0) = 2;
vec(1) = 3;
vec(2) = 4;
std::cout << A*vec << "\n";
std::cout << A.eigenvalues() << "\n";
}
I compile via
icc -I${MKLROOT}/include -L${MKLROOT}/lib -Wl,-rpath,${MKLROOT}/lib \
-lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl \
-L/Users/user/eigen -I/Users/user/eigen
However I receive the error message:
/Users/user/eigen/Eigen/src/Core/DenseStorage.h(372): warning #3495: rvalue references
are a C++11 feature DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
How to solve this warning?

Eigen seems to detect that your compiler supports rvalue references. You can either disable that by defining -DEIGEN_HAS_RVALUE_REFERENCES=0 via the command line or before including Eigen in your source by:
#define EIGEN_HAS_RVALUE_REFERENCES 0
Preferably, tell icc that it shall compile with C++11 support (I assume -std=c++11 works for icc as well).

Related

Dynamic loading libpython with pybind11

I'm trying to build some shared library with pybind11 from Mac OSX. I'm running into the error:
dyld: Symbol not found: _PyBaseObject_Type
Referenced from: /Users/xxxxx/work/test_dynamic_linking/./example
Expected in: flat namespace
in /Users/xxxxx/work/test_dynamic_linking/./example
Abort trap: 6
What I'm trying to achieve is to turn off build time linking, but dynamic loading libpython in runtime with dlopen. Note the -Wl,-undefined,dynamic_lookup flag in the cmake file. I'm doing it this way because I want to build a wheel, and linking to libpython is not a good idea AFAIU.
Below is a minimial reproducible example. I'm confused that if you call functions like Py_DecodeLocale() or Py_InitializeEx() directly from main.cpp, it works fine. But calling pybind11::initialize_interpreter() fails with the error above.
If I do
nm -gU /opt/anaconda3/envs/py38/lib/libpython3.8.dylib | grep PyBaseObject
the symbol _PyBaseObject_Type is indeed defined in the lib:
0000000000334528 D _PyBaseObject_Type
If I create a wrapper shared library which wraps the calls to pybind11 functions, and dlopen it from main.cpp, it works fine. This makes me more confused.
Cmake file:
cmake_minimum_required(VERSION 3.4)
project(example)
set (CMAKE_CXX_STANDARD 11)
set(UNDEFINED_SYMBOLS_IGNORE_FLAG "-Wl,-undefined,dynamic_lookup")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${UNDEFINED_SYMBOLS_IGNORE_FLAG}")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " ${UNDEFINED_SYMBOLS_IGNORE_FLAG}")
include_directories(pybind11/include)
include_directories(/opt/anaconda3/envs/py38/include/python3.8)
add_library(pywrapper SHARED ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.cpp)
add_executable(example main.cpp)
pyembed.hpp:
#pragma once
#include "pybind11/embed.h"
namespace py = pybind11;
void initialize_interpreter_func();
struct pybind_wrap_api {
decltype(&initialize_interpreter_func) initialize_interpreter;
};
wrapper.cpp:
#include "pyembed.hpp"
#include <set>
#include <vector>
#include <iostream>
#include "pybind11/embed.h"
#include "pybind11/stl.h"
namespace py = pybind11;
void initialize_interpreter_func() {
pybind11::initialize_interpreter();
}
pybind_wrap_api init_pybind_wrap_api() noexcept {
return {
&initialize_interpreter_func,
};
}
__attribute__((visibility("default"))) pybind_wrap_api pybind_wrapper_api =
init_pybind_wrap_api();
main.cpp:
#include <pybind11/embed.h> // everything needed for embedding
#include "pyembed.hpp"
#include <stdlib.h>
#include <dlfcn.h>
#include <iostream>
#include <string>
namespace py = pybind11;
static void* pylib_handle = nullptr;
static void* pybind_wrapper_handle = nullptr;
pybind_wrap_api* wrappers = nullptr;
int main() {
std::string path_libpython = "/opt/anaconda3/envs/py38/lib/libpython3.8.dylib";
pylib_handle = dlopen(path_libpython.c_str(), RTLD_NOW | RTLD_GLOBAL);
if(!pylib_handle) {
std::cout << "load libpython failed..." << std::endl;
} else {
std::cout << "load libpython succeeded..." << std::endl;
}
std::string path_wrapper = "./libpywrapper.dylib";
pybind_wrapper_handle = dlopen(path_wrapper.c_str(), RTLD_NOW | RTLD_GLOBAL);
wrappers = static_cast<pybind_wrap_api*>(dlsym(pybind_wrapper_handle, "pybind_wrapper_api"));
std::string pythonhome = "/opt/anaconda3/envs/py38";
setenv("PYTHONHOME", pythonhome.c_str(), 1);
std::string pythonpath = "/opt/anaconda3/envs/py38/lib/python3.8/site-packages";
setenv("PYTHONPATH", pythonpath.c_str(), true);
// this line will cause it to fail with the symbol not found error
py::initialize_interpreter();
// if comment out the previous line and do the following line, it works fine. I'm confused why is so.
//wrappers->initialize_interpreter();
return 0;
}
Then do
cmake . && make && ./example

gtkmm undefined reference to certain gtk::builder function add_from_file

I am using eclipse, mingw-w64, gtkmm2.4, glade to compile some simple program.
I can compile hello world gtkmm examples, following a tutorial to, however when it comes to glade came a little strange undefined to error.
program that compiled and run smoothly, which was the gtkmm 2.24 simple example tutorial https://developer.gnome.org/gtkmm-tutorial/2.24/sec-basics-simple-example.html.en
#include <gtkmm.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
Gtk::Window window;
Gtk::Main::run(*window);
return 0;
}
however when I try to run another simple example from the glade chapter (24.2.1) things does not work out.
https://developer.gnome.org/gtkmm-tutorial/2.24/sec-builder-accessing-widgets.html.en
example:
#include <gtkmm.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
//Gtk::Window window; //I changed it to fit with the glade example
Gtk::Window* window; //I changed this line from the example
//////////////// this part was pretty much just copied out from the example//////
Glib::RefPtr<Gtk::Builder> refBuilder = Gtk::Builder::create();
try
{
refBuilder->add_from_file("something.glade"); //this is the line with problem.
}
catch(const Glib::FileError& ex)
{
std::cerr << "FileError: " << ex.what() << std::endl;
return 1;
}
catch(const Gtk::BuilderError& ex)
{
std::cerr << "BuilderError: " << ex.what() << std::endl;
return 1;
}
refBuilder->get_widget("window1", window);
//////////////// end of copied out from the example//////
Gtk::Main::run(*window);
return 0;
}
when compiled, it gave error as follow
test.cpp:(.text.startup+0x281): undefined reference to Gtk::Builder::add_from_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
It seems to take the argument "something.glade" as type std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const& (which I have no idea what it is).
according to the gtkmm manual (https:developer.gnome.org/gtkmm/stable/classGtk_1_1Builder.html#aa3f4af4e7eaf7861c8283dc0dbd5254c) seems it only takes Gtk::Builder::add_from_file(const std::string & filename). So is the argument type really the problem?
I have tried casting it as std::string by doing std::string() or string(), but it gave the same error.
I have tried commenting out the line in question, and it compiled fine.
Gtk::Builder::create() did not receive undefined reference to compilation error
refBuilder->get_widget("window1", window); did not receive undefined reference to compilation error
So now I am scratching my head all over this seems trivial issue. Please provide some help.
For more information
pkg-config --cflags --libs yielded -IE:/gtkmm64/include/gtkmm-2.4 -IE:/gtkmm64/lib/gtkmm-2.4/include -IE:/gtkmm64/include/atkmm-1.6 -IE:/gtkmm64/include/giomm-2.4 -IE:/gtkmm64/lib/giomm-2.4/include -IE:/gtkmm64/include/pangomm-1.4 -IE:/gtkmm64/lib/pangomm-1.4/include -IE:/gtkmm64/include/gtk-2.0 -IE:/gtkmm64/include/gdkmm-2.4 -IE:/gtkmm64/lib/gdkmm-2.4/include -IE:/gtkmm64/include/atk-1.0 -IE:/gtkmm64/include/glibmm-2.4 -IE:/gtkmm64/lib/glibmm-2.4/include -IE:/gtkmm64/include/glib-2.0 -IE:/gtkmm64/lib/glib-2.0/include -IE:/gtkmm64/include/sigc++-2.0 -IE:/gtkmm64/lib/sigc++-2.0/include -IE:/gtkmm64/include/cairomm-1.0 -IE:/gtkmm64/lib/cairomm-1.0/include -IE:/gtkmm64/include/pango-1.0 -IE:/gtkmm64/include/cairo -IE:/gtkmm64/include -IE:/gtkmm64/include/freetype2 -IE:/gtkmm64/include/libpng14 -IE:/gtkmm64/lib/gtk-2.0/include -IE:/gtkmm64/include/gdk-pixbuf-2.0 -LE:/gtkmm64/lib -lgtkmm-2.4 -latkmm-1.6 -lgdkmm-2.4 -lgiomm-2.4 -lpangomm-1.4 -lgtk-win32-2.0 -lglibmm-2.4 -lcairomm-1.0 -lsigc-2.0 -lgdk-win32-2.0 -latk-1.0 -lgio-2.0 -lpangowin32-1.0 -lgdi32 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpng14 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl, Which I have included into the project
pkg-config --modversion gtkmm2.4 yielded 2.22.0, so I doubt it has anything to do with the 2.14 requirement for add_from_file()
pkg-config --modversion gtk+2.0 yielded 2.22.0
I did not use any flags like --std=c++xx.
windows 8 64bit
seems Converting std::__cxx11::string to std::string solved it.
put #define _GLIBCXX_USE_CXX11_ABI 0 at start because I am using gcc 5.

Storing a boost::spirit::qi::rule in a std::list

I have read the other thread about copy or reference semantics for boost::spirt::qi::rule. I am using Boost 1.42.
using boost::spirit::qi::phrase_parse;
typedef boost::spirit::qi::rule < std::string::const_iterator, boost::spirit::ascii::space_type > rule_type;
std::list < rule_type > ruleList;
std::string const s("abcdef");
std::string::const_iterator iter = s.begin(), end = s.end();
std::cout << typeid(char_).name() << std::endl;
ruleList.push_back(char_);
ruleList.push_back(*ruleList.back());
assert(phrase_parse(iter, s.end(), ruleList.back(), boost::spirit::ascii::space));
assert(iter == s.end());
This fails with...
Assertion `phrase_parse(iter, s.end(), ruleList.back(), traits::space())' failed.
Aborted (core dumped)
Is there a way to store rules in a STL list or deque? (References don't die until removed).
With Boost V1.45, this (essentially your code from above) works without problems (MSVC2010, g++ 4.5.1):
#include <list>
#include <string>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
using namespace boost::spirit;
int main()
{
typedef qi::rule<std::string::const_iterator, ascii::space_type> rule_type;
std::list<rule_type> ruleList;
std::string const s("abcdef");
std::string::const_iterator iter = s.begin(), end = s.end();
std::cout << typeid(qi::char_).name() << std::endl;
ruleList.push_back(qi::char_);
ruleList.push_back(*ruleList.back());
assert(qi::phrase_parse(iter, s.end(), ruleList.back(), ascii::space));
assert(iter == s.end());
return 0;
}
Therefore, I assume it's a bug in the version of Spirit you're using.
I could not get your example to compile. Aside from not using the correct types from ...::qi, you added a () to the trait::space type.
This works w/o problem for me (boost 1.44)
#include <boost/spirit/include/qi.hpp>
#include <string>
#include <vector>
#include <cassert>
using boost::spirit::qi::phrase_parse;
typedef boost::spirit::qi::rule < std::string::const_iterator, boost::spirit::qi::space_type > rule_type;
int main() {
std::list < rule_type > ruleList;
std::string const s("abcdef");
std::string::const_iterator iter = s.begin(), end = s.end();
ruleList.push_back(*boost::spirit::qi::char_);
assert(phrase_parse(iter, s.end(), ruleList.back(), boost::spirit::qi::space));
assert(iter == s.end());
}
~>g++ test.cpp && ./a.out
~>
please note I use qi::space_type and `qi::space instead of the ascii namespace. I have no idea what/where the trait namespace is.

Overriding functions from dynamic libraries

Hello I have a program with a global function that I'd like to customize at run time. Say, there are many versions of function foo() scattered over shared libraries. Now, based on system configuration detected at run time I'd like to use function from appropriate library.
File loader.cpp:
#include <dlfcn.h>
#include <iostream>
void __attribute__((weak)) foo();
int main(int argc, char *argv[])
{
void* dl = dlopen("./other.so", RTLD_NOW | RTLD_GLOBAL);
if (!dl)
{
std::cerr << dlerror() << std::endl;
return 1;
}
if (foo)
{
foo();
}
else
{
std::cerr << "No foo?" << std::endl;
}
dlclose(dl);
return 0;
}
File other.cpp:
#include <iostream>
void foo()
{
std::cout << "FOO!" << std::endl;
}
I compile the program with
g++ -Wall -fPIC -o loaded loader.cpp -ldl
g++ -Wall -fPIC -shared -o other.so other.cpp
However the weak symbol is not overriden. Any hints?
Symbols are resolved during load time of the image in which they are referenced. So when your executable is loaded, the reference to foo is already resolved. A later dlopen won't go and rebind all symbols - it only may affect later loads.
You'll have to use dlsym instead, or set LD_PRELOAD:
martin#mira:/tmp$ LD_PRELOAD=/tmp/other.so ./loaded
FOO!
You compiled the shared lib with g++.
As a result, the name of the function is mangled:
$ nm -S other.so |grep foo
0000000000000690 000000000000002e T _Z3foov
If you make it a pure C code and compile with
gcc instead of g++, you'll find it working as you expect.
Alternatively, define it as follows:
extern "C" void foo()
{
std::cout << "FOO!" << std::endl;
}

Not getting strcpy errors on Mac while I do on Windows?

-- All of the revised code still refuses to run well, please help --
When I compile my code in Windows, I get memory errors. However on the Mac, where I initially coded this code, it works fine. I need to get this working on Windows.
It's something to do with the way I handle my char strings using strcpy that the Mac seems to be fine with (I guess it's related to gcc vs. Microsoft's way of doing things).
Here's the code for the complainers:
main.cpp
#include "Cust.h"
using namespace std;
int main (int argc, char * const argv[]) {
Cust customers[500];
char tmpString[70] = " ";
char * pch = new char[255];
string tmpAcctFN = " ";
string tmpAcctLN = " ";
ifstream input("P3_custData.txt");
for (int idx = 0; idx < 130; idx++){
input.getline(tmpString, 70, '\n');
strcpy(pch,strtok(tmpString," "),255);
customers[idx].setAcctNum(pch);
cout << pch << endl;
strcpy(pch, strtok(NULL," "));;
customers[idx].setAcctFN(pch);
cout << pch << endl;
strcpy(pch, strtok(NULL," "));;
customers[idx].setAcctLN(pch);
cout << pch << endl;
strcpy(pch, strtok(NULL," "));;
customers[idx].setCurrBalance(atol(pch));
cout << pch << endl;
strcpy(pch, strtok(NULL," "));;
customers[idx].setPIN(atoi(pch));
cout << pch << endl;
}
input.close();
return 0;
}
Cust.h
/*
* Cust.h
* Project 3
*
* Created by Anthony Glyadchenko on 11/17/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include <iostream>
#include <string>
using namespace std;
#ifndef CUST_H
#define CUST_H
class Cust{
public:
char * getAcctNum();
void setAcctNum(char num[]);
double getCurrBalance();
void setCurrBalance(double balance);
void addToCurrBalance(double amount);
void subFromCurrBalance(double amount);
void setAcctFN(char firstName[]);
void setAcctLN(char lastName[]);
char * getAcctFN();
char * getAcctLN();
void setPIN(int pin);
int getPIN();
private:
char acctNum[255];
char acctFN[255];
char acctLN[255];
double currBalance;
int pin;
char fileName[255];
};
#endif
Cust.cpp
/*
* Cust.cpp
* Project 3
*
* Created by Anthony Glyadchenko on 11/17/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include <fstream>
#include <string>
#include <sstream>
#include "Cust.h"
using namespace std;
char * Cust::getAcctNum(){
return acctNum;
}
void Cust::setAcctNum(char num[]){
strcpy(acctNum,num);
}
double Cust::getCurrBalance(){
return currBalance;
}
void Cust::setCurrBalance(double balance){
currBalance = balance;
}
void Cust::addToCurrBalance(double amount){
currBalance += amount;
}
void Cust::subFromCurrBalance(double amount){
currBalance -= amount;
}
void Cust::setAcctFN(char firstName[]){
strcpy(acctFN,firstName);
}
void Cust::setAcctLN(char lastName[]){
strcpy(acctLN,lastName);
}
char * Cust::getAcctFN(){
return acctFN;
}
char * Cust::getAcctLN(){
return acctLN;
}
void Cust::setPIN(int pin){
Cust::pin = pin;
}
int Cust::getPIN(){
return pin;
}
Here is my stack trace:
Index Function
--------------------------------------------------------------------------------
1 msvcr90d.dll!68d7f693()
2 [Frames below may be incorrect and/or missing, no symbols loaded for msvcr90d.dll]
*3 P3.exe!main(int argc=0, char * const * argv=0x0036fcd0)
4 P3.exe!_FreeLibrary#4()
5 P3.exe!#ILT+170(__except_handler4)()
6 kernel32.dll!75eb3677()
7 ntdll.dll!77b29d72()
8 ntdll.dll!77b29d45()
A few things to check (sorry not going to download the code):
does g++ *.c have warnings? If so fix them.
does g++ -W have warnings? If so fix them.
does g++ -W -Wall have warnings? If so fix them.
does g++ -W -Wall -Wextra have warnings? If so fix them.
does g++ -W -Wall -Wextra -ansi have warnings? If so fix them.
does g++ -W -Wall -Wextra -ansi -pedantic have warnings? If so fix them.
On microsoft try adding /W4 to the command line to turn the warning up, again fix any issues.
Odds are you are doing something "silly" and chances are that the compiler can help you catch what it is.
Edit:
From compiling your code with the flags above you will see:
Cust.h:33: error: ISO C++ forbids zero-size array ‘acctNum’
Cust.h:34: error: ISO C++ forbids zero-size array ‘acctFN’
Cust.h:35: error: ISO C++ forbids zero-size array ‘acctLN’
Cust.h:38: error: ISO C++ forbids zero-size array ‘fileName’
Cust.h:33: error: ISO C++ forbids zero-size array ‘acctNum’
Cust.h:34: error: ISO C++ forbids zero-size array ‘acctFN’
Cust.h:35: error: ISO C++ forbids zero-size array ‘acctLN’
Cust.h:38: error: ISO C++ forbids zero-size array ‘fileName’
So your code is not valid C++. You are copying a name into an array that is too small - the array has 0 elements. What you really need to do is give the arrays a size when you declare them or declare them as pointers and then use "new" to allocate the right amount of memroy.
Passing invalid buffers, buffers that are too small, etc., to strcpy results in undefined behavior - just about anything can happen. On the Mac, the problems happen but aren't apparent, while on Windows it results in a crash.
char acctNum[];
char acctFN[];
char acctLN[];
There's your problem right there. You never seem to allocate any space for these strings anywhere. The strcpy() in setAcctNum() is overflowing the bounds of that unsized array, and overwriting something else. It's pretty amazing that this compiles at all, actually.
You probably ought to be using std::string, instead - that'll make the memory management easier, at least.
Probably is your implementation of the strcpy function, which could have differences between how it is coded on the mac and how it's coded on Windows.

Resources