Skip to content

Commit

Permalink
Change BOOST_COMPUTE_FUNCTION() to use custom argument names
Browse files Browse the repository at this point in the history
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
kylelutz committed Apr 21, 2014
1 parent 2511bdb commit 4b67907
Show file tree
Hide file tree
Showing 17 changed files with 199 additions and 96 deletions.
4 changes: 2 additions & 2 deletions doc/advanced_topics.qbk
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -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 This can also be done more succinctly using the [macroref BOOST_COMPUTE_FUNCTION
BOOST_COMPUTE_FUNCTION()] macro: 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); boost::compute::transform(vector.begin(), vector.end(), vector.begin(), add_four);
Expand Down
4 changes: 1 addition & 3 deletions example/batched_determinant.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@ int main()
); );


// function returning the determinant of a 4x4 matrix. // 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 + 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.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 + m.s2*m.s4*m.s9*m.sf + m.s2*m.s5*m.sb*m.sc + m.s2*m.s7*m.s8*m.sd +
Expand Down
4 changes: 2 additions & 2 deletions example/inline_ptx.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ int main()


// function returning the number of bits set (aka population count or // function returning the number of bits set (aka population count or
// popcount) using the "popc" inline ptx assembly instruction. // 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; uint count;
asm("popc.b32 %0, %1;" : "=r"(count) : "r"(_1)); asm("popc.b32 %0, %1;" : "=r"(count) : "r"(x));
return count; return count;
}); });


Expand Down
6 changes: 3 additions & 3 deletions example/monte_carlo.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ int main()
rng.generate(vector.begin(), vector.end(), queue); rng.generate(vector.begin(), vector.end(), queue);


// function returing true if the point is within the unit circle // 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 x = point.x / (float) UINT_MAX - 1;
const float y = _1.y / (float) UINT_MAX - 1; const float y = point.y / (float) UINT_MAX - 1;


return (x*x + y*y) < 1.0f; return (x*x + y*y) < 1.0f;
}); });
Expand Down
8 changes: 4 additions & 4 deletions example/price_cross.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@ int main()
compute::copy(prices2.begin(), prices2.end(), gpu_prices2.begin(), queue); compute::copy(prices2.begin(), prices2.end(), gpu_prices2.begin(), queue);


// function returning true if the second price is less than the first price // 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 // first price
const float x = boost_tuple_get(_1, 0); const float first = boost_tuple_get(prices, 0);


// second price // 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 true if second price is less than first
return y < x; return second < first;
}); });


// find cross point (should be 10.5) // find cross point (should be 10.5)
Expand Down
49 changes: 32 additions & 17 deletions include/boost/compute/closure.hpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ class closure


namespace detail { 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 struct closure_signature_argument_inserter
{ {
closure_signature_argument_inserter(std::stringstream &s_, closure_signature_argument_inserter(std::stringstream &s_,
Expand Down Expand Up @@ -230,7 +237,8 @@ struct closure_signature_argument_inserter


template<class Signature, class CaptureTuple> template<class Signature, class CaptureTuple>
inline std::string inline std::string
make_closure_declaration(const std::string &name, make_closure_declaration(const char *name,
const char *arguments,
const CaptureTuple &capture, const CaptureTuple &capture,
const char *capture_string) const char *capture_string)
{ {
Expand All @@ -246,7 +254,7 @@ make_closure_declaration(const std::string &name,
s << "("; s << "(";


// insert function arguments // insert function arguments
signature_argument_inserter i(s, arity_type::value); signature_argument_inserter i(s, arguments, arity_type::value);
mpl::for_each< mpl::for_each<
typename mpl::transform<parameter_types, boost::add_pointer<mpl::_1> typename mpl::transform<parameter_types, boost::add_pointer<mpl::_1>
>::type>(i); >::type>(i);
Expand All @@ -264,17 +272,20 @@ make_closure_declaration(const std::string &name,


// used by the BOOST_COMPUTE_CLOSURE() macro to create a closure // used by the BOOST_COMPUTE_CLOSURE() macro to create a closure
// function with the given signature, name, capture, and source. // function with the given signature, name, capture, and source.
template<class Signature, class CaptureTuple> template<class Prototype, class CaptureTuple>
inline closure<Signature, CaptureTuple> inline typename make_closure_type<Prototype, CaptureTuple>::type
make_closure_impl(const std::string &name, make_closure_impl(const char *name,
const char *arguments,
const CaptureTuple &capture, const CaptureTuple &capture,
const char *capture_string, const char *capture_string,
const std::string &source) const std::string &source)
{ {
std::stringstream s; std::stringstream s;
s << make_closure_declaration<Signature>(name, capture, capture_string); s << make_closure_declaration<Prototype>(name, arguments, capture, capture_string);
s << source; 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 } // end detail namespace
Expand All @@ -285,7 +296,7 @@ make_closure_impl(const std::string &name,
/// ///
/// \param return_type The return type for the function. /// \param return_type The return type for the function.
/// \param name The name of 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 capture A list of variables to capture.
/// \param source The OpenCL C source code for the function. /// \param source The OpenCL C source code for the function.
/// ///
Expand All @@ -297,9 +308,9 @@ make_closure_impl(const std::string &name,
/// ///
/// // create a closure function which returns true if the 2D point /// // create a closure function which returns true if the 2D point
/// // argument is contained within a circle of the given radius /// // 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 /// // vector of 2D points
Expand All @@ -313,14 +324,18 @@ make_closure_impl(const std::string &name,
/// ///
/// \see BOOST_COMPUTE_FUNCTION() /// \see BOOST_COMPUTE_FUNCTION()
#ifdef BOOST_COMPUTE_DOXYGEN_INVOKED #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 #else
#define BOOST_COMPUTE_CLOSURE(return_type, name, args, capture, ...) \ #define BOOST_COMPUTE_CLOSURE(return_type, name, arguments, capture, ...) \
::boost::compute::closure< \ return_type BOOST_PP_CAT(BOOST_COMPUTE_DETAIL_CLOSURE_DECL_, name) arguments; \
return_type args, BOOST_TYPEOF(boost::make_tuple capture) \ typename ::boost::compute::detail::make_closure_type< \
> name = \ BOOST_TYPEOF(BOOST_PP_CAT(BOOST_COMPUTE_DETAIL_CLOSURE_DECL_, name)), \
::boost::compute::detail::make_closure_impl<return_type args>( \ BOOST_TYPEOF(boost::make_tuple capture) \
#name, boost::make_tuple capture, #capture, #__VA_ARGS__ \ >::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 #endif


Expand Down
Loading

0 comments on commit 4b67907

Please sign in to comment.