Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 0 additions & 49 deletions java/src/main/java/ai/rapids/cudf/ColumnVector.java
Original file line number Diff line number Diff line change
Expand Up @@ -819,42 +819,6 @@ public ColumnVector castTo(DType type) {
return super.castTo(type);
}

/**
* Replace the null mask of a column. The resultant null mask is the bitwise {@code mergeOp} of
* null masks in the columns given as arguments, AND-ed with this column's existing null mask.
*
* If applying the null mask would be a no-op, the original column is returned with incremented
* refcount. Otherwise, a deep copy of the column is made.
*
* For STRUCT columns the new mask is also pushed down into every descendant column, to
* stay consistent with the parent. For LIST/STRING columns the resultant offsets are
* sanitized to not contain any non-empty nulls.
*
* If {@code columns} is empty, the column is returned unchanged (no-op).
*
* @param mergeOp binary operator (either BITWISE_AND or BITWISE_OR)
* @param columns array of columns whose null masks are merged, must have identical number of rows.
* @return the new ColumnVector with merged null mask.
*/
@Override
public ColumnVector mergeAndSetValidity(BinaryOp mergeOp, ColumnView... columns) {
assert mergeOp == BinaryOp.BITWISE_AND || mergeOp == BinaryOp.BITWISE_OR : "Only BITWISE_AND and BITWISE_OR supported right now";
long[] columnViews = new long[columns.length];
long size = getRowCount();

for (int i = 0; i < columns.length; i++) {
assert columns[i] != null : "Column vectors passed may not be null";
assert columns[i].getRowCount() == size : "Row count mismatch, all columns must be the same size";
columnViews[i] = columns[i].getNativeView();
}

long mergeOutput = bitwiseMergeAndSetValidity(getNativeView(), columnViews, mergeOp.nativeId);
if (mergeOutput == 0) { // no-op, the current column is unchanged
return incRefCount();
}
return new ColumnVector(mergeOutput);
}

