Permalink
Browse files

Change BOOST_COMPUTE_FUNCTION() to use custom argument names

This changes the BOOST_COMPUTE_FUNCTION() macro (and the related
BOOST_COMPUTE_CLOSURE() macro) to use custom, user-provided argument
names instead of auto-generating them based on their index.

This is an API-breaking change. Users should now provide argument
names when using the BOOST_COMPUTE_FUNCTION() macro. The examples
and documentation have been updated to reflect the new API.
  • Loading branch information...
1 parent 2511bdb commit 4b67907023a84265eb4b389cdd9d47e564e39422 @kylelutz kylelutz committed Apr 21, 2014
@@ -28,9 +28,9 @@ boost::compute::transform(vector.begin(), vector.end(), vector.begin(), add_four
This can also be done more succinctly using the [macroref BOOST_COMPUTE_FUNCTION
BOOST_COMPUTE_FUNCTION()] macro:
``
-BOOST_COMPUTE_FUNCTION(int, add_four, (int),
+BOOST_COMPUTE_FUNCTION(int, add_four, (int x),
{
- return _1 + 4;
+ return x + 4;
});
boost::compute::transform(vector.begin(), vector.end(), vector.begin(), add_four);
@@ -57,10 +57,8 @@ int main()
);
// function returning the determinant of a 4x4 matrix.
- BOOST_COMPUTE_FUNCTION(float, determinant4x4, (float16_),
+ BOOST_COMPUTE_FUNCTION(float, determinant4x4, (const float16_ m),
{
- const float16 m = _1;
-
return m.s0*m.s5*m.sa*m.sf + m.s0*m.s6*m.sb*m.sd + m.s0*m.s7*m.s9*m.se +
m.s1*m.s4*m.sb*m.se + m.s1*m.s6*m.s8*m.sf + m.s1*m.s7*m.sa*m.sc +
m.s2*m.s4*m.s9*m.sf + m.s2*m.s5*m.sb*m.sc + m.s2*m.s7*m.s8*m.sd +
@@ -45,10 +45,10 @@ int main()
// function returning the number of bits set (aka population count or
// popcount) using the "popc" inline ptx assembly instruction.
- BOOST_COMPUTE_FUNCTION(uint_, nvidia_popc, (uint_),
+ BOOST_COMPUTE_FUNCTION(uint_, nvidia_popc, (uint_ x),
{
uint count;
- asm("popc.b32 %0, %1;" : "=r"(count) : "r"(_1));
+ asm("popc.b32 %0, %1;" : "=r"(count) : "r"(x));
return count;
});
@@ -41,10 +41,10 @@ int main()
rng.generate(vector.begin(), vector.end(), queue);
// function returing true if the point is within the unit circle
- BOOST_COMPUTE_FUNCTION(bool, is_in_unit_circle, (uint2_),
+ BOOST_COMPUTE_FUNCTION(bool, is_in_unit_circle, (const uint2_ point),
{
- const float x = _1.x / (float) UINT_MAX - 1;
- const float y = _1.y / (float) UINT_MAX - 1;
+ const float x = point.x / (float) UINT_MAX - 1;
+ const float y = point.y / (float) UINT_MAX - 1;
return (x*x + y*y) < 1.0f;
});
@@ -49,16 +49,16 @@ int main()
compute::copy(prices2.begin(), prices2.end(), gpu_prices2.begin(), queue);
// function returning true if the second price is less than the first price
- BOOST_COMPUTE_FUNCTION(bool, check_price_cross, (boost::tuple<float, float>),
+ BOOST_COMPUTE_FUNCTION(bool, check_price_cross, (boost::tuple<float, float> prices),
{
// first price
- const float x = boost_tuple_get(_1, 0);
+ const float first = boost_tuple_get(prices, 0);
// second price
- const float y = boost_tuple_get(_1, 1);
+ const float second = boost_tuple_get(prices, 1);
// return true if second price is less than first
- return y < x;
+ return second < first;
});
// find cross point (should be 10.5)
@@ -190,6 +190,13 @@ class closure
namespace detail {
+template<class Prototype, class ClosureTuple>
+struct make_closure_type
+{
+ typedef typename make_function_type<Prototype>::type FunctionType;
+ typedef closure<typename FunctionType::signature, ClosureTuple> type;
+};
+
struct closure_signature_argument_inserter
{
closure_signature_argument_inserter(std::stringstream &s_,
@@ -230,7 +237,8 @@ struct closure_signature_argument_inserter
template<class Signature, class CaptureTuple>
inline std::string
-make_closure_declaration(const std::string &name,
+make_closure_declaration(const char *name,
+ const char *arguments,
const CaptureTuple &capture,
const char *capture_string)
{
@@ -246,7 +254,7 @@ make_closure_declaration(const std::string &name,
s << "(";
// insert function arguments
- signature_argument_inserter i(s, arity_type::value);
+ signature_argument_inserter i(s, arguments, arity_type::value);
mpl::for_each<
typename mpl::transform<parameter_types, boost::add_pointer<mpl::_1>
>::type>(i);
@@ -264,17 +272,20 @@ make_closure_declaration(const std::string &name,
// used by the BOOST_COMPUTE_CLOSURE() macro to create a closure
// function with the given signature, name, capture, and source.
-template<class Signature, class CaptureTuple>
-inline closure<Signature, CaptureTuple>
-make_closure_impl(const std::string &name,
+template<class Prototype, class CaptureTuple>
+inline typename make_closure_type<Prototype, CaptureTuple>::type
+make_closure_impl(const char *name,
+ const char *arguments,
const CaptureTuple &capture,
const char *capture_string,
const std::string &source)
{
std::stringstream s;
- s << make_closure_declaration<Signature>(name, capture, capture_string);
+ s << make_closure_declaration<Prototype>(name, arguments, capture, capture_string);
s << source;
- return closure<Signature, CaptureTuple>(name, capture, s.str());
+
+ typedef typename make_closure_type<Prototype, CaptureTuple>::type Closure;
+ return Closure(name, capture, s.str());
}
} // end detail namespace
@@ -285,7 +296,7 @@ make_closure_impl(const std::string &name,
///
/// \param return_type The return type for the function.
/// \param name The name of the function.
-/// \param args A list of argument types for the function.
+/// \param arguments A list of arguments for the function.
/// \param capture A list of variables to capture.
/// \param source The OpenCL C source code for the function.
///
@@ -297,9 +308,9 @@ make_closure_impl(const std::string &name,
///
/// // create a closure function which returns true if the 2D point
/// // argument is contained within a circle of the given radius
-/// BOOST_COMPUTE_CLOSURE(bool, is_in_circle, (float2_), (radius),
+/// BOOST_COMPUTE_CLOSURE(bool, is_in_circle, (const float2_ p), (radius),
/// {
-/// return sqrt(_1.x*_1.x + _1.y*_1.y) < radius;
+/// return sqrt(p.x*p.x + p.y*p.y) < radius;
/// });
///
/// // vector of 2D points
@@ -313,14 +324,18 @@ make_closure_impl(const std::string &name,
///
/// \see BOOST_COMPUTE_FUNCTION()
#ifdef BOOST_COMPUTE_DOXYGEN_INVOKED
-#define BOOST_COMPUTE_CLOSURE(return_type, name, args, capture, source)
+#define BOOST_COMPUTE_CLOSURE(return_type, name, arguments, capture, source)
#else
-#define BOOST_COMPUTE_CLOSURE(return_type, name, args, capture, ...) \
- ::boost::compute::closure< \
- return_type args, BOOST_TYPEOF(boost::make_tuple capture) \
- > name = \
- ::boost::compute::detail::make_closure_impl<return_type args>( \
- #name, boost::make_tuple capture, #capture, #__VA_ARGS__ \
+#define BOOST_COMPUTE_CLOSURE(return_type, name, arguments, capture, ...) \
+ return_type BOOST_PP_CAT(BOOST_COMPUTE_DETAIL_CLOSURE_DECL_, name) arguments; \
+ typename ::boost::compute::detail::make_closure_type< \
+ BOOST_TYPEOF(BOOST_PP_CAT(BOOST_COMPUTE_DETAIL_CLOSURE_DECL_, name)), \
+ BOOST_TYPEOF(boost::make_tuple capture) \
+ >::type name = \
+ ::boost::compute::detail::make_closure_impl< \
+ BOOST_TYPEOF(BOOST_PP_CAT(BOOST_COMPUTE_DETAIL_CLOSURE_DECL_, name)) \
+ >( \
+ #name, #arguments, boost::make_tuple capture, #capture, #__VA_ARGS__ \
)
#endif
Oops, something went wrong.

0 comments on commit 4b67907

Please sign in to comment.