Skip to content

Commit

Permalink
Fixes #546 + some runtime compilation option code tweaks
Browse files Browse the repository at this point in the history
* Discarded an unused `true_or_false()` string producer function
* Renamed `need_delimiter_after_every_option` into `need_delimiter_after_last_option` + fixed typo in this name in one of the `rtc::process()` template instantiations
* Now using SFINAE to avoid instantiating `marshalled_options_t::operator<<` for delimitation/marshalling control gadgets - so as to guarantee we don't have overload set clashes (which were reported in #546).
* Replaced `optend()` with a struct, renamed it `advance_gadget`, and moved it inside `marshalled_options_t`, since it's only used with marshalled options
  • Loading branch information
eyalroz committed Oct 12, 2023
1 parent e51f7a7 commit 32d5564
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 21 deletions.
23 changes: 10 additions & 13 deletions src/cuda/rtc/compilation_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,11 +470,8 @@ class compilation_options_t<cuda_cpp> final :
}
};


namespace detail_ {

inline const char* true_or_false(bool b) { return b ? "true" : "false"; }

template <typename Delimiter>
struct opt_start_t {
bool ever_used;
Expand All @@ -497,17 +494,17 @@ MarshalTarget& operator<<(MarshalTarget& mt, detail_::opt_start_t<Delimiter>& op
return mt;
}


/**
* Use the left-shift operator (<<) to render a delimited sequence of
* Uses the streaming/left-shift operator (<<) to render a delimited sequence of
* command-line-argument-like options (with or without a value as relevant)
* into some target entity - which could be a buffer or a more complex
* structure.
*
* into some target entity - which could be a buffer of chars or a more complex
* structure like @ref marshalled_options_t.
*/
template <typename MarshalTarget, typename Delimiter>
void process(
const compilation_options_t<ptx>& opts, MarshalTarget& marshalled, Delimiter delimiter,
bool need_delimited_after_every_option = false)
bool need_delimiter_after_last_option = false)
{
detail_::opt_start_t<Delimiter> opt_start { delimiter };
// TODO: Consider taking an option to be verbose in specifying compilation flags, and setting option values
Expand Down Expand Up @@ -581,15 +578,15 @@ void process(
}
}

if (need_delimited_after_every_option) {
if (need_delimiter_after_last_option) {
marshalled << opt_start; // If no options were marshalled, this does nothing
}
}

template <typename MarshalTarget, typename Delimiter>
void process(
const compilation_options_t<cuda_cpp>& opts, MarshalTarget& marshalled, Delimiter delimiter,
bool need_delimited_after_every_option = false)
bool need_delimiter_after_last_option = false)
{
detail_::opt_start_t<Delimiter> opt_start { delimiter };
if (opts.generate_relocatable_device_code) { marshalled << opt_start << "--relocatable-device-code=true"; }
Expand Down Expand Up @@ -675,7 +672,7 @@ void process(
marshalled << opt_start << extra_opt;
}

if (need_delimited_after_every_option) {
if (need_delimiter_after_last_option) {
marshalled << opt_start; // If no options were marshalled, this does nothing
}
}
Expand All @@ -685,8 +682,8 @@ inline marshalled_options_t marshal(const compilation_options_t<Kind>& opts)
{
marshalled_options_t mo;
// TODO: Can we easily determine the max number of options here?
constexpr bool need_delimiter_after_every_option { true };
process(opts, mo, detail_::optend, need_delimiter_after_every_option);
constexpr bool need_delimiter_after_last_option { true };
process(opts, mo, marshalled_options_t::advance_gadget{}, need_delimiter_after_last_option);
return mo;
}

Expand Down
33 changes: 25 additions & 8 deletions src/cuda/rtc/detail/marshalled_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ namespace cuda {

namespace rtc {

namespace detail_ {

// These two structs are streamed to a marshalled options object (see below)
// to indicate the start of a new option or the conclusion of all options,
// respectively

template <typename Delimiter> struct opt_start_t;

template<typename T>
struct is_marshalling_control : ::std::false_type {};

} // namespace detail_

/**
* This class is necessary for realizing everything we need from
* the marshalled options: Easy access using an array of pointers,
Expand All @@ -24,6 +37,8 @@ class marshalled_options_t {
public:
using size_type = size_t;

struct advance_gadget {}; /// triggers an advance() when streamed into an object of this class

marshalled_options_t()
{
option_positions.push_back(0);
Expand All @@ -49,14 +64,13 @@ class marshalled_options_t {
return oss.tellp() == 0;
}

template <typename T>
template <typename T, typename = ::cuda::detail_::enable_if_t<not detail_::is_marshalling_control<typename ::std::decay<T>::type>::value>>
marshalled_options_t& operator<<(T&& x)
{
oss << x;
return *this;
}

// TODO: Make a similar "stream manipulator"?
marshalled_options_t& advance()
{
oss << '\0';
Expand All @@ -75,16 +89,19 @@ class marshalled_options_t {
}
};

inline marshalled_options_t& operator<< (marshalled_options_t& mo, marshalled_options_t::advance_gadget)
{
mo.advance();
return mo;
}

namespace detail_ {

inline void optend() { }
template<> struct is_marshalling_control<marshalled_options_t::advance_gadget> : ::std::true_type {};

} // namespace detail_
template<typename Delimiter>
struct is_marshalling_control<opt_start_t<Delimiter>> : ::std::true_type {};

inline marshalled_options_t& operator<< (marshalled_options_t& mo, decltype(detail_::optend))
{
mo.advance();
return mo;
}

} // namespace rtc
Expand Down

0 comments on commit 32d5564

Please sign in to comment.