简体   繁体   English

返回推力二进制函数

[英]Return thrust binary function

I'm trying to define a function that will return the desired type operator based on the content of a string. 我正在尝试定义一个函数,该函数将基于字符串的内容返回所需的类型运算符。 I have tried this, but it doesn't work: 我已经尝试过了,但是没有用:

impl.cpp impl.cpp

template <typename T> thrust::binary_function<T,T,bool>
 get_filter_operator(const std::string &op)
    if (op == "!=")
        return thrust::not_equal_to<T>();
    else if (op == ">")
        return thrust::greater<T>();
    else if (op == "<")
        return thrust::less<T>();
    else if (op == ">=")
        return thrust::greater_equal<T>();
    else if (op == "<=")
        return thrust::less_equal<T>();
    else
    {
        return thrust::equal_to<T>();
    }

template thrust::binary_function<float,float,bool> get_filter_operator<float>(const std::string &);

impl.h 展示次数

template <typename T> thrust::binary_function<T, T, bool> get_filter_operator(const std::string &op);

How can I return a pointer to an arbitrary function like thrust::not_equal_to<int>() , or thrust::equal_to<int>() ? 如何返回指向thrust::not_equal_to<int>()thrust::equal_to<int>()类的任意函数的指针? I can't find the correct type to return. 我找不到要返回的正确类型。

EDIT 编辑

As requested, Compiler error: 根据要求,编译器错误:

In instantiation of 'thrust::binary_function<T, T, bool> get_filter_operator(const string&) [with T = float; 在'thrust :: binary_function <T,T,bool>的实例中,get_filter_operator(const string&)[with T = float; std::string = std::basic_string<char>]': std :: string = std :: basic_string <char>]':

error: could not convert 'thrust::equal_to<float>()' from 'thrust::equal_to<float>' to 'thrust::binary_function<float, float, bool>' return thrust::equal_to() 错误:无法将'thrust :: equal_to <float>()'从'thrust :: equal_to <float>'转换为'thrust :: binary_function <float,float,bool>'返回推力:: equal_to()

Update 更新资料

Ok sorry to not have mentioned this before: The problem with this is I can't use std::function because it would only work on host code. 好的,很抱歉以前没有提到过:问题是我不能使用std :: function,因为它只能在主机代码上使用。 I wanted to use thrust binary functions so that I could use them both in the GPU and the CPU. 我想使用推力二进制函数,以便可以在GPU和CPU中使用它们。

How can I return a pointer to an arbitrary function like thrust::not_equal_to(), or thrust::equal_to()? 如何返回指向推力:: not_equal_to()或推力:: equal_to()等任意函数的指针? I cant find the correct type to return 我找不到要返回的正确类型

Each of the things that you are trying to return is a function of two arguments, each of some type T , that returns bool . 您尝试返回的每件事都是两个参数的函数,每个参数的类型均为T ,这些参数返回bool The correct return type is 正确的返回类型是

std::function<bool(T, T)>

As in: 如:

#include <thrust/functional.h>
#include <functional>
#include <string>

template<typename T>
std::function<bool(T, T)>
get_filter_operator(const std::string &op)
{
    if (op == "!=")
        return thrust::not_equal_to<T>();
    else if (op == ">")
        return thrust::greater<T>();
    else if (op == "<")
        return thrust::less<T>();
    else if (op == ">=")
        return thrust::greater_equal<T>();
    else if (op == "<=")
        return thrust::less_equal<T>();
    else
    {
        return thrust::equal_to<T>();
    }
}

#include <iostream>

using namespace std;

int main()
{
    auto relop = get_filter_operator<int>("!=");
    cout << boolalpha << relop(1,0) << endl;
    cout << boolalpha << relop(1,1) << endl;

    return 0;
}

Now, you may wish to re-iterate your comment to @MohamadElghawi: 现在,您可能希望重申对@MohamadElghawi的评论:

