How to get the future value? - c++

In using packaged_task, I collected all the futures in a vector. After that, I push back the future values with get(). However, I got the wrong answer. Can anyone help? Thank you very much.
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>
using namespace std;
vector<int> subFun(int n) {
vector<int> a{ 2 * n, 3 * n };
return a;
}
int main() {
vector<boost::future<vector<int>>> g;
vector<vector<int>> x(10, vector<int>(2));
int i;
for (i = 0; i < 10; i++) {
boost::packaged_task<vector<int>> task{ boost::bind(&subFun, i) };
g.push_back(task.get_future());
boost::thread t{ std::move(task) };
}
for (auto& m : g) {
x.push_back(m.get());
}
cout << x[3][0] << endl;//should be 6, now is 0
return 0;
}

The realest issue is that you push_back into x, but you already had it initialized here:
vector<vector<int>> x(10, vector<int>(2));
So, you just add 10 more elements, instead of putting the result at indices 0..9. I'd suggest not pre-filling, like #patrick's answer, or instead filling the designated slot:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>
using namespace std;
void subFun(int n, vector<int>& into) {
into = { 2 * n, 3 * n };
}
int main() {
vector<boost::future<void>> futures;
vector<vector<int>> x(10, vector<int>(2));
for (size_t i = 0; i < x.size(); i++) {
boost::packaged_task<void> task{ boost::bind(&subFun, i, std::ref(x[i])) };
futures.push_back(task.get_future());
boost::thread(std::move(task)).detach();
}
for (auto& f : futures)
f.wait();
cout << x[3][0] << endl;
}
Of course you can be more complex:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>
struct TaskResult {
int index;
std::vector<int> data;
};
TaskResult subFun(int n) {
return { n, { 2 * n, 3 * n } };
}
int main() {
std::vector<boost::future<TaskResult>> futures;
std::vector<std::vector<int>> x(10, std::vector<int>(2));
for (size_t i = 0; i < x.size(); i++) {
boost::packaged_task<TaskResult> task{ boost::bind(&subFun, i) };
futures.push_back(task.get_future());
boost::thread(std::move(task)).detach();
}
for (auto& f : futures) {
auto r = f.get();
x[r.index] = r.data;
}
std::cout << x[3][0] << std::endl;
}

After much tinkering, I found this program works without abort traps (which I'm surprised you weren't getting):
#include <future>
#include <thread>
#include <functional>
#include <vector>
#include <iostream>
std::vector<int> subFun(int n) {
std::vector<int> a { 2 * n, 3 * n };
return a;
}
int main() {
std::vector<std::future<std::vector<int>>> g;
std::vector<std::vector<int>> x;
int i;
for (i = 0; i < 10; i++) {
std::packaged_task<std::vector<int>(int)> task{ subFun };
g.push_back(task.get_future());
std::thread { std::move(task), i }.detach();
}
for (auto& m : g) {
m.wait();
x.push_back(m.get());
}
std::cout << x[3][0] << std::endl; // is now 6
return 0;
}
Convert to boost as necessary. This answer was extremely helpful in finding a couple of key issues.

Related

C++ std::any how to check if type of std::any is vector

