K-ballo changed the topic of #ste||ar to: STE||AR: Systems Technology, Emergent Parallelism, and Algorithm Research | stellar.cct.lsu.edu | HPX: A cure for performance impaired parallel applications | github.com/STEllAR-GROUP/hpx | Buildbot: http://rostam.cct.lsu.edu/ | Log: http://irclog.cct.lsu.edu/
<hkaiser>
yes, we built things around Vc at that time, but any newer library should be easily adapted as the Vc specific are encapsulated in a couple of traits
<srinivasyadav227>
you mean like in datapar/detail/?
<hkaiser>
hold on, need to look
<srinivasyadav227>
ok
<srinivasyadav227>
here libs/parallelism/execution/include/hpx/execution/traits/detail/vc/ ?
<hkaiser>
srinivasyadav227: yes, that's what I was looking for
<hkaiser>
it should work if you create those four traits for any other library
<hkaiser>
for instance for the std::experimental::simd types available in the gcc std library
<hkaiser>
srinivasyadav227: to answer your other question: yes, the use of the simd types requires the use of the datapar policy
<srinivasyadav227>
hkaiser: currently datapar supports only for couple of algorithms right (for_each, count, ...), so how do they interact or use datapar internally?..only through execution policy right?..and what if that a particular algorithm does not support datapar, say copy , it silently uses hpx::execution::seq?
<srinivasyadav227>
<hkaiser "I'd rather simplify the normal a"> this was long back, but since then I have been trying to find something related to datapar and understand, could you please elaborate this?.. here by "normal algorithms" you mean these libs/parallelism/algorithms/include/hpx/parallel/algorithms right? or you were referring to something else?.. because in this, I could not find anything related to datapar or am I missing
<srinivasyadav227>
something? ;)
<hkaiser>
yes, by normal I meant the ones in hpx/parallel/algorithms
<hkaiser>
and yes, we have only a few datapar enabled algorithms, I don't even know what would happen if the policy was used with another algorithm ;-)
<srinivasyadav227>
omg, haha, this is scary, ;)
<hkaiser>
srinivasyadav227: it was an experiment...
<srinivasyadav227>
yea I get it! ;)
<srinivasyadav227>
does this mean that changes for for_each algo related to datapar are only available in older commit?.. or could you please direct me to changes for for_each related to datapar?, I did not understand from where to separate them using tag_invoke
<gonidelis[m]>
but, what if I passed a sentinel value
<gonidelis[m]>
instead of a "distance"?
<gonidelis[m]>
(that's more of a general sentinels question I must admit)
<k-ballo[m]>
then you have to get to the end iterator manually?
<gonidelis[m]>
but how does the code know that?
<gonidelis[m]>
how does the code know that this sentinel<int>{5} is saying, reverse the thing from start until 5. it could may as well be reverse the thing from start until start+5
<gonidelis[m]>
no?
<gonidelis[m]>
k-ballo: ^^
jehelset has quit [Remote host closed the connection]
K-ballo has joined #ste||ar
<K-ballo>
the end iterator is that which is equal to the sentinel
<K-ballo>
you need to get your hands on the end iterator, as efficiently as possible
<K-ballo>
worst case scenario, you just keep incrementing from first until the iterator equals last
<K-ballo>
that's what ranges::next does
<gonidelis[m]>
K-ballo: isn't it ambiquous?
<K-ballo>
no
<gonidelis[m]>
so again, it's like saying start incrementing until you either find a 5 or you have been incremented 5 times
<gonidelis[m]>
it's not well defined
<K-ballo>
no, that's not what it means
<K-ballo>
the meaning is defined by the Sentinel type, and its relation to the iterator
<gonidelis[m]>
but how does the implementation handle that?
<K-ballo>
I don't see what the problem would be
<K-ballo>
where's the implementation difficulty?
<gonidelis[m]>
<K-ballo "worst case scenario, you just ke"> that means that last is a sentinel_value and not a distance
<K-ballo>
I don't follow
<gonidelis[m]>
sentinel being a distance and sentinel being a sentinel_value requires different implementations
<K-ballo>
those are not things, a sentinel is just a sentinel
<K-ballo>
and the algorithm just needs the iterator that corresponds to the sentinel
<K-ballo>
and ranges::next does that job
<K-ballo>
efficiently
<gonidelis[m]>
ranges::next makes first equal to last+1?
<K-ballo>
no, to last
<K-ballo>
and not first, it returns the new value
<gonidelis[m]>
yy
<gonidelis[m]>
why do we pass first then?
<K-ballo>
ranges(it, sentinel) returns the first iterator starting from it for which the sentinel predicate holds
<gonidelis[m]>
as an arg to rangeS::next
<K-ballo>
where would you start otherwise?
<K-ballo>
you can't produce an iterator out of thin air
<gonidelis[m]>
so it produces an iterator, and that iterator is last2
<K-ballo>
that iterator is the iterator that corresponds to the sentinel
<gonidelis[m]>
ok my problem is this "Return the nth successor of iterator i. "
<gonidelis[m]>
that's not the case you are describing
<gonidelis[m]>
that treats the second argument as a distance
<K-ballo>
3) The first iterator equivalent to bound
<K-ballo>
you want the overload taking a sentinel
<gonidelis[m]>
i saw that... but the "Return the nth successor of iterator i. " is outer
<gonidelis[m]>
so i guess it encapsulates all the cases
<K-ballo>
it does, in the sentinel case the n is determined by the sentinel
<gonidelis[m]>
ahhhhhh!!!!!!!!!!
<K-ballo>
in the first case, the n is 1
<gonidelis[m]>
okkkk yeah great!
<gonidelis[m]>
finally! now it makes sense
<K-ballo>
in the other two cases, n is given
<gonidelis[m]>
c'moonnn... yeah. now i feel comfortable
<K-ballo>
that was probably just copied over from std::next, you could suggest an eidt
<gonidelis[m]>
K-ballo: do you know if we have any ranges::next impl btw? :p
<gonidelis[m]>
<K-ballo "that was probably just copied ov"> oh ok
<gonidelis[m]>
and say what ;p ?
<K-ballo>
I don't know, I'd guess not, what other algorithms take bidirectional iterators?
<gonidelis[m]>
K-ballo: haven't come accross any other
<gonidelis[m]>
reverse is my first
<gonidelis[m]>
bidir algo
<K-ballo>
copy_backward?
<gonidelis[m]>
yeah sure
<gonidelis[m]>
i don't think we have implemented that
<gonidelis[m]>
we have not
<gonidelis[m]>
hkaiser constantly refers to that issue
hkaiser has joined #ste||ar
jehelset has joined #ste||ar
<gonidelis[m]>
hkaiser: hey. i think we need a proper sequential impl for reverse (since once gain we use std::reverse). i though of going with the "possible implementation" here but we don't have a `ranges::iter_swap` right?
<hkaiser>
gonidelis[m]: should be easy enough to implement
<gonidelis[m]>
hkaiser: it has a `detail::reverse` call yeah
<jedi18[m]1>
What about reverse? I see that is unimplemented too
<hkaiser>
jedi18[m]1: #1668 will be a natural byproduct, I think
<hkaiser>
jedi18[m]1: gonidelis[m] is wroking on reverse, currently
<gonidelis[m]>
<K-ballo "first thing it has to do is turn"> what's your point?
<K-ballo>
there is no sentinel-aware reverse implementation
<K-ballo>
reverse has to be implemented in terms of a pair of iterators
<K-ballo>
that's why ranges::reverse starts by turning the sentinel into an iterator
<jedi18[m]1>
Ohh ok fine, I'll try adjacent_difference then. Are there any pre-requisites I need to know or will gonidelis 's article from yesterday(thanks again for that btw) be enough?
<gonidelis[m]>
hkaiser: it uses std::adjacent_difference for the seq impl...
<hkaiser>
hmm, and there is no ranges::adjacent_difference
<gonidelis[m]>
because <numeric> ?
<gonidelis[m]>
i think
<hkaiser>
jedi18[m]1: ok, let's go with min/max/minmax_element
<hkaiser>
ranges v3 has one, though - not sure what's different, will look
<K-ballo>
concepts
<K-ballo>
<numeric> stuff wasn't rangeified because figuring out the concepts was hard
<gonidelis[m]>
i thought numeric had not been adapted yet
<hkaiser>
ahh
<hkaiser>
right
<gonidelis[m]>
<K-ballo "that's why ranges::reverse start"> why not do `auto last2{ ranges::next(first, last) }; std::reverse(first, last2);` then?
<K-ballo>
yes, that's effectively what you'd do
<K-ballo>
how is that different from any other std:: algorithm?
<hkaiser>
K-ballo: it might be more efficient not to forward the iter to the sentinel before calling the std:: algorithm, rather reimplement it
<K-ballo>
?
<K-ballo>
reverse cannot be implemented in terms of sentinels
<gonidelis[m]>
K-ballo: why?
<hkaiser>
that is correct, I misunderstood what you were saying
<K-ballo>
it's what we discussde earlier today
<K-ballo>
you can't walk backwards from a sentinel, you need to turn it into an iterator in order to do that
<gonidelis[m]>
<K-ballo "yes, that's effectively what you"> then why does `iter_swap(first, tail);` uses the ranges version? i mean since we deducted the problem to an iterator based range
<gonidelis[m]>
it could may as well use `std::iter_swap`
<K-ballo>
ranges::iter_swap differs from std::iter_swap in its support of proxy iterators
<K-ballo>
proxy iterators are not supported by traditional algorithms
<gonidelis[m]>
hm... so last2 is a proxy
<gonidelis[m]>
I admit I didn't know about proxy iters
<K-ballo>
it can be a proxy, it doesn't have to be
<gonidelis[m]>
in other words I could may as well implement the std::iter_swap and just make it support idfferent first-last types
<hkaiser>
I think you're fine with just using std::iter_swap
<K-ballo>
if you are fine with std::iter_swap then you are fine with std::reverse just as well
<K-ballo>
ranges::iter_swap doesn't support sentinels anyhow
K-ballo has quit [Read error: Connection reset by peer]
K-ballo has joined #ste||ar
<gonidelis[m]>
hkaiser: yt?
<hkaiser>
gonidelis[m]: here
<gonidelis[m]>
hkaiser: i guess neither of those two would work for our sentinel case
<hkaiser>
K-ballo: does operator*() for vector<bool> return a reference? I thought it returned a proxy object
<K-ballo>
it returns an `std::vector<bool>::reference`, the proxy object
<hkaiser>
ahh, ok
<hkaiser>
sure
<gonidelis[m]>
K-ballo: so it's like a[x] is implemented immediately within the vector class and `*a.begin()` is possible because there is the `begin()` implemented there
<K-ballo>
?
<K-ballo>
`*a.begin()` is possible because `a.begin()` returns an iterator
<gonidelis[m]>
and the iterator can be referenced
<K-ballo>
assuming non-empty, sure
<K-ballo>
any dereferenceable iterator can be dereferenced
<gonidelis[m]>
ok so back to the subject, making a.begin() return an iterator leads to the vector<bool> giving a reference-like object
<gonidelis[m]>
?
<gonidelis[m]>
i am 90% what i said is wrong
<K-ballo>
uhm? no
<K-ballo>
vector<bool> (and it's corresponding iterator) yield a reference-like object because they can't yield a proper reference, there's no bool object stored anywhere
<K-ballo>
for context: references reference objects (and sometimes functions too, but those aren't relevant here)
<K-ballo>
no object -> no reference
<gonidelis[m]>
where is it declared that *a.begin() where a is a vector<bool> is not a straightforward ref?
<gonidelis[m]>
but we do have a vector<bool> object
<K-ballo>
no good for producing references to bools, only goot for producing refernces to vector<bool>s
<K-ballo>
std::vector<bool>::iterator having a reference type of std::vector<bool>::reference is implied throught the docs, but just of think of it.. if it were a proper bool&, what would it refer to?
<gonidelis[m]>
what does int& refer to?
<K-ballo>
an int object
<gonidelis[m]>
so there are not bool objects
<K-ballo>
?
<K-ballo>
you mean within std::vector<bool>? no, std::vector<bool> does not contain bools, it contains bits
<gonidelis[m]>
so there don't exist such things as boob objects