Spaces:
Runtime error
Runtime error
| // This example illustrates use of the set operation algorithms | |
| // - merge | |
| // - set_union | |
| // - set_intersection | |
| // - set_difference | |
| // - set_symmetric_difference | |
| // | |
| // In this context a "set" is simply a sequence of sorted values, | |
| // allowing the standard set operations to be performed more efficiently | |
| // than on unsorted data. Since the output of a set operation is a valid | |
| // set (i.e. a sorted sequence) it is possible to apply the set operations | |
| // in a nested fashion to compute arbitrary set expressions. | |
| // | |
| // Set operation usage notes: | |
| // - The output set size is variable (except for thrust::merge), | |
| // so the return value is important. | |
| // - Generally one would conservatively allocate storage for the output | |
| // and then resize or shrink an output container as necessary. | |
| // Alternatively, one can compute the exact output size by | |
| // outputting to a discard_iterator. This approach is more computationally | |
| // expensive (approximately 2x), but conserves memory capacity. | |
| // Refer to the SetIntersectionSize function for implementation details. | |
| // - Sets are allowed to have duplicate elements, which are carried | |
| // through to the output in a algorithm-specific manner. Refer | |
| // to the full documentation for precise semantics. | |
| // helper routine | |
| template <typename String, typename Vector> | |
| void print(const String& s, const Vector& v) | |
| { | |
| std::cout << s << " ["; | |
| for(size_t i = 0; i < v.size(); i++) | |
| std::cout << " " << v[i]; | |
| std::cout << " ]\n"; | |
| } | |
| template <typename Vector> | |
| void Merge(const Vector& A, const Vector& B) | |
| { | |
| // merged output is always exactly A.size() + B.size() | |
| Vector C(A.size() + B.size()); | |
| thrust::merge(A.begin(), A.end(), B.begin(), B.end(), C.begin()); | |
| print("Merge(A,B)", C); | |
| } | |
| template <typename Vector> | |
| void SetUnion(const Vector& A, const Vector& B) | |
| { | |
| // union output is at most A.size() + B.size() | |
| Vector C(A.size() + B.size()); | |
| // set_union returns an iterator C_end denoting the end of input | |
| typename Vector::iterator C_end; | |
| C_end = thrust::set_union(A.begin(), A.end(), B.begin(), B.end(), C.begin()); | |
| // shrink C to exactly fit output | |
| C.erase(C_end, C.end()); | |
| print("Union(A,B)", C); | |
| } | |
| template <typename Vector> | |
| void SetIntersection(const Vector& A, const Vector& B) | |
| { | |
| // intersection output is at most min(A.size(), B.size()) | |
| Vector C(thrust::min(A.size(), B.size())); | |
| // set_union returns an iterator C_end denoting the end of input | |
| typename Vector::iterator C_end; | |
| C_end = thrust::set_intersection(A.begin(), A.end(), B.begin(), B.end(), C.begin()); | |
| // shrink C to exactly fit output | |
| C.erase(C_end, C.end()); | |
| print("Intersection(A,B)", C); | |
| } | |
| template <typename Vector> | |
| void SetDifference(const Vector& A, const Vector& B) | |
| { | |
| // difference output is at most A.size() | |
| Vector C(A.size()); | |
| // set_union returns an iterator C_end denoting the end of input | |
| typename Vector::iterator C_end; | |
| C_end = thrust::set_difference(A.begin(), A.end(), B.begin(), B.end(), C.begin()); | |
| // shrink C to exactly fit output | |
| C.erase(C_end, C.end()); | |
| print("Difference(A,B)", C); | |
| } | |
| template <typename Vector> | |
| void SetSymmetricDifference(const Vector& A, const Vector& B) | |
| { | |
| // symmetric difference output is at most A.size() + B.size() | |
| Vector C(A.size() + B.size()); | |
| // set_union returns an iterator C_end denoting the end of input | |
| typename Vector::iterator C_end; | |
| C_end = thrust::set_symmetric_difference(A.begin(), A.end(), B.begin(), B.end(), C.begin()); | |
| // shrink C to exactly fit output | |
| C.erase(C_end, C.end()); | |
| print("SymmetricDifference(A,B)", C); | |
| } | |
| template <typename Vector> | |
| void SetIntersectionSize(const Vector& A, const Vector& B) | |
| { | |
| // computes the exact size of the intersection without allocating output | |
| thrust::discard_iterator<> C_begin, C_end; | |
| C_end = thrust::set_intersection(A.begin(), A.end(), B.begin(), B.end(), C_begin); | |
| std::cout << "SetIntersectionSize(A,B) " << (C_end - C_begin) << std::endl; | |
| } | |
| int main(void) | |
| { | |
| int a[] = {0,2,4,5,6,8,9}; | |
| int b[] = {0,1,2,3,5,7,8}; | |
| thrust::device_vector<int> A(a, a + sizeof(a) / sizeof(int)); | |
| thrust::device_vector<int> B(b, b + sizeof(b) / sizeof(int)); | |
| print("Set A", A); | |
| print("Set B", B); | |
| Merge(A,B); | |
| SetUnion(A,B); | |
| SetIntersection(A,B); | |
| SetDifference(A,B); | |
| SetSymmetricDifference(A,B); | |
| SetIntersectionSize(A,B); | |
| return 0; | |
| } | |