Yeah, I knew that worked, but the problem is that I'm trying to return a thrust::binary_function, not from std 是的,我知道这行得通,但是问题是我想返回一个推力:: binary_function,而不是从std返回

That may be what you are trying to do, but it is the wrong thing to be trying to do and an impossible thing to do. 那可能就是您要尝试做的事情,但这是错误的尝试,也是不可能的事情。 Look at the definition of template<typename A1, typename A2, typename R> struct thrust::binary_function in <thrust/functional> and at the associated documentation. 查看<thrust/functional>template<typename A1, typename A2, typename R> struct thrust::binary_function和相关文档的定义。 Note: 注意:

binary_function is an empty base class: it contains no member functions or member variables, but only type information binary_function是一个空的基类:它不包含成员函数或成员变量,而仅包含类型信息

In particular, thrust::binary_function<A1,A2,R> has no operator() . 特别地, thrust::binary_function<A1,A2,R>没有operator() It is not callable. 它是不可调用的。 It cannot store any other callable object (or anything at all). 它不能存储任何其他可调用对象(或任何其他对象)。 See also the definitions of equal_to , not_equal_to , etc. in the same file. 另请参见同一文件中的equal_tonot_equal_to等的定义。 binary_function is not a even base of any of them. binary_function不是其中任何一个的偶数基数。 There is no conversion from any of them to binary_function . 没有任何转换到binary_function

Note too: 还要注意:

binary_function is currently redundant with the C++ STL type std::binary_function. Binary_function当前是冗余的,C ++ STL类型为std :: binary_function。 We reserve it here for potential additional functionality at a later date. 我们稍后将其保留在此处,以备将来使用。

( std::binary_function is itself deprecated as of C++11 and will be removed in C++17). std::binary_function本身在C ++ 11中已被弃用,并将在C ++ 17中删除)。

thrust::binary_function<T,T,bool> is not what you are looking for. thrust::binary_function<T,T,bool>不是您要找的东西。 std::function<bool(T, T)> is. std::function<bool(T, T)>是。

std::function<bool(int, int)> f = thrust::greater<int>(); 

makes f encapsulate a callable object that is a thrust::greater<int> 使f封装一个作为thrust::greater<int>的可调用对象thrust::greater<int>

Later 后来

The problem with this is that it can only be used in host code doesnt it? 问题是它只能在宿主代码中使用,不是吗? The beauty of thrust binary functions is that they can be used both in the GPU and the CPU. 推力二进制函数的优点在于它们可以在GPU和CPU中使用。

I think you may be under the impression that, eg 我认为您可能会觉得,例如

std::function<bool(int, int)> f = thrust::greater<int>();  /*A*/

takes a thrust::greater<int> and in some manner downgrades it into a std::function<bool(int, int)> that has similar but more restricted ("std") execution capabilities. 采取thrust::greater<int>并以某种方式降级std::function<bool(int, int)>具有类似但更受限制的(“ std”)执行功能。

Nothing like that is the case. 事实并非如此。 An std::function<bool(int, int)> foo is simply a receptacle for anything bar that is callable with two arguments that are implicitly convertible to int and returns something implicitly convertible to bool , such that if: std::function<bool(int, int)> foo只是任何bar的容器,该bar可通过两个可隐式转换为int并返回隐式转换为bool参数调用,例如:

std::function<bool(int, int)> foo = bar; 

then when you call foo(i,j) you are returned the result, as bool , of executing bar(i,j) . 然后,当您调用foo(i,j) ,以bool形式返回执行 bar(i,j) Not the result of executing anything that is in any way different from bar(i,j) . 不是执行任何与bar(i,j)不同的结果的结果。

Thus in /*A*/ above, the callable thing contained by, and called by, f is a thrust binary function; 因此,在上面的/*A*/f包含并被f调用的可调用事物推力二元函数; it is a thrust::greater<int>() . 是一个 thrust::greater<int>() The method that is invoked by the f 's operator() is thrust::greater<int>::operator() . foperator()调用的方法 thrust::greater<int>::operator()

