Does C++17 offer generators or another built-in way to transform a non-instantiated sequence in parallel?
up vote
1
down vote
favorite
I'm trying to transform a sequence of numbers in parallel in C++17 and store the results in a vector. But so far I'm unable to find a way to represent the sequence without explicitly filling an array with it, like so:
void transformRange(size_t N)
// Want to replace nums with a generator (an iterator that is not associated with a container)
std::vector<size_t> nums(N);
std::iota(nums.begin(), nums.end(), 0);
std::vector<size_t> a(N);
std::transform(std::execution::par, nums.begin(), nums.end(), a.begin(), fun);
I want this to be doable in parallel (hence the std::execution::par), and the above transform does work in parallel, but the iota does not and it's 3X the memory bandwidth.
I'm also open to deriving the sequence number from the reference to the value being transformed, but I can't get the syntax right. Something like:
void transformRange2(size_t N)
std::vector<size_t> a(N);
std::transform(std::execution::par, a.begin(), a.end(), a.begin(), [&](auto & i) fun(&i - a.begin()); );
c++ range c++17 lazy-evaluation lazy-sequences
add a comment |
up vote
1
down vote
favorite
I'm trying to transform a sequence of numbers in parallel in C++17 and store the results in a vector. But so far I'm unable to find a way to represent the sequence without explicitly filling an array with it, like so:
void transformRange(size_t N)
// Want to replace nums with a generator (an iterator that is not associated with a container)
std::vector<size_t> nums(N);
std::iota(nums.begin(), nums.end(), 0);
std::vector<size_t> a(N);
std::transform(std::execution::par, nums.begin(), nums.end(), a.begin(), fun);
I want this to be doable in parallel (hence the std::execution::par), and the above transform does work in parallel, but the iota does not and it's 3X the memory bandwidth.
I'm also open to deriving the sequence number from the reference to the value being transformed, but I can't get the syntax right. Something like:
void transformRange2(size_t N)
std::vector<size_t> a(N);
std::transform(std::execution::par, a.begin(), a.end(), a.begin(), [&](auto & i) fun(&i - a.begin()); );
c++ range c++17 lazy-evaluation lazy-sequences
You can use std::distance to create the index of an iterator: stackoverflow.com/questions/2152986/…
– José Manuel Ramos
Nov 10 at 21:29
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I'm trying to transform a sequence of numbers in parallel in C++17 and store the results in a vector. But so far I'm unable to find a way to represent the sequence without explicitly filling an array with it, like so:
void transformRange(size_t N)
// Want to replace nums with a generator (an iterator that is not associated with a container)
std::vector<size_t> nums(N);
std::iota(nums.begin(), nums.end(), 0);
std::vector<size_t> a(N);
std::transform(std::execution::par, nums.begin(), nums.end(), a.begin(), fun);
I want this to be doable in parallel (hence the std::execution::par), and the above transform does work in parallel, but the iota does not and it's 3X the memory bandwidth.
I'm also open to deriving the sequence number from the reference to the value being transformed, but I can't get the syntax right. Something like:
void transformRange2(size_t N)
std::vector<size_t> a(N);
std::transform(std::execution::par, a.begin(), a.end(), a.begin(), [&](auto & i) fun(&i - a.begin()); );
c++ range c++17 lazy-evaluation lazy-sequences
I'm trying to transform a sequence of numbers in parallel in C++17 and store the results in a vector. But so far I'm unable to find a way to represent the sequence without explicitly filling an array with it, like so:
void transformRange(size_t N)
// Want to replace nums with a generator (an iterator that is not associated with a container)
std::vector<size_t> nums(N);
std::iota(nums.begin(), nums.end(), 0);
std::vector<size_t> a(N);
std::transform(std::execution::par, nums.begin(), nums.end(), a.begin(), fun);
I want this to be doable in parallel (hence the std::execution::par), and the above transform does work in parallel, but the iota does not and it's 3X the memory bandwidth.
I'm also open to deriving the sequence number from the reference to the value being transformed, but I can't get the syntax right. Something like:
void transformRange2(size_t N)
std::vector<size_t> a(N);
std::transform(std::execution::par, a.begin(), a.end(), a.begin(), [&](auto & i) fun(&i - a.begin()); );
c++ range c++17 lazy-evaluation lazy-sequences
c++ range c++17 lazy-evaluation lazy-sequences
edited Nov 10 at 21:40
Deduplicator
33.9k64787
33.9k64787
asked Nov 10 at 20:57
All the Rage
16411
16411
You can use std::distance to create the index of an iterator: stackoverflow.com/questions/2152986/…
– José Manuel Ramos
Nov 10 at 21:29
add a comment |
You can use std::distance to create the index of an iterator: stackoverflow.com/questions/2152986/…
– José Manuel Ramos
Nov 10 at 21:29
You can use std::distance to create the index of an iterator: stackoverflow.com/questions/2152986/…
– José Manuel Ramos
Nov 10 at 21:29
You can use std::distance to create the index of an iterator: stackoverflow.com/questions/2152986/…
– José Manuel Ramos
Nov 10 at 21:29
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
Ranges not backed by a container (or the nightmare called std::vector<bool>) are not part of C++17.
But don't despair, Boost provides the counting_iterator, just what you need for a lazy range.
It even provides it conveniently packaged as a range using counting_range.
Why isstd::vector<bool>a nightmare and why is it not part of C++17?
– V0ldek
Nov 10 at 21:48
2
@V0ldek Well, the ranges TS might make it into C++20, as might concepts. (Huh, I'm not quite sure a counting-range is actually part of that. Oh well.) Andstd::vector<bool>is a nightmare because it is not really astd::vector, as it has a very different interface, nor is it really a contyiner. There are good posts on SO going further into it than a comment should try.
– Deduplicator
Nov 10 at 21:51
add a comment |
up vote
0
down vote
template<class F, class R=std::result_of_t<F&(std::size_t)>>
std::vector<R> rangeFromIndex(F&& f, std::size_t N)
std::vector<R> a(N);
std::for_each(std::execution::par,
a.begin(), a.end(),
[&](auto & i) i = fun(std::size_t(std::addressof(i) - a.data()));
);
that should do it.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Ranges not backed by a container (or the nightmare called std::vector<bool>) are not part of C++17.
But don't despair, Boost provides the counting_iterator, just what you need for a lazy range.
It even provides it conveniently packaged as a range using counting_range.
Why isstd::vector<bool>a nightmare and why is it not part of C++17?
– V0ldek
Nov 10 at 21:48
2
@V0ldek Well, the ranges TS might make it into C++20, as might concepts. (Huh, I'm not quite sure a counting-range is actually part of that. Oh well.) Andstd::vector<bool>is a nightmare because it is not really astd::vector, as it has a very different interface, nor is it really a contyiner. There are good posts on SO going further into it than a comment should try.
– Deduplicator
Nov 10 at 21:51
add a comment |
up vote
1
down vote
Ranges not backed by a container (or the nightmare called std::vector<bool>) are not part of C++17.
But don't despair, Boost provides the counting_iterator, just what you need for a lazy range.
It even provides it conveniently packaged as a range using counting_range.
Why isstd::vector<bool>a nightmare and why is it not part of C++17?
– V0ldek
Nov 10 at 21:48
2
@V0ldek Well, the ranges TS might make it into C++20, as might concepts. (Huh, I'm not quite sure a counting-range is actually part of that. Oh well.) Andstd::vector<bool>is a nightmare because it is not really astd::vector, as it has a very different interface, nor is it really a contyiner. There are good posts on SO going further into it than a comment should try.
– Deduplicator
Nov 10 at 21:51
add a comment |
up vote
1
down vote
up vote
1
down vote
Ranges not backed by a container (or the nightmare called std::vector<bool>) are not part of C++17.
But don't despair, Boost provides the counting_iterator, just what you need for a lazy range.
It even provides it conveniently packaged as a range using counting_range.
Ranges not backed by a container (or the nightmare called std::vector<bool>) are not part of C++17.
But don't despair, Boost provides the counting_iterator, just what you need for a lazy range.
It even provides it conveniently packaged as a range using counting_range.
answered Nov 10 at 21:39
Deduplicator
33.9k64787
33.9k64787
Why isstd::vector<bool>a nightmare and why is it not part of C++17?
– V0ldek
Nov 10 at 21:48
2
@V0ldek Well, the ranges TS might make it into C++20, as might concepts. (Huh, I'm not quite sure a counting-range is actually part of that. Oh well.) Andstd::vector<bool>is a nightmare because it is not really astd::vector, as it has a very different interface, nor is it really a contyiner. There are good posts on SO going further into it than a comment should try.
– Deduplicator
Nov 10 at 21:51
add a comment |
Why isstd::vector<bool>a nightmare and why is it not part of C++17?
– V0ldek
Nov 10 at 21:48
2
@V0ldek Well, the ranges TS might make it into C++20, as might concepts. (Huh, I'm not quite sure a counting-range is actually part of that. Oh well.) Andstd::vector<bool>is a nightmare because it is not really astd::vector, as it has a very different interface, nor is it really a contyiner. There are good posts on SO going further into it than a comment should try.
– Deduplicator
Nov 10 at 21:51
Why is
std::vector<bool> a nightmare and why is it not part of C++17?– V0ldek
Nov 10 at 21:48
Why is
std::vector<bool> a nightmare and why is it not part of C++17?– V0ldek
Nov 10 at 21:48
2
2
@V0ldek Well, the ranges TS might make it into C++20, as might concepts. (Huh, I'm not quite sure a counting-range is actually part of that. Oh well.) And
std::vector<bool> is a nightmare because it is not really a std::vector, as it has a very different interface, nor is it really a contyiner. There are good posts on SO going further into it than a comment should try.– Deduplicator
Nov 10 at 21:51
@V0ldek Well, the ranges TS might make it into C++20, as might concepts. (Huh, I'm not quite sure a counting-range is actually part of that. Oh well.) And
std::vector<bool> is a nightmare because it is not really a std::vector, as it has a very different interface, nor is it really a contyiner. There are good posts on SO going further into it than a comment should try.– Deduplicator
Nov 10 at 21:51
add a comment |
up vote
0
down vote
template<class F, class R=std::result_of_t<F&(std::size_t)>>
std::vector<R> rangeFromIndex(F&& f, std::size_t N)
std::vector<R> a(N);
std::for_each(std::execution::par,
a.begin(), a.end(),
[&](auto & i) i = fun(std::size_t(std::addressof(i) - a.data()));
);
that should do it.
add a comment |
up vote
0
down vote
template<class F, class R=std::result_of_t<F&(std::size_t)>>
std::vector<R> rangeFromIndex(F&& f, std::size_t N)
std::vector<R> a(N);
std::for_each(std::execution::par,
a.begin(), a.end(),
[&](auto & i) i = fun(std::size_t(std::addressof(i) - a.data()));
);
that should do it.
add a comment |
up vote
0
down vote
up vote
0
down vote
template<class F, class R=std::result_of_t<F&(std::size_t)>>
std::vector<R> rangeFromIndex(F&& f, std::size_t N)
std::vector<R> a(N);
std::for_each(std::execution::par,
a.begin(), a.end(),
[&](auto & i) i = fun(std::size_t(std::addressof(i) - a.data()));
);
that should do it.
template<class F, class R=std::result_of_t<F&(std::size_t)>>
std::vector<R> rangeFromIndex(F&& f, std::size_t N)
std::vector<R> a(N);
std::for_each(std::execution::par,
a.begin(), a.end(),
[&](auto & i) i = fun(std::size_t(std::addressof(i) - a.data()));
);
that should do it.
answered Nov 11 at 3:44
Yakk - Adam Nevraumont
179k19186365
179k19186365
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243343%2fdoes-c17-offer-generators-or-another-built-in-way-to-transform-a-non-instantia%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You can use std::distance to create the index of an iterator: stackoverflow.com/questions/2152986/…
– José Manuel Ramos
Nov 10 at 21:29