@@ -42,7 +42,7 @@ namespace cuco {
4242 * - Host-side "bulk" operations
4343 * - Device-side "singular" operations
4444 *
45- * The host-side bulk operations include ` add`, ` contains` , etc. These APIs should be used when
45+ * The host-side bulk operations include add(), contains() , etc. These APIs should be used when
4646 * there are a large number of keys to add or lookup. For example, given a range of keys
4747 * specified by device-accessible iterators, the bulk `add` function will add all keys into
4848 * the filter.
@@ -124,7 +124,7 @@ class bloom_filter {
124124 * @brief Erases all information from the filter.
125125 *
126126 * @note This function synchronizes the given stream. For asynchronous execution use
127- * ` clear_async` .
127+ * clear_async() .
128128 *
129129 * @param stream CUDA stream used for device memory operations and kernel launches
130130 */
@@ -142,7 +142,7 @@ class bloom_filter {
142142 * @brief Adds all keys in the range `[first, last)` to the filter.
143143 *
144144 * @note This function synchronizes the given stream. For asynchronous execution use
145- * ` add_async` .
145+ * add_async() .
146146 *
147147 * @tparam InputIt Device-accessible random access input key iterator
148148 * @param first Beginning of the sequence of keys
@@ -173,7 +173,7 @@ class bloom_filter {
173173 *
174174 * @note The key `*(first + i)` is added if `pred( *(stencil + i) )` returns `true`.
175175 * @note This function synchronizes the given stream and returns the number of successful
176- * insertions. For asynchronous execution use ` add_if_async` .
176+ * insertions. For asynchronous execution use add_if_async() .
177177 *
178178 * @tparam InputIt Device-accessible random access input key iterator
179179 * @tparam StencilIt Device-accessible random-access iterator whose `value_type` is
@@ -227,7 +227,7 @@ class bloom_filter {
227227 * filter.
228228 *
229229 * @note This function synchronizes the given stream. For asynchronous execution use
230- * ` contains_async` .
230+ * contains_async() .
231231 *
232232 * @tparam InputIt Device-accessible random access input key iterator
233233 * @tparam OutputIt Device-accessible output iterator assignable from `bool`
@@ -269,7 +269,7 @@ class bloom_filter {
269269 *
270270 * @note The key `*(first + i)` is queried if `pred( *(stencil + i) )` returns `true`.
271271 * @note This function synchronizes the given stream. For asynchronous execution use
272- * ` contains_if_async` .
272+ * contains_if_async() .
273273 *
274274 * @tparam InputIt Device-accessible random access input key iterator
275275 * @tparam StencilIt Device-accessible random-access iterator whose `value_type` is
@@ -325,6 +325,91 @@ class bloom_filter {
325325 cuda::stream_ref stream = cuda::stream_ref{
326326 cudaStream_t{nullptr }}) const noexcept ;
327327
328+ /* *
329+ * @brief Merge another bloom filter into this.
330+ *
331+ * @note Modifies `this` in place.
332+ * @note This function synchronizes the given stream. For asynchronous execution use
333+ * merge_async().
334+ *
335+ * @note This performs the set union of the two filters. Let \f$f : X \to B\f$ denote the
336+ * construction of a bloom filter on some set \f$X\f$, and let \f$A\f$ and \f$B\f$ be two sets,
337+ * then it holds that \f$f(A \cup B) = f(A) \cup f(B)\f$.
338+ *
339+ * @param other Other filter with matching type to this. The policy object must be equal to that
340+ * of this filter, otherwise behavior is undefined.
341+ * @param stream CUDA stream used for device memory operations and kernel launches.
342+ *
343+ * @throws cuco::logic_error If the other filter does not have the same number of blocks as this.
344+ */
345+ __host__ constexpr void merge (bloom_filter<Key, Extent, Scope, Policy, Allocator> const & other,
346+ cuda::stream_ref stream = cuda::stream_ref{cudaStream_t{nullptr }});
347+
348+ /* *
349+ * @brief Asynchronously merge another bloom filter into this.
350+ *
351+ * @note Modifies `this` in place.
352+ *
353+ * @note This performs the set union of the two filters. Let \f$f : X \to B\f$ denote the
354+ * construction of a bloom filter on some set \f$X\f$, and let \f$A\f$ and \f$B\f$ be two sets,
355+ * then it holds that \f$f(A \cup B) = f(A) \cup f(B)\f$
356+ *
357+ * @param other Other filter with matching type to this. The policy object must be equal to that
358+ * of this filter, otherwise behavior is undefined.
359+ * @param stream CUDA stream used for device memory operations and kernel launches.
360+ *
361+ * @throws cuco::logic_error If the other filter does not have the same number of blocks as this.
362+ */
363+ __host__ constexpr void merge_async (
364+ bloom_filter<Key, Extent, Scope, Policy, Allocator> const & other,
365+ cuda::stream_ref stream = cuda::stream_ref{cudaStream_t{nullptr }});
366+
367+ /* *
368+ * @brief Intersect another bloom filter into this.
369+ *
370+ * @note Modifies `this` in place.
371+ * @note This function synchronizes the given stream. For asynchronous execution use
372+ * intersect_async().
373+ *
374+ * @note This performs the set intersection of the two filters. Unlike merge(), this operation
375+ * does not distribute over filter construction and therefore only approximates the bloom filter
376+ * of the intersection of the input sets. In other words, let \f$f : X \to B\f$ denote the
377+ * construction of a bloom filter on some set \f$X\f$, and let \f$A\f$ and \f$B\f$ be two sets,
378+ * then \f$(A \cap B) \ne f(A) \cap f(B)\f$. Despite this, it is guaranteed that for all \f$x \in
379+ * (A \cap B)\f$, it holds \f$x \in f(A) \cap f(B)\f$.
380+ *
381+ * @param other Other filter with matching type to this. The policy object must be equal to that
382+ * of this filter, otherwise behavior is undefined.
383+ * @param stream CUDA stream used for device memory operations and kernel launches.
384+ *
385+ * @throws cuco::logic_error If the other filter does not have the same number of blocks as this.
386+ */
387+ __host__ constexpr void intersect (
388+ bloom_filter<Key, Extent, Scope, Policy, Allocator> const & other,
389+ cuda::stream_ref stream = cuda::stream_ref{cudaStream_t{nullptr }});
390+
391+ /* *
392+ * @brief Asynchronously intersect another bloom filter into this.
393+ *
394+ * @note Modifies `this` in place.
395+ *
396+ * @note This performs the set intersection of the two filters. Unlike merge_async(), this
397+ * operation does not distribute over filter construction and therefore only approximates the
398+ * bloom filter of the intersection of the input sets. In other words, let \f$f : X \to B\f$
399+ * denote the construction of a bloom filter on some set \f$X\f$, and let \f$A\f$ and \f$B\f$ be
400+ * two sets, then \f$(A \cap B) \ne f(A) \cap f(B)\f$. Despite this, it is guaranteed that for
401+ * all \f$x \in (A \cap B)\f$, it holds \f$x \in f(A) \cap f(B)\f$.
402+ *
403+ * @param other Other filter with matching type to this. The policy object must be equal to that
404+ * of this filter, otherwise behavior is undefined.
405+ * @param stream CUDA stream used for device memory operations and kernel launches.
406+ *
407+ * @throws cuco::logic_error If the other filter does not have the same number of blocks as this.
408+ */
409+ __host__ constexpr void intersect_async (
410+ bloom_filter<Key, Extent, Scope, Policy, Allocator> const & other,
411+ cuda::stream_ref stream = cuda::stream_ref{cudaStream_t{nullptr }});
412+
328413 /* *
329414 * @brief Gets a pointer to the underlying filter storage.
330415 *
@@ -369,4 +454,4 @@ class bloom_filter {
369454};
370455} // namespace cuco
371456
372- #include < cuco/detail/bloom_filter/bloom_filter.inl>
457+ #include < cuco/detail/bloom_filter/bloom_filter.inl>
0 commit comments