Here is a program: 这是一个程序:

#include <thrust/functional.h>
#include <functional>
#include <iostream>

using namespace std;

int main()
{
    auto thrust_greater_than_int = thrust::greater<int>();
    std::function<bool(int, int)> f = thrust_greater_than_int;
    cout << "f " 
        << (f.target<thrust::greater<int>>() ? "calls" : "does not call") 
        << " a thrust::greater<int>" << endl;
    cout << "f " 
        << (f.target<thrust::equal_to<int>>() ? "calls" : "does not call") 
        << " a thrust::equal_to<int>" << endl;
    cout << "f " 
        << (f.target<std::greater<int>>() ? "calls" : "does not call") 
        << " an std::greater<int>" << endl;
    cout << "f " 
        << (f.target<std::function<bool(int,int)>>() ? "calls" : "does not call") 
        << " an std::function<bool(int,int)>" << endl;
    return 0;
}

that stores a thrust::greater<int> in a std::function<bool(int, int)> f and then informs you that: std::function<bool(int, int)> f中存储thrust::greater<int> ,然后通知您:

f calls a thrust::greater<int>
f does not call a thrust::equal_to<int>
f does not call an std::greater<int>
f does not call an std::function<bool(int,int)>

Even though there was no exact answer, I'm going to put here what I have ended up using, in case someone needs something similar. 即使没有确切的答案,如果有人需要类似的东西,我将把我最终使用的东西放在这里。

In a .cuh file 在.cuh文件中

#include <cuda.h>
#include <cuda_runtime_api.h>

namespace BinaryFunction
{
    enum class ComparisonOperator
    {
      equal_to,
      not_equal_to,
      greater,
      less,
      greater_equal,
      less_equal
    };

    enum class BitwiseOperator
    {
      bit_and,
      bit_or
    };

    template<typename T>
    struct CompareFunction
    {
      __host__ __device__ T operator()(const T &lhs, const T &rhs, ComparisonOperator &op) const
      {
            switch (op)
            {
                case ComparisonOperator::equal_to:
                    return lhs==rhs;
                case ComparisonOperator::not_equal_to:
                    return lhs!=rhs;
                case ComparisonOperator::greater:
                    return lhs>rhs;
                case ComparisonOperator::less:
                    return lhs<rhs;
                case ComparisonOperator::greater_equal:
                    return lhs>=rhs;
                case ComparisonOperator::less_equal:
                    return lhs<=rhs;

            }
        }
    };

    template<typename T>
    struct BitwiseFunction
    {
      __host__ __device__ T operator()(const T &lhs, const T &rhs, BitwiseOperator &op) const
      {
        if (op==BitwiseOperator::bit_and)
          return lhs & rhs;
        else if (op==BitwiseOperator::bit_or)
          return lhs | rhs;
      }
    };
}

Then use it like this: In the cpp file: 然后像这样使用它:在cpp文件中:

BinaryFunction::ComparisonOperator comp_op = BinaryFunction::ComparisonOperator::equal_to;

BinaryFunction::CompareFunction<int> comp_func;

And then, in the kernel or in a normal function: 然后,在内核或正常函数中:

int value_a;
int value_b;
comp_func(value_a, value_b, comp_op)

The following works for me. 以下对我有用。

#include <iostream>
#include <functional>

template<class T>
std::function<bool(T, T)> GetOperator(const std::string& op)
{
    if (op == "!=")
        return std::not_equal_to<T>();
    else if (op == ">")
        return std::greater<T>();
    else if (op == "<")
        return std::less<T>();
    else if (op == ">=")
        return std::greater_equal<T>();
    else if (op == "<=")
        return std::less_equal<T>();
    else
    {
        return std::equal_to<T>();
    }
}

int main()
{
    auto op = GetOperator<int>(">");
    std::cout << op(1, 2) << '\n';
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM