Skip to content

Commit

Permalink
Replaced permutation class with permutation function
Browse files Browse the repository at this point in the history
Vector based permutations (permutation class) are easily modelled with
expression based permutations (used to be called vex::eslice()). This
commit drops permutation class and renames vex::eslice() to
vex::permutation(). See README and tests/vector_view.cpp for examples.
  • Loading branch information
ddemidov committed Sep 11, 2013
1 parent 7d6f372 commit b31bbb4
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 71 deletions.
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,26 +315,25 @@ a sequence position N.

### <a name="permutations"></a>Permutations

`vex::permutation` allows to use permuted vector in a vector expression. The
class constructor accepts `vex::vector<size_t>` of indices. The following
example assigns reversed vector `X` to `Y`:
`vex::permutation()` function allows to use permuted vector in a vector
expression. The function accepts a vector expression that returns integral
values (indices). The following example assigns reversed vector `X` to `Y`:

~~~{.cpp}
vex::vector<size_t> I(ctx, N);
I = N - 1 - vex::element_index();
vex::permutation reverse(I);
auto reverse = vex::permutation(I)
Y = reverse(X);
~~~

The drawback of the above approach is that you have to store and access an
index vector. Sometimes this is a necessary evil, but in this simple example we
can do better. `vex::eslice()` function returns an expression-based permutation
operator. Here is how we use it:
can do better. In the following example lightweight expression is used to
construct the same permutation:

~~~{.cpp}
auto reverse = vex::eslice( N - 1 - vex::element_index() );
auto reverse = vex::permutation( N - 1 - vex::element_index() );
Y = reverse(X);
~~~

Expand Down
8 changes: 4 additions & 4 deletions tests/vector_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,16 @@ BOOST_AUTO_TEST_CASE(vector_permutation)
{
vex::vector<size_t> I(queue, N);
I = N - 1 - vex::element_index();
vex::permutation reverse(I);
Y = reverse(X);
auto reverse = vex::permutation(I);

Y = reverse(X);
check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, x[N - 1 - idx]); });
}

Y = 0;

{
auto reverse = vex::eslice(N - 1 - vex::element_index());
auto reverse = vex::permutation(N - 1 - vex::element_index());

Y = reverse(X);
check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, x[N - 1 - idx]); });
Expand Down Expand Up @@ -192,7 +192,7 @@ BOOST_AUTO_TEST_CASE(assign_to_view) {

I = vex::element_index() * m;

vex::permutation first_col(I);
auto first_col = vex::permutation(I);

first_col(x) = 42;

Expand Down
66 changes: 7 additions & 59 deletions vexcl/vector_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,64 +507,12 @@ struct slicer {
}
};

/// Permutation operator.
struct permutation {
const vector<size_t> &index;

permutation(const vector<size_t> &index) : index(index) {
assert(index.queue_list().size() == 1);
}

size_t size() const {
return index.size();
}

std::string partial_expression(const std::string &prm_name,
const cl::Device&) const
{
std::ostringstream s;
s << prm_name << "_base[" << prm_name << "_index[idx]]";

return s.str();
}

std::string indexing_function(const std::string &/*prm_name*/,
const cl::Device&) const
{
return "";
}

template <typename T>
std::string parameter_declaration(const std::string &prm_name,
const cl::Device&) const
{
std::ostringstream s;

s << ",\n\tglobal " << type_name<T>() << " * " << prm_name << "_base"
<< ", global " << type_name<size_t>() << " * " << prm_name << "_index";

return s.str();
}

void setArgs(cl::Kernel &kernel, unsigned device, size_t/*index_offset*/,
unsigned &position) const
{
kernel.setArg(position++, index(device));
}

template <typename T>
vector_view<T, permutation> operator()(const vector<T> &base) const {
assert(base.queue_list().size() == 1);
return vector_view<T, permutation>(base, *this);
}
};

/// Expression-based permutation operator.
template <class Expr>
struct expr_slice {
struct expr_permutation {
const Expr expr;

expr_slice(const Expr &expr) : expr(expr) {}
expr_permutation(const Expr &expr) : expr(expr) {}

size_t size() const {
detail::get_expression_properties prop;
Expand Down Expand Up @@ -618,9 +566,9 @@ struct expr_slice {
}

template <typename T>
vector_view<T, expr_slice> operator()(const vector<T> &base) const {
vector_view<T, expr_permutation> operator()(const vector<T> &base) const {
assert(base.queue_list().size() == 1);
return vector_view<T, expr_slice>(base, *this);
return vector_view<T, expr_permutation>(base, *this);
}
};

Expand All @@ -635,10 +583,10 @@ struct expr_slice {
template <class Expr>
typename std::enable_if<
std::is_integral<typename detail::return_type<Expr>::type>::value,
expr_slice<Expr>
expr_permutation<Expr>
>::type
eslice(const Expr &expr) {
return expr_slice<Expr>(expr);
permutation(const Expr &expr) {
return expr_permutation<Expr>(expr);
}

//---------------------------------------------------------------------------
Expand Down

0 comments on commit b31bbb4

Please sign in to comment.