/////////////////////////////////////////////////////////////////////////////
// NATIVE METHODS
/////////////////////////////////////////////////////////////////////////////
Expand All @@ -878,19 +842,6 @@ private static native long makeListFromOffsets(long childHandle, long offsetsHan

private static native long concatenate(long[] viewHandles) throws CudfException;

/**
* Native method to replace a column's null mask. The null mask is the
* bitwise merge of the null masks in the columns given as arguments.
*
* @param baseHandle column view of the column whose null mask is being replaced.
* @param viewHandles array of views whose null masks are merged, must have identical row counts.
* @param mergeOp native id of the binary op (BITWISE_AND or BITWISE_OR) used to merge the null masks.
* @return native handle of the resulting column, or 0 when the original is unchanged
* (a no-op) and no copied column was produced.
*/
private static native long bitwiseMergeAndSetValidity(long baseHandle, long[] viewHandles,
int mergeOp) throws CudfException;

/**
* Native method to concatenate columns of lists horizontally (row by row), combining a row
* from each column into a single list.
Expand Down
12 changes: 6 additions & 6 deletions java/src/main/java/ai/rapids/cudf/ColumnView.java
Original file line number Diff line number Diff line change
Expand Up @@ -883,9 +883,9 @@ public final ColumnVector normalizeNANsAndZeros() {
* Replace the null mask of a column. The resultant null mask is the bitwise {@code mergeOp} of
* null masks in the columns given as arguments, AND-ed with this column's existing null mask.
*
* If applying the null mask would be a no-op, the original column is returned with incremented
* refcount. Otherwise, a deep copy of the column is made (for a non-owning ColumnView, a deep copy
* must be made in either case).
* If applying the null mask would be a no-op and this is a {@link ColumnVector}, the original
* column is returned with incremented refcount. Otherwise, a deep copy of the column is made.
* For a non-owning ColumnView, a deep copy must be made in either case.
*
* For STRUCT columns the new mask is also pushed down into every descendant column, to
* stay consistent with the parent. For LIST/STRING columns the resultant offsets are
Expand All @@ -896,10 +896,8 @@ public final ColumnVector normalizeNANsAndZeros() {
* @param mergeOp binary operator (either BITWISE_AND or BITWISE_OR)
* @param columns array of columns whose null masks are merged, must have identical number of rows.
* @return the new ColumnVector with merged null mask.
* @deprecated Use {@link ColumnVector#mergeAndSetValidity(BinaryOp, ColumnView...)} instead.
*/
@Deprecated
public ColumnVector mergeAndSetValidity(BinaryOp mergeOp, ColumnView... columns) {
public final ColumnVector mergeAndSetValidity(BinaryOp mergeOp, ColumnView... columns) {
assert mergeOp == BinaryOp.BITWISE_AND || mergeOp == BinaryOp.BITWISE_OR : "Only BITWISE_AND and BITWISE_OR supported right now";
long[] columnViews = new long[columns.length];
long size = getRowCount();
Expand All @@ -912,6 +910,8 @@ public ColumnVector mergeAndSetValidity(BinaryOp mergeOp, ColumnView... columns)

long mergeOutput = bitwiseMergeAndSetValidity(getNativeView(), columnViews, mergeOp.nativeId);
if (mergeOutput == 0) { // no-op, the current column is unchanged
// For a ColumnVector, copyToColumnVector() is simply an incRefCount(), making this
// zero-copy. Otherwise for a ColumnView, we must materialize an owning column.
return copyToColumnVector();
}
return new ColumnVector(mergeOutput);
Expand Down
53 changes: 0 additions & 53 deletions java/src/main/native/src/ColumnVectorJni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
#include "dtype_utils.hpp"
#include "jni_utils.hpp"

#include <cudf/binaryop.hpp>
#include <cudf/column/column_factories.hpp>
#include <cudf/concatenate.hpp>
#include <cudf/copying.hpp>
#include <cudf/detail/structs/utilities.hpp>
#include <cudf/filling.hpp>
#include <cudf/hashing.hpp>
#include <cudf/interop.hpp>
Expand All @@ -22,7 +20,6 @@
#include <cudf/scalar/scalar_factories.hpp>
#include <cudf/strings/combine.hpp>
#include <cudf/utilities/bit.hpp>
#include <cudf/utilities/default_stream.hpp>
#include <cudf/utilities/memory_resource.hpp>

#include <arrow/api.h>
Expand Down Expand Up @@ -432,56 +429,6 @@ JNIEXPORT jlong JNICALL Java_ai_rapids_cudf_ColumnVector_sha1(JNIEnv* env,
JNI_CATCH(env, 0);
}

JNIEXPORT jlong JNICALL Java_ai_rapids_cudf_ColumnVector_bitwiseMergeAndSetValidity(
JNIEnv* env, jobject j_object, jlong base_column, jlongArray column_handles, jint bin_op)
{
JNI_NULL_CHECK(env, base_column, "base column native handle is null", 0);
JNI_NULL_CHECK(env, column_handles, "array of column handles is null", 0);
JNI_TRY
{
cudf::jni::auto_set_device(env);
cudf::column_view* original_column = reinterpret_cast<cudf::column_view*>(base_column);
cudf::jni::native_jpointerArray<cudf::column_view> n_cudf_columns(env, column_handles);

auto const op = static_cast<cudf::binary_operator>(bin_op);
if (op != cudf::binary_operator::BITWISE_AND && op != cudf::binary_operator::BITWISE_OR) {
JNI_THROW_NEW(env, cudf::jni::ILLEGAL_ARG_EXCEPTION_CLASS, "Unsupported merge operation", 0);
}

// If we have no columns to merge, return the original column unchanged.
// 0 signals to the caller that this was a no-op.
if (n_cudf_columns.size() == 0) { return 0; }

// Merge the null masks of the provided columns using the binary op.
auto const cudf_columns = n_cudf_columns.get_dereferenced();
auto const input_table = cudf::table_view{cudf_columns};
auto [merge_mask, merge_null_count] = op == cudf::binary_operator::BITWISE_AND
? cudf::bitmask_and(input_table)
: cudf::bitmask_or(input_table);

// If the merge null count is 0, the merged mask is all-valid - either the binop returned
// an empty mask or the mask was allocated but had no nulls.
// in either case this is a no-op on the original mask and we can return as-is.
if (merge_null_count == 0) { return 0; }

auto copy = std::make_unique<cudf::column>(*original_column);

// Now apply the merged mask to the original by AND-ing it into
// the parent's null mask. This will also push it down through any
// descendants for STRUCTs so that child masks stay consistent ,
// and fix offsets for LIST/STRINGs by purging non-empty nulls.
auto result = cudf::structs::detail::superimpose_and_sanitize_nulls(
static_cast<cudf::bitmask_type const*>(merge_mask.data()),
merge_null_count,
std::move(copy),
cudf::get_default_stream(),
cudf::get_current_device_resource_ref());

return release_as_jlong(result);
}
JNI_CATCH(env, 0);
}

////////
// Native methods specific to cudf::column. These either take or return a cudf::column
// instead of a cudf::column_view so they need to be used with caution. These should
Expand Down
Loading