#include <iostream>
#include <vector>
#include <string>
#include <any>
#include <map>
#include <functional>
#include <exception>
using namespace std;
using MapAny = std::map<string, any>;
int square(int x) {
return x*x;
}
vector<int> parse(map<string, vector<MapAny>> mapping)
{
vector<MapAny> func_square = mapping["square"];
vector<int> res;
for (const auto &mapany : func_square) {
try {
int x = any_cast<int>(mapany.at("x"));
res.push_back(square(x));
}
catch (exception e) {
vector<int> xs = any_cast<vector<int>>(mapany.at("x"));
for (int x : xs) res.push_back(square(x));
}
}
return res;
}
int main()
{
map<string, vector<MapAny>> function_map_value, function_map_array;
function_map_value = {
{"square", { {{"x", 5}}, {{"x", 10}} }}
};
vector<MapAny> vec;
vec.push_back({{"x", vector<int>({5, 10}) }});
function_map_array = {
{"square", vec}
};
vector<int> res1 = parse(function_map_value);
vector<int> res2 = parse(function_map_array);
for (int i=0; i<res1.size(); i++) cout << res1[i] << " "; cout << "\n";
for (int i=0; i<res2.size(); i++) cout << res2[i] << " "; cout << "\n";
return 0;
}
I'm trying to make a function parser that can accept any type, such as both scalar and vector values, like in Python dict().
However, I'm not sure how to check if a std::any object has type std::vector. In the code above, if any_cast fails, it will throw exception and I know it's a std::vector. It's ugly and rely on throwing exception as an expected behavior.
How can I change the above code into something like:
if (is_vector(mapany.at("x")) {
// deal with vector
}
else {
// deal with scalar
}

Brace-enclosed initializer for matrix constructor fail in type std::complex<double> >

I implented a contructor for my matrix class to do brace-enclosed initialization using nested std::initializer_list. The constructor works fine for primary type: `int`, `double`; but renders error-reading for `complex`. How to fix this error reading?
The matrix class
template <typename T> class xxx
{
public:
T *ptr;
int col, row, size;
xxx() = delete;
xxx(const int i, const int j):row(i), col(j), size(i*j)
{
ptr = new T [this->size] ;
}
xxx(const std::initializer_list< std::initializer_list<T> > s):xxx(s.size(), s.begin()->size())
{
int j = 0;
for (const auto& i : s) { std::copy (i.begin(), i.end(), ptr + j*col); ++j ; }
}
~xxx() {delete [] this->ptr;}
T operator()(const int i, const int j) const { return ptr[i*col+j]; }
};
A typical ouput overload is added here for complete.
template <typename X> std::ostream& operator<<(std::ostream&p, const xxx<X>&a)
{
for (int i=0; i<a.row; i++) {
for (int j=0; j <a.col; j++) p << std::setw(6) << a(i, j);
p << std::endl;
}
return p;
}
The first test main() with type `double` works well.
#include <iostream>
#include <initializer_list>
#include <iomanip>
#include <complex>
int main()
{
xxx<double> x = {{1, 2,3,4} , {3, 4,5,6}, {5, 6,7,8} };
std::cout << x << std::endl;
}
It prints what is expected:
$ ./a.exe
1 2 3 4
3 4 5 6
5 6 7 8
Then, I try with another type of my interested, `complex`:
int main()
{
xxx< std::complex<double> > z = { {(1,2), (3,4)}, {(5,6), (7,8)} };
std::cout << z << std::endl;
}
The outpur is wrong as follows:
$ ./a.exe
(2,0) (4,0)
(6,0) (8,0)
The imaginery part is missing, and the real parts are taking values of the counter imaginery part. Any idea or suggestion will be highly appreciated.
Your problem is not related to the initializer list. The problem is that this code
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = (1,2);
std::cout << x;
}
Is not doing what you expect it to do. Output is
(2,0)
Because (1,2) is the comma operator at work. std::complex<double> x = (1,2); is the same as std::complex<double> x = 2;.
You need to use curly braces for initialization:
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = {1,2};
std::cout << x;
}
Output
(1,2)
PS I would strongly advise you to use a std::vector<T> to hold the data rather than a T*. Currently copying a xxx will cause undefined behavior, due to not following the rule of 3/5.

C++: I got wrong results while using a class to search for a specific element in a vector

I am searching for a specif element K in a vector. Instead of getting
1
0
I got
0
0
When I used the same code directly in the main () without the class, I got right results.
#include <iostream>
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <algorithm>
#include <vector>
using namespace std;
class Answer
{
public:
static bool exists(int ints[], int size, int k)
{
std::vector<int> v( ints, ints + sizeof(ints)/sizeof(ints[0]) ) ;
auto result1 = std::find(v.begin(), v.end(), k);
if (result1 != v.end()) {
return true;
} else {
return false;
}
}
};
int main()
{
int ints[] = { -9, 14, 37, 102 };
cout << Answer::exists(ints, 4, 102) << endl; // 1
cout << Answer::exists(ints, 4, 36) << endl; // 0
return 0;
}
You cannot obtain the number of elements in an array once you have passed it to a function since it will decay to a pointer. So instead of
std::vector<int> v(ints, ints + sizeof(ints) / sizeof(ints[0]));
use the 2nd parameter size:
std::vector<int> v(ints, ints + size);
As #WhozCraig pointed out in the comments to your question there is no need for a temporary vector since you can use std::find() on arrays perfectly fine:
class Answer
{
public:
static bool exists(int ints[], int size, int k)
{
auto result = std::find(ints, ints + size, k);
return result != ints + size;
}
};

