头文件的定义
//filter.h
#ifndef __FILTER_HEADER__
#define __FILTER_HEADER__
#include <sstream>
#include <string>
#include <vector>
namespace ruda {
const int RUDA_ERR = -1;
const int RUDA_OK = 0;
enum CompOperator {
EQ = 0, LESS, GREATER, LESS_EQ, GREATER_EQ,
};
inline std::string toStringCompOperator(CompOperator op) {
switch (op) {
case EQ: return "EQ";
case LESS: return "LESS";
case GREATER: return "GREATER";
case LESS_EQ: return "LESS_EQ";
case GREATER_EQ: return "GREATER_EQ";
default: return "INVALID";
}
}
struct IntComparator {
CompOperator _op;
int _pivot;
std::string toString() const {
std::stringstream ss;
ss << "_op: " << toStringCompOperator(this->_op) << ", "
<< "_pivot: " << _pivot;
return ss.str();
}
};
int sstIntFilter(const std::vector<int>& values,
const IntComparator rawComp,
std::vector<bool>& results);
}
#endif
//filter.cu
#include "filter.h"
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/transform.h>
#include <thrust/functional.h>
#include <algorithm>
namespace ruda {
struct CudaIntComparator {
IntComparator _rawComp;
CudaIntComparator(IntComparator rawComp) {
this->_rawComp = rawComp;
}
__host__ __device__
bool operator()(const int target) {
switch (this->_rawComp._op) {
case EQ:
return target == this->_rawComp._pivot;
case LESS:
return target < this->_rawComp._pivot;
case GREATER:
return target > this->_rawComp._pivot;
case LESS_EQ:
return target <= this->_rawComp._pivot;
case GREATER_EQ:
return target >= this->_rawComp._pivot;
default:
return false;
}
}
std::string toString() {
return this->_rawComp.toString();
}
};
int sstIntFilter(const std::vector<int>& values,
const IntComparator rawComp,
std::vector<bool>& results) {
std::cout << "[RUDA][sstIntFilter] Start" << std::endl;
results.resize(values.size());
std::cout << "[sstIntFilter] Inputs" << std::endl;
std::cout << "[sstIntFilter] Inputs - values" << std::endl;
for (int i = 0; i < values.size(); ++i) {
std::cout << values[i] << " ";
}
std::cout << std::endl;
std::cout << "[sstIntFilter] Inputs - rawComp: " << rawComp.toString()
<< std::endl;
thrust::device_vector<int> d_values(values);
thrust::device_vector<int> d_results(values.size());
CudaIntComparator cudaComp(rawComp);
std::cout << "[sstIntFilter] Devices" << std::endl;
std::cout << "[sstIntFilter] Devices - d_values" << std::endl; //非并行的搬移数据到device
for (int i = 0; i < d_values.size(); ++i) {
std::cout << d_values[i] << " ";
}
std::cout << std::endl;
std::cout << "[sstIntFilter] cudaComp: " << cudaComp.toString() << std::endl;
thrust::copy_if(d_values.begin(), d_values.end(), d_results.begin(),
cudaComp); //条件复制,按照cudaComp复制符合条件的value到result
cudaDeviceSynchronize();
std::cout << "[sstIntFilter] Results" << std::endl;
std::cout << "[sstIntFilter] Results - d_results" << std::endl;
for (int i = 0; i < d_results.size(); ++i) {
std::cout << d_results[i] << " ";
}
std::cout << std::endl;
thrust::copy(d_results.begin(), d_results.end(), results.begin());
std::cout << "[sstIntFilter] Results - results" << std::endl;
for (int i = 0; i < results.size(); ++i) {
std::cout << results[i] << " ";
}
std::cout << std::endl;
return ruda::RUDA_OK;
}
}
//实现GPU上简单的int比较操作符
#include <iostream>
#include <vector>
#include "filter.h"
int main() {
std::cout << "[FILTER_TEST] Starts" << std::endl;
ruda::IntComparator comp = {
ruda::GREATER_EQ, 5,
};
std::vector<int> values{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<bool> results;
std::cout << "[FILTER_TEST] Run SST Filter" << std::endl;
ruda::sstIntFilter(values, comp, results);
std::cout << "[FILTER_TEST] Results" << std::endl;
for (int i = 0; i < results.size(); ++i) {
std::cout << results[i] << " ";
}
std::cout << std::endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(FilterProject)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
cuda_add_library(filter STATIC filter.cu)
add_executable(runnable_filter_test filter_test.cc)
target_link_libraries(runnable_filter_test filter ${CUDA_LIBRARIES})
输出