| 61 | |
| 62 | template<typename T> |
| 63 | Array<T> setUnion(const Array<T> &first, const Array<T> &second, |
| 64 | const bool is_unique) { |
| 65 | try { |
| 66 | Array<T> unique_first = first; |
| 67 | Array<T> unique_second = second; |
| 68 | |
| 69 | if (!is_unique) { |
| 70 | unique_first = setUnique(first, false); |
| 71 | unique_second = setUnique(second, false); |
| 72 | } |
| 73 | |
| 74 | size_t out_size = unique_first.elements() + unique_second.elements(); |
| 75 | Array<T> out = createEmptyArray<T>(dim4(out_size, 1, 1, 1)); |
| 76 | |
| 77 | compute::command_queue queue(getQueue()()); |
| 78 | |
| 79 | compute::buffer first_data((*unique_first.get())()); |
| 80 | compute::buffer second_data((*unique_second.get())()); |
| 81 | compute::buffer out_data((*out.get())()); |
| 82 | |
| 83 | compute::buffer_iterator<type_t<T>> first_begin(first_data, 0); |
| 84 | compute::buffer_iterator<type_t<T>> first_end(first_data, |
| 85 | unique_first.elements()); |
| 86 | compute::buffer_iterator<type_t<T>> second_begin(second_data, 0); |
| 87 | compute::buffer_iterator<type_t<T>> second_end( |
| 88 | second_data, unique_second.elements()); |
| 89 | compute::buffer_iterator<type_t<T>> out_begin(out_data, 0); |
| 90 | |
| 91 | compute::buffer_iterator<type_t<T>> out_end = compute::set_union( |
| 92 | first_begin, first_end, second_begin, second_end, out_begin, queue); |
| 93 | |
| 94 | out.resetDims(dim4(std::distance(out_begin, out_end), 1, 1, 1)); |
| 95 | return out; |
| 96 | |
| 97 | } catch (const std::exception &ex) { AF_ERROR(ex.what(), AF_ERR_INTERNAL); } |
| 98 | } |
| 99 | |
| 100 | template<typename T> |
| 101 | Array<T> setIntersect(const Array<T> &first, const Array<T> &second, |