天天看點

分享一個 thrust 中的删除操作分享一個 thrust 中的删除操作

分享一個 thrust 中的删除操作

工作需要,目前已知資料有400w,最終資料大小隻有幾w,如何将400w資料根據條件快速删除至w級别

參考:

copy_if()

remove_copy_if()

remove_if()

remove_if()

函數原型[2]

ForwardIterator thrust::remove_if(ForwardIterator first, ForwardIterator last, Predicate pred)	
           

解釋:

remove_if

從[first, last) 範圍内删除每一個使謂詞 pred(x) 為真的元素,

remove_if

是穩定的,意味着被删除的元素的相對順序是不變的。值得注意的是:

remove_if

不會破壞任何疊代器,不會改變疊代器範圍。傳回的疊代器是元素被移除後指向結果範圍的末尾,此疊代器到末尾之間的元素将會是無意義的。

如果想真正删除,可以使用

S.erase(remove_if(S.begin(), S.end(), pred), S.end()))
           
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <thrust/remove.h>
#include <stdio.h>
#include <thrust/device_vector.h>

#define BLOCKSIZE 256

extern "C" {
	class tmpvec3 {
	public:
		float x, y, z;
		__host__ __device__
		tmpvec3() :x(0.0), y(0.0), z(0.0) {}
		__host__ __device__
		tmpvec3(float tx, float ty, float tz) : x(tx), y(ty), z(tz) {}
	};
}

struct is_empty_point
{
	__host__ __device__
		bool operator()(const tmpvec3 p)
	{
		return (p.x == 0 && p.y == 0 && p.z == 0);
	}
};

__global__ void changeValue(tmpvec3* vertices, int start, int end, float val)
{
	int index = blockIdx.x * blockDim.x + threadIdx.x;
	int stride = blockDim.x * gridDim.x;
	for (int tIndex = index; tIndex < end && tIndex >= start; tIndex += stride)
	{
		vertices[tIndex].x = val;
		vertices[tIndex].y = val;
		vertices[tIndex].z = val;
	}
}

int main()
{
	const int N = 6;
	thrust::device_vector<tmpvec3> test_data(4000000);
	tmpvec3* raw_ptr_data = thrust::raw_pointer_cast(&test_data[0]);
	int start = 40000, end = 50000;
	changeValue << <(end + BLOCKSIZE - 1) / BLOCKSIZE, BLOCKSIZE >> > (raw_ptr_data, start, end, 1.0);
	printf("before erase data size : %d \n", test_data.size());
	test_data.erase(thrust::remove_if(test_data.begin(), test_data.end(), is_empty_point()), test_data.end());
	printf("data size : %d\n", test_data.size());
	system("pause");
	return 0;
}
           
分享一個 thrust 中的删除操作分享一個 thrust 中的删除操作

remove_copy_if()

函數原型[2]

__host__ __device__ 
OutputIterator thrust::remove_copy_if(const thrust::detail::execution_policy_base<DerivedPolicy>& exec,
InputIterator first,
InputIterator last,
OutputIterator result,
Predicate pred 
)	
           

解釋:

remove_copy_if

将 [first, last) 範圍内中,除了謂詞為 true 的元素複制到結果中,這個操作是穩定的,也就是說順序不會改變。

// 和上一個例子相比僅改變了 main 函數
int main()
{
	const int N = 6;
	thrust::device_vector<tmpvec3> test_data(4000000);
	thrust::host_vector<tmpvec3> h_test_data(4000000);
	thrust::device_vector<tmpvec3> res_data(10000);
	thrust::host_vector<tmpvec3> h_res_data(10000);

	tmpvec3* raw_ptr_data = thrust::raw_pointer_cast(&test_data[0]);
	
	int start = 40000, end = 50000;
	changeValue << <(end + BLOCKSIZE - 1) / BLOCKSIZE, BLOCKSIZE >> > (raw_ptr_data, start, end, 1.0);
	thrust::copy(test_data.begin(), test_data.end(), h_test_data.begin());
	printf("before erase data size : %d  first data x: %f, y: %f, z: %f \n", test_data.size(), h_test_data[0].x, h_test_data[0].y, h_test_data[0].z);
	thrust::remove_copy_if(test_data.begin(), test_data.end(), res_data.begin(), is_empty_point());
	thrust::copy(res_data.begin(), res_data.end(), h_res_data.begin());
	printf("data size : %d  first data x: %f, y: %f, z: %f \n", res_data.size(), h_res_data[0].x, h_res_data[0].y, h_res_data[0].z);
	system("pause");
	return 0;
}

           
分享一個 thrust 中的删除操作分享一個 thrust 中的删除操作

這次将資料列印出來,可以看到複制前的資料[0]号元素值均為0,複制後的資料[0]号元素值均為1

copy_if()

函數原型 [2/4]

OutputIterator thrust::copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred)
           

**解釋:**這個版本的

copy_if

将元素從[first,last)範圍内複制到一個從結果開始的範圍内,但是任何導緻 pred 為false的元素都不會被複制。

int main()
{
	const int N = 6;
	thrust::device_vector<tmpvec3> test_data(4000000);
	thrust::host_vector<tmpvec3> h_test_data(4000000);
	thrust::device_vector<tmpvec3> res_data(3990000);
	thrust::host_vector<tmpvec3> h_res_data(3990000);

	tmpvec3* raw_ptr_data = thrust::raw_pointer_cast(&test_data[0]);
	
	int start = 40000, end = 50000;
	changeValue << <(end + BLOCKSIZE - 1) / BLOCKSIZE, BLOCKSIZE >> > (raw_ptr_data, start, end, 1.0);
	thrust::copy(test_data.begin(), test_data.end(), h_test_data.begin());
	printf("before erase data size : %d  first data x: %f, y: %f, z: %f \n", test_data.size(), h_test_data[0].x, h_test_data[0].y, h_test_data[0].z);
	thrust::copy_if(test_data.begin(), test_data.end(), res_data.begin(), is_empty_point());
	thrust::copy(res_data.begin(), res_data.end(), h_res_data.begin());
	printf("data size : %d  first data x: %f, y: %f, z: %f \n", res_data.size(), h_res_data[0].x, h_res_data[0].y, h_res_data[0].z);
	system("pause");
	return 0;
}
           
分享一個 thrust 中的删除操作分享一個 thrust 中的删除操作

看起來這個函數和

remove_copy_if()

對謂詞操作是相反的