Custom Functor in std::set

#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int order[26];
struct lexcmp
{
bool operator()(const string &s1,const string &s2)
{
int i=0;
int j=min(s1.size(),s2.size());
while(1)
{
if(order[s1[i]-'a']<order[s2[i]-'a'])
return true;
if(order[s1[i]-'a']>order[s2[i]-'a'])
return false;
if(i==j-1)
return false;
i++;
}
}
};
int main()
{
string s;
cin>>s;
for(int i=0;i<s.size();i++)
{
order[s[i]-'a']=i;
}
set<string,lexcmp> store;
int m;
cin>>m;
while(m--)
{
string q;
cin>>q;
store.insert(q);
}
for(auto i=store.begin();i!=store.end();i++)
{
cout<<*i<<endl;
}
}
return 0;
}
Problem in making the Custom Functor
The problem is, i have a new order of elements (instead of simple a-z). //Saved in order array
All i want is order the given strings on the based of new order.
for eg: Order is : bacdefghijklmnopqrstuvwxyz
So if the strings are ss , aa , bb
The new ordering will be bb,aa,ss.
The Code is working fine but it is giving me a problem while the strings are like "pas" "p" to be compared.
p should come before pas but it is coming after.
What modifications should i do in the functor?
Here's one approach:
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <algorithm>
#include <numeric>
#include <array>
#include <string>
#include <locale>
struct lexcmp {
lexcmp() { std::iota(order_.begin(), order_.end(), std::int_fast8_t{}); }
explicit lexcmp(std::string const& order) {
assert(order.size() == order_.size());
for (std::size_t i{}; i != order_.size(); ++i) {
char const order_letter = order[i];
assert(std::isalpha(order_letter, std::locale::classic()));
assert(std::islower(order_letter, std::locale::classic()));
order_[i] = order_letter - 'a';
}
auto unique_order_letters = [this]{
auto order = order_;
std::sort(order.begin(), order.end());
return order.end() - std::unique(order.begin(), order.end()) == 0;
};
assert(unique_order_letters());
}
bool operator ()(std::string const& a, std::string const& b) const {
auto const a_len = a.size(), b_len = b.size();
std::size_t i{};
for (auto const len = std::min(a_len, b_len); i != len; ++i) {
if (auto const diff = order_[a[i] - 'a'] - order_[b[i] - 'a']) {
return diff < 0;
}
}
return i == a_len && i != b_len;
}
private:
std::array<std::int_fast8_t, 26> order_;
};
Online Demo

Increasing allocation performance for strings

