Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different execution policies at runtime

In C++17, a number of functions in the algorithm header now can take an execution policy. I can for example define and call a function like this:

template <class ExecutionPolicy>
void f1(const std::vector<std::string>& vec, const std::string& elem, ExecutionPolicy&& policy) {
    const auto it = std::find(
        std::forward<ExecutionPolicy>(policy),
        vec.cbegin(), vec.cend(), elem
    );
}

std::vector<std::string> vec;
f1(vec, "test", std::execution::seq);

However I haven't found a good way to use different policies at runtime. For example when I want to use a different policy depending on some input file.

I toyed around with variants, but in the end the problem was always the different types of std::execution::seq, std::execution::par and std::execution::par_unseq.

A working but cumbersome solution would look like this:

void f2(const std::vector<std::string>& vec, const std::string& elem, const int policy) {
    const auto it = [&]() {
        if (policy == 0) {
            return std::find(
                std::execution::seq,
                vec.cbegin(), vec.cend(), elem
            );
        }
        else if (policy == 1) {
            return std::find(
                std::execution::par,
                vec.cbegin(), vec.cend(), elem
            );
        }
        else{
            return std::find(
                std::execution::par_unseq,
                vec.cbegin(), vec.cend(), elem
            );
        }
    };
}

f2(vec, "test", 0);

Is there any more elegant solution I'm overlooking?

edit: maybe I should be more precise. Let's say the goal is to save the policy in a variable that can have either of the three policies. That variable should be a parameter to the function.

like image 212
Basti Avatar asked Oct 24 '18 17:10

Basti


People also ask

How do you determine the effective execution policy for a session?

When determining the effective execution policy for a session, PowerShell evaluates the execution policies in the following precedence order: Group Policy: MachinePolicy. Group Policy: UserPolicy. Execution Policy: Process (or pwsh.exe -ExecutionPolicy) Execution Policy: CurrentUser. Execution Policy: LocalMachine.

What are the different execution policies in PowerShell?

There are four execution policies: Restricted, AllSigned, RemoteSigned, Unrestricted, and Bypass. The Restricted policy, which is also the default execution policy, prevents us from running any PowerShell scripts, but does allow us to use the shell interactively.

Is there an execution policy set in the current scope?

There is no execution policy set in the current scope. If the execution policy in all scopes is Undefined, the effective execution policy is Restricted for Windows clients and RemoteSigned for Windows Server. The default execution policy for non-Windows computers and cannot be changed.

What is Microsoft’s execution policy?

Microsoft says an execution policy isn’t technically a “security” measure but more of a gate you can open and close. After all, you can bypass a defined execution policy easily, as you’ll learn later. Execution policies are based on trust.


1 Answers

The standard approach here is to separate the selection of a type from the use of the type: the latter takes the form of a function template instantiated several times by the former non-template function (or function template with fewer template parameters).

To avoid duplicating the normal parameters between these two layers, use a generic lambda as the template. To avoid duplicating the selection logic, make a function template that calls whatever lambda with the appropriate policy:

enum Policy {seq,par,par_unseq};

template<class F>
auto maybe_parallel(F f,Policy p) {
  switch(p) {
  case seq: return f(std::execution::seq);
  case par: return f(std::execution::par);
  default: return f(std::execution::par_unseq);
  }
}

auto f2(const std::vector<std::string>& vec,
        const std::string& elem,Policy p) {
  return maybe_parallel
    ([&](auto &pol) {return std::find(pol,vec.begin(),vec.end(),elem);},p);
}
like image 65
Davis Herring Avatar answered Oct 05 '22 11:10

Davis Herring