I ported a Java GC test program to C++ (see the code below) as well as Python. The Java and Python performance is much greater than C++ and I was thinking this was due to all the calls to new that have to be done to create the strings each time. I've tried using Boost's fast_pool_allocator but that actually worsened performance from 700ms to 1200ms. Am I using the allocator wrong, or is there something else I should be doing?
EDIT: Compiled with g++ -O3 -march=native --std=c++11 garbage.cpp -lboost_system. g++ is version 4.8.1
One iteration takes in Python is about 300ms and with Java about 50ms. std::allocator gives about 700ms and boost::fast_pool_allocator gives about 1200ms.
#include <string>
#include <vector>
#include <chrono>
#include <list>
#include <iostream>
#include <boost/pool/pool_alloc.hpp>
#include <memory>
//#include <gc/gc_allocator.h>
using namespace std;
#include <sstream>
typedef boost::fast_pool_allocator<char> c_allocator;
//typedef std::allocator<char> c_allocator;
typedef basic_string<char, char_traits<char>, c_allocator> pool_string;
namespace patch {
template <typename T> pool_string to_string(const T& in) {
std::basic_stringstream<char, char_traits<char>, c_allocator> stm;
stm << in;
return stm.str();
}
}
#include "mytime.hpp"
class Garbage {
public:
vector<pool_string> outer;
vector<pool_string> old;
const int nThreads = 1;
//static auto time = chrono::high_resolution_clock();
void go() {
// outer.resize(1000000);
//old.reserve(1000000);
auto tt = mytime::msecs();
for (int i = 0; i < 10; ++i) {
if (i % 100 == 0) {
cout << "DOING AN OLD" << endl;
doOld();
tt = mytime::msecs();
}
for (int j = 0; j < 1000000/nThreads; ++j)
outer.push_back(patch::to_string(j));
outer.clear();
auto t = mytime::msecs();
cout << (t - tt) << endl;
tt = t;
}
}
void doOld() {
old.clear();
for (int i = 0; i < 1000000/nThreads; ++i)
old.push_back(patch::to_string(i));
}
};
int main() {
Garbage().go();
}
The problem is you're using a new string stream each time to convert an integer.
Fix it:
namespace patch {
template <typename T> pool_string to_string(const T& in) {
return boost::lexical_cast<pool_string>(in);
}
}
Now the timings are:
DOING AN OLD
0.175462
0.0670085
0.0669926
0.0687969
0.0692518
0.0669318
0.0669196
0.0669187
0.0668962
0.0669185
real 0m0.801s
user 0m0.784s
sys 0m0.016s
See it Live On Coliru
Full code for reference:
#include <boost/pool/pool_alloc.hpp>
#include <chrono>
#include <iostream>
#include <list>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include <boost/lexical_cast.hpp>
//#include <gc/gc_allocator.h>
using string = std::string;
namespace patch {
template <typename T> string to_string(const T& in) {
return boost::lexical_cast<string>(in);
}
}
class Timer
{
typedef std::chrono::high_resolution_clock clock;
clock::time_point _start;
public:
Timer() { reset(); }
void reset() { _start = now(); }
double elapsed()
{
using namespace std::chrono;
auto e = now() - _start;
return duration_cast<nanoseconds>(e).count()*1.0e-9;
}
clock::time_point now()
{
return clock::now();
}
};
class Garbage {
public:
std::vector<string> outer;
std::vector<string> old;
const int nThreads = 1;
void go() {
outer.resize(1000000);
//old.reserve(1000000);
Timer timer;
for (int i = 0; i < 10; ++i) {
if (i % 100 == 0) {
std::cout << "DOING AN OLD" << std::endl;
doOld();
}
for (int j = 0; j < 1000000/nThreads; ++j)
outer.push_back(patch::to_string(j));
outer.clear();
std::cout << timer.elapsed() << std::endl;
timer.reset();
}
}
void doOld() {
old.clear();
for (int i = 0; i < 1000000/nThreads; ++i)
old.push_back(patch::to_string(i));
}
};
int main() {
Garbage().go();
}
Since I don't use boost on my machine, I simplified the code to use standard C++11 to_string (thus accidentally "fixing" the problem sehe found), and got this:
#include <string>
#include <vector>
#include <chrono>
#include <list>
#include <iostream>
#include <memory>
//#include <gc/gc_allocator.h>
#include <sstream>
using namespace std;
class Timer
{
typedef std::chrono::high_resolution_clock clock;
clock::time_point _start;
public:
Timer() { reset(); }
void reset() { _start = now(); }
double elapsed()
{
using namespace std::chrono;
auto e = now() - _start;
return duration_cast<nanoseconds>(e).count()*1.0e-9;
}
clock::time_point now()
{
return clock::now();
}
};
class Garbage {
public:
vector<string> outer;
vector<string> old;
const int nThreads = 1;
Timer timer;
void go() {
// outer.resize(1000000);
//old.reserve(1000000);
for (int i = 0; i < 10; ++i) {
if (i % 100 == 0) {
cout << "DOING AN OLD" << endl;
doOld();
}
for (int j = 0; j < 1000000/nThreads; ++j)
outer.push_back(to_string(j));
outer.clear();
cout << timer.elapsed() << endl;
timer.reset();
}
}
void doOld() {
old.clear();
for (int i = 0; i < 1000000/nThreads; ++i)
old.push_back(to_string(i));
}
};
int main() {
Garbage().go();
}
Compiling with:
$ g++ -O3 -std=c++11 gc.cpp
$ ./a.out
DOING AN OLD
0.414637
0.189082
0.189143
0.186336
0.184449
0.18504
0.186302
0.186055
0.183123
0.186835
clang 3.5 build with source from Friday 18th of April 2014 gives similar results with the same compiler options.
My processor is a AMD Phenom(tm) II X4 965, running at 3.6GHz (